import http from "node:http"; import { URL } from "node:url"; import { host, port } from "./config.js"; import { readJsonBody, sendJson, sendText } from "./lib/http.js"; import { listEvidenceArtifacts, loadRegistry, resetRegistry, writeEvidenceArtifact, writeRegistry } from "./lib/store.js"; import { validateRegistry } from "../src/lib/validation.js"; const server = http.createServer(async (req, res) => { if (!req.url) return sendJson(res, 400, { error: "Missing URL." }); const url = new URL(req.url, `http://${req.headers.host || `${host}:${port}`}`); if (req.method === "OPTIONS") { res.writeHead(204, { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET,POST,PUT,DELETE,OPTIONS", "Access-Control-Allow-Headers": "Content-Type", }); return res.end(); } try { if (req.method === "GET" && url.pathname === "/health") { return sendText(res, 200, "ok"); } if (req.method === "GET" && url.pathname === "/api/health") { const registry = await loadRegistry(); const validation = validateRegistry(registry); return sendJson(res, 200, { ok: true, service: "soc2-cockpit-api", registryValid: validation.isValid, warningCount: validation.warnings.length, errorCount: validation.errors.length, }); } if (req.method === "GET" && url.pathname === "/api/registry") { const registry = await loadRegistry(); return sendJson(res, 200, { registry, validation: validateRegistry(registry) }); } if (req.method === "PUT" && url.pathname === "/api/registry") { const payload = await readJsonBody(req); const result = await writeRegistry(payload); return sendJson(res, 200, result); } if (req.method === "POST" && url.pathname === "/api/registry/reset") { const result = await resetRegistry(); return sendJson(res, 200, result); } if (req.method === "GET" && url.pathname === "/api/evidence") { const artifacts = await listEvidenceArtifacts(); return sendJson(res, 200, { artifacts }); } if (req.method === "POST" && url.pathname === "/api/evidence") { const payload = await readJsonBody(req); const artifact = await writeEvidenceArtifact(payload); return sendJson(res, 201, { artifact }); } return sendJson(res, 404, { error: "Not found." }); } catch (error) { if (error?.validation) { return sendJson(res, 400, { error: error.message, validation: error.validation }); } return sendJson(res, 500, { error: error?.message || "Internal server error." }); } }); server.listen(port, host, () => { console.log(`SOC 2 cockpit API listening on http://${host}:${port}`); });