A social knowledge tool for researchers built on ATProto
at development 78 lines 2.4 kB view raw
1import { Request, Response, NextFunction } from 'express'; 2import { ITokenService } from '../../../../modules/user/application/services/ITokenService'; 3 4export interface AuthenticatedRequest extends Request { 5 did?: string; 6} 7 8export class AuthMiddleware { 9 constructor(private tokenService: ITokenService) {} 10 11 public ensureAuthenticated() { 12 return async ( 13 req: AuthenticatedRequest, 14 res: Response, 15 next: NextFunction, 16 ): Promise<void> => { 17 try { 18 // Extract token from Authorization header 19 const authHeader = req.headers.authorization; 20 if (!authHeader || !authHeader.startsWith('Bearer ')) { 21 res.status(401).json({ message: 'No access token provided' }); 22 return; // Stop execution after sending a response 23 } 24 25 const token = authHeader.substring(7); // Remove 'Bearer ' prefix 26 27 // Validate token 28 const didResult = await this.tokenService.validateToken(token); 29 30 if (didResult.isErr() || !didResult.value) { 31 res.status(403).json({ message: 'Invalid or expired token' }); 32 return; // Stop execution after sending a response 33 } 34 35 // Attach user DID to request for use in controllers 36 req.did = didResult.value; 37 38 // Continue to the next middleware or controller 39 next(); 40 } catch (error) { 41 res.status(500).json({ message: 'Authentication error' }); 42 } 43 }; 44 } 45 46 public optionalAuth() { 47 return async ( 48 req: AuthenticatedRequest, 49 res: Response, 50 next: NextFunction, 51 ) => { 52 try { 53 // Extract token from Authorization header 54 const authHeader = req.headers.authorization; 55 if (!authHeader || !authHeader.startsWith('Bearer ')) { 56 // No token, but that's okay - continue without authentication 57 return next(); 58 } 59 60 const token = authHeader.substring(7); // Remove 'Bearer ' prefix 61 62 // Validate token 63 const didResult = await this.tokenService.validateToken(token); 64 65 if (didResult.isOk() && didResult.value) { 66 // Attach user DID to request for use in controllers 67 req.did = didResult.value; 68 } 69 70 // Continue to the controller regardless of token validity 71 next(); 72 } catch (error) { 73 // Continue without authentication in case of error 74 next(); 75 } 76 }; 77 } 78}