import { createServer } from "node:http"; import { mkdtempSync, writeFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { expect, it } from "vitest"; import { probeBootstrapDependencies } from "../src/catalog/bootstrap-probes.js"; import { probePublicEvidenceUrl } from "../src/catalog/evidence-probe-http.js"; it("refuses loopback literals and DNS answers before sending an Evidence GET", async () => { for (const hostname of ["[::1]", "127.0.0.1", "localhost", "[::ffff:127.0.0.1]"]) { await expect(probePublicEvidenceUrl(new URL(`http://${hostname}/private`))).rejects.toThrow("Evidence network policy refused"); } }); it("authenticates a bounded read-only REST probe and blocks unavailable credentials/services", async () => { const directory = mkdtempSync(join(tmpdir(), "tht-probe-")); const secret = join(directory, "key"); writeFileSync(secret, "PRIVATE_SENTINEL", { mode: 0o600 }); let status = 200; const requests: string[] = []; const server = createServer((req, res) => { requests.push(`${req.method} ${req.url}`); res.writeHead(req.headers.authorization === "Bearer PRIVATE_SENTINEL" ? status : 401); res.end("PRIVATE_SERVER_RESPONSE"); }); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); const address = server.address() as { port: number }; const document = { schemaVersion: 1, databases: [{ workspaceId: "demo", engine: "postgres", databaseName: "demo", schema: "public", binding: { transport: "rest_api", baseUrl: `http://127.0.0.1:${address.port}`, restPath: "/health", restAuth: "bearer" }, secretFiles: { apiKey: secret } }] }; try { expect((await probeBootstrapDependencies(document)).ok).toBe(true); status = 503; const failed = await probeBootstrapDependencies(document); expect(failed.ok).toBe(false); expect(JSON.stringify(failed)).not.toContain("PRIVATE"); status = 200; writeFileSync(secret, "rotated-but-invalid"); expect((await probeBootstrapDependencies(document)).ok).toBe(false); expect(requests).toEqual(["GET /health", "GET /health", "GET /health"]); } finally { await new Promise((resolve) => server.close(() => resolve())); rmSync(directory, { recursive: true }); } });