import { describe, expect, it } from "vitest"; import { issueCsrf, verifyCsrf } from "./csrf"; const SECRET = "test-secret-32-bytes-or-more-please-make-it-long"; describe("CSRF double-submit token", () => { it("issues a token where cookie carries raw + sig and header carries raw", () => { const t = issueCsrf(SECRET); expect(t.cookieValue.split(".").length).toBe(2); expect(t.cookieValue.startsWith(t.headerValue)).toBe(true); }); it("verifies a freshly issued token", () => { const t = issueCsrf(SECRET); expect(verifyCsrf(t.cookieValue, t.headerValue, SECRET)).toBe(true); }); it("rejects mismatched header", () => { const t = issueCsrf(SECRET); expect(verifyCsrf(t.cookieValue, "different-header", SECRET)).toBe(false); }); it("rejects tampered signature", () => { const t = issueCsrf(SECRET); const tampered = t.cookieValue.replace(/.$/, (c) => (c === "0" ? "1" : "0")); expect(verifyCsrf(tampered, t.headerValue, SECRET)).toBe(false); }); it("rejects different secret (forgery)", () => { const t = issueCsrf(SECRET); expect(verifyCsrf(t.cookieValue, t.headerValue, "wrong-secret")).toBe(false); }); it("rejects null/empty inputs", () => { expect(verifyCsrf(null, "x", SECRET)).toBe(false); expect(verifyCsrf("x.y", null, SECRET)).toBe(false); expect(verifyCsrf("x.y", "x", "")).toBe(false); }); it("rejects malformed cookie (no dot)", () => { expect(verifyCsrf("nodothere", "nodothere", SECRET)).toBe(false); }); it("rejects empty secret on issue", () => { expect(() => issueCsrf("")).toThrow(); }); });