36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
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("…");
|
|
});
|
|
});
|