// Authentication route registration for the web app. const { normalizeReturnToPath, getRequestOrigin } = require('../../lib/auth/session'); module.exports = function registerAuthRoutes(app, deps) { const pool = deps.pool; const pages = deps.pages; const createUserSession = deps.createUserSession; const setSessionCookie = deps.setSessionCookie; const clearSessionCookie = deps.clearSessionCookie; const parseCookies = deps.parseCookies; const consumeAuthMessageCookie = deps.consumeAuthMessageCookie; const setAuthMessageCookie = deps.setAuthMessageCookie; const hashSessionToken = deps.hashSessionToken; const verifyPassword = deps.verifyPassword; const sessionCookieName = deps.sessionCookieName; function getReturnTo(req) { return normalizeReturnToPath(req && (req.query && req.query.returnTo || req.body && req.body.returnTo), getRequestOrigin(req)); } function buildLoginRedirect(returnTo) { return returnTo ? '/login?returnTo=' + encodeURIComponent(returnTo) : '/login'; } app.get('/', function (req, res) { res.redirect(req.currentUser ? '/dashboard' : '/login'); }); app.get('/login', function (req, res) { const returnTo = getReturnTo(req); if (req.currentUser) { return res.redirect(returnTo || '/dashboard'); } const message = typeof consumeAuthMessageCookie === 'function' ? consumeAuthMessageCookie(req, res) : (req.query.message ? String(req.query.message) : ''); res.send(pages.renderLoginPage(message, returnTo)); }); app.post('/login', async function (req, res, next) { try { const username = String(req.body.username || '').trim(); const password = String(req.body.password || ''); if (!username || !password) { return res.status(400).send('Username and password are required.'); } const [rows] = await pool.query('SELECT id, name, username, password_hash, password_salt, password_iterations FROM a_users WHERE username = ? LIMIT 1', [username]); const user = rows[0] || null; if (!user || !verifyPassword(password, user)) { const returnTo = getReturnTo(req); if (typeof setAuthMessageCookie === 'function') { setAuthMessageCookie(res, 'Invalid username or password.'); return res.redirect(buildLoginRedirect(returnTo)); } return res.status(401).send(pages.renderLoginPage('Invalid username or password.', returnTo)); } const returnTo = getReturnTo(req); const token = await createUserSession(pool, user.id); setSessionCookie(res, token); res.redirect(returnTo || '/dashboard'); } catch (error) { next(error); } }); app.get('/logout', async function (req, res, next) { try { const cookies = parseCookies(req.headers.cookie || ''); const token = cookies[sessionCookieName]; if (token) { await pool.query('DELETE FROM a_sessions WHERE session_hash = ?', [hashSessionToken(token)]); } clearSessionCookie(res); if (typeof setAuthMessageCookie === 'function') { setAuthMessageCookie(res, 'You have been signed out.'); return res.redirect('/login'); } res.redirect('/login'); } catch (error) { next(error); } }); };