文件
tennis-training-hub/server/_core/sdk.test.ts
2026-03-16 18:05:58 +08:00

58 行
1.9 KiB
TypeScript

import { SignJWT } from "jose";
import { describe, expect, it, vi } from "vitest";
async function loadSdkForTest() {
process.env.JWT_SECRET = "test-cookie-secret";
process.env.VITE_APP_ID = "test-app";
vi.resetModules();
const [{ sdk }, { ENV }] = await Promise.all([
import("./sdk"),
import("./env"),
]);
return { sdk, ENV };
}
async function signLegacyToken(openId: string, appId: string, name: string) {
const secret = new TextEncoder().encode(process.env.JWT_SECRET || "");
return new SignJWT({
openId,
appId,
name,
})
.setProtectedHeader({ alg: "HS256", typ: "JWT" })
.setExpirationTime(Math.floor((Date.now() + 60_000) / 1000))
.sign(secret);
}
describe("sdk.verifySession", () => {
it("derives a stable legacy sid when the token payload does not include sid", async () => {
const { sdk, ENV } = await loadSdkForTest();
const legacyToken = await signLegacyToken("username_H1_legacy", ENV.appId, "H1");
const session = await sdk.verifySession(legacyToken);
expect(session).not.toBeNull();
expect(session?.sid).toMatch(/^legacy-token:/);
expect(session?.sid).toHaveLength("legacy-token:".length + 32);
});
it("derives different legacy sid values for different legacy login tokens", async () => {
const firstLoad = await loadSdkForTest();
const tokenA = await signLegacyToken("username_H1_legacy", firstLoad.ENV.appId, "H1");
await new Promise((resolve) => setTimeout(resolve, 5));
const secondLoad = await loadSdkForTest();
const tokenB = await signLegacyToken("username_H1_legacy", secondLoad.ENV.appId, "H1-second");
const sessionA = await firstLoad.sdk.verifySession(tokenA);
const sessionB = await secondLoad.sdk.verifySession(tokenB);
expect(sessionA?.sid).toMatch(/^legacy-token:/);
expect(sessionB?.sid).toMatch(/^legacy-token:/);
expect(sessionA?.sid).not.toBe(sessionB?.sid);
});
});