Something went wrong. Try again.
The logic for serving and storing associations between users and apps
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788import { describe, expect, it } from "vitest";import { base64UrlDecode, base64UrlEncode, bearerToken, DEVICE_TOKEN_TTL_SEC, mintDeviceToken, verifyDeviceToken,} from "./device-token";
const SECRET = "test-secret-at-least-32-characters-long";const SID = "ab".repeat(16);const ORIGIN = "https://your-app.example";
function future(): number { return Math.floor(Date.now() / 1000) + DEVICE_TOKEN_TTL_SEC;}
describe("base64url", () => { it("round-trips bytes without padding", () => { const bytes = new Uint8Array([0, 1, 250, 251, 252, 253, 254, 255]); const encoded = base64UrlEncode(bytes); expect(encoded).not.toContain("="); expect(encoded).not.toContain("+"); expect(encoded).not.toContain("/"); expect([...base64UrlDecode(encoded)]).toEqual([...bytes]); });});
describe("device token", () => { it("mints and verifies a token carrying the session id and origin", async () => { const token = await mintDeviceToken(SECRET, { sid: SID, origin: ORIGIN, expiresAt: future() }); const result = await verifyDeviceToken(SECRET, token); expect(result.ok).toBe(true); if (!result.ok) return; expect(result.claims.sid).toBe(SID); expect(result.claims.origin).toBe(ORIGIN); });
it("rejects a token signed with another secret", async () => { const token = await mintDeviceToken(SECRET, { sid: SID, origin: ORIGIN, expiresAt: future() }); const result = await verifyDeviceToken("a-different-secret-value-32-chars!!", token); expect(result).toEqual({ ok: false, reason: "token signature is invalid" }); });
it("rejects a tampered session id", async () => { const token = await mintDeviceToken(SECRET, { sid: SID, origin: ORIGIN, expiresAt: future() }); const [version, payload, signature] = token.split("."); const forgedPayload = base64UrlEncode( new TextEncoder().encode(JSON.stringify({ s: "cd".repeat(16), o: ORIGIN, e: future() })), ); expect(forgedPayload).not.toBe(payload); const result = await verifyDeviceToken(SECRET, `${version}.${forgedPayload}.${signature}`); expect(result.ok).toBe(false); });
it("rejects an expired token", async () => { const past = Math.floor(Date.now() / 1000) - 1; const token = await mintDeviceToken(SECRET, { sid: SID, origin: ORIGIN, expiresAt: past }); const result = await verifyDeviceToken(SECRET, token); expect(result).toEqual({ ok: false, reason: "token has expired" }); });
it("rejects malformed tokens and unknown versions", async () => { expect((await verifyDeviceToken(SECRET, "nope")).ok).toBe(false); expect((await verifyDeviceToken(SECRET, "v2.abc.def")).ok).toBe(false); expect((await verifyDeviceToken(SECRET, "v1.!!!.???")).ok).toBe(false); });
it("refuses to work when no secret is configured", async () => { const token = await mintDeviceToken(SECRET, { sid: SID, origin: ORIGIN, expiresAt: future() }); expect((await verifyDeviceToken("", token)).ok).toBe(false); await expect( mintDeviceToken("", { sid: SID, origin: ORIGIN, expiresAt: future() }), ).rejects.toThrow(/not configured/); });});
describe("bearerToken", () => { it("accepts a bare token or a Bearer prefix", () => { expect(bearerToken("abc")).toBe("abc"); expect(bearerToken("Bearer abc")).toBe("abc"); expect(bearerToken("bearer abc")).toBe("abc"); expect(bearerToken(null)).toBeNull(); expect(bearerToken(" ")).toBeNull(); });});