Skip to content

Add cookie-based auth#8

Open
trezy wants to merge 24 commits intobigmoves:mainfrom
gamesgamesgamesgamesgames:feat/cookie-based-auth
Open

Add cookie-based auth#8
trezy wants to merge 24 commits intobigmoves:mainfrom
gamesgamesgamesgamesgames:feat/cookie-based-auth

Conversation

@trezy
Copy link
Contributor

@trezy trezy commented Feb 4, 2026

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. 😅

trezy added 20 commits January 23, 2026 16:53
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
@trezy trezy mentioned this pull request Feb 4, 2026
trezy added 2 commits February 6, 2026 18:14
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.
trezy added 2 commits February 7, 2026 02:05
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant