115 lines
4.6 KiB
JavaScript
115 lines
4.6 KiB
JavaScript
'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})`);
|
||
});
|