fix: Fix embedded tokens not persisting across sessions (#7860)

This commit is contained in:
Michael Genson
2026-07-08 15:13:42 -05:00
committed by GitHub
parent 7bc19beb70
commit 5d1f9ff72a
2 changed files with 89 additions and 4 deletions

View File

@@ -0,0 +1,81 @@
import { describe, expect, test, vi, beforeEach, afterEach } from "vitest";
import { getTokenCookieOptions } from "./use-token-cookie";
function setLocation(protocol: string) {
Object.defineProperty(window, "location", {
value: { ...window.location, protocol },
configurable: true,
writable: true,
});
}
function setFramed(framed: boolean) {
Object.defineProperty(window, "top", {
value: framed ? ({} as Window) : window,
configurable: true,
});
}
function stubNuxtApp(production: boolean) {
vi.stubGlobal("useNuxtApp", () => ({
$appInfo: { production, tokenTime: 48 },
}));
}
describe("getTokenCookieOptions", () => {
beforeEach(() => {
setFramed(false);
});
afterEach(() => {
vi.unstubAllGlobals();
});
test("top-level https connection gets a lax, non-partitioned cookie", () => {
stubNuxtApp(true);
setLocation("https:");
setFramed(false);
const options = getTokenCookieOptions();
expect(options.secure).toBe(true);
expect(options.sameSite).toBe("lax");
expect(options.partitioned).toBe(false);
});
test("iframe-embedded https connection gets a none, partitioned cookie", () => {
stubNuxtApp(true);
setLocation("https:");
setFramed(true);
const options = getTokenCookieOptions();
expect(options.secure).toBe(true);
expect(options.sameSite).toBe("none");
expect(options.partitioned).toBe(true);
});
test("insecure (http) connection stays lax and non-partitioned even when framed", () => {
stubNuxtApp(true);
setLocation("http:");
setFramed(true);
const options = getTokenCookieOptions();
expect(options.secure).toBe(false);
expect(options.sameSite).toBe("lax");
expect(options.partitioned).toBe(false);
});
test("non-production build stays lax and non-partitioned even when framed over https", () => {
stubNuxtApp(false);
setLocation("https:");
setFramed(true);
const options = getTokenCookieOptions();
expect(options.secure).toBe(false);
expect(options.sameSite).toBe("lax");
expect(options.partitioned).toBe(false);
});
});

View File

@@ -1,9 +1,13 @@
export function getTokenCookieOptions() { export function getTokenCookieOptions() {
const isSecureConnection = useNuxtApp().$appInfo.production && window?.location?.protocol === "https:"; const { $appInfo } = useNuxtApp();
const isSecureConnection = $appInfo.production && window?.location?.protocol === "https:";
const isEmbedded = isSecureConnection && window?.self !== window?.top;
return { return {
maxAge: useNuxtApp().$appInfo.tokenTime * 60 * 60, maxAge: $appInfo.tokenTime * 60 * 60,
secure: isSecureConnection, secure: isSecureConnection,
sameSite: (isSecureConnection ? "none" : "lax") as "none" | "lax", sameSite: (isEmbedded ? "none" : "lax") as "none" | "lax",
partitioned: isSecureConnection, partitioned: isEmbedded,
}; };
} }