1717 */
1818
1919import { URL } from 'url' ;
20- import { createRemoteJWKSet , jwtVerify , JWTVerifyResult , JWTPayload , JWTVerifyOptions } from 'jose' ;
20+ import { createRemoteJWKSet , jwtVerify , JWTVerifyResult , JWTPayload , JWTVerifyOptions , ResolvedKey } from 'jose' ;
2121
2222export default async function validateAccessToken (
2323 accessToken : string ,
@@ -47,13 +47,13 @@ export default async function validateAccessToken(
4747 throw new Error ( 'Audience must be a non-empty string or array of strings in options.' ) ;
4848 }
4949
50- const JWKS = createRemoteJWKSet ( jwksUrl ) ;
50+ const JWKS : ReturnType < typeof createRemoteJWKSet > = createRemoteJWKSet ( jwksUrl ) ;
5151
5252 try {
53- const result = await jwtVerify ( accessToken , JWKS , {
54- issuer,
53+ const result : JWTVerifyResult < JWTPayload > & ResolvedKey = await jwtVerify ( accessToken , JWKS , {
5554 audience,
5655 clockTolerance,
56+ issuer,
5757 } ) ;
5858
5959 const SUPPORTED_SIGNATURE_ALGORITHMS : string [ ] = [ 'RS256' , 'RS512' , 'RS384' , 'PS256' ] ;
@@ -70,22 +70,42 @@ export default async function validateAccessToken(
7070 } catch ( error : any ) {
7171 if ( error . code ) {
7272 switch ( error . code ) {
73- case 'ERR_JOSE_GENERIC' :
74- if ( error . message . includes ( 'request failed' ) ) {
75- throw new Error ( `Failed to fetch JWKS from ${ jwksUri } : ${ error . message } ` ) ;
76- }
77- break ;
78- case 'ERR_JOSE_NO_KEY_MATCHED' :
79- throw new Error ( `No matching key found in JWKS for the token's 'kid' header: ${ error . message } ` ) ;
80- case 'ERR_JOSE_JWK_SET_MALFORMED' :
81- throw new Error ( `Malformed JWKS found at ${ jwksUri } : ${ error . message } ` ) ;
73+ // JWKS specific issues
74+ case 'ERR_JWKS_TIMEOUT' :
75+ throw new Error ( `Timeout while fetching JWKS from ${ jwksUri } : ${ error . message } ` ) ;
76+ case 'ERR_JWKS_NO_MATCHING_KEY' :
77+ throw new Error ( `No matching key found in JWKS at ${ jwksUri } for the token's header: ${ error . message } ` ) ;
78+ case 'ERR_JWKS_INVALID' :
79+ throw new Error ( `Invalid or malformed JWKS found at ${ jwksUri } : ${ error . message } ` ) ;
80+
81+ // JWS/JWT structural or signature issues
82+ case 'ERR_JWS_INVALID' :
83+ throw new Error ( `Invalid JWS structure: ${ error . message } ` ) ;
84+ case 'ERR_JWT_INVALID' :
85+ throw new Error ( `Invalid JWT structure or payload: ${ error . message } ` ) ;
86+ case 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED' :
87+ throw new Error ( `Token signature verification failed: ${ error . message } ` ) ;
88+
89+ // Common JWT claim validation issues
90+ case 'ERR_JWT_EXPIRED' :
91+ throw new Error ( `Token has expired: ${ error . message } ` ) ;
92+ case 'ERR_JWT_CLAIM_VALIDATION_FAILED' :
93+ throw new Error ( `JWT claim validation failed (${ error . claim || 'unknown claim' } ): ${ error . message } ` ) ;
94+
95+ // Other JOSE potential issues
96+ case 'ERR_JOSE_ALG_NOT_ALLOWED' :
97+ throw new Error ( `Token algorithm is not allowed: ${ error . message } ` ) ;
98+ case 'ERR_JOSE_NOT_SUPPORTED' :
99+ throw new Error ( `An unsupported JOSE feature/algorithm was encountered: ${ error . message } ` ) ;
100+
82101 default :
83- if ( error . code . startsWith ( 'ERR_JWT_' ) ) {
84- throw new Error ( `JWT validation error: ${ error . message } (Code: ${ error . code } )` ) ;
85- }
102+ throw new Error ( `JOSE validation error: ${ error . message } (Code: ${ error . code } )` ) ;
86103 }
87104 }
88105
89- throw new Error ( `An unexpected error occurred during token validation: ${ error . message } ` ) ;
106+ // Fallback for non-JOSE errors or errors without a code property
107+ throw new Error (
108+ `An unexpected error occurred during token validation: ${ error instanceof Error ? error . message : String ( error ) } ` ,
109+ ) ;
90110 }
91111}
0 commit comments