1
8import { describe, expect, it } from "vitest";
9import {
10 MasterKeyMissingError,
11 aes256gcmDecrypt,
12 aes256gcmEncrypt,
13 requireMasterKey
14} from "../lib/encrypt.js";
15
16const KEY = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
17
18describe("worker encrypt (shared delegation)", () => {
19 it("roundtrips with the shared (plaintext, key) argument order", () => {
20 const enc = aes256gcmEncrypt("whsec_worker-parity", KEY);
21 expect(aes256gcmDecrypt(enc, KEY)).toBe("whsec_worker-parity");
22 });
23
24 it("a ciphertext the API wrote (shared fns, different key shape) decrypts here", () => {
25
26 const apiEnc = aes256gcmEncrypt("cross-app-secret", KEY);
27 expect(aes256gcmDecrypt(apiEnc, KEY)).toBe("cross-app-secret");
28 });
29
30 it("tampering throws (GCM auth tag)", () => {
31 const enc = aes256gcmEncrypt("sensitive", KEY);
32 const buf = Buffer.from(enc, "base64");
33 buf[buf.length - 1]! ^= 0x01;
34 expect(() => aes256gcmDecrypt(buf.toString("base64"), KEY)).toThrow();
35 });
36});
37
38describe("requireMasterKey (refuse to sign without a master key)", () => {
39 it("throws MasterKeyMissingError on blank key", () => {
40 expect(() => requireMasterKey("")).toThrow(MasterKeyMissingError);
41 });
42 it("returns the key when set", () => {
43 expect(requireMasterKey(KEY)).toBe(KEY);
44 });
45});
46