import test from "node:test"; import assert from "node:assert/strict"; import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { EncryptedPoolStore } from "./encrypted-pool-store.mjs"; async function makeStore() { const root = await fs.mkdtemp(path.join(os.tmpdir(), "enc-pool-store-test-")); const store = new EncryptedPoolStore({ dataDir: path.join(root, "data"), cryptoKey: "test-crypto-key", }); await store.init(); return { root, store }; } test("EncryptedPoolStore writes encrypted payload without plaintext secrets", async () => { const { store } = await makeStore(); await store.savePool("codex-api", [ { name: "main", type: "codex", baseUrl: "https://example.com/v1", apiKey: "sk-test-secret", model: "gpt-5.4", disabled: false, }, ]); const encryptedPath = path.join(store.dataDir, "pools", "codex-api.enc"); const encrypted = await fs.readFile(encryptedPath, "utf8"); assert.doesNotMatch(encrypted, /sk-test-secret/); const loaded = await store.loadPool("codex-api"); assert.equal(loaded.items[0].apiKey, ""); assert.ok(loaded.items[0].apiKeyMasked); const raw = await store.loadRawPoolItems("codex-api"); assert.equal(raw[0].apiKey, "sk-test-secret"); }); test("EncryptedPoolStore preserves existing secrets when admin submits blank replacements", async () => { const { store } = await makeStore(); await store.savePool("claude-code-api", [ { name: "claude-main", type: "claude-code", baseUrl: "https://claude.example.com", apiKey: "sk-claude-secret", model: "claude-sonnet", disabled: false, }, ]); await store.savePool("claude-code-api", [ { name: "claude-main-renamed", type: "claude-code", baseUrl: "https://claude.example.com", apiKey: "", model: "claude-sonnet", disabled: false, }, ]); const raw = await store.loadRawPoolItems("claude-code-api"); assert.equal(raw[0].name, "claude-main-renamed"); assert.equal(raw[0].apiKey, "sk-claude-secret"); }); test("EncryptedPoolStore can persist to a private hf dataset backend", async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), "enc-pool-store-hf-test-")); const files = new Map(); const fetchCalls = []; const fetchFn = async (url, options = {}) => { fetchCalls.push({ url, options }); if (String(url) === "https://huggingface.co/api/datasets/alice/private-db") { return new Response("{}", { status: 200 }); } if (String(url).includes("/resolve/")) { const relativePath = String(url).split("/main/")[1]; if (options.method === "HEAD") { if (!files.has(relativePath)) { return new Response("", { status: 404 }); } return new Response("", { status: 200, headers: { "last-modified": new Date("2026-04-08T00:00:00.000Z").toUTCString() }, }); } if (!files.has(relativePath)) { return new Response("", { status: 404 }); } return new Response(files.get(relativePath), { status: 200, headers: { "last-modified": new Date("2026-04-08T00:00:00.000Z").toUTCString() }, }); } if (String(url) === "https://huggingface.co/api/datasets/alice/private-db/commit/main") { const body = String(options.body || "").trim().split("\n").map((line) => JSON.parse(line)); const fileOp = body.find((item) => item.key === "file"); files.set(fileOp.value.path, Buffer.from(fileOp.value.content, "base64").toString("utf8")); return new Response(JSON.stringify({ commitOid: "abc123", commitUrl: "https://huggingface.co/commit/abc123" }), { status: 200, headers: { "content-type": "application/json" }, }); } throw new Error(`Unexpected fetch: ${url}`); }; const store = new EncryptedPoolStore({ dataDir: path.join(root, "data"), cryptoKey: "test-crypto-key", storageBackend: "hf-dataset", hfDatasetRepo: "alice/private-db", hfToken: "hf_test_token", fetchFn, }); await store.init(); await store.savePool("codex-api", [ { name: "dataset-main", type: "codex", baseUrl: "https://example.com/v1", apiKey: "sk-dataset-secret", model: "gpt-5.4", disabled: false, }, ]); const pool = await store.loadPool("codex-api"); assert.equal(pool.pool.filePath, "hf://datasets/alice/private-db/main/pools/codex-api.enc"); assert.equal(pool.items[0].apiKey, ""); assert.ok(fetchCalls.some(({ url }) => String(url) === "https://huggingface.co/api/datasets/alice/private-db")); assert.ok(fetchCalls.some(({ url }) => String(url) === "https://huggingface.co/api/datasets/alice/private-db/commit/main")); }); test("EncryptedPoolStore marks hf dataset backend as read-only without HF_TOKEN", async () => { const root = await fs.mkdtemp(path.join(os.tmpdir(), "enc-pool-store-hf-ro-test-")); const store = new EncryptedPoolStore({ dataDir: path.join(root, "data"), cryptoKey: "test-crypto-key", storageBackend: "hf-dataset", hfDatasetRepo: "alice/private-db", }); await store.init(); assert.equal(store.readOnly, true); assert.match(store.readOnlyReason, /HF_TOKEN is required/i); });