/** * TASK-0130 — the worker's crypto now DELEGATES to @factory/shared * (one envelope + key derivation for API-write / worker-read — C-13.8a). * The full envelope contract (known vector, tamper detection, hex-raw key) * is unit-tested in packages/shared/src/crypto.test.ts; here we pin the * worker's re-exported surface + the master-key guard the dispatcher uses. */ import { describe, expect, it } from "vitest"; import { MasterKeyMissingError, aes256gcmDecrypt, aes256gcmEncrypt, requireMasterKey } from "../lib/encrypt.js"; const KEY = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"; describe("worker encrypt (shared delegation)", () => { it("roundtrips with the shared (plaintext, key) argument order", () => { const enc = aes256gcmEncrypt("whsec_worker-parity", KEY); expect(aes256gcmDecrypt(enc, KEY)).toBe("whsec_worker-parity"); }); it("a ciphertext the API wrote (shared fns, different key shape) decrypts here", () => { // 64-hex master key used RAW by the API; the worker must agree. const apiEnc = aes256gcmEncrypt("cross-app-secret", KEY); expect(aes256gcmDecrypt(apiEnc, KEY)).toBe("cross-app-secret"); }); it("tampering throws (GCM auth tag)", () => { const enc = aes256gcmEncrypt("sensitive", KEY); const buf = Buffer.from(enc, "base64"); buf[buf.length - 1]! ^= 0x01; expect(() => aes256gcmDecrypt(buf.toString("base64"), KEY)).toThrow(); }); }); describe("requireMasterKey (refuse to sign without a master key)", () => { it("throws MasterKeyMissingError on blank key", () => { expect(() => requireMasterKey("")).toThrow(MasterKeyMissingError); }); it("returns the key when set", () => { expect(requireMasterKey(KEY)).toBe(KEY); }); });