PeerCortex/server/routes/changelog.js
Rene Fichtmueller 570c178c61
Some checks failed
build-verify / build-verify (push) Failing after 10s
build-verify / build-verify (pull_request) Failing after 10s
refactor: extract proxy-stubs/changelog/hijack-alerts/pdf-export/aspa-adoption routes
Final Phase C batch: moves the remaining inline route bodies (12 proxy
stubs, /changelog, the webhooks/hijacks group, PDF export, ASPA adoption
tracker + IPv6 stats endpoints) into server/routes/*.js and
server/services/api-proxy.js, verified byte-for-byte via the smoke-test
diff. Also drops the now-duplicate proxyToApiServer()/API_SERVER_PORT
that were left behind in server.js after api-proxy.js absorbed them.

server.js: 6838 -> 578 lines, under the 800-line project limit.
2026-07-17 08:08:48 +02:00

47 lines
2.7 KiB
JavaScript

const fs = require("fs");
// Changelog page: renders CHANGELOG.md as HTML
function handleChangelog(req, res) {
try {
const md = fs.readFileSync('/opt/peercortex-app/CHANGELOG.md', 'utf8');
const lines = md.split('\n');
let html = '';
for (const line of lines) {
if (line.startsWith('## ')) {
html += `<h2 style="font-family:var(--serif);font-size:1.4rem;font-weight:800;margin:2rem 0 .5rem;border-top:2px solid var(--text);padding-top:1rem">${line.slice(3)}</h2>`;
} else if (line.startsWith('### ')) {
html += `<h3 style="font-family:var(--body);font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:1rem 0 .4rem">${line.slice(4)}</h3>`;
} else if (line.startsWith('- **')) {
const m = line.replace(/^- \*\*(.+?)\*\*(.*)$/, '<strong>$1</strong>$2');
html += `<p style="font-family:var(--body);font-size:.85rem;margin:.2rem 0;padding-left:1rem;border-left:2px solid var(--border)">· ${m}</p>`;
} else if (line.startsWith('- ')) {
html += `<p style="font-family:var(--body);font-size:.82rem;margin:.15rem 0;color:var(--muted);padding-left:1rem">· ${line.slice(2)}</p>`;
} else if (line.startsWith('# ')) {
html += `<h1 style="font-family:var(--serif);font-size:2rem;font-weight:900;margin-bottom:.25rem">${line.slice(2)}</h1>`;
}
}
const page = `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>PeerCortex Changelog</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=Source+Serif+4:ital,wght@0,400;0,600;1,400&family=IBM+Plex+Mono:wght@400;600&display=swap" rel="stylesheet">
<style>
:root{--bg:#F5F2EC;--text:#1C1917;--muted:#57534E;--border:#C9C3B6;--serif:'Playfair Display',Georgia,serif;--body:'Source Serif 4',Georgia,serif;--mono:'IBM Plex Mono',monospace;--purple:#B83A1B}
body{font-family:var(--body);background:var(--bg);color:var(--text);max-width:760px;margin:0 auto;padding:2rem}
a{color:var(--purple);text-decoration:none}
.back{font-family:var(--mono);font-size:.72rem;color:var(--muted);margin-bottom:2rem;display:block}
body.dark{--bg:#0f0f0f;--text:#e8e4dc;--muted:#a09890;--border:#333}
</style></head><body>
<a href="/" class="back">← peercortex.org</a>
${html}
<p style="margin-top:3rem;font-family:var(--mono);font-size:.6rem;color:var(--muted)">PeerCortex · v0.5.0 · Open Source · MIT</p>
</body></html>`;
res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader('Cache-Control', 'no-store');
res.writeHead(200);
return res.end(page);
} catch(e) {
res.writeHead(500); return res.end('Changelog not available');
}
}
module.exports = { handleChangelog };