feat: JSON API voor React SPA onder /api/spa + 401-json voor /api paden

This commit is contained in:
mo
2026-07-21 21:13:33 +02:00
parent b2d6a9a2f6
commit 4cf9248c0b
7 changed files with 1314 additions and 0 deletions
+18
View File
@@ -50,6 +50,10 @@ app.use((req, res, next) => {
const publicPaths = ['/login', '/auth/login', '/css/dynamic.css', '/js/theme.js', '/health'];
const publicPrefixes = ['/wachtwoord-vergeten', '/wachtwoord-reset/', '/css/', '/js/', '/health'];
if (!publicPaths.includes(req.path) && !publicPrefixes.some(p => req.path.startsWith(p)) && !req.session.userId) {
// API-aanroepen krijgen 401 JSON i.p.v. een HTML-redirect (o.a. voor de React SPA)
if (req.path.startsWith('/api/')) {
return res.status(401).json({ error: 'Niet ingelogd' });
}
return res.redirect('/login');
}
res.locals.user = req.session.userId ? { username: req.session.username } : null;
@@ -172,6 +176,20 @@ app.use('/reports', require('./routes/reports'));
app.use('/integrations', require('./routes/integrations'));
app.use('/ai', require('./routes/ai'));
app.use('/api/v1', require('./routes/api'));
app.use('/api/spa', require('./routes/spa'));
// ---- React SPA (production build in public/spa) ----
const spaDir = path.join(__dirname, 'public', 'spa');
if (require('fs').existsSync(spaDir)) {
app.use('/app', express.static(spaDir));
// History-API fallback: alle niet-bestand paden onder /app -> index.html
app.get('/app/*', (req, res) => {
res.sendFile(path.join(spaDir, 'index.html'));
});
app.get('/app', (req, res) => {
res.sendFile(path.join(spaDir, 'index.html'));
});
}
app.get('/health', async (req, res) => {
try {