← back to Socrata Cre Viewer
Serve public/ static assets so nav-agent (/nav-agent/*) returns 200 on :9778
713a9bdeaf03dda885c8196f44b1c47a571f8203 · 2026-08-13 14:28:44 -0700 · Steve Abrams
Files touched
Diff
commit 713a9bdeaf03dda885c8196f44b1c47a571f8203
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Aug 13 14:28:44 2026 -0700
Serve public/ static assets so nav-agent (/nav-agent/*) returns 200 on :9778
---
server.js | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/server.js b/server.js
index 9bbc7d0..5e9d431 100644
--- a/server.js
+++ b/server.js
@@ -94,6 +94,27 @@ function send(res, code, body, type = 'application/json') {
res.end(typeof body === 'string' || Buffer.isBuffer(body) ? body : JSON.stringify(body));
}
+// Static assets from public/ (e.g. the nav-agent drop-in). Additive: only serves
+// files that resolve INSIDE public/ — path-traversal attempts fall through to 404.
+const PUBLIC_DIR = path.join(__dirname, 'public');
+const MIME = {
+ '.js': 'application/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8',
+ '.html': 'text/html; charset=utf-8', '.json': 'application/json; charset=utf-8',
+ '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg',
+ '.gif': 'image/gif', '.webp': 'image/webp', '.ico': 'image/x-icon', '.woff2': 'font/woff2',
+ '.woff': 'font/woff', '.ttf': 'font/ttf', '.map': 'application/json; charset=utf-8',
+};
+function serveStatic(res, pathname) {
+ const rel = decodeURIComponent(pathname).replace(/^\/+/, '');
+ const abs = path.resolve(PUBLIC_DIR, rel);
+ if (abs !== PUBLIC_DIR && !abs.startsWith(PUBLIC_DIR + path.sep)) return false; // traversal guard
+ if (!fs.existsSync(abs) || !fs.statSync(abs).isFile()) return false;
+ const type = MIME[path.extname(abs).toLowerCase()] || 'application/octet-stream';
+ res.writeHead(200, { 'Content-Type': type });
+ res.end(fs.readFileSync(abs));
+ return true;
+}
+
const server = http.createServer(async (req, res) => {
if (!authed(req)) { res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="socrata-cre"' }); return res.end('Auth required'); }
const url = new URL(req.url, 'http://x');
@@ -103,6 +124,7 @@ const server = http.createServer(async (req, res) => {
if (url.pathname === '/api/facets') return send(res, 200, await apiFacets());
if (url.pathname === '/api/rows') return send(res, 200, await apiRows(url.searchParams));
if (url.pathname === '/healthz') return send(res, 200, { ok: true });
+ if (serveStatic(res, url.pathname)) return;
return send(res, 404, { error: 'not found' });
} catch (e) { console.error(e); return send(res, 500, { error: String(e.message || e) }); }
});
← e9ca4ee nav-agent: universal grid-controls drop-in on internal dashb
·
back to Socrata Cre Viewer
·
chore: version-up v0.1.0 → v0.1.1 (session close) 130bdf8 →