1- import type { NextFunction , Request , Response } from ' express' ;
2- import jwt from ' jsonwebtoken' ;
1+ import type { NextFunction , Request , Response } from " express" ;
2+ import jwt from " jsonwebtoken" ;
33
4- import type { AuthenticatedUser } from ' ../types/auth.js' ;
5- import { UnauthorizedError } from ' ../errors/index.js' ;
6- import { logger } from ' ../logger.js' ;
4+ import type { AuthenticatedUser } from " ../types/auth.js" ;
5+ import { UnauthorizedError } from " ../errors/index.js" ;
6+ import { logger } from " ../logger.js" ;
77
8- export interface AuthenticatedLocals {
8+ // Re-export the locals shape for files that import it from this module
9+ export type AuthenticatedLocals = {
910 authenticatedUser ?: AuthenticatedUser ;
10- }
11-
12- // Extend Express Request to carry the authenticated developer id
13- declare module 'express-serve-static-core' {
14- interface Request {
15- developerId ?: string ;
16- }
17- }
11+ } ;
1812
1913/** Restrict accepted signing algorithms to prevent algorithm-confusion attacks. */
20- const ALLOWED_ALGORITHMS : jwt . Algorithm [ ] = [ ' HS256' ] ;
14+ const ALLOWED_ALGORITHMS : jwt . Algorithm [ ] = [ " HS256" ] ;
2115
2216export const requireAuth = (
2317 req : Request ,
2418 res : Response < unknown , AuthenticatedLocals > ,
25- next : NextFunction
19+ next : NextFunction ,
2620) : void => {
2721 let userId : string | undefined ;
2822
29- const authHeader = req . header ( ' authorization' ) ;
30- if ( authHeader ?. startsWith ( ' Bearer ' ) ) {
31- const token = authHeader . slice ( ' Bearer ' . length ) . trim ( ) ;
23+ const authHeader = req . header ( " authorization" ) ;
24+ if ( authHeader ?. startsWith ( " Bearer " ) ) {
25+ const token = authHeader . slice ( " Bearer " . length ) . trim ( ) ;
3226
3327 if ( ! token ) {
34- next ( new UnauthorizedError ( ' Missing token' , ' MISSING_TOKEN' ) ) ;
28+ next ( new UnauthorizedError ( " Missing token" , " MISSING_TOKEN" ) ) ;
3529 return ;
3630 }
3731
3832 const secret = process . env . JWT_SECRET ;
3933 if ( ! secret ) {
40- logger . error ( ' [requireAuth] JWT_SECRET is not configured' ) ;
34+ logger . error ( " [requireAuth] JWT_SECRET is not configured" ) ;
4135 next ( new UnauthorizedError ( ) ) ;
4236 return ;
4337 }
@@ -48,37 +42,45 @@ export const requireAuth = (
4842 } ) ;
4943
5044 // jwt.verify can return a plain string for unsigned payloads
51- if ( typeof decoded === ' string' || ! decoded ) {
52- logger . warn ( ' [requireAuth] Token payload is not a valid object' ) ;
53- next ( new UnauthorizedError ( ' Invalid token' , ' INVALID_TOKEN' ) ) ;
45+ if ( typeof decoded === " string" || ! decoded ) {
46+ logger . warn ( " [requireAuth] Token payload is not a valid object" ) ;
47+ next ( new UnauthorizedError ( " Invalid token" , " INVALID_TOKEN" ) ) ;
5448 return ;
5549 }
5650
5751 const uid = ( decoded as Record < string , unknown > ) . userId ;
58- if ( typeof uid !== 'string' || uid . trim ( ) === '' ) {
59- logger . warn ( '[requireAuth] Token missing required userId claim' ) ;
60- next ( new UnauthorizedError ( 'Token missing required claims' , 'MISSING_CLAIMS' ) ) ;
52+ if ( typeof uid !== "string" || uid . trim ( ) === "" ) {
53+ logger . warn ( "[requireAuth] Token missing required userId claim" ) ;
54+ next (
55+ new UnauthorizedError (
56+ "Token missing required claims" ,
57+ "MISSING_CLAIMS" ,
58+ ) ,
59+ ) ;
6160 return ;
6261 }
6362
6463 userId = uid ;
6564 } catch ( err ) {
6665 // Log the failure reason but never the token contents
67- const code = err instanceof jwt . TokenExpiredError
68- ? 'TOKEN_EXPIRED'
69- : err instanceof jwt . NotBeforeError
70- ? 'TOKEN_NOT_ACTIVE'
71- : 'INVALID_TOKEN' ;
66+ const code =
67+ err instanceof jwt . TokenExpiredError
68+ ? "TOKEN_EXPIRED"
69+ : err instanceof jwt . NotBeforeError
70+ ? "TOKEN_NOT_ACTIVE"
71+ : "INVALID_TOKEN" ;
7272
73- logger . warn ( '[requireAuth] JWT verification failed' , { code } ) ;
74- next ( new UnauthorizedError (
75- code === 'TOKEN_EXPIRED' ? 'Token expired' : 'Invalid token' ,
76- code ,
77- ) ) ;
73+ logger . warn ( "[requireAuth] JWT verification failed" , { code } ) ;
74+ next (
75+ new UnauthorizedError (
76+ code === "TOKEN_EXPIRED" ? "Token expired" : "Invalid token" ,
77+ code ,
78+ ) ,
79+ ) ;
7880 return ;
7981 }
8082 } else {
81- userId = req . header ( ' x-user-id' ) ;
83+ userId = req . header ( " x-user-id" ) ;
8284 }
8385
8486 if ( ! userId ) {
0 commit comments