Skip to content
File

Blob: test/pat-format.test.ts

typescript44 lines
1import { describe, expect, it } from "vitest";
2 
3import {
4 generatePatPlaintext,
5 hashPatPlaintext,
6 parsePatPlaintext,
7 validatePatName,
8} from "@/worker/auth/pat";
9 
10describe("PAT format", () => {
11 it("round-trips generated tokens through parse/hash", async () => {
12 const generated = generatePatPlaintext();
13 expect(generated.plaintext.startsWith(`${generated.publicPrefix}_`)).toBe(true);
14 const parsed = parsePatPlaintext(generated.plaintext);
15 expect(parsed.ok).toBe(true);
16 if (!parsed.ok) return;
17 expect(parsed.publicPrefix).toBe(generated.publicPrefix);
18 expect(parsed.secret).toMatch(/^[abcdefghijklmnopqrstuvwxyz234567]{32}$/);
19 const hash = await hashPatPlaintext(generated.plaintext);
20 expect(hash).toMatch(/^[0-9a-f]{64}$/);
21 expect(await hashPatPlaintext(generated.plaintext)).toBe(hash);
22 });
23 
24 it("rejects malformed plaintexts", () => {
25 expect(parsePatPlaintext("")).toEqual({ ok: false, reason: "malformed" });
26 expect(parsePatPlaintext("goc_xx_yy")).toEqual({ ok: false, reason: "malformed" });
27 expect(parsePatPlaintext("nope_aaaaaaaa_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")).toEqual({
28 ok: false,
29 reason: "malformed",
30 });
31 // Wrong segment lengths.
32 expect(parsePatPlaintext("goc_aaa_bbbb")).toEqual({ ok: false, reason: "malformed" });
33 });
34 
35 it("validates token names", () => {
36 expect(validatePatName("ci")).toEqual({ ok: true, name: "ci" });
37 expect(validatePatName("CI Push")).toEqual({ ok: true, name: "CI Push" });
38 expect(validatePatName("")).toEqual({ ok: false, reason: "length" });
39 expect(validatePatName(" ")).toEqual({ ok: false, reason: "length" });
40 expect(validatePatName("a".repeat(41))).toEqual({ ok: false, reason: "length" });
41 expect(validatePatName("$bad")).toEqual({ ok: false, reason: "format" });
42 });
43});