38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { API_URL, registerVerifyLogin, uniqueEmail } from "../helpers/api";
|
|
|
|
function extractRefreshCookie(headers: Record<string, string>): string {
|
|
const setCookie = headers["set-cookie"] ?? headers["Set-Cookie"] ?? "";
|
|
const match = setCookie.match(/refresh_token=([^;]+)/);
|
|
if (!match) {
|
|
throw new Error("refresh_token cookie missing");
|
|
}
|
|
return match[1];
|
|
}
|
|
|
|
test.describe("§15.7 scenario 7: Refresh rotation", () => {
|
|
test("old refresh token rejected after rotation; reuse revokes family", async ({ request }) => {
|
|
const email = uniqueEmail("e2e-refresh");
|
|
await registerVerifyLogin(request, email);
|
|
|
|
const login = await request.post(`${API_URL}/api/v1/auth/login`, { data: { email, password: "Valid1234" } });
|
|
const oldRefresh = extractRefreshCookie(login.headers());
|
|
|
|
const rotated = await request.post(`${API_URL}/api/v1/auth/refresh`, {
|
|
headers: { Cookie: `refresh_token=${oldRefresh}` }
|
|
});
|
|
expect(rotated.ok()).toBeTruthy();
|
|
const newRefresh = extractRefreshCookie(rotated.headers());
|
|
|
|
const oldReuse = await request.post(`${API_URL}/api/v1/auth/refresh`, {
|
|
headers: { Cookie: `refresh_token=${oldRefresh}` }
|
|
});
|
|
expect(oldReuse.status()).toBe(401);
|
|
|
|
const familyReuse = await request.post(`${API_URL}/api/v1/auth/refresh`, {
|
|
headers: { Cookie: `refresh_token=${newRefresh}` }
|
|
});
|
|
expect(familyReuse.status()).toBe(401);
|
|
});
|
|
});
|