diff --git a/src/server/base-path-logout-integration.test.ts b/src/server/base-path-logout-integration.test.ts new file mode 100644 index 00000000..6ac77e7e --- /dev/null +++ b/src/server/base-path-logout-integration.test.ts @@ -0,0 +1,420 @@ +import { RequestCookies, ResponseCookies } from "@edge-runtime/cookies"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { Auth0Client } from "./client.js"; +import { deleteChunkedCookie, deleteCookie } from "./cookies.js"; +import { StatelessSessionStore } from "./session/stateless-session-store.js"; +import { TransactionStore } from "./transaction-store.js"; + +describe("Base path and cookie configuration tests", () => { + let originalEnv: NodeJS.ProcessEnv; + + beforeEach(() => { + originalEnv = { ...process.env }; + vi.clearAllMocks(); + vi.resetModules(); + // Clear any existing environment variables + delete process.env.NEXT_PUBLIC_BASE_PATH; + delete process.env.AUTH0_COOKIE_PATH; + }); + + afterEach(() => { + process.env = originalEnv; + vi.restoreAllMocks(); + delete process.env.NEXT_PUBLIC_BASE_PATH; + delete process.env.AUTH0_COOKIE_PATH; + }); + + describe("Logout integration with base paths", () => { + it("should reproduce the bug scenario: cookies set with base path should be deleted with same path", async () => { + // Set up environment with base path + process.env.NEXT_PUBLIC_BASE_PATH = "/dashboard"; + + // Create Auth0Client which should auto-detect the base path + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com/dashboard", + secret: "test-secret-that-is-long-enough-for-jwt" + }); + + // Get the session store + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + + // Verify that the session store has the correct path configuration + expect((sessionStore as any).cookieConfig.path).toBe("/dashboard"); + + // Simulate cookie deletion during logout + const mockResCookies = new ResponseCookies(new Headers()); + const mockReqCookies = new RequestCookies(new Headers()) as any; + + // Mock the get method to simulate an existing session cookie + mockReqCookies.get = () => ({ value: "mock-session-value" }); + mockReqCookies.getAll = () => []; + + // Call delete method (this would be called during logout) + await sessionStore.delete(mockReqCookies, mockResCookies); + + // Verify that the cookie deletion header includes the correct path + const cookieHeader = mockResCookies.toString(); + + // The cookie should be deleted with the same path it was set with + expect(cookieHeader).toContain("Path=/dashboard"); + expect(cookieHeader).toContain("Max-Age=0"); + }); + + it("should work correctly without base path (backward compatibility)", async () => { + // No base path set + delete process.env.NEXT_PUBLIC_BASE_PATH; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com", + secret: "test-secret-that-is-long-enough-for-jwt" + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + + // Should default to root path + expect((sessionStore as any).cookieConfig.path).toBe("/"); + + // Test deletion + const mockResCookies = new ResponseCookies(new Headers()); + const mockReqCookies = new RequestCookies(new Headers()) as any; + + mockReqCookies.get = () => ({ value: "mock-session-value" }); + mockReqCookies.getAll = () => []; + + await sessionStore.delete(mockReqCookies, mockResCookies); + + const cookieHeader = mockResCookies.toString(); + + // Should use root path or no path specified + expect(cookieHeader).toContain("Max-Age=0"); + }); + + it("should prioritize explicit cookie path over base path", async () => { + process.env.NEXT_PUBLIC_BASE_PATH = "/dashboard"; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com", + secret: "test-secret-that-is-long-enough-for-jwt", + session: { + cookie: { + path: "/custom-path" + } + } + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + + // Should use the explicit path, not the base path + expect((sessionStore as any).cookieConfig.path).toBe("/custom-path"); + }); + }); + + describe("Cookie deletion functions", () => { + let mockResCookies: ResponseCookies; + + beforeEach(() => { + // Create a mock ResponseCookies object + const mockHeaders = new Headers(); + mockResCookies = new ResponseCookies(mockHeaders); + }); + + it("should delete cookie with default path when no path is specified", () => { + deleteCookie(mockResCookies, "test-cookie"); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("test-cookie="); + expect(cookieHeader).toContain("Max-Age=0"); + expect(cookieHeader).toContain("Path=/"); + }); + + it("should delete cookie with specified path", () => { + deleteCookie(mockResCookies, "test-cookie", "/dashboard"); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("test-cookie="); + expect(cookieHeader).toContain("Max-Age=0"); + expect(cookieHeader).toContain("Path=/dashboard"); + }); + + it("should delete cookie with root path explicitly", () => { + deleteCookie(mockResCookies, "test-cookie", "/"); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("test-cookie="); + expect(cookieHeader).toContain("Max-Age=0"); + expect(cookieHeader).toContain("Path=/"); + }); + + it("should handle chunked cookie deletion with path", () => { + const mockReqCookies = { + getAll: () => [ + { name: "test-cookie__0", value: "chunk1" }, + { name: "test-cookie__1", value: "chunk2" } + ] + } as any; + + deleteChunkedCookie( + "test-cookie", + mockReqCookies, + mockResCookies, + false, + "/dashboard" + ); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("test-cookie="); + expect(cookieHeader).toContain("Path=/dashboard"); + expect(cookieHeader).toContain("test-cookie__0="); + expect(cookieHeader).toContain("test-cookie__1="); + }); + }); + + describe("Auth0Client constructor base path auto-detection", () => { + it("should use NEXT_PUBLIC_BASE_PATH for cookie paths when configured", () => { + process.env.NEXT_PUBLIC_BASE_PATH = "/dashboard"; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com" + }); + + // Access private properties through any casting for testing + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + const transactionStore = (client as any) + .transactionStore as TransactionStore; + + expect((sessionStore as any).cookieConfig.path).toBe("/dashboard"); + expect((transactionStore as any).cookieConfig.path).toBe("/dashboard"); + }); + + it("should use explicit AUTH0_COOKIE_PATH over base path", () => { + process.env.NEXT_PUBLIC_BASE_PATH = "/dashboard"; + process.env.AUTH0_COOKIE_PATH = "/custom"; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com" + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + expect((sessionStore as any).cookieConfig.path).toBe("/custom"); + }); + + it("should use client options over environment variables", () => { + process.env.NEXT_PUBLIC_BASE_PATH = "/dashboard"; + process.env.AUTH0_COOKIE_PATH = "/custom"; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com", + session: { + cookie: { + path: "/explicit" + } + }, + transactionCookie: { + path: "/txn-explicit" + } + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + const transactionStore = (client as any) + .transactionStore as TransactionStore; + + expect((sessionStore as any).cookieConfig.path).toBe("/explicit"); + expect((transactionStore as any).cookieConfig.path).toBe("/txn-explicit"); + }); + + it("should default to root path when no base path is configured", () => { + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com" + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + const transactionStore = (client as any) + .transactionStore as TransactionStore; + + expect((sessionStore as any).cookieConfig.path).toBe("/"); + expect((transactionStore as any).cookieConfig.path).toBe("/"); + }); + }); + + describe("Session store cookie deletion with paths", () => { + it("should delete session cookies with configured path during logout", async () => { + const mockReqCookies = { + get: vi.fn().mockReturnValue({ value: "encrypted-session" }), + getAll: vi.fn().mockReturnValue([]) + } as any; + + const mockResCookies = new ResponseCookies(new Headers()); + + const sessionStore = new StatelessSessionStore({ + secret: "test-secret", + cookieOptions: { + name: "__session", + path: "/dashboard" + } + }); + + await sessionStore.delete(mockReqCookies, mockResCookies); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("__session="); + expect(cookieHeader).toContain("Max-Age=0"); + expect(cookieHeader).toContain("Path=/dashboard"); + }); + }); + + describe("Transaction store cookie deletion with paths", () => { + it("should delete transaction cookies with configured path", async () => { + const mockResCookies = new ResponseCookies(new Headers()); + + const transactionStore = new TransactionStore({ + secret: "test-secret", + cookieOptions: { + path: "/dashboard" + } + }); + + await transactionStore.delete(mockResCookies, "test-state"); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("__txn_test-state="); + expect(cookieHeader).toContain("Max-Age=0"); + expect(cookieHeader).toContain("Path=/dashboard"); + }); + + it("should delete all transaction cookies with configured path", async () => { + const mockReqCookies = { + getAll: () => [ + { name: "__txn_state1", value: "value1" }, + { name: "__txn_state2", value: "value2" }, + { name: "other-cookie", value: "other" } + ] + } as any; + + const mockResCookies = new ResponseCookies(new Headers()); + + const transactionStore = new TransactionStore({ + secret: "test-secret", + cookieOptions: { + path: "/dashboard" + } + }); + + await transactionStore.deleteAll(mockReqCookies, mockResCookies); + + const cookieHeader = mockResCookies.toString(); + expect(cookieHeader).toContain("__txn_state1="); + expect(cookieHeader).toContain("__txn_state2="); + expect(cookieHeader).toContain("Max-Age=0"); + expect(cookieHeader).toContain("Path=/dashboard"); + expect(cookieHeader).not.toContain("other-cookie=; Max-Age=0"); + }); + }); + + describe("Edge Cases", () => { + it("should handle nested base paths correctly", () => { + process.env.NEXT_PUBLIC_BASE_PATH = "/app/dashboard"; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com" + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + expect((sessionStore as any).cookieConfig.path).toBe("/app/dashboard"); + }); + + it("should handle base path with trailing slash", () => { + process.env.NEXT_PUBLIC_BASE_PATH = "/dashboard/"; + + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com" + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + expect((sessionStore as any).cookieConfig.path).toBe("/dashboard/"); + }); + + it("should handle empty path correctly", () => { + deleteCookie(new ResponseCookies(new Headers()), "test-cookie", ""); + + // Should not throw and should create valid cookie deletion + expect(true).toBe(true); + }); + }); + + describe("Backward Compatibility", () => { + it("should maintain existing behavior when no base path is configured", () => { + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com" + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + const transactionStore = (client as any) + .transactionStore as TransactionStore; + + // Should default to root path as before + expect((sessionStore as any).cookieConfig.path).toBe("/"); + expect((transactionStore as any).cookieConfig.path).toBe("/"); + }); + + it("should not break existing explicit cookie configurations", () => { + const client = new Auth0Client({ + domain: "test.auth0.com", + clientId: "test-client-id", + clientSecret: "test-client-secret", + appBaseUrl: "https://app.example.com", + session: { + cookie: { + path: "/legacy-path", + name: "legacy-session" + } + } + }); + + const sessionStore = (client as any) + .sessionStore as StatelessSessionStore; + expect((sessionStore as any).cookieConfig.path).toBe("/legacy-path"); + expect((sessionStore as any).sessionCookieName).toBe("legacy-session"); + }); + }); +}); diff --git a/src/server/chunked-cookies.test.ts b/src/server/chunked-cookies.test.ts index 1c5c35fe..091c3520 100644 --- a/src/server/chunked-cookies.test.ts +++ b/src/server/chunked-cookies.test.ts @@ -170,7 +170,8 @@ describe("Chunked Cookie Utils", () => { // Check removal of non-chunked cookie expect(resCookies.set).toHaveBeenCalledWith(name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); }); @@ -193,13 +194,16 @@ describe("Chunked Cookie Utils", () => { expect(resCookies.set).toHaveBeenCalledTimes(4); expect(resCookies.set).toHaveBeenNthCalledWith(1, name, value, options); expect(resCookies.set).toHaveBeenNthCalledWith(2, `${name}__1`, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(resCookies.set).toHaveBeenNthCalledWith(3, `${name}__0`, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(resCookies.set).toHaveBeenNthCalledWith(4, `${name}__2`, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(reqCookies.set).toHaveBeenCalledTimes(1); expect(reqCookies.set).toHaveBeenCalledWith(name, value); @@ -244,7 +248,8 @@ describe("Chunked Cookie Utils", () => { options ); expect(resCookies.set).toHaveBeenNthCalledWith(4, name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(reqCookies.set).toHaveBeenCalledTimes(3); }); @@ -335,7 +340,8 @@ describe("Chunked Cookie Utils", () => { expect.objectContaining({ domain: "example.com" }) ); expect(resCookies.set).toHaveBeenNthCalledWith(4, name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); }); @@ -405,7 +411,8 @@ describe("Chunked Cookie Utils", () => { expectedOptions ); expect(resCookies.set).toHaveBeenNthCalledWith(4, name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(resCookies.set).not.toHaveBeenCalledWith( expect.any(String), @@ -478,7 +485,8 @@ describe("Chunked Cookie Utils", () => { expectedOptions ); expect(resCookies.set).toHaveBeenNthCalledWith(4, name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); }); @@ -552,7 +560,8 @@ describe("Chunked Cookie Utils", () => { deleteChunkedCookie(name, reqCookies, resCookies); expect(resCookies.set).toHaveBeenCalledWith(name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); }); @@ -572,20 +581,25 @@ describe("Chunked Cookie Utils", () => { // Should delete main cookie and 3 chunks expect(resCookies.set).toHaveBeenCalledTimes(4); expect(resCookies.set).toHaveBeenCalledWith(name, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(resCookies.set).toHaveBeenCalledWith(`${name}__0`, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(resCookies.set).toHaveBeenCalledWith(`${name}__1`, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); expect(resCookies.set).toHaveBeenCalledWith(`${name}__2`, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); // Should not delete unrelated cookies expect(resCookies.set).not.toHaveBeenCalledWith("otherCookie", "", { - maxAge: 0 + maxAge: 0, + path: "/" }); }); }); diff --git a/src/server/client.ts b/src/server/client.ts index bbbc6549..fc7948c6 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -226,6 +226,9 @@ export class Auth0Client { options.clientAssertionSigningAlg || process.env.AUTH0_CLIENT_ASSERTION_SIGNING_ALG; + // Auto-detect base path for cookie configuration + const basePath = process.env.NEXT_PUBLIC_BASE_PATH; + const sessionCookieOptions: SessionCookieOptions = { name: options.session?.cookie?.name ?? "__session", secure: @@ -236,7 +239,10 @@ export class Auth0Client { (process.env.AUTH0_COOKIE_SAME_SITE as "lax" | "strict" | "none") ?? "lax", path: - options.session?.cookie?.path ?? process.env.AUTH0_COOKIE_PATH ?? "/", + options.session?.cookie?.path ?? + process.env.AUTH0_COOKIE_PATH ?? + basePath ?? + "/", transient: options.session?.cookie?.transient ?? process.env.AUTH0_COOKIE_TRANSIENT === "true", @@ -247,7 +253,7 @@ export class Auth0Client { prefix: options.transactionCookie?.prefix ?? "__txn_", secure: options.transactionCookie?.secure ?? false, sameSite: options.transactionCookie?.sameSite ?? "lax", - path: options.transactionCookie?.path ?? "/" + path: options.transactionCookie?.path ?? basePath ?? "/" }; if (appBaseUrl) { diff --git a/src/server/cookies.ts b/src/server/cookies.ts index f734ca0a..2a303cca 100644 --- a/src/server/cookies.ts +++ b/src/server/cookies.ts @@ -226,7 +226,7 @@ export function setChunkedCookie( // When we are writing a non-chunked cookie, we should remove the chunked cookies getAllChunkedCookies(reqCookies, name).forEach((cookieChunk) => { - deleteCookie(resCookies, cookieChunk.name); + deleteCookie(resCookies, cookieChunk.name, finalOptions.path); reqCookies.delete(cookieChunk.name); }); @@ -256,13 +256,13 @@ export function setChunkedCookie( for (let i = 0; i < chunksToRemove; i++) { const chunkIndexToRemove = chunkIndex + i; const chunkName = `${name}${CHUNK_PREFIX}${chunkIndexToRemove}`; - deleteCookie(resCookies, chunkName); + deleteCookie(resCookies, chunkName, finalOptions.path); reqCookies.delete(chunkName); } } // When we have written chunked cookies, we should remove the non-chunked cookie - deleteCookie(resCookies, name); + deleteCookie(resCookies, name, finalOptions.path); reqCookies.delete(name); } @@ -328,13 +328,14 @@ export function deleteChunkedCookie( name: string, reqCookies: RequestCookies, resCookies: ResponseCookies, - isLegacyCookie?: boolean + isLegacyCookie?: boolean, + path?: string ): void { // Delete main cookie - deleteCookie(resCookies, name); + deleteCookie(resCookies, name, path); getAllChunkedCookies(reqCookies, name, isLegacyCookie).forEach((cookie) => { - deleteCookie(resCookies, cookie.name); // Delete each filtered cookie + deleteCookie(resCookies, cookie.name, path); // Delete each filtered cookie }); } @@ -357,8 +358,13 @@ export function addCacheControlHeadersForSession(res: NextResponse): void { res.headers.set("Expires", "0"); } -export function deleteCookie(resCookies: ResponseCookies, name: string) { +export function deleteCookie( + resCookies: ResponseCookies, + name: string, + path?: string +) { resCookies.set(name, "", { - maxAge: 0 // Ensure the cookie is deleted immediately + maxAge: 0, // Ensure the cookie is deleted immediately + path: path || "/" }); } diff --git a/src/server/session/stateful-session-store.test.ts b/src/server/session/stateful-session-store.test.ts index 6f8302cd..5df23b6d 100644 --- a/src/server/session/stateful-session-store.test.ts +++ b/src/server/session/stateful-session-store.test.ts @@ -759,7 +759,8 @@ describe("Stateful Session Store", async () => { await sessionStore.set(requestCookies, responseCookies, session); expect(responseCookies.set).toHaveBeenCalledWith(LEGACY_COOKIE_NAME, "", { - maxAge: 0 + maxAge: 0, + path: "/" }); }); diff --git a/src/server/session/stateful-session-store.ts b/src/server/session/stateful-session-store.ts index a3aaa3d5..c0ddd5c3 100644 --- a/src/server/session/stateful-session-store.ts +++ b/src/server/session/stateful-session-store.ts @@ -168,7 +168,11 @@ export class StatefulSessionStore extends AbstractSessionStore { this.sessionCookieName !== LEGACY_COOKIE_NAME && reqCookies.has(LEGACY_COOKIE_NAME) ) { - cookies.deleteCookie(resCookies, LEGACY_COOKIE_NAME); + cookies.deleteCookie( + resCookies, + LEGACY_COOKIE_NAME, + this.cookieConfig.path + ); } } @@ -177,7 +181,11 @@ export class StatefulSessionStore extends AbstractSessionStore { resCookies: cookies.ResponseCookies ) { const cookieValue = reqCookies.get(this.sessionCookieName)?.value; - cookies.deleteCookie(resCookies, this.sessionCookieName); + cookies.deleteCookie( + resCookies, + this.sessionCookieName, + this.cookieConfig.path + ); if (!cookieValue) { return; diff --git a/src/server/session/stateless-session-store.test.ts b/src/server/session/stateless-session-store.test.ts index 7c136cae..8345a48c 100644 --- a/src/server/session/stateless-session-store.test.ts +++ b/src/server/session/stateless-session-store.test.ts @@ -447,7 +447,8 @@ describe("Stateless Session Store", async () => { LEGACY_COOKIE_NAME, "", { - maxAge: 0 + maxAge: 0, + path: "/" } ); }); @@ -488,25 +489,25 @@ describe("Stateless Session Store", async () => { 1, "__session", expect.any(String), - expect.not.objectContaining({ maxAge: 0 }) + expect.not.objectContaining({ maxAge: 0, path: "/" }) ); expect(responseCookies.set).toHaveBeenNthCalledWith( 2, LEGACY_COOKIE_NAME, "", - { maxAge: 0 } + { maxAge: 0, path: "/" } ); expect(responseCookies.set).toHaveBeenNthCalledWith( 3, `${LEGACY_COOKIE_NAME}.0`, "", - { maxAge: 0 } + { maxAge: 0, path: "/" } ); expect(responseCookies.set).toHaveBeenNthCalledWith( 4, `${LEGACY_COOKIE_NAME}.1`, "", - { maxAge: 0 } + { maxAge: 0, path: "/" } ); }); }); @@ -784,14 +785,15 @@ describe("Stateless Session Store", async () => { 1, "__session", expect.any(String), - expect.not.objectContaining({ maxAge: 0 }) + expect.not.objectContaining({ maxAge: 0, path: "/" }) ); expect(setSpy).toHaveBeenNthCalledWith( 2, legacyCookiesInSetup[0].name, "", { - maxAge: 0 + maxAge: 0, + path: "/" } ); }); diff --git a/src/server/session/stateless-session-store.ts b/src/server/session/stateless-session-store.ts index c5089cbe..38cb68dc 100644 --- a/src/server/session/stateless-session-store.ts +++ b/src/server/session/stateless-session-store.ts @@ -140,7 +140,8 @@ export class StatelessSessionStore extends AbstractSessionStore { LEGACY_COOKIE_NAME, reqCookies, resCookies, - true + true, + this.cookieConfig.path ); } @@ -148,10 +149,16 @@ export class StatelessSessionStore extends AbstractSessionStore { reqCookies: cookies.RequestCookies, resCookies: cookies.ResponseCookies ) { - cookies.deleteChunkedCookie(this.sessionCookieName, reqCookies, resCookies); + cookies.deleteChunkedCookie( + this.sessionCookieName, + reqCookies, + resCookies, + false, + this.cookieConfig.path + ); this.getConnectionTokenSetsCookies(reqCookies).forEach((cookie) => - cookies.deleteCookie(resCookies, cookie.name) + cookies.deleteCookie(resCookies, cookie.name, this.cookieConfig.path) ); } diff --git a/src/server/transaction-store.ts b/src/server/transaction-store.ts index 3c520ed8..33eebddd 100644 --- a/src/server/transaction-store.ts +++ b/src/server/transaction-store.ts @@ -118,7 +118,11 @@ export class TransactionStore { } async delete(resCookies: cookies.ResponseCookies, state: string) { - cookies.deleteCookie(resCookies, this.getTransactionCookieName(state)); + cookies.deleteCookie( + resCookies, + this.getTransactionCookieName(state), + this.cookieConfig.path + ); } /** @@ -131,7 +135,7 @@ export class TransactionStore { const txnPrefix = this.getCookiePrefix(); reqCookies.getAll().forEach((cookie) => { if (cookie.name.startsWith(txnPrefix)) { - cookies.deleteCookie(resCookies, cookie.name); + cookies.deleteCookie(resCookies, cookie.name, this.cookieConfig.path); } }); }