fix: make impersonation cookies session-only

This commit is contained in:
Linus Rath
2026-05-16 18:59:46 +02:00
parent 482493a10d
commit 3a559479bd
+12 -4
View File
@@ -2,7 +2,7 @@ import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers'; import { cookies } from 'next/headers';
import { logger } from '@/lib/logger'; import { logger } from '@/lib/logger';
import { encryptSession } from '@/lib/auth/crypto'; import { encryptSession } from '@/lib/auth/crypto';
import { SESSION_COOKIE_MAX_AGE, sessionCookieName } from '@/lib/auth/session-cookie'; import { sessionCookieName } from '@/lib/auth/session-cookie';
import { getCookieOptions } from '@/lib/oauth/cookie-config'; import { getCookieOptions } from '@/lib/oauth/cookie-config';
import { normalizeJmapServerUrl } from '@/lib/auth/verify-jmap-auth'; import { normalizeJmapServerUrl } from '@/lib/auth/verify-jmap-auth';
import { setStalwartAuthContextInStore } from '@/lib/stalwart/auth-context'; import { setStalwartAuthContextInStore } from '@/lib/stalwart/auth-context';
@@ -21,8 +21,16 @@ export const runtime = 'nodejs';
const IMPERSONATION_SLOT = 0; const IMPERSONATION_SLOT = 0;
function sessionCookieOptions() { /**
return { ...getCookieOptions(), maxAge: SESSION_COOKIE_MAX_AGE }; * Impersonation cookies deliberately omit Max-Age so the browser treats
* them as session cookies — the impersonated session ends when the user
* closes the browser, not 30 days later. Impersonation is a temporary
* support handoff; a normal password login is the only thing that should
* survive a browser restart.
*/
function impersonationCookieOptions() {
const { maxAge: _maxAge, ...rest } = getCookieOptions();
return rest;
} }
/** /**
@@ -97,7 +105,7 @@ export async function GET(request: NextRequest) {
impersonatedUsername, impersonatedUsername,
config.masterPassword, config.masterPassword,
); );
cookieStore.set(sessionCookieName(IMPERSONATION_SLOT), sessionToken, sessionCookieOptions()); cookieStore.set(sessionCookieName(IMPERSONATION_SLOT), sessionToken, impersonationCookieOptions());
setStalwartAuthContextInStore(cookieStore, IMPERSONATION_SLOT, { setStalwartAuthContextInStore(cookieStore, IMPERSONATION_SLOT, {
serverUrl: normalizedServerUrl, serverUrl: normalizedServerUrl,
username: impersonatedUsername, username: impersonatedUsername,