Regalamiunsorriso/rus/facematch/server.js
2026-03-14 20:04:39 +01:00

115 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict';
require('dotenv').config();
const express = require('express');
const cookieParser = require('cookie-parser');
const fetch = require('node-fetch');
const path = require('path');
const app = express();
// ─── Configuration ────────────────────────────────────────────────────────────
// PUBLIC_BASE the public-facing prefix behind which this app is mounted
// e.g. if Nginx proxies /face_match → this app, set PUBLIC_BASE=/face_match
// JAVA_APP_INTERNAL_URL internal (loopback) URL to reach the Tomcat app
// e.g. http://localhost:8080
// LOGIN_URL where to redirect unauthenticated users (public URL of the login)
const PUBLIC_BASE = (process.env.PUBLIC_BASE || '/face_match').replace(/\/$/, '');
const JAVA_INTERNAL_URL = (process.env.JAVA_APP_INTERNAL_URL || 'http://localhost:8080').replace(/\/$/, '');
const LOGIN_URL = process.env.LOGIN_URL || 'https://www.regalamiunsorriso.it/admin/menu/Menu4.abl';
const PORT = process.env.PORT || 3001;
// ─── Middleware ───────────────────────────────────────────────────────────────
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(cookieParser());
// Strip the public base prefix so routes work both mounted and standalone
app.use((req, _res, next) => {
if (PUBLIC_BASE && req.path.startsWith(PUBLIC_BASE)) {
req.url = req.url.slice(PUBLIC_BASE.length) || '/';
}
next();
});
// ─── Session validation helper ────────────────────────────────────────────────
/**
* Calls the lightweight JSP endpoint on the main Java app, forwarding the
* browser's JSESSIONID cookie. Returns { authenticated, userId } or throws.
*
* The Java app stores the session server-side; both apps are on the same host
* so the JSESSIONID issued by Tomcat is forwarded here by the browser.
*/
async function checkJavaSession(jsessionId) {
if (!jsessionId) return { authenticated: false };
const url = `${JAVA_INTERNAL_URL}/admin/pg/checkSession.jsp`;
const response = await fetch(url, {
method: 'GET',
headers: {
Cookie: `JSESSIONID=${jsessionId}`,
},
// Don't follow redirects a redirect usually means the session expired
redirect: 'manual',
});
if (response.status === 401 || response.status >= 300) {
return { authenticated: false };
}
try {
return await response.json(); // { authenticated, userId }
} catch {
return { authenticated: false };
}
}
// ─── Auth middleware ──────────────────────────────────────────────────────────
async function requireAuth(req, res, next) {
const jsessionId = req.cookies['JSESSIONID'];
let sessionInfo;
try {
sessionInfo = await checkJavaSession(jsessionId);
} catch (err) {
console.error('Session validation request failed:', err.message);
sessionInfo = { authenticated: false };
}
if (!sessionInfo.authenticated) {
// Redirect to the main app login, passing the desired return URL
const returnUrl = encodeURIComponent(`https://www.regalamiunsorriso.it${PUBLIC_BASE}${req.path}`);
return res.redirect(`${LOGIN_URL}?returnUrl=${returnUrl}`);
}
// Attach session info for use in route handlers / views
req.sessionInfo = sessionInfo;
next();
}
// ─── Routes ───────────────────────────────────────────────────────────────────
// Main entry point protected
app.get('/', requireAuth, (req, res) => {
res.render('index', {
userId: req.sessionInfo.userId,
publicBase: PUBLIC_BASE,
});
});
// Health-check unprotected (used by reverse proxy / monitoring)
app.get('/health', (_req, res) => {
res.json({ status: 'ok' });
});
// Catch-all 404
app.use((_req, res) => {
res.status(404).send('Not found');
});
// ─── Start ────────────────────────────────────────────────────────────────────
app.listen(PORT, () => {
console.log(`facematch app listening on port ${PORT} (base: ${PUBLIC_BASE})`);
});