feat(graphql-server): Cookie Lifecycle & CSRF Enforcement#1041
Open
theothersideofgod wants to merge 9 commits intomainfrom
Open
feat(graphql-server): Cookie Lifecycle & CSRF Enforcement#1041theothersideofgod wants to merge 9 commits intomainfrom
theothersideofgod wants to merge 9 commits intomainfrom
Conversation
- Add AuthSettings interface for cookie configuration - Add cookie.ts with session/device cookie helpers: - buildCookieOptions() - builds Express cookie options from settings - setSessionCookie() / clearSessionCookie() - setDeviceTokenCookie() / clearDeviceTokenCookie() - Support rememberMe for extended session duration - Parse PostgreSQL interval format for durations Refs: constructive-io/constructive-planning#749 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Intercept auth mutation responses (signIn, signUp, signOut, etc.) - Set constructive_session cookie on successful authentication - Clear session cookie on signOut/revokeSession - Set constructive_device_token cookie for device tracking - Support rememberMe from mutation input variables Refs: constructive-io/constructive-planning#749 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add sessions_module query to get auth_settings table location - Add queryAuthSettings() to fetch settings from tenant DB - Update toApiStructure() to include authSettings - Load auth settings in parallel with RLS module Refs: constructive-io/constructive-planning#749 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add cookie-parser and @constructive-io/csrf dependencies - Add CSRF middleware with double-submit cookie pattern - Skip CSRF check for Bearer token authentication - Add auth-cookie middleware to intercept responses - Add CSRF error codes to SAFE_ERROR_CODES allowlist Refs: constructive-io/constructive-planning#749 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add cookie.test.ts with 9 tests for cookie helpers - Add auth-cookie.test.ts with 13 tests for middleware - Test session cookie set/clear on auth mutations - Test device token cookie handling - Test rememberMe duration extension Refs: constructive-io/constructive-planning#749 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Test Bearer token authentication skips CSRF - Test GET/HEAD/OPTIONS requests skip CSRF - Test anonymous requests (no session cookie) skip CSRF - Test cookie-authenticated requests require valid CSRF token - Test CSRF token validation (missing, invalid, valid) - Test CSRF token from header and body Refs: constructive-io/constructive-planning#749 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The captcha middleware references this property, so it needs to be included in the AuthSettings type definition. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…v plugin - Replace Express middleware with grafserv processRequest plugin - Fix cookie handling for grafserv streaming responses (buffer parsing) - Handle multiple Set-Cookie headers correctly (array format) - Preserve CSRF cookies when setting session cookies - Fix rememberMe cookie duration logic - Remove old middleware and tests (will add plugin tests separately) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Test preset structure and plugin metadata - Test session cookie on auth mutations (signIn, signUp, etc.) - Test cookie clearing on sign out mutations - Test device token cookie handling - Test CSRF cookie preservation - Test buffer and JSON response handling - Test mutation detection regex patterns Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
7263419 to
8b29938
Compare
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.
Summary
Implements server-side cookie management for authentication flows, addressing #749.
constructive_sessioncookie on successful auth mutations (signIn, signUp, SSO, MFA, etc.)Why grafserv Plugin Instead of Express Middleware?
Initially attempted to implement this using Express middleware, but encountered architectural limitations:
Express middleware approach (doesn't work):
The problem: PostGraphile v5 (grafserv) uses streaming responses. The response is serialized to a buffer internally by grafserv and written directly to the stream — it never passes through
res.json(). Express middleware cannot intercept this.grafserv plugin approach (correct solution):
This allows us to modify headers before grafserv sends the response, correctly setting cookies at the right layer.
Key Changes
New Files
graphql/server/src/plugins/auth-cookie-plugin.ts- grafserv plugin for cookie lifecyclegraphql/server/src/plugins/__tests__/auth-cookie-plugin.test.ts- 25 unit testsModified Files
graphql/server/src/middleware/graphile.ts- Wire AuthCookiePreset into PostGraphilegraphql/server/src/middleware/cookie.ts- Fix rememberMe duration logicgraphql/server/src/server.ts- Remove old Express middlewareRemoved Files
graphql/server/src/middleware/auth-cookie.ts- Old Express middleware (didn't work with grafserv streaming)graphql/server/src/middleware/__tests__/auth-cookie.test.ts- Old testsCookie Behavior
constructive_sessioncookie (+constructive_device_tokenif returned)Cookie Attributes
HttpOnly: true(XSS protection)SameSite: Lax(CSRF protection)Path: /MaxAge: 1 hour default, 30 days withrememberMe: trueTest Plan
Related
Closes #749
🤖 Generated with Claude Code