@@ -217,4 +217,56 @@ describe('verifyJwt(jwt, options)', () => {
217217 expect ( error ?. message ) . toContain ( 'Invalid JWT type' ) ;
218218 expect ( error ?. message ) . toContain ( 'Expected "at+jwt, application/at+jwt"' ) ;
219219 } ) ;
220+
221+ it ( 'rejects an expired JWT when clockSkewInMs is explicitly 0' , async ( ) => {
222+ vi . setSystemTime ( new Date ( ( mockJwtPayload . exp + 1 ) * 1000 ) ) ;
223+ const inputVerifyJwtOptions = {
224+ key : mockJwks . keys [ 0 ] ,
225+ issuer : mockJwtPayload . iss ,
226+ authorizedParties : [ 'https://accounts.inspired.puma-74.lcl.dev' ] ,
227+ clockSkewInMs : 0 ,
228+ } ;
229+ const { errors : [ error ] = [ ] } = await verifyJwt ( mockJwt , inputVerifyJwtOptions ) ;
230+ expect ( error ) . toBeDefined ( ) ;
231+ expect ( error ?. message ) . toContain ( 'JWT is expired' ) ;
232+ } ) ;
233+
234+ it ( 'accepts a recently expired JWT within the default clock skew when clockSkewInMs is undefined' , async ( ) => {
235+ vi . setSystemTime ( new Date ( ( mockJwtPayload . exp + 1 ) * 1000 ) ) ;
236+ const inputVerifyJwtOptions = {
237+ key : mockJwks . keys [ 0 ] ,
238+ issuer : mockJwtPayload . iss ,
239+ authorizedParties : [ 'https://accounts.inspired.puma-74.lcl.dev' ] ,
240+ } ;
241+ const { data } = await verifyJwt ( mockJwt , inputVerifyJwtOptions ) ;
242+ expect ( data ) . toEqual ( mockJwtPayload ) ;
243+ } ) ;
244+
245+ it ( 'falls back to the default clock skew when clockSkewInMs is NaN' , async ( ) => {
246+ vi . setSystemTime ( new Date ( ( mockJwtPayload . exp + 1 ) * 1000 ) ) ;
247+ const inputVerifyJwtOptions = {
248+ key : mockJwks . keys [ 0 ] ,
249+ issuer : mockJwtPayload . iss ,
250+ authorizedParties : [ 'https://accounts.inspired.puma-74.lcl.dev' ] ,
251+ clockSkewInMs : Number . NaN ,
252+ } ;
253+ const { data } = await verifyJwt ( mockJwt , inputVerifyJwtOptions ) ;
254+ expect ( data ) . toEqual ( mockJwtPayload ) ;
255+
256+ vi . setSystemTime ( new Date ( ( mockJwtPayload . exp + 60 ) * 1000 ) ) ;
257+ const { errors : [ error ] = [ ] } = await verifyJwt ( mockJwt , inputVerifyJwtOptions ) ;
258+ expect ( error ?. message ) . toContain ( 'JWT is expired' ) ;
259+ } ) ;
260+
261+ it ( 'falls back to the default clock skew when clockSkewInMs is Infinity' , async ( ) => {
262+ vi . setSystemTime ( new Date ( ( mockJwtPayload . exp + 3600 ) * 1000 ) ) ;
263+ const inputVerifyJwtOptions = {
264+ key : mockJwks . keys [ 0 ] ,
265+ issuer : mockJwtPayload . iss ,
266+ authorizedParties : [ 'https://accounts.inspired.puma-74.lcl.dev' ] ,
267+ clockSkewInMs : Number . POSITIVE_INFINITY ,
268+ } ;
269+ const { errors : [ error ] = [ ] } = await verifyJwt ( mockJwt , inputVerifyJwtOptions ) ;
270+ expect ( error ?. message ) . toContain ( 'JWT is expired' ) ;
271+ } ) ;
220272} ) ;
0 commit comments