veilstream-demo/web/server.js

73 lines
2.3 KiB
JavaScript
Raw Normal View History

const http = require("http");
const os = require("os");
const { Pool } = require("pg");
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const label = process.env.APP_LABEL || "VeilStream demo";
const port = Number(process.env.PORT || 3000);
const esc = (s) =>
String(s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" }[c]));
async function page() {
let rows = [];
let dbError = null;
try {
const r = await pool.query(
"SELECT id, full_name, email, phone, city, plan, mrr_cents FROM customers ORDER BY id"
);
rows = r.rows;
} catch (err) {
dbError = err.message;
}
const body = dbError
? `<p class="err">Database unreachable: ${esc(dbError)}</p>`
: `<table>
<tr><th>id</th><th>name</th><th>email</th><th>phone</th><th>city</th><th>plan</th><th>mrr</th></tr>
${rows
.map(
(r) =>
`<tr><td>${r.id}</td><td>${esc(r.full_name)}</td><td>${esc(r.email)}</td><td>${esc(
r.phone
)}</td><td>${esc(r.city)}</td><td>${esc(r.plan)}</td><td>$${(r.mrr_cents / 100).toFixed(
2
)}</td></tr>`
)
.join("\n ")}
</table>
<p class="meta">${rows.length} rows. If these values look like real people, the seed was not sanitized.</p>`;
return `<!doctype html>
<html><head><meta charset="utf-8"><title>${esc(label)}</title>
<style>
body{font:15px/1.5 -apple-system,system-ui,sans-serif;margin:2rem auto;max-width:52rem;padding:0 1rem}
table{border-collapse:collapse;width:100%;margin:1rem 0}
th,td{border:1px solid #ccc;padding:.4rem .6rem;text-align:left}
th{background:#f4f4f4}
.meta{color:#666}
.err{color:#b00}
dl{display:grid;grid-template-columns:max-content 1fr;gap:.2rem 1rem}
dt{color:#666}
</style></head><body>
<h1>${esc(label)}</h1>
<dl>
<dt>hostname</dt><dd>${esc(os.hostname())}</dd>
<dt>served at</dt><dd>${new Date().toISOString()}</dd>
<dt>node</dt><dd>${esc(process.version)}</dd>
</dl>
${body}
</body></html>`;
}
http
.createServer(async (req, res) => {
if (req.url === "/healthz") {
res.writeHead(200, { "content-type": "text/plain" });
return res.end("ok\n");
}
res.writeHead(200, { "content-type": "text/html; charset=utf-8" });
res.end(await page());
})
.listen(port, "0.0.0.0", () => console.log(`listening on ${port}`));