/home/techb158/cosmic.abdallabala.com
Edit: /home/techb158/cosmic.abdallabala.com/server.js (37203B)
const http = require("http");
const fs = require("fs");
const path = require("path");
const url = require("url");
const engine = require("./public/risk-engine.js");
const { JsonDatabase } = require("./src/storage/jsonDatabase.js");
const { DashboardService } = require("./src/services/dashboardService.js");
const { ProjectRepository } = require("./src/repositories/projectRepository.js");
const { RiskRepository } = require("./src/repositories/riskRepository.js");
const { GateWorkflowService } = require("./src/services/gateWorkflowService.js");
const { IntegrationService } = require("./src/services/integrationService.js");
const { ReportingService } = require("./src/services/reportingService.js");
const { OAuthService } = require("./src/services/oauthService.js");
const { AccessControlService } = require("./src/security/accessControl.js");
const { getRuntimeConfig, validateRuntimeConfig } = require("./src/config/runtimeConfig.js");
const { withCommonHeaders, buildCorsHeaders, isHttpsRequest } = require("./src/security/securityHeaders.js");
const { OperationsService } = require("./src/operations/operationsService.js");
const ROOT = __dirname;
const APP_CONFIG = getRuntimeConfig(process.env, ROOT);
const PORT = APP_CONFIG.port;
const PUBLIC = APP_CONFIG.publicDir;
const LEGACY_DATA_FILE = APP_CONFIG.legacyDataFile;
const DATABASE_FILE = APP_CONFIG.databaseFile;
const DEFAULT_PROJECT_ID = APP_CONFIG.defaultProjectId;
const database = new JsonDatabase(DATABASE_FILE);
const dashboardService = new DashboardService(database);
const projectRepository = new ProjectRepository(database);
const riskRepository = new RiskRepository(database);
const gateWorkflowService = new GateWorkflowService(database);
const oauthService = new OAuthService(database);
const integrationService = new IntegrationService(database, { oauthService });
const reportingService = new ReportingService(database);
const accessControlService = new AccessControlService(database);
const operationsService = new OperationsService(database, APP_CONFIG);
accessControlService.ensureDefaultRolesAndUsers("USER-SYSTEM");
function sendJson(res, status, payload) {
const body = JSON.stringify(payload, null, 2);
res.writeHead(status, withCommonHeaders(res._cosmicReq || { headers: {} }, APP_CONFIG, {
"Content-Type": "application/json; charset=utf-8",
"Cache-Control": "no-store"
}));
res.end(body);
}
function sendText(res, status, payload, contentType, filename) {
const headers = withCommonHeaders(res._cosmicReq || { headers: {} }, APP_CONFIG, {
"Content-Type": contentType || "text/plain; charset=utf-8",
"Cache-Control": "no-store"
});
if (filename) {
headers["Content-Disposition"] = `attachment; filename="${filename}"`;
}
res.writeHead(status, headers);
res.end(payload);
}
function sendFile(res, filePath) {
if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory()) {
res.writeHead(404, withCommonHeaders(res._cosmicReq || { headers: {} }, APP_CONFIG, { "Content-Type": "text/plain; charset=utf-8" }));
res.end("Not found");
return;
}
const ext = path.extname(filePath).toLowerCase();
const types = {
".html": "text/html; charset=utf-8",
".css": "text/css; charset=utf-8",
".js": "application/javascript; charset=utf-8",
".json": "application/json; charset=utf-8",
".svg": "image/svg+xml; charset=utf-8",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg"
};
const cacheHeader = [".html", ".json"].includes(ext) ? "no-store" : "public, max-age=300";
res.writeHead(200, withCommonHeaders(res._cosmicReq || { headers: {} }, APP_CONFIG, {
"Content-Type": types[ext] || "application/octet-stream",
"Cache-Control": cacheHeader
}));
fs.createReadStream(filePath).pipe(res);
}
function parseBody(req) {
return new Promise((resolve, reject) => {
let body = "";
req.on("data", chunk => {
body += chunk;
if (body.length > APP_CONFIG.maxBodyBytes) {
req.destroy();
reject(new Error("Payload too large"));
}
});
req.on("end", () => {
if (!body) return resolve(null);
try {
resolve(JSON.parse(body));
} catch (error) {
reject(new Error("Invalid JSON"));
}
});
});
}
function projectRoute(pathname, suffix) {
const match = pathname.match(/^\/api\/projects\/([^/]+)(\/.*)?$/);
if (!match) return null;
const projectId = decodeURIComponent(match[1]);
const rest = match[2] || "";
if (rest === suffix) return projectId;
return null;
}
function idRoute(pathname, prefix) {
const pattern = new RegExp(`^${prefix}([^/]+)$`);
const match = pathname.match(pattern);
return match ? decodeURIComponent(match[1]) : null;
}
function requireDashboard(projectId, res) {
const result = dashboardService.getDashboard(projectId);
if (!result) {
sendJson(res, 404, { error: `Project not found: ${projectId}` });
return null;
}
return result;
}
function normalizeActorUserId(value) {
if (!value || value === "system") return "USER-SYSTEM";
return String(value);
}
function getActorUserId(req, query = {}, body = null) {
return normalizeActorUserId(req.headers["x-cosmic-user-id"] || query.actorUserId || (body && body.actorUserId) || "USER-SYSTEM");
}
function requirePermission(req, res, query, body, permission, context = {}) {
const actorUserId = getActorUserId(req, query, body);
try {
accessControlService.requirePermission(actorUserId, permission, context);
return actorUserId;
} catch (error) {
sendJson(res, error.status || 403, {
error: error.message,
permission,
actorUserId,
context
});
return null;
}
}
function canAccess(req, query, body, permission) {
try {
return accessControlService.hasPermission(getActorUserId(req, query, body), permission);
} catch (_error) {
return false;
}
}
function handleApi(req, res, pathname, query = {}) {
if (req.method === "GET" && pathname === "/api/health") {
return sendJson(res, 200, operationsService.getHealth());
}
if (req.method === "GET" && pathname === "/api/ready") {
const readiness = operationsService.getReadiness();
return sendJson(res, readiness.ok ? 200 : 503, readiness);
}
if (req.method === "GET" && pathname === "/api/operations/security") {
const actorUserId = requirePermission(req, res, query, null, "audit:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { security: operationsService.getSecurityStatus() });
}
if (req.method === "GET" && pathname === "/api/operations/backups") {
const actorUserId = requirePermission(req, res, query, null, "audit:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { backups: operationsService.listBackups() });
}
if (req.method === "POST" && pathname === "/api/operations/backups") {
const actorUserId = requirePermission(req, res, query, null, "user:write", { route: pathname });
if (!actorUserId) return;
try {
return sendJson(res, 201, { backup: operationsService.createBackup(actorUserId) });
} catch (error) {
return sendJson(res, 400, { error: error.message });
}
}
if (req.method === "GET" && pathname === "/api/access/permissions") {
const actorUserId = requirePermission(req, res, query, null, "user:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { permissions: accessControlService.listPermissions() });
}
if (req.method === "GET" && pathname === "/api/access/me") {
const actorUserId = getActorUserId(req, query);
const summary = accessControlService.getAccessSummary(actorUserId);
if (!summary) return sendJson(res, 404, { error: `Actor not found: ${actorUserId}` });
return sendJson(res, 200, summary);
}
if (req.method === "POST" && pathname === "/api/access/seed-defaults") {
const actorUserId = requirePermission(req, res, query, null, "user:write", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, accessControlService.ensureDefaultRolesAndUsers(actorUserId));
}
if (req.method === "GET" && pathname === "/api/users") {
const actorUserId = requirePermission(req, res, query, null, "user:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { users: accessControlService.listUsers() });
}
if (req.method === "POST" && pathname === "/api/users") {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "user:write", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 201, { user: accessControlService.createUser(body || {}, actorUserId) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const userId = idRoute(pathname, "^/api/users/");
if (req.method === "GET" && userId) {
const actorUserId = requirePermission(req, res, query, null, "user:read", { route: pathname });
if (!actorUserId) return;
const user = accessControlService.getUser(userId);
if (!user) return sendJson(res, 404, { error: `User not found: ${userId}` });
return sendJson(res, 200, { user });
}
if (req.method === "PATCH" && userId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "user:write", { route: pathname });
if (!actorUserId) return;
const user = accessControlService.updateUser(userId, body || {}, actorUserId);
if (!user) return sendJson(res, 404, { error: `User not found: ${userId}` });
return sendJson(res, 200, { user });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
if (req.method === "GET" && pathname === "/api/roles") {
const actorUserId = requirePermission(req, res, query, null, "user:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { roles: accessControlService.listRoles() });
}
if (req.method === "POST" && pathname === "/api/roles") {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "user:write", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 201, { role: accessControlService.createRole(body || {}, actorUserId) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const roleId = idRoute(pathname, "^/api/roles/");
if (req.method === "GET" && roleId) {
const actorUserId = requirePermission(req, res, query, null, "user:read", { route: pathname });
if (!actorUserId) return;
const role = accessControlService.getRole(roleId);
if (!role) return sendJson(res, 404, { error: `Role not found: ${roleId}` });
return sendJson(res, 200, { role });
}
if (req.method === "PATCH" && roleId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "user:write", { route: pathname });
if (!actorUserId) return;
const role = accessControlService.updateRole(roleId, body || {}, actorUserId);
if (!role) return sendJson(res, 404, { error: `Role not found: ${roleId}` });
return sendJson(res, 200, { role });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
if (req.method === "GET" && pathname === "/api/oauth/providers") {
const actorUserId = requirePermission(req, res, query, null, "oauth:manage", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { providers: oauthService.listProviders() });
}
const oauthProviderStatusMatch = pathname.match(/^\/api\/oauth\/([^/]+)\/status$/);
if (req.method === "GET" && oauthProviderStatusMatch) {
try {
const actorUserId = requirePermission(req, res, query, null, "oauth:manage", { route: pathname });
if (!actorUserId) return;
const provider = decodeURIComponent(oauthProviderStatusMatch[1]);
return sendJson(res, 200, { status: oauthService.getProviderStatus(provider) });
} catch (error) {
return sendJson(res, 400, { error: error.message });
}
}
const oauthAuthorizeMatch = pathname.match(/^\/api\/oauth\/([^/]+)\/authorize$/);
if (req.method === "GET" && oauthAuthorizeMatch) {
try {
const actorUserId = requirePermission(req, res, query, null, "oauth:manage", { route: pathname });
if (!actorUserId) return;
const provider = decodeURIComponent(oauthAuthorizeMatch[1]);
const payload = oauthService.buildAuthorizePayload(provider, query.integrationId || null, actorUserId);
return sendJson(res, 200, payload);
} catch (error) {
return sendJson(res, 400, { error: error.message });
}
}
const oauthCallbackMatch = pathname.match(/^\/api\/oauth\/([^/]+)\/callback$/);
if (req.method === "GET" && oauthCallbackMatch) {
const provider = decodeURIComponent(oauthCallbackMatch[1]);
if (query.error) return sendText(res, 400, `OAuth authorization failed for ${provider}: ${query.error}`, "text/plain; charset=utf-8");
return oauthService.exchangeAuthorizationCode(provider, query.code, query.state)
.then(token => sendText(res, 200, `COSMIC AI-Risk OAuth connection completed for ${provider}. Stored token ${token.id}. You can close this window.`, "text/plain; charset=utf-8"))
.catch(error => sendText(res, 400, `OAuth callback failed for ${provider}: ${error.message}`, "text/plain; charset=utf-8"));
}
if (req.method === "POST" && pathname === "/api/oauth/Trello/store-token") {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "oauth:manage", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 201, { token: oauthService.storeTrelloToken(body && body.token, body && body.state) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const reportMatch = pathname.match(/^\/api\/projects\/([^/]+)\/reports\/([^/]+)$/);
if (req.method === "GET" && reportMatch) {
const reportProjectId = decodeURIComponent(reportMatch[1]);
const reportName = decodeURIComponent(reportMatch[2]);
const actorUserId = requirePermission(req, res, query, null, "report:export", { projectId: reportProjectId, reportName });
if (!actorUserId) return;
try {
if (reportName === "executive") return sendJson(res, 200, { report: reportingService.getExecutiveReport(reportProjectId) });
if (reportName === "executive.html") return sendText(res, 200, reportingService.renderExecutiveHtml(reportProjectId), "text/html; charset=utf-8");
if (reportName === "full") return sendJson(res, 200, { report: reportingService.getFullReport(reportProjectId) });
if (reportName === "full.json") return sendText(res, 200, JSON.stringify(reportingService.getFullReport(reportProjectId), null, 2), "application/json; charset=utf-8", `cosmic-ai-risk-full-report-${reportProjectId}.json`);
if (reportName === "risk-register") return sendJson(res, 200, { report: reportingService.getRiskRegisterReport(reportProjectId) });
if (reportName === "risk-register.csv") return sendText(res, 200, reportingService.getRiskRegisterCsv(reportProjectId), "text/csv; charset=utf-8", `cosmic-ai-risk-register-${reportProjectId}.csv`);
if (reportName === "mitigations") return sendJson(res, 200, { report: reportingService.getMitigationReport(reportProjectId) });
if (reportName === "mitigations.csv") return sendText(res, 200, reportingService.getMitigationCsv(reportProjectId), "text/csv; charset=utf-8", `cosmic-ai-risk-mitigations-${reportProjectId}.csv`);
if (reportName === "gate") return sendJson(res, 200, { report: reportingService.getGateReport(reportProjectId) });
if (reportName === "indicators") return sendJson(res, 200, { report: reportingService.getIndicatorReport(reportProjectId) });
if (reportName === "integrations") return sendJson(res, 200, { report: reportingService.getIntegrationReport(reportProjectId) });
if (reportName === "audit") return sendJson(res, 200, { report: reportingService.getAuditReport(reportProjectId) });
return sendJson(res, 404, { error: `Report not found: ${reportName}` });
} catch (error) {
const status = error.message.startsWith("Project not found") ? 404 : 400;
return sendJson(res, status, { error: error.message });
}
}
if (req.method === "GET" && pathname === "/api/projects") {
const actorUserId = requirePermission(req, res, query, null, "project:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { projects: projectRepository.listProjects() });
}
if (req.method === "GET" && pathname === "/api/dashboard") {
const actorUserId = requirePermission(req, res, query, null, "project:read", { projectId: DEFAULT_PROJECT_ID });
if (!actorUserId) return;
const result = requireDashboard(DEFAULT_PROJECT_ID, res);
if (!result) return;
return sendJson(res, 200, result);
}
const projectBase = idRoute(pathname, "^/api/projects/");
if (req.method === "GET" && projectBase && !pathname.includes("/dashboard") && !pathname.includes("/risks") && !pathname.includes("/gate") && !pathname.includes("/indicators") && !pathname.includes("/metrics") && !pathname.includes("/mitigations")) {
const actorUserId = requirePermission(req, res, query, null, "project:read", { projectId: projectBase });
if (!actorUserId) return;
const project = projectRepository.getProject(projectBase);
if (!project) return sendJson(res, 404, { error: `Project not found: ${projectBase}` });
return sendJson(res, 200, { project });
}
let projectId = projectRoute(pathname, "/dashboard");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "project:read", { projectId });
if (!actorUserId) return;
const result = requireDashboard(projectId, res);
if (!result) return;
return sendJson(res, 200, result);
}
projectId = projectRoute(pathname, "/risks");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "risk:read", { projectId });
if (!actorUserId) return;
const result = requireDashboard(projectId, res);
if (!result) return;
return sendJson(res, 200, { risks: result.dashboard.scoredRisks });
}
if (req.method === "POST" && projectId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "risk:write", { projectId });
if (!actorUserId) return;
const risk = riskRepository.createRisk(projectId, body || {}, actorUserId);
const scoredRisk = engine.scoreRisk(risk);
return sendJson(res, 201, { risk: scoredRisk });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const riskId = idRoute(pathname, "^/api/risks/");
if (req.method === "GET" && riskId) {
const actorUserId = requirePermission(req, res, query, null, "risk:read", { riskId });
if (!actorUserId) return;
const risk = riskRepository.getRisk(riskId);
if (!risk) return sendJson(res, 404, { error: `Risk not found: ${riskId}` });
return sendJson(res, 200, { risk: engine.scoreRisk(risk) });
}
if (req.method === "PATCH" && riskId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "risk:write", { riskId });
if (!actorUserId) return;
const risk = riskRepository.updateRisk(riskId, body || {}, actorUserId);
if (!risk) return sendJson(res, 404, { error: `Risk not found: ${riskId}` });
return sendJson(res, 200, { risk: engine.scoreRisk(risk) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
if (req.method === "DELETE" && riskId) {
const actorUserId = requirePermission(req, res, query, null, "risk:delete", { riskId });
if (!actorUserId) return;
const deleted = riskRepository.deleteRisk(riskId, actorUserId);
if (!deleted) return sendJson(res, 404, { error: `Risk not found: ${riskId}` });
return sendJson(res, 200, { deleted: true });
}
projectId = projectRoute(pathname, "/mitigations");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "risk:read", { projectId });
if (!actorUserId) return;
return sendJson(res, 200, { mitigations: riskRepository.listMitigations(projectId) });
}
const riskMitigationMatch = pathname.match(/^\/api\/risks\/([^/]+)\/mitigations$/);
if (req.method === "POST" && riskMitigationMatch) {
const targetRiskId = decodeURIComponent(riskMitigationMatch[1]);
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "mitigation:write", { riskId: targetRiskId });
if (!actorUserId) return;
return sendJson(res, 201, { mitigation: riskRepository.createMitigation(targetRiskId, body || {}, actorUserId) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const mitigationEvidenceMatch = pathname.match(/^\/api\/mitigations\/([^/]+)\/evidence$/);
if (req.method === "POST" && mitigationEvidenceMatch) {
const targetMitigationId = decodeURIComponent(mitigationEvidenceMatch[1]);
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "mitigation:write", { mitigationId: targetMitigationId });
if (!actorUserId) return;
const evidence = riskRepository.addEvidenceToMitigation(targetMitigationId, body || {}, actorUserId);
if (!evidence) return sendJson(res, 404, { error: `Mitigation not found: ${targetMitigationId}` });
return sendJson(res, 201, { evidence });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const mitigationId = idRoute(pathname, "^/api/mitigations/");
if (req.method === "GET" && mitigationId) {
const actorUserId = requirePermission(req, res, query, null, "risk:read", { mitigationId });
if (!actorUserId) return;
const mitigation = riskRepository.getMitigation(mitigationId);
if (!mitigation) return sendJson(res, 404, { error: `Mitigation not found: ${mitigationId}` });
return sendJson(res, 200, { mitigation });
}
if (req.method === "PATCH" && mitigationId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "mitigation:write", { mitigationId });
if (!actorUserId) return;
const mitigation = riskRepository.updateMitigation(mitigationId, body || {}, actorUserId);
if (!mitigation) return sendJson(res, 404, { error: `Mitigation not found: ${mitigationId}` });
return sendJson(res, 200, { mitigation });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
if (req.method === "DELETE" && mitigationId) {
const actorUserId = requirePermission(req, res, query, null, "mitigation:write", { mitigationId });
if (!actorUserId) return;
const deleted = riskRepository.deleteMitigation(mitigationId, actorUserId);
if (!deleted) return sendJson(res, 404, { error: `Mitigation not found: ${mitigationId}` });
return sendJson(res, 200, { deleted: true });
}
projectId = projectRoute(pathname, "/gate");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "gate:read", { projectId });
if (!actorUserId) return;
const result = requireDashboard(projectId, res);
if (!result) return;
const history = gateWorkflowService.listGateHistory(projectId);
return sendJson(res, 200, { gate: result.dashboard.gate, latestPersistedGate: history[0] || null });
}
projectId = projectRoute(pathname, "/gate/history");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "gate:read", { projectId });
if (!actorUserId) return;
return sendJson(res, 200, { gates: gateWorkflowService.listGateHistory(projectId) });
}
projectId = projectRoute(pathname, "/audit");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "audit:read", { projectId });
if (!actorUserId) return;
return sendJson(res, 200, { auditEvents: gateWorkflowService.listAuditEvents(projectId) });
}
projectId = projectRoute(pathname, "/gate/evaluate");
if (req.method === "POST" && projectId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "gate:evaluate", { projectId });
if (!actorUserId) return;
const gate = dashboardService.evaluateGate(projectId, actorUserId);
if (!gate) return sendJson(res, 404, { error: `Project not found: ${projectId}` });
return sendJson(res, 200, { gate, persistedGate: gate.persistedGate });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const gateDecisionMatch = pathname.match(/^\/api\/gates\/([^/]+)\/decisions$/);
if (req.method === "POST" && gateDecisionMatch) {
const gateId = decodeURIComponent(gateDecisionMatch[1]);
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "gate:review", { gateId });
if (!actorUserId) return;
const gate = gateWorkflowService.addDecision(gateId, body || {}, actorUserId);
if (!gate) return sendJson(res, 404, { error: `Gate not found: ${gateId}` });
return sendJson(res, 201, { gate });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const gateId = idRoute(pathname, "^/api/gates/");
if (req.method === "GET" && gateId) {
const actorUserId = requirePermission(req, res, query, null, "gate:read", { gateId });
if (!actorUserId) return;
const gate = gateWorkflowService.getGate(gateId);
if (!gate) return sendJson(res, 404, { error: `Gate not found: ${gateId}` });
return sendJson(res, 200, { gate });
}
const gateCriterionId = idRoute(pathname, "^/api/gate-criteria/");
if (req.method === "PATCH" && gateCriterionId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "gate:review", { criterionId: gateCriterionId });
if (!actorUserId) return;
const criterion = gateWorkflowService.updateCriterion(gateCriterionId, body || {}, actorUserId);
if (!criterion) return sendJson(res, 404, { error: `Gate criterion not found: ${gateCriterionId}` });
return sendJson(res, 200, { criterion });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
projectId = projectRoute(pathname, "/indicators");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "project:read", { projectId });
if (!actorUserId) return;
const result = requireDashboard(projectId, res);
if (!result) return;
return sendJson(res, 200, { indicators: result.dashboard.indicators });
}
projectId = projectRoute(pathname, "/metrics");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "project:read", { projectId });
if (!actorUserId) return;
const result = requireDashboard(projectId, res);
if (!result) return;
return sendJson(res, 200, { experiments: result.dashboard.experiments });
}
if (req.method === "GET" && pathname === "/api/integration-providers") {
const actorUserId = requirePermission(req, res, query, null, "integration:read", { route: pathname });
if (!actorUserId) return;
return sendJson(res, 200, { providers: integrationService.listSupportedProviders() });
}
projectId = projectRoute(pathname, "/integrations");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "integration:read", { projectId });
if (!actorUserId) return;
return sendJson(res, 200, { integrations: integrationService.listIntegrations(projectId) });
}
if (req.method === "POST" && projectId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "integration:write", { projectId });
if (!actorUserId) return;
return sendJson(res, 201, { integration: integrationService.createIntegration(projectId, body || {}, actorUserId) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
projectId = projectRoute(pathname, "/integration-mappings");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "integration:read", { projectId });
if (!actorUserId) return;
return sendJson(res, 200, { mappings: integrationService.listMappings(projectId) });
}
projectId = projectRoute(pathname, "/sync-runs");
if (req.method === "GET" && projectId) {
const actorUserId = requirePermission(req, res, query, null, "integration:read", { projectId });
if (!actorUserId) return;
return sendJson(res, 200, { syncRuns: integrationService.listSyncRuns(projectId) });
}
const integrationSyncMatch = pathname.match(/^\/api\/integrations\/([^/]+)\/sync$/);
if (req.method === "POST" && integrationSyncMatch) {
const integrationId = decodeURIComponent(integrationSyncMatch[1]);
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "integration:sync", { integrationId });
if (!actorUserId) return;
const result = integrationService.syncIntegration(integrationId, body || {}, actorUserId);
if (!result) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, 200, result);
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const integrationRiskMappingMatch = pathname.match(/^\/api\/integrations\/([^/]+)\/mappings\/risks\/([^/]+)$/);
if (req.method === "POST" && integrationRiskMappingMatch) {
const integrationId = decodeURIComponent(integrationRiskMappingMatch[1]);
const mappedRiskId = decodeURIComponent(integrationRiskMappingMatch[2]);
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "integration:write", { integrationId, riskId: mappedRiskId });
if (!actorUserId) return;
const mapping = integrationService.createRiskMapping(integrationId, mappedRiskId, body || {}, actorUserId);
if (!mapping) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, 201, { mapping });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const integrationLiveStatusMatch = pathname.match(/^\/api\/integrations\/([^/]+)\/live\/status$/);
if (req.method === "GET" && integrationLiveStatusMatch) {
const integrationId = decodeURIComponent(integrationLiveStatusMatch[1]);
const actorUserId = requirePermission(req, res, query, null, "integration:read", { integrationId });
if (!actorUserId) return;
const status = integrationService.getLiveStatus(integrationId);
if (!status) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, 200, status);
}
const integrationLiveTestMatch = pathname.match(/^\/api\/integrations\/([^/]+)\/live\/test$/);
if (req.method === "POST" && integrationLiveTestMatch) {
const integrationId = decodeURIComponent(integrationLiveTestMatch[1]);
const actorUserId = requirePermission(req, res, query, null, "integration:sync", { integrationId });
if (!actorUserId) return;
return integrationService.testLiveIntegration(integrationId)
.then(result => {
if (!result) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, result.ok || result.dryRun ? 200 : 400, result);
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const integrationLiveSyncMatch = pathname.match(/^\/api\/integrations\/([^/]+)\/live\/sync$/);
if (req.method === "POST" && integrationLiveSyncMatch) {
const integrationId = decodeURIComponent(integrationLiveSyncMatch[1]);
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "integration:sync", { integrationId });
if (!actorUserId) return { forbiddenHandled: true };
return integrationService.syncIntegrationLive(integrationId, body || {}, actorUserId);
})
.then(result => {
if (result && result.forbiddenHandled) return;
if (!result) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, 200, result);
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
const integrationId = idRoute(pathname, "^/api/integrations/");
if (req.method === "GET" && integrationId) {
const actorUserId = requirePermission(req, res, query, null, "integration:read", { integrationId });
if (!actorUserId) return;
const integration = integrationService.getIntegration(integrationId);
if (!integration) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, 200, { integration });
}
if (req.method === "PATCH" && integrationId) {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "integration:write", { integrationId });
if (!actorUserId) return;
const integration = integrationService.updateIntegration(integrationId, body || {}, actorUserId);
if (!integration) return sendJson(res, 404, { error: `Integration not found: ${integrationId}` });
return sendJson(res, 200, { integration });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
if (req.method === "POST" && pathname === "/api/calculate-risk") {
return parseBody(req)
.then(body => {
const actorUserId = requirePermission(req, res, query, body, "risk:read", { route: pathname });
if (!actorUserId) return;
const payload = body && body.risk ? body.risk : body;
if (!payload) return sendJson(res, 400, { error: "Missing risk payload" });
return sendJson(res, 200, { risk: dashboardService.calculateRisk(payload) });
})
.catch(error => sendJson(res, 400, { error: error.message }));
}
return sendJson(res, 404, { error: "API route not found" });
}
const server = http.createServer((req, res) => {
res._cosmicReq = req;
if (req.method === "OPTIONS") {
return res.writeHead(204, withCommonHeaders(req, APP_CONFIG, buildCorsHeaders(req, APP_CONFIG))).end();
}
if (APP_CONFIG.forceHttps && !isHttpsRequest(req, APP_CONFIG)) {
const host = req.headers.host || `localhost:${PORT}`;
const location = `https://${host}${req.url}`;
if (req.method === "GET" || req.method === "HEAD") {
res.writeHead(308, withCommonHeaders(req, APP_CONFIG, { Location: location }));
return res.end();
}
return sendJson(res, 426, { error: "HTTPS required", location });
}
const startedAt = Date.now();
res.on("finish", () => {
if (APP_CONFIG.requestLogEnabled) {
console.log(JSON.stringify({
time: new Date().toISOString(),
method: req.method,
path: url.parse(req.url).pathname,
status: res.statusCode,
ms: Date.now() - startedAt
}));
}
});
const parsed = url.parse(req.url);
const pathname = parsed.pathname;
if (pathname.startsWith("/api/")) {
return handleApi(req, res, pathname, parsed.query ? Object.fromEntries(new URLSearchParams(parsed.query)) : {});
}
if (pathname === "/" || pathname === "/index.html") {
return sendFile(res, path.join(PUBLIC, "index.html"));
}
if (pathname === "/data/sample-project.json") {
return sendFile(res, LEGACY_DATA_FILE);
}
const safePath = path.normalize(path.join(PUBLIC, pathname));
if (!safePath.startsWith(PUBLIC)) {
res.writeHead(403, withCommonHeaders(req, APP_CONFIG, { "Content-Type": "text/plain; charset=utf-8" }));
return res.end("Forbidden");
}
return sendFile(res, safePath);
});
server.listen(PORT, () => {
const validation = validateRuntimeConfig(APP_CONFIG);
if (validation.warnings.length) {
validation.warnings.forEach(warning => console.warn(`COSMIC configuration warning: ${warning}`));
}
if (!validation.ok) {
validation.errors.forEach(error => console.error(`COSMIC configuration error: ${error}`));
}
console.log(`COSMIC AI-Risk Dashboard running at http://localhost:${PORT}`);
});
module.exports = { server, APP_CONFIG };