const express = require('express'); const path = require('path'); const cookieParser = require('cookie-parser'); const config = require('./config.js'); const { verifyToken } = require('./auth.js'); function requireAuth(req, res, next) { const token = req.cookies?.libreportal_token; if (!token) return res.status(401).json({ error: 'Unauthorized' }); const payload = verifyToken(token); if (!payload) return res.status(401).json({ error: 'Token expired or invalid' }); req.user = payload; next(); } // Prevent the browser from caching authenticated /data/* responses so they're // not retained after logout or persisted to disk caches. function noStore(req, res, next) { res.setHeader('Cache-Control', 'no-store'); next(); } function setup(app) { app.use(express.json()); app.use(cookieParser()); // Block MIME sniffing on every response. app.use((req, res, next) => { res.setHeader('X-Content-Type-Options', 'nosniff'); next(); }); // /data/* requires auth. express.static doesn't generate directory listings, // so the only way to read anything is to know an exact path. app.use('/data', requireAuth, noStore, express.static(path.join(config.FRONTEND_PATH, 'data'))); // All other static assets (js, css, icons, html partials, index.html) remain public. // dotfiles='ignore' by default so .auth.json is never served. app.use(express.static(config.FRONTEND_PATH)); } module.exports = { setup, requireAuth };