import { Request, Response, NextFunction } from 'express' import { prisma } from '../lib/prisma' import { getAuthToken, sendUnauthorized } from './authHelpers' import { verifyActorToken } from '../security/tokens' import { getSessionCookieName } from '../security/sessionCookies' import { actorLimiter } from './rateLimiter' /** * Validates a company-scoped Bearer token and loads the employee + company onto `req`. * * Guarantees on success: * req.employee — full employee record (with company relation) * req.company — the employee's company * req.companyId — string shorthand for req.company.id */ async function authenticateCompanyRequest(req: Request, res: Response, next: NextFunction) { const token = getAuthToken(req, getSessionCookieName('employee')) if (!token) return sendUnauthorized(res, 'unauthenticated', 'Authentication required') let payload: { sub: string; type: string } try { payload = verifyActorToken(token, 'employee') } catch { return sendUnauthorized(res, 'invalid_token', 'Invalid or expired session token') } const employee = await prisma.employee.findUnique({ where: { id: payload.sub }, include: { company: true }, }) if (!employee || !employee.isActive) { return sendUnauthorized(res, 'unauthenticated', 'Employee account not found or inactive') } req.employee = employee req.company = employee.company req.companyId = employee.companyId return actorLimiter(req, res, next) } export async function requireCompanyAuth(req: Request, res: Response, next: NextFunction) { return authenticateCompanyRequest(req, res, next) } export async function requireCompanyDocumentAuth(req: Request, res: Response, next: NextFunction) { return authenticateCompanyRequest(req, res, next) }