host: live writes via signed sessions + kernel multi-Set-Cookie (193/193)
Unblock the guarded blog write routes for browsers: a login form sets a signed session cookie that the same routes accept (alongside Bearer), so publishing works end-to-end on blog.rose-ash.com without Quart. - kernel: http-listen emit serialises a response :set-cookies LIST as one Set-Cookie header each (a headers dict can't hold more than one). Purely additive — responses without :set-cookies are unchanged. - server.sx: host/-dream->native forwards :set-cookies to the native resp. - lib/host/session.sx: durable, signed sessions on the persist KV (session/create|exists|get|set|clear), wired via dream-sessions-signed. - lib/host/auth.sx: GET/POST /login + POST /logout; host/require-user accepts a session principal OR a Bearer token. - router.sx: host/make-app wraps the whole app in the session middleware and auto-mounts /login + /logout — the front door always has sessions. - blog.sx: write routes use host/require-user; serve.sh flips POST /new from the experimental UNGUARDED route to the guarded write routes, with admin creds + signing secret + ACL grant from the container env. - session conformance suite (12): login->cookie->guarded write 201; no cookie/forged/logged-out -> 401; Bearer fallback still works. Verified live on blog.rose-ash.com: 401 unauthenticated, 303 login, 303 publish, anonymous read renders, post persists across container recreate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -850,6 +850,18 @@ let setup_evaluator_bridge env =
|
||||
List.iter (fun (k, v) ->
|
||||
Buffer.add_string buf
|
||||
(Printf.sprintf "%s: %s\r\n" k v)) rhdrs;
|
||||
(* Cookies: a response carries :set-cookies as a LIST of pre-formatted
|
||||
cookie strings (Dream's dream-set-cookie), because a headers Dict
|
||||
cannot hold more than one Set-Cookie. Emit one header per item. *)
|
||||
(match getk "set-cookies" with
|
||||
| Some (List items) ->
|
||||
List.iter (fun v ->
|
||||
match v with
|
||||
| String s ->
|
||||
Buffer.add_string buf
|
||||
(Printf.sprintf "Set-Cookie: %s\r\n" s)
|
||||
| _ -> ()) items
|
||||
| _ -> ());
|
||||
if not (List.exists
|
||||
(fun (k, _) ->
|
||||
String.lowercase_ascii k = "content-type")
|
||||
|
||||
Reference in New Issue
Block a user