import { describe, expect, test } from "bun:test"; import { mkdtempSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { decrypt, encrypt, loadOrCreateKey, mask } from "../src/lib/crypto"; describe("crypto", () => { test("key is created once and reused", () => { const dir = mkdtempSync(join(tmpdir(), "helios-")); const a = loadOrCreateKey(dir); const b = loadOrCreateKey(dir); expect(a.length).toBe(32); expect(a.equals(b)).toBe(true); }); test("encrypt/decrypt round-trip; ciphertexts differ per call", () => { const key = loadOrCreateKey(mkdtempSync(join(tmpdir(), "helios-"))); const sealed = encrypt(key, "sk-or-v1-secret"); expect(sealed.startsWith("enc:")).toBe(true); expect(decrypt(key, sealed)).toBe("sk-or-v1-secret"); expect(encrypt(key, "sk-or-v1-secret")).not.toBe(sealed); }); test("tampering fails closed", () => { const key = loadOrCreateKey(mkdtempSync(join(tmpdir(), "helios-"))); const sealed = encrypt(key, "x"); const bad = sealed.slice(0, -2) + (sealed.endsWith("A") ? "BB" : "AA"); expect(() => decrypt(key, bad)).toThrow(); }); test("mask keeps only tail", () => { expect(mask("sk-or-v1-abcdef")).toBe("…cdef"); expect(mask("abc")).toBe("…"); }); });