← back to The Ai Factory

viewer.js

35 lines

// The AI Factory — viewer (:9891)
// Static viewer that polls the orchestrator's /runs endpoint.

require('dotenv').config();
const express = require('express');
const path = require('path');

const app = express();
const PORT = Number(process.env.VIEWER_PORT || 9891);

// LAN/tailnet auth gate
const BASIC_AUTH = process.env.BASIC_AUTH || 'admin:DWSecure2024!';
const AUTH_HEADER = 'Basic ' + Buffer.from(BASIC_AUTH).toString('base64');
app.use((req, res, next) => {
  if (req.path === '/healthz') return next();
  if (req.get('authorization') === AUTH_HEADER) return next();
  res.set('WWW-Authenticate', 'Basic realm="mac2-pm2"');
  res.status(401).send('auth required');
});

// 404-guard: never serve snapshot/backup files even if one accidentally
// lands in public/. Matches *.bak, *.bak.<anything>, *.pre-*, *.orig.
app.use((req, res, next) => {
  if (/\.(bak|orig)(\.|$)|\.pre-/i.test(req.path)) {
    return res.status(404).send('not found');
  }
  next();
});

app.use(express.static(path.join(__dirname, 'public')));

app.listen(PORT, '0.0.0.0', () => {
  console.log(`[ai-factory] viewer listening on http://0.0.0.0:${PORT} (basic-auth gated)`);
});