← back to Fabricfriday

server.js

52 lines

const express = require('express');
const path = require('path');
const fs = require('fs');

const app = express();
const PORT = process.env.PORT || 9898;

app.use(express.json());
// Vendor-redact: strip DW vendor names from /api/* responses (titles + vendor field).
// Standing rule — DW vendor names NEVER appear in customer-facing UI. (Matches the fleet.)
app.use(require('../_shared/api-vendor-redact'));

// Guard: never serve backup / snapshot artifacts from static root,
// even if one accidentally lands in public/.
app.use((req, res, next) => {
  if (/\.(bak|orig|rej)(\.|$)|\.pre-|~$/i.test(req.path)) {
    return res.status(404).send('Not Found');
  }
  next();
});

require('../_shared/_universal-promo-banner')(app, { slug: 'fabricfriday' });
app.use(express.static(path.join(__dirname, 'public')));

const products = JSON.parse(fs.readFileSync(path.join(__dirname, 'data/products.json'), 'utf8'));

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public/index.html'));
});

app.get('/health', (req, res) => {
  res.json({ status: 'ok', site: 'fabricfriday.com', port: PORT });
});

app.get('/api/products', (req, res) => {
  res.json(products);
});

app.post('/api/subscribe', (req, res) => {
  const { email } = req.body;
  if (!email || !email.includes('@')) {
    return res.status(400).json({ error: 'Valid email required' });
  }
  const entry = JSON.stringify({ email, site: 'fabricfriday.com', ts: new Date().toISOString() }) + '\n';
  fs.appendFileSync(path.join(__dirname, 'data/subscribers.jsonl'), entry);
  res.json({ ok: true, message: 'You\'re on the list. Every Friday, one exceptional fabric.' });
});

app.listen(PORT, () => {
  console.log(`fabricfriday.com running on port ${PORT}`);
});