import { describe, expect, it } from "vitest"; import { createPkcePair, deriveCodeChallenge, generateCodeVerifier, generateState, isValidCodeVerifier, } from "../src"; describe("PKCE helpers", () => { it("derives the RFC 7636 S256 example", async () => { const verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; await expect(deriveCodeChallenge(verifier)).resolves.toBe( "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM", ); }); it("generates valid verifier lengths", () => { for (const length of [43, 64, 128]) { const verifier = generateCodeVerifier(length); expect(verifier).toHaveLength(length); expect(isValidCodeVerifier(verifier)).toBe(true); } }); it("rejects invalid verifier lengths and characters", async () => { expect(() => generateCodeVerifier(42)).toThrow(RangeError); expect(isValidCodeVerifier("a".repeat(42))).toBe(false); await expect(deriveCodeChallenge(`${"a".repeat(42)}!`)).rejects.toThrow( "Invalid RFC 7636 code verifier", ); }); it("creates an S256 pair and a high-entropy state", async () => { const pair = await createPkcePair(); expect(pair.method).toBe("S256"); expect(pair.challenge).toBe(await deriveCodeChallenge(pair.verifier)); expect(generateState()).toMatch(/^[A-Za-z0-9_-]{43}$/); }); });