A free, open, self-hosted app platform (GNU AGPLv3): one-click app deploys, Traefik reverse proxy with automatic SSL, rootless Docker support, gluetun VPN routing, and a web dashboard to manage it all. Free & open forever to self-host; optional paid hosted services fund it. See PROMISE.md. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
43 lines
1.4 KiB
JavaScript
Executable File
43 lines
1.4 KiB
JavaScript
Executable File
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 };
|