76 lines
2.7 KiB
JavaScript
76 lines
2.7 KiB
JavaScript
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}`);
|
|
});
|