← back to Labj Cre Banks
Add zero-dep pm2 static server for LABJ CRE+Banking viewer (basic-auth, serves public/)
4675306b2e5ea8da0fbcb40376a9b09152a2ddb0 · 2026-08-10 17:15:42 -0700 · steve
Files touched
Diff
commit 4675306b2e5ea8da0fbcb40376a9b09152a2ddb0
Author: steve <steve@designerwallcoverings.com>
Date: Mon Aug 10 17:15:42 2026 -0700
Add zero-dep pm2 static server for LABJ CRE+Banking viewer (basic-auth, serves public/)
---
server.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..1950b8b
--- /dev/null
+++ b/server.js
@@ -0,0 +1,55 @@
+#!/usr/bin/env node
+'use strict';
+/*
+ * LABJ CRE + Banking — RENTV Prospect Database viewer.
+ * Zero-dependency static server (Node built-in http) for public/,
+ * behind Basic Auth admin / DW2024! (override via VIEWER_USER/PASS).
+ * Serves index.html + labj_master.json — no DB, no framework.
+ */
+const http = require('http');
+const fs = require('fs');
+const path = require('path');
+const crypto = require('crypto');
+
+const PORT = Number(process.env.PORT || 0);
+const HOST = process.env.HOST || '127.0.0.1';
+const USER = process.env.VIEWER_USER || 'admin';
+const PASS = process.env.VIEWER_PASS || 'DW2024!';
+const ROOT = path.join(__dirname, 'public');
+
+const TYPES = {
+ '.html': 'text/html; charset=utf-8', '.json': 'application/json; charset=utf-8',
+ '.js': 'text/javascript', '.css': 'text/css', '.csv': 'text/csv',
+ '.png': 'image/png', '.jpg': 'image/jpeg', '.svg': 'image/svg+xml',
+};
+
+function safeEq(a, b) {
+ const ab = Buffer.from(a), bb = Buffer.from(b);
+ return ab.length === bb.length && crypto.timingSafeEqual(ab, bb);
+}
+function authed(req) {
+ const h = req.headers.authorization || '';
+ if (!h.startsWith('Basic ')) return false;
+ const [u, p] = Buffer.from(h.slice(6), 'base64').toString('utf8').split(':');
+ return safeEq(u || '', USER) && safeEq(p || '', PASS);
+}
+
+const server = http.createServer((req, res) => {
+ if (!authed(req)) {
+ res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="labj-viewer"' });
+ return res.end('Auth required');
+ }
+ let rel = decodeURIComponent(new URL(req.url, 'http://x').pathname);
+ if (rel === '/' || rel === '') rel = '/index.html';
+ const full = path.normalize(path.join(ROOT, rel));
+ if (!full.startsWith(ROOT)) { res.writeHead(403); return res.end('Forbidden'); }
+ fs.readFile(full, (err, buf) => {
+ if (err) { res.writeHead(404); return res.end('Not found'); }
+ res.writeHead(200, { 'Content-Type': TYPES[path.extname(full)] || 'application/octet-stream', 'Cache-Control': 'no-store' });
+ res.end(buf);
+ });
+});
+
+server.listen(PORT, HOST, () => {
+ console.log(`LABJ viewer live: http://${HOST}:${server.address().port} (login ${USER} / ${PASS})`);
+});
← 992b50e chore: gitignore __pycache__ (session close)
·
back to Labj Cre Banks
·
Expand LABJ CRE prospect DB 99->182 firms (5-lane public-sou 026d3c7 →