This commit is contained in:
Luke Vella 2025-02-12 15:21:48 +07:00
parent a5a45fe13b
commit 3c959eba2b
No known key found for this signature in database
GPG key ID: 469CAD687F0D784C
2 changed files with 90 additions and 0 deletions

View file

@ -0,0 +1,37 @@
import hkdf from "@panva/hkdf";
import { nanoid } from "@rallly/utils/nanoid";
import { EncryptJWT } from "jose";
import type { JWT } from "next-auth/jwt";
const now = () => (Date.now() / 1000) | 0;
export async function getDerivedEncryptionKey(
keyMaterial: string | Buffer,
salt: string,
) {
return await hkdf(
"sha256",
keyMaterial,
salt,
`NextAuth.js Generated Encryption Key${salt ? ` (${salt})` : ""}`,
32,
);
}
interface JWTEncodeParams {
token?: JWT;
salt?: string;
secret: string | Buffer;
maxAge?: number;
}
export async function encode(params: JWTEncodeParams) {
/** @note empty `salt` means a session token. See {@link JWTEncodeParams.salt}. */
const { token = {}, secret, maxAge = 30 * 24 * 60 * 60, salt = "" } = params;
const encryptionSecret = await getDerivedEncryptionKey(secret, salt);
return await new EncryptJWT(token)
.setProtectedHeader({ alg: "dir", enc: "A256GCM" })
.setIssuedAt()
.setExpirationTime(now() + maxAge)
.setJti(nanoid())
.encrypt(encryptionSecret);
}

View file

@ -0,0 +1,53 @@
import { expect, test } from "@playwright/test";
import { prisma } from "@rallly/database";
import { nanoid } from "@rallly/utils/nanoid";
import { encode } from "./helpers/next-auth-v4";
const legacyGuestId = "user-1234";
test.describe.serial(() => {
test.beforeAll(async () => {
await prisma.poll.create({
data: {
id: "legacy-guest-poll",
title: "Test Poll",
adminUrlId: nanoid(),
participantUrlId: nanoid(),
guestId: legacyGuestId,
},
});
});
test.afterAll(async () => {
await prisma.poll.delete({
where: {
id: "legacy-guest-poll",
},
});
});
test("should see poll on login page", async ({ page }) => {
const context = page.context();
const token = await encode({
token: {
sub: legacyGuestId,
},
secret: process.env.SECRET_PASSWORD,
});
// set cookie to simulate legacy guest
await context.addCookies([
{
name: "next-auth.session-token",
value: token,
httpOnly: true,
secure: false,
sameSite: "Lax",
path: "/",
domain: "localhost",
},
]);
await page.goto("/login");
await expect(page.getByText("Test Poll")).toBeVisible();
});
});