@@ -3,9 +3,9 @@ import { UnionOneOf } from "../utils/typebox/union-oneof.js";
33import { Type } from "@sinclair/typebox" ;
44import { FastifyReply , FastifyRequest } from "fastify" ;
55import fp from "fastify-plugin" ;
6- import { skipSubjectCheck } from "oauth4webapi" ;
6+ import jwt , { JwtHeader , SigningKeyCallback } from "jsonwebtoken" ;
7+ import { JwksClient } from "jwks-rsa" ;
78import * as client from "openid-client" ;
8- import { WWWAuthenticateChallengeError } from "openid-client" ;
99
1010export interface AuthPluginOptions {
1111 /** The discovery URL of the OpenID Connect provider. */
@@ -66,29 +66,37 @@ export default fp<AuthPluginOptions>(async (fastify, opts) => {
6666 fastify . log . warn ( "Skip Auth: ON" ) ;
6767 }
6868
69- const config = await ( async ( ) => {
69+ const key = await ( async ( ) => {
7070 if ( skip ) {
7171 return null ;
7272 } else {
73- return await client . discovery (
73+ const config = await client . discovery (
7474 new URL ( opts . authDiscoveryURL ) ,
7575 opts . authClientID ,
7676 ) ;
77+ fastify . log . info (
78+ { opts, metadata : config ?. serverMetadata ( ) } ,
79+ "Successfully discovered the OpenID Connect provider." ,
80+ ) ;
81+
82+ const jwksClient = new JwksClient ( {
83+ jwksUri : config . serverMetadata ( ) . jwks_uri ?? "" ,
84+ } ) ;
85+ return async ( header : JwtHeader , callback : SigningKeyCallback ) => {
86+ jwksClient . getSigningKey ( header . kid , ( err , key ) => {
87+ const signingKey = key ?. getPublicKey ( ) ;
88+ callback ( err , signingKey ) ;
89+ } ) ;
90+ } ;
7791 }
7892 } ) ( ) ;
7993
80- fastify . log . info (
81- { opts, metadata : config ?. serverMetadata ( ) } ,
82- "Successfully discovered the OpenID Connect provider." ,
83- ) ;
84-
8594 fastify . decorateRequest ( "user" , undefined ) ;
8695 fastify . decorate (
8796 "auth" ,
8897 async function ( request : FastifyRequest , reply : FastifyReply ) {
89- if ( skip || ! config ) {
90- return ;
91- }
98+ if ( skip ) return ;
99+ if ( ! key ) return ;
92100
93101 // Extract the authorization header from the request
94102 const { authorization } = request . headers ;
@@ -106,23 +114,24 @@ export default fp<AuthPluginOptions>(async (fastify, opts) => {
106114 return reply . status ( 400 ) . send ( "Invalid Authorization Scheme" ) ;
107115 }
108116
109- // Verify the token with the client
110117 try {
111- const info = await client . fetchUserInfo (
112- config ,
113- token ,
114- skipSubjectCheck ,
115- ) ;
118+ const info = await new Promise < jwt . JwtPayload > ( ( resolve , reject ) => {
119+ jwt . verify ( token , key , ( err , info ) => {
120+ if ( err ) {
121+ return reject ( err ) ;
122+ }
123+ resolve ( info as jwt . JwtPayload ) ;
124+ } ) ;
125+ } ) ;
116126 request . user = info . email && getUsernameFromEmail ( info . email ) ;
117127 } catch ( e ) {
128+ console . log ( e ) ;
118129 if (
119- e instanceof WWWAuthenticateChallengeError &&
120- e . response ?. status === 401
130+ e instanceof jwt . JsonWebTokenError ||
131+ e instanceof jwt . TokenExpiredError ||
132+ e instanceof jwt . NotBeforeError
121133 ) {
122- return reply
123- . status ( 401 )
124- . type ( "application/json" )
125- . send ( await e . response . json ( ) ) ;
134+ return reply . status ( 401 ) . send ( `${ e . name } : ${ e . message } ` ) ;
126135 }
127136 throw e ;
128137 }
0 commit comments