Open
Conversation
Add database schema for client session storage. This table stores cookie-based session data for JS SDK clients, linking session cookies to OAuth tokens stored server-side.
Add functions to manage cookie settings stored in the config table: - cookie_same_site: strict (default), lax, none - cookie_secure: auto (default), always, never - cookie_domain: optional domain for subdomain sharing
Add CRUD operations for client_session table: - insert: create new session - get: lookup by session_id - touch: update last_activity_at - update_auth: set user_did and atp_session_id after OAuth - delete: remove session (logout) - delete_expired: cleanup inactive sessions
Add session management module for cookie-based authentication: - generate_session_id: cryptographically secure session IDs - set_session_cookie: configurable HTTP-only cookies from DB settings - get_session_id: retrieve session ID from signed cookie - clear_session_cookie: logout - get_session_info: resolve session to user info - get_session_access_token: get token for authenticated requests - verify_dpop_jkt: ensure DPoP key matches session - create_session/destroy_session: session lifecycle
Add REST endpoints for session management: - POST /api/client/session: create session after OAuth - GET /api/client/session: get current session status - DELETE /api/client/session: logout (destroy session)
Wire up /api/client/session endpoint to the client session handler.
Update GraphQL handler to support both auth methods: 1. Cookie-based (primary): session cookie + DPoP for JS SDK v2+ 2. Authorization header (fallback): for backward compatibility Auth is checked in order: cookie first, then header.
Add admin UI configuration for client session cookies: - CookieSettings type with sameSite, secure, domain fields - CookieSameSite enum (STRICT, LAX, NONE) - CookieSecure enum (AUTO, ALWAYS, NEVER) - cookieSettings query (admin only) - updateCookieSettings mutation (admin only)
Add client-side session management for cookie-based auth: - createSession: POST to server after OAuth to get session cookie - getSession: GET current session status - destroySession: DELETE session (logout) - computeJkt: compute JWK thumbprint for DPoP binding
Remove token storage since tokens are now stored server-side. Keep only OAuth flow state: - clientId (localStorage) - codeVerifier, oauthState, redirectUri (sessionStorage)
Update handleOAuthCallback to create server-side session instead of storing tokens locally. Update logout to destroy server session.
Update client to use session cookies instead of client-side tokens: - graphqlRequest: use credentials: 'include' for cookie auth - isAuthenticated: query server session status - getUser: return session info including handle - handleRedirectCallback: return SessionInfo - Remove getAccessToken (tokens are server-side now) - Export SessionInfo type
Delete tokens.ts and lock.ts since token storage is now server-side. Multi-tab coordination is handled by the shared session cookie.
- Use token_generator.current_timestamp() instead of executor method - Use request.get_header for header access - Fix optional_field decoder syntax - Remove unused imports - Fix linter formatting issues
Rebuild dist after cookie-based auth changes.
Add comprehensive test coverage for the new cookie-based auth system: - client_session repository: CRUD operations, session expiry - config cookie helpers: parsing, validation, database storage - client_session handler: REST API endpoints (POST/GET/DELETE) - client_session module: session ID generation, creation - GraphQL cookie settings types
Closed
The SQLite migration existed but the Postgres variant was missing, causing session creation to fail with a 500 error on Supabase.
The token endpoint was not returning session_id in the JSON response, causing client_session rows to be created with atp_session_id = NULL. This broke the cookie → client_session → access_token → viewer chain.
4 tasks
The cookie-based auth PR added a DELETE /api/client/session endpoint but the CORS config was never updated to allow DELETE requests, causing logout to fail from cross-origin clients.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I've made significant structural changes to the auth system to enable using cookies for auth instead of storing them in the browser. This enables the JS client to be used in server-side contexts, as well as prevents a lot of XSS issues.
DPoP tokens remain in the browser only. This means server-side requests are limited to non-authenticated queries, but it allows the client to appropriately provide proof-of-possession.
I did add tests for the changes, but there's a lot of changes here and I'm still brand new to Gleam. A thorough review would be a very good idea. 😅