import { Request, Response, NextFunction } from 'express'; import jwt from 'jsonwebtoken'; import prisma from '../lib/prisma'; export interface AuthRequest extends Request { user?: { id: string; role: string; username: string; }; } export const authenticate = async (req: AuthRequest, res: Response, next: NextFunction) => { const apiKey = req.headers['x-api-key'] as string | undefined; if (apiKey) { const user = await prisma.user.findUnique({ where: { apiKey } }); if (!user || user.role !== 'SERVICE') { return res.status(401).json({ error: 'Invalid API key' }); } req.user = { id: user.id, role: user.role, username: user.username }; return next(); } const authHeader = req.headers.authorization; if (!authHeader?.startsWith('Bearer ')) { return res.status(401).json({ error: 'Unauthorized' }); } const token = authHeader.split(' ')[1]; try { const payload = jwt.verify(token, process.env.JWT_SECRET!) as { id: string; role: string; username: string; }; req.user = payload; next(); } catch { return res.status(401).json({ error: 'Invalid or expired token' }); } }; export const requireAdmin = (req: AuthRequest, res: Response, next: NextFunction) => { if (req.user?.role !== 'ADMIN') { return res.status(403).json({ error: 'Admin access required' }); } next(); }; // Blocks USER role — allows ADMIN, AGENT, SERVICE export const requireAgent = (req: AuthRequest, res: Response, next: NextFunction) => { if (req.user?.role === 'USER') { return res.status(403).json({ error: 'Insufficient permissions' }); } next(); };