85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
import { readFile } from "node:fs/promises";
|
|
|
|
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import type { AuthSession } from "@/lib/auth/session";
|
|
import {
|
|
authorizePlatformSession,
|
|
type PlatformAuthorizationSnapshot,
|
|
} from "@/lib/server/auth/platform-session";
|
|
|
|
type ContractCase = {
|
|
name: string;
|
|
session: AuthSession;
|
|
snapshot: PlatformAuthorizationSnapshot | null;
|
|
expected:
|
|
| { outcome: "authenticated"; loaderCalls: number; session: AuthSession }
|
|
| { outcome: "unauthenticated"; loaderCalls: number; reason: string };
|
|
};
|
|
|
|
type ContractFixture = {
|
|
version: 1;
|
|
requiredClientId: string;
|
|
cases: ContractCase[];
|
|
};
|
|
|
|
const fixtureUrl = new URL("../contracts/auth/platform-session-authorization-v1.json", import.meta.url);
|
|
|
|
async function loadFixture(): Promise<ContractFixture> {
|
|
return JSON.parse(await readFile(fixtureUrl, "utf8")) as ContractFixture;
|
|
}
|
|
|
|
describe("platform session authorization v1 cross-language contract", () => {
|
|
it("refreshes an active user's forged Cookie claims from the database", async () => {
|
|
const fixture = await loadFixture();
|
|
const contractCase = fixture.cases[0];
|
|
const loader = vi.fn(async () => contractCase.snapshot);
|
|
|
|
const result = await authorizePlatformSession(
|
|
contractCase.session,
|
|
loader,
|
|
fixture.requiredClientId,
|
|
);
|
|
|
|
expect(result).toEqual(contractCase.expected.outcome === "authenticated"
|
|
? { outcome: "authenticated", session: contractCase.expected.session }
|
|
: { outcome: "unauthenticated", reason: contractCase.expected.reason });
|
|
expect(loader).toHaveBeenCalledTimes(contractCase.expected.loaderCalls);
|
|
});
|
|
|
|
it("matches every remaining authorization and rejection case", async () => {
|
|
const fixture = await loadFixture();
|
|
|
|
for (const contractCase of fixture.cases.slice(1)) {
|
|
const loader = vi.fn(async () => contractCase.snapshot);
|
|
const result = await authorizePlatformSession(
|
|
contractCase.session,
|
|
loader,
|
|
fixture.requiredClientId,
|
|
);
|
|
|
|
expect(result, contractCase.name).toEqual(contractCase.expected.outcome === "authenticated"
|
|
? { outcome: "authenticated", session: contractCase.expected.session }
|
|
: { outcome: "unauthenticated", reason: contractCase.expected.reason });
|
|
expect(loader, contractCase.name).toHaveBeenCalledTimes(contractCase.expected.loaderCalls);
|
|
if (contractCase.expected.loaderCalls > 0) {
|
|
expect(loader, contractCase.name).toHaveBeenCalledWith(contractCase.session.user.id);
|
|
}
|
|
}
|
|
});
|
|
|
|
it("rejects a mismatched joined organization instead of trusting its display claims", async () => {
|
|
const fixture = await loadFixture();
|
|
const contractCase = fixture.cases[0];
|
|
const snapshot = structuredClone(contractCase.snapshot);
|
|
if (!snapshot?.organization) throw new Error("fixture requires organization");
|
|
snapshot.organization.id = "org-other";
|
|
|
|
await expect(authorizePlatformSession(
|
|
contractCase.session,
|
|
async () => snapshot,
|
|
fixture.requiredClientId,
|
|
)).resolves.toEqual({ outcome: "unauthenticated", reason: "organization_not_active" });
|
|
});
|
|
});
|