← back to Re Flyers

server.js

53 lines

#!/usr/bin/env node
// TK-10708  re-flyers — normalized cross-source flyer index viewer/API.
// Serves data/flyers.json (built by scripts/build-seed.mjs from the existing
// re-flyer-aggregator outputs). Zero deps. Basic-auth admin/DW2024! (DW viewer standard).
//
// GATED-tier note: rows with rights_basis containing GATED are served WITH their flag so
// the viewer can visually mark/hide them. This surface NEVER downloads or re-hosts a file.

import http from 'node:http';
import { readFileSync, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';

const ROOT = dirname(fileURLToPath(import.meta.url));
const PORT = process.env.PORT || 0; // 0 = OS-assigned free port (no permanent port)
const USER = process.env.BASIC_USER || 'admin';
const PASS = process.env.BASIC_PASS || 'DW2024!';
const DATA = join(ROOT, 'data', 'flyers.json');

function loadFlyers() {
  if (!existsSync(DATA)) return { count: 0, flyers: [] };
  return JSON.parse(readFileSync(DATA, 'utf8'));
}

const server = http.createServer((req, res) => {
  const hdr = req.headers.authorization || '';
  const [, b64] = hdr.split(' ');
  const [u, p] = Buffer.from(b64 || '', 'base64').toString().split(':');
  if (u !== USER || p !== PASS) {
    res.writeHead(401, { 'WWW-Authenticate': 'Basic realm="re-flyers"' });
    return res.end('Auth required');
  }
  try {
    if (req.url.startsWith('/api/flyers')) {
      const data = loadFlyers();
      res.writeHead(200, { 'content-type': 'application/json' });
      return res.end(JSON.stringify(data));
    }
    if (req.url === '/health') { res.writeHead(200); return res.end('ok'); }
    const idx = join(ROOT, 'public', 'index.html');
    res.writeHead(200, { 'content-type': 'text/html' });
    return res.end(existsSync(idx) ? readFileSync(idx) : '<h1>re-flyers</h1>');
  } catch (e) {
    res.writeHead(500, { 'content-type': 'text/plain' });
    res.end('err: ' + e.message);
  }
});

server.listen(PORT, () => {
  const a = server.address();
  console.log(`re-flyers viewer on :${a.port} (basic-auth ${USER}) — GET /api/flyers`);
});