// Authelia SSO helpers shared by the JSON API middleware (server.js authenticateSSO) // and the HTML page middleware (authenticatePage). const crypto = require('crypto'); const { renderError } = require('./render'); const ALLOWED_GROUPS = ['admin', 'employee']; // Upsert the SSO user into the `users` table. Extracted verbatim from authenticateSSO. async function upsertUser(pool, headers) { const userId = crypto.randomUUID(); await pool.query( `INSERT INTO users (id, username, display_name, email, groups, last_login) VALUES (?, ?, ?, ?, ?, NOW()) ON DUPLICATE KEY UPDATE display_name=VALUES(display_name), email=VALUES(email), groups=VALUES(groups), last_login=NOW()`, [ userId, headers['remote-user'], headers['remote-name'], headers['remote-email'], headers['remote-groups'] ] ); } // Express middleware factory for HTML page routes: same auth rules as the API, // but failures render a themed HTML page instead of JSON. function makeAuthenticatePage(pool) { return async function authenticatePage(req, res, next) { const remoteUser = req.headers['remote-user']; const remoteName = req.headers['remote-name']; const remoteEmail = req.headers['remote-email']; const remoteGroups = req.headers['remote-groups']; if (!remoteUser) { return renderError(req, res, 401, 'Not authenticated', 'Not authenticated — access via Authelia SSO (auth.lotusguild.org).'); } const groups = remoteGroups ? remoteGroups.split(',').map(g => g.trim()) : []; const hasAccess = groups.some(g => ALLOWED_GROUPS.includes(g)); if (!hasAccess) { return renderError(req, res, 403, 'Access denied', 'You must be in the admin or employee group to use this service.'); } try { await upsertUser(pool, req.headers); } catch (error) { console.error('Error updating user:', error); } req.user = { username: remoteUser, name: remoteName || remoteUser, email: remoteEmail || '', groups: groups, isAdmin: groups.includes('admin') }; next(); }; } module.exports = { upsertUser, makeAuthenticatePage, ALLOWED_GROUPS };