From ac9791c8ef2726586d5dfa843107285a4955b2dc Mon Sep 17 00:00:00 2001 From: Stefan Lazic Date: Fri, 4 Sep 2026 22:53:35 +0100 Subject: [PATCH] cookie handling --- .../management/__tests__/management-auth.test.ts | 1 + src/services/management/management-auth.ts | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/services/management/__tests__/management-auth.test.ts b/src/services/management/__tests__/management-auth.test.ts index f5b5282..ec16328 100644 --- a/src/services/management/__tests__/management-auth.test.ts +++ b/src/services/management/__tests__/management-auth.test.ts @@ -35,6 +35,7 @@ describe("Manager session cookie", () => { expect.any(String), expect.objectContaining({ secure: false, path: "/" }), ); + expect(cookieSet).toHaveBeenCalledWith("nextchair_manager_session", "", { path: "/manager", maxAge: 0 }); }); it("marks the cookie Secure for an HTTPS deployment", async () => { diff --git a/src/services/management/management-auth.ts b/src/services/management/management-auth.ts index c3960e7..67a5ec6 100644 --- a/src/services/management/management-auth.ts +++ b/src/services/management/management-auth.ts @@ -25,7 +25,11 @@ export function authenticateManager(email: string, password: string) { export async function createManagerSession() { const config = getManagerConfig(); const value = `${config.adminEmail.trim().toLowerCase()}.${Date.now()}`; - (await cookies()).set(COOKIE_NAME, `${value}.${signature(value, config.authSecret)}`, { + const store = await cookies(); + // Remove sessions issued by older builds with Path=/manager. Browsers can + // retain both cookies, and the stale one may be selected first on /manager. + store.set(COOKIE_NAME, "", { path: "/manager", maxAge: 0 }); + store.set(COOKIE_NAME, `${value}.${signature(value, config.authSecret)}`, { httpOnly: true, sameSite: "strict", secure: isSecureDeployment(), @@ -37,7 +41,9 @@ export async function createManagerSession() { } export async function clearManagerSession() { - (await cookies()).delete(COOKIE_NAME); + const store = await cookies(); + store.delete(COOKIE_NAME); + store.set(COOKIE_NAME, "", { path: "/manager", maxAge: 0 }); } export async function isManagerAuthenticated() {