import { Request, Response, NextFunction } from 'express'; import { JWTService } from '../../Application/Services/JWTService'; import { UserState } from '../../Domain/User/UserAggregate'; import { logAuth, logWarning } from '../../Application/Services/Logger'; interface AuthenticatedRequest extends Request { user?: { userId: string; authLevel: 0 | 1; userStatus: UserState; orgId: string | null; }; } /** * Optional authentication middleware - extracts JWT data if present but doesn't require authentication * Used for endpoints that work for both authenticated and anonymous users */ export const optionalAuth = (req: AuthenticatedRequest, res: Response, next: NextFunction) => { const jwtService = new JWTService(); try { // Try to extract token from Authorization header or cookies const authHeader = req.headers.authorization; const token = authHeader?.startsWith('Bearer ') ? authHeader.substring(7) : req.cookies?.auth_token; if (token) { // If token exists, try to verify it const payload = jwtService.verify(req); if (payload) { req.user = { userId: payload.userId, authLevel: payload.authLevel, userStatus: payload.userStatus, orgId: payload.orgId || null }; logAuth('Optional auth - user authenticated', payload.userId, { authLevel: payload.authLevel, userStatus: payload.userStatus, orgId: payload.orgId }); } else { logWarning('Optional auth - invalid token provided', { hasToken: true, tokenLength: token.length }); } } // Continue regardless of authentication status next(); } catch (error) { // Log the error but continue without authentication logWarning('Optional auth - error processing token', { error: error instanceof Error ? error.message : String(error), hasAuthHeader: !!req.headers.authorization, hasCookie: !!req.cookies?.auth_token }); next(); } };