Files
familysync/.planning/quick/260610-k1z-persist-oidc-session-cookie-with-maxage-/260610-k1z-SUMMARY.md
T

3.3 KiB


phase: 260610-k1z plan: 01 subsystem: auth tags: [oidc, session, cookie, pwa, persistence] dependency_graph: requires: [@hono/oidc-auth oidcAuthJwt context var] provides: [persistSessionCookie middleware, AUTH-02] affects: [apps/api/src/index.ts] tech_stack: added: [] patterns: [hono-middleware, cookie-upgrade] key_files: created: - apps/api/src/auth/persistSessionCookie.ts - apps/api/tests/auth/persistSessionCookie.test.ts modified: - apps/api/src/index.ts decisions:

  • "Set-before-next ordering: cookie re-issued before await next() so any future downstream logout/delete wins as the last Set-Cookie"
  • "Guard on c.get('oidcAuthJwt'): falsy path does nothing — no resurrection of deleted/absent cookies"
  • "Conditional domain: domain key absent (not undefined) when OIDC_COOKIE_DOMAIN unset — mirrors library logic" metrics: duration: ~5m completed: "2026-06-10T18:32:47Z" tasks_completed: 2 files_changed: 3

Phase 260610-k1z Plan 01: Persist OIDC Session Cookie with Max-Age Summary

One-liner: Hono middleware that upgrades the session-scoped oidc-auth cookie (no maxAge) set by @hono/oidc-auth to a persistent cookie with Max-Age, SameSite=Lax, guarded to never resurrect absent/deleted cookies.

What Was Built

persistSessionCookie() is a thin Hono MiddlewareHandler mounted immediately after oidcAuthMiddleware() in index.ts (inside the !devBypassActive block). It reads c.get('oidcAuthJwt') — a context key set by @hono/oidc-auth only on requests where a valid session was created or refreshed — and re-issues the same signed JWT as a persistent Set-Cookie (adding Max-Age + SameSite=Lax). When oidcAuthJwt is falsy (logged-out, no session, unauthenticated), it is a pure passthrough: no cookie is emitted.

Tasks Completed

Task Name Commit Files
1 Create persistSessionCookie() middleware aabcb5d apps/api/src/auth/persistSessionCookie.ts
2 Wire into index.ts + unit tests 8343fad apps/api/src/index.ts, apps/api/tests/auth/persistSessionCookie.test.ts

Verification Results

typecheck

$ pnpm --filter @familysync/api typecheck
$ tsc --noEmit
(exit 0 — no output)

vitest run tests/auth/

 RUN  v4.1.8 /home/luc/Projects/familysync/apps/api

 Test Files  3 passed (3)
      Tests  14 passed (14)
   Start at  14:32:33
   Duration  2.45s (transform 162ms, setup 1.74s, import 142ms, tests 152ms, environment 0ms)

All 3 auth test files pass (devBypass, user, persistSessionCookie). 14/14 tests green including:

  • Test A (persist path): truthy oidcAuthJwt → Set-Cookie with Max-Age, SameSite=Lax, HttpOnly, Secure
  • Test B (guard path): absent oidcAuthJwt → no oidc-auth Set-Cookie emitted
  • Guard variant: empty string oidcAuthJwt → no resurrection

Deviations from Plan

None — plan executed exactly as written.

Known Stubs

None.

Threat Flags

None. The new middleware only re-issues a cookie that @hono/oidc-auth already set; it does not open new network endpoints or auth paths.

Self-Check: PASSED

  • apps/api/src/auth/persistSessionCookie.ts exists
  • apps/api/tests/auth/persistSessionCookie.test.ts exists
  • apps/api/src/index.ts contains persistSessionCookie()
  • Commit aabcb5d exists
  • Commit 8343fad exists
  • typecheck exits 0
  • vitest tests/auth/ all pass