71 lines
2.2 KiB
JavaScript
71 lines
2.2 KiB
JavaScript
// 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 };
|