@@ -189,6 +189,145 @@ describe('verify', function() {
189
189
} ) ;
190
190
} ) ;
191
191
} ) ;
192
- } ) ;
193
192
193
+ describe ( 'option: clockTimestamp' , function ( ) {
194
+ var clockTimestamp = 1000000000 ;
195
+ it ( 'should verify unexpired token relative to user-provided clockTimestamp' , function ( done ) {
196
+ var token = jwt . sign ( { foo : 'bar' , iat : clockTimestamp , exp : clockTimestamp + 1 } , key ) ;
197
+ jwt . verify ( token , key , { clockTimestamp : clockTimestamp } , function ( err , p ) {
198
+ assert . isNull ( err ) ;
199
+ done ( ) ;
200
+ } ) ;
201
+ } ) ;
202
+ it ( 'should error on expired token relative to user-provided clockTimestamp' , function ( done ) {
203
+ var token = jwt . sign ( { foo : 'bar' , iat : clockTimestamp , exp : clockTimestamp + 1 } , key ) ;
204
+ jwt . verify ( token , key , { clockTimestamp : clockTimestamp + 1 } , function ( err , p ) {
205
+ assert . equal ( err . name , 'TokenExpiredError' ) ;
206
+ assert . equal ( err . message , 'jwt expired' ) ;
207
+ assert . equal ( err . expiredAt . constructor . name , 'Date' ) ;
208
+ assert . equal ( Number ( err . expiredAt ) , ( clockTimestamp + 1 ) * 1000 ) ;
209
+ assert . isUndefined ( p ) ;
210
+ done ( ) ;
211
+ } ) ;
212
+ } ) ;
213
+ it ( 'should verify clockTimestamp is a number' , function ( done ) {
214
+ var token = jwt . sign ( { foo : 'bar' , iat : clockTimestamp , exp : clockTimestamp + 1 } , key ) ;
215
+ jwt . verify ( token , key , { clockTimestamp : 'notANumber' } , function ( err , p ) {
216
+ assert . equal ( err . name , 'JsonWebTokenError' ) ;
217
+ assert . equal ( err . message , 'clockTimestamp must be a number' ) ;
218
+ assert . isUndefined ( p ) ;
219
+ done ( ) ;
220
+ } ) ;
221
+ } ) ;
222
+ it ( 'should verify valid token with nbf' , function ( done ) {
223
+ var token = jwt . sign ( {
224
+ foo : 'bar' ,
225
+ iat : clockTimestamp ,
226
+ nbf : clockTimestamp + 1 ,
227
+ exp : clockTimestamp + 2
228
+ } , key ) ;
229
+ jwt . verify ( token , key , { clockTimestamp : clockTimestamp + 1 } , function ( err , p ) {
230
+ assert . isNull ( err ) ;
231
+ done ( ) ;
232
+ } ) ;
233
+ } ) ;
234
+ it ( 'should error on token used before nbf' , function ( done ) {
235
+ var token = jwt . sign ( {
236
+ foo : 'bar' ,
237
+ iat : clockTimestamp ,
238
+ nbf : clockTimestamp + 1 ,
239
+ exp : clockTimestamp + 2
240
+ } , key ) ;
241
+ jwt . verify ( token , key , { clockTimestamp : clockTimestamp } , function ( err , p ) {
242
+ assert . equal ( err . name , 'NotBeforeError' ) ;
243
+ assert . equal ( err . date . constructor . name , 'Date' ) ;
244
+ assert . equal ( Number ( err . date ) , ( clockTimestamp + 1 ) * 1000 ) ;
245
+ assert . isUndefined ( p ) ;
246
+ done ( ) ;
247
+ } ) ;
248
+ } ) ;
249
+ } ) ;
250
+
251
+ describe ( 'option: maxAge and clockTimestamp' , function ( ) {
252
+ // { foo: 'bar', iat: 1437018582, exp: 1437018800 }
253
+ var token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJpYXQiOjE0MzcwMTg1ODIsImV4cCI6MTQzNzAxODgwMH0.AVOsNC7TiT-XVSpCpkwB1240izzCIJ33Lp07gjnXVpA' ;
254
+ it ( 'should error for claims issued before a certain timespan' , function ( done ) {
255
+ var clockTimestamp = 1437018682 ;
256
+ var options = { algorithms : [ 'HS256' ] , clockTimestamp : clockTimestamp , maxAge : '1m' } ;
257
+
258
+ jwt . verify ( token , key , options , function ( err , p ) {
259
+ assert . equal ( err . name , 'TokenExpiredError' ) ;
260
+ assert . equal ( err . message , 'maxAge exceeded' ) ;
261
+ assert . equal ( err . expiredAt . constructor . name , 'Date' ) ;
262
+ assert . equal ( Number ( err . expiredAt ) , 1437018642000 ) ;
263
+ assert . isUndefined ( p ) ;
264
+ done ( ) ;
265
+ } ) ;
266
+ } ) ;
267
+ it ( 'should not error for claims issued before a certain timespan but still inside clockTolerance timespan' , function ( done ) {
268
+ var clockTimestamp = 1437018582 ;
269
+ var options = {
270
+ algorithms : [ 'HS256' ] ,
271
+ clockTimestamp : clockTimestamp ,
272
+ maxAge : '321ms' ,
273
+ clockTolerance : 100
274
+ } ;
275
+
276
+ jwt . verify ( token , key , options , function ( err , p ) {
277
+ assert . isNull ( err ) ;
278
+ assert . equal ( p . foo , 'bar' ) ;
279
+ done ( ) ;
280
+ } ) ;
281
+ } ) ;
282
+ it ( 'should not error if within maxAge timespan' , function ( done ) {
283
+ var clockTimestamp = 1437018582 ;
284
+ var options = { algorithms : [ 'HS256' ] , clockTimestamp : clockTimestamp , maxAge : '600ms' } ;
285
+
286
+ jwt . verify ( token , key , options , function ( err , p ) {
287
+ assert . isNull ( err ) ;
288
+ assert . equal ( p . foo , 'bar' ) ;
289
+ done ( ) ;
290
+ } ) ;
291
+ } ) ;
292
+ it ( 'can be more restrictive than expiration' , function ( done ) {
293
+ var clockTimestamp = 1437018588 ;
294
+ var options = { algorithms : [ 'HS256' ] , clockTimestamp : clockTimestamp , maxAge : '5s' } ;
295
+
296
+ jwt . verify ( token , key , options , function ( err , p ) {
297
+ assert . equal ( err . name , 'TokenExpiredError' ) ;
298
+ assert . equal ( err . message , 'maxAge exceeded' ) ;
299
+ assert . equal ( err . expiredAt . constructor . name , 'Date' ) ;
300
+ assert . equal ( Number ( err . expiredAt ) , 1437018587000 ) ;
301
+ assert . isUndefined ( p ) ;
302
+ done ( ) ;
303
+ } ) ;
304
+ } ) ;
305
+ it ( 'cannot be more permissive than expiration' , function ( done ) {
306
+ var clockTimestamp = 1437018900 ;
307
+ var options = { algorithms : [ 'HS256' ] , clockTimestamp : clockTimestamp , maxAge : '1000y' } ;
308
+
309
+ jwt . verify ( token , key , options , function ( err , p ) {
310
+ // maxAge not exceded, but still expired
311
+ assert . equal ( err . name , 'TokenExpiredError' ) ;
312
+ assert . equal ( err . message , 'jwt expired' ) ;
313
+ assert . equal ( err . expiredAt . constructor . name , 'Date' ) ;
314
+ assert . equal ( Number ( err . expiredAt ) , 1437018800000 ) ;
315
+ assert . isUndefined ( p ) ;
316
+ done ( ) ;
317
+ } ) ;
318
+ } ) ;
319
+ it ( 'should error if maxAge is specified but there is no iat claim' , function ( done ) {
320
+ var clockTimestamp = 1437018582 ;
321
+ var token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmb28iOiJiYXIifQ.0MBPd4Bru9-fK_HY3xmuDAc6N_embknmNuhdb9bKL_U' ;
322
+ var options = { algorithms : [ 'HS256' ] , clockTimestamp : clockTimestamp , maxAge : '1s' } ;
323
+
324
+ jwt . verify ( token , key , options , function ( err , p ) {
325
+ assert . equal ( err . name , 'JsonWebTokenError' ) ;
326
+ assert . equal ( err . message , 'iat required when maxAge is specified' ) ;
327
+ assert . isUndefined ( p ) ;
328
+ done ( ) ;
329
+ } ) ;
330
+ } ) ;
331
+ } ) ;
332
+ } ) ;
194
333
} ) ;
0 commit comments