From 2baa00dfd4ad79408688a8993910fd8a79f85ee8 Mon Sep 17 00:00:00 2001 From: Tony Balascio Date: Mon, 10 Aug 2026 02:35:15 +0000 Subject: [PATCH] Add/Update web/server.js (Batch 4: real audit API backend + fetch wiring; port 8199 to avoid Gitea 3000 collision) --- web/server.js | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 web/server.js diff --git a/web/server.js b/web/server.js new file mode 100644 index 0000000..4b4a344 --- /dev/null +++ b/web/server.js @@ -0,0 +1,58 @@ +// DOP Cold Audit intake API — Node.js, zero-dependency. +// Listens for POST /api/audit and appends leads to audit_leads.jsonl. +// +// NOTE: Port is intentionally NOT hardcoded to 3000 — Gitea occupies +// localhost:3000 on this VPS. Set PORT env (systemd) or it defaults to 8199. +// Bind to 127.0.0.1 when fronted by the Caddy same-origin /api/audit route. + +const http = require('http'); +const fs = require('fs'); +const path = require('path'); + +const PORT = parseInt(process.env.PORT || '8199', 10); +const HOST = process.env.HOST || '127.0.0.1'; +const LEADS_FILE = process.env.LEADS_FILE || path.join(__dirname, 'audit_leads.jsonl'); + +const server = http.createServer((req, res) => { + // CORS — in production restrict this to your actual site origin, + // or (preferred) drop CORS entirely and use the Caddy same-origin proxy. + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + res.writeHead(204); + res.end(); + return; + } + + if (req.method === 'POST' && req.url === '/api/audit') { + let body = ''; + req.on('data', (chunk) => { body += chunk.toString(); }); + req.on('end', () => { + try { + const data = JSON.parse(body); + + // TODO: Pipe this directly into the agent-assisted audit engine. + // For now, append to a JSONL file for human review. + const record = { ...data, received_at: new Date().toISOString() }; + fs.appendFileSync(LEADS_FILE, JSON.stringify(record) + '\n'); + + console.log('New Audit Request Received:', JSON.stringify(record)); + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ status: 'success', message: 'Audit request received.' })); + } catch (error) { + res.writeHead(400, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ status: 'error', message: 'Invalid JSON payload.' })); + } + }); + } else { + res.writeHead(404, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ status: 'error', message: 'Not Found' })); + } +}); + +server.listen(PORT, HOST, () => { + console.log(`DOP Audit API listening on ${HOST}:${PORT}`); + console.log(`Leads will be appended to: ${LEADS_FILE}`); +});