// Authentication Middleware const pool = require('../db'); const { teamToIvanti } = require('../helpers/teams'); // Require authenticated user — no parameters needed, pool is imported directly function requireAuth() { return async (req, res, next) => { const sessionId = req.cookies?.session_id; if (!sessionId) { return res.status(401).json({ error: 'Authentication required' }); } try { const { rows } = await pool.query( `SELECT s.*, u.id as user_id, u.username, u.email, u.role, u.user_group, u.bu_teams, u.is_active FROM sessions s JOIN users u ON s.user_id = u.id WHERE s.session_id = $1 AND s.expires_at > NOW()`, [sessionId] ); const session = rows[0]; if (!session) { return res.status(401).json({ error: 'Session expired or invalid' }); } if (!session.is_active) { return res.status(401).json({ error: 'Account is disabled' }); } // Attach user to request req.user = { id: session.user_id, username: session.username, email: session.email, role: session.role, group: session.user_group, teams: session.bu_teams ? session.bu_teams.split(',').filter(Boolean) : [] }; next(); } catch (err) { console.error('Auth middleware error:', err); return res.status(500).json({ error: 'Authentication error' }); } }; } // Require specific group(s) function requireGroup(...allowedGroups) { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: 'Authentication required' }); } if (!allowedGroups.includes(req.user.group)) { return res.status(403).json({ error: 'Insufficient permissions', required: allowedGroups, current: req.user.group }); } next(); }; } // Require team assignment — enforces team-scoped data access. // Admin group bypasses (req.teamScope = null means "no filter"). // Non-admin users without teams get 403. // Non-admin users with teams get req.teamScope = { short: [...], ivanti: [...] }. function requireTeam() { return (req, res, next) => { if (!req.user) { return res.status(401).json({ error: 'Authentication required' }); } // Admin bypass — full access to all teams if (req.user.group === 'Admin') { req.teamScope = null; return next(); } // No teams assigned — block access if (!req.user.teams || req.user.teams.length === 0) { return res.status(403).json({ error: 'No team assignment. Contact an administrator to assign BU teams to your account.', code: 'NO_TEAM_ASSIGNMENT' }); } // Build scope with both naming conventions req.teamScope = { short: req.user.teams, ivanti: req.user.teams.map(t => teamToIvanti(t)) }; next(); }; } module.exports = { requireAuth, requireGroup, requireTeam };