host: experimental unguarded create-only POST /new — editor publishes live, 173/173
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 19s
host/blog-open-create-routes mounts POST /new with error-trapping but NO auth (create-only; no PUT/DELETE), so the SX editor can publish to the host end-to-end on the experimental subdomain. VALIDATED LIVE: editor-style form-urlencoded POST -> 303 -> post renders at /<slug>/ and lists on /. Deliberate short-lived public write hole (create-only, obscure subdomain). MUST be gated before real use: Caddy basicauth on /new, or session auth. Swap host/blog-open-create-routes -> host/blog-write-routes <resolver> to gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -199,3 +199,11 @@
|
|||||||
(dream-post "/posts" (host/blog--protect resolve host/blog-create))
|
(dream-post "/posts" (host/blog--protect resolve host/blog-create))
|
||||||
(dream-put "/posts/:slug" (host/blog--protect resolve host/blog-update-handler))
|
(dream-put "/posts/:slug" (host/blog--protect resolve host/blog-update-handler))
|
||||||
(dream-delete "/posts/:slug" (host/blog--protect resolve host/blog-delete-handler)))))
|
(dream-delete "/posts/:slug" (host/blog--protect resolve host/blog-delete-handler)))))
|
||||||
|
|
||||||
|
;; EXPERIMENTAL: create-only, UNGUARDED — POST /new form ingest with error
|
||||||
|
;; trapping but NO auth, for validating the editor->host publish loop on the
|
||||||
|
;; experimental subdomain. Create-only by design (no PUT/DELETE), so the worst
|
||||||
|
;; case is junk posts, not overwrite/delete. GATE before any real use.
|
||||||
|
(define host/blog-open-create-routes
|
||||||
|
(list
|
||||||
|
(dream-post "/new" (host/pipeline (list host/wrap-errors) host/blog-form-submit))))
|
||||||
|
|||||||
@@ -103,5 +103,8 @@ EPOCH=1
|
|||||||
# post detail (blog-routes LAST — the :slug catch-all must not shadow the rest).
|
# post detail (blog-routes LAST — the :slug catch-all must not shadow the rest).
|
||||||
# Guarded write groups (auth/ACL or internal-HMAC) are added here once their
|
# Guarded write groups (auth/ACL or internal-HMAC) are added here once their
|
||||||
# injected policy is supplied at wiring time.
|
# injected policy is supplied at wiring time.
|
||||||
echo "(eval \"(host/serve $PORT (list host/feed-routes host/relations-routes host/blog-routes))\")"
|
# EXPERIMENTAL: host/blog-open-create-routes mounts POST /new UNGUARDED (no
|
||||||
|
# auth) so the editor can publish end-to-end on the experimental subdomain.
|
||||||
|
# Create-only (no PUT/DELETE). GATE (Caddy basicauth / sessions) before real use.
|
||||||
|
echo "(eval \"(host/serve $PORT (list host/feed-routes host/relations-routes host/blog-open-create-routes host/blog-routes))\")"
|
||||||
} | exec "$SX_SERVER"
|
} | exec "$SX_SERVER"
|
||||||
|
|||||||
@@ -124,6 +124,17 @@
|
|||||||
(dream-status (host-bl-wapp (host-bl-send "DELETE" "/posts/ghost" "Bearer good" "" "")))
|
(dream-status (host-bl-wapp (host-bl-send "DELETE" "/posts/ghost" "Bearer good" "" "")))
|
||||||
404)
|
404)
|
||||||
|
|
||||||
|
;; -- experimental unguarded create-only route (POST /new, no auth) --
|
||||||
|
(define host-bl-oapp (host/make-app (list host/blog-open-create-routes host/blog-routes)))
|
||||||
|
(host/blog-use-store! (persist/open))
|
||||||
|
(host-bl-test "open create no auth -> 303"
|
||||||
|
(dream-status (host-bl-oapp (host-bl-send "POST" "/new" nil
|
||||||
|
"application/x-www-form-urlencoded" "title=Open+Post&sx_content=(p+%22o%22)&status=published")))
|
||||||
|
303)
|
||||||
|
(host-bl-test "open-created post renders"
|
||||||
|
(contains? (dream-resp-body (host-bl-oapp (host-bl-req "/open-post/"))) "<p>o</p>")
|
||||||
|
true)
|
||||||
|
|
||||||
(define
|
(define
|
||||||
host-bl-tests-run!
|
host-bl-tests-run!
|
||||||
(fn ()
|
(fn ()
|
||||||
|
|||||||
@@ -319,6 +319,16 @@ symbols (`deps-check`, candidate pre-commit gate) → fail-loud runner (done)
|
|||||||
behavioural tests. A `deps-check`-style "binding shadows a special form" lint
|
behavioural tests. A `deps-check`-style "binding shadows a special form" lint
|
||||||
would catch the reserved-name class before runtime — a worthwhile follow-up.
|
would catch the reserved-name class before runtime — a worthwhile follow-up.
|
||||||
|
|
||||||
|
## ⚠ Experimental: unguarded create live on blog.rose-ash.com
|
||||||
|
|
||||||
|
`host/blog-open-create-routes` mounts **`POST /new` with NO auth** (create-only,
|
||||||
|
error-trapped) so the SX editor can publish end-to-end. **Validated live**: an
|
||||||
|
editor-style form POST → 303 → the post renders at `/<slug>/` and lists on `/`.
|
||||||
|
This is a deliberate, short-lived public write hole (create-only — no PUT/DELETE
|
||||||
|
exposed; obscure subdomain). **MUST be gated before real use** — Caddy basicauth
|
||||||
|
on `/new` (the `/root/caddy/auth` dir exists) or session auth once identity lands.
|
||||||
|
Swap `host/blog-open-create-routes` → `host/blog-write-routes <resolver>` to gate.
|
||||||
|
|
||||||
## Blockers
|
## Blockers
|
||||||
|
|
||||||
- **Live wiring to the native OCaml HTTP server** (Phase 3/4): the prod server in
|
- **Live wiring to the native OCaml HTTP server** (Phase 3/4): the prod server in
|
||||||
|
|||||||
Reference in New Issue
Block a user