Share session cookies across www and app subdomains

Groundwork for moving the app to app.qrmaster.net: the session has to survive the
host change from www.qrmaster.net to app.qrmaster.net.

- Add COOKIE_DOMAIN and apply it to the auth, CSRF, attribution and OAuth flow
  cookies. Honoured only in production, because browsers reject dotted domains on
  localhost - a prod .env copied into a dev environment would otherwise break
  every login instead of just ignoring the value.
- Expire both the host-only and the domain-scoped variant on logout. Next's
  ResponseCookies is keyed by cookie name and rewrites the entire set-cookie
  header from its internal map on every set(), so the two variants must be
  appended manually - otherwise one overwrites the other and the surviving stale
  cookie keeps the user signed in.
- Pass COOKIE_DOMAIN as both build arg and runtime env: process.env is inlined
  into the Edge middleware bundle, so a runtime-only value would leave the
  middleware and the route handlers disagreeing about the cookie scope.

No behaviour change while COOKIE_DOMAIN is unset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-12 19:01:14 +02:00
parent e3276f5943
commit 35ea8cc3e9
8 changed files with 423 additions and 92 deletions

View File

@@ -6,6 +6,7 @@ import {
serializeAttributionCookie,
} from '@/lib/revops';
import { verifySignedUserIdEdge } from '@/lib/session-edge';
import { getCookieDomain } from '@/lib/cookieConfig';
const isProduction = process.env.NODE_ENV === 'production';
@@ -37,6 +38,7 @@ function attachAttributionCookie(req: NextRequest, response: NextResponse) {
sameSite: 'lax',
path: '/',
maxAge: 60 * 60 * 24 * 90,
domain: getCookieDomain(),
});
return response;