@@ -7,6 +7,8 @@ import * as JWT from './jwt'
77import { verifyWithJwks } from './jwt'
88import {
99 JwtAlgorithmNotImplemented ,
10+ JwtPayloadRequiresAud ,
11+ JwtTokenAudience ,
1012 JwtTokenExpired ,
1113 JwtTokenInvalid ,
1214 JwtTokenIssuedAt ,
@@ -226,6 +228,265 @@ describe('JWT', () => {
226228 expect ( authorized ?. iss ) . toEqual ( 'hello' )
227229 } )
228230
231+ it ( 'JwtPayloadRequireAud' , async ( ) => {
232+ const tok =
233+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiaWF0IjoxfQ.3Yd0dDicCKA6zu_G6AvxMX_fRH5wMz9gMCedOsYNAGc'
234+ const secret = 'a-secret'
235+ let err
236+ let authorized
237+ try {
238+ authorized = await JWT . verify ( tok , secret , {
239+ alg : AlgorithmTypes . HS256 ,
240+ aud : 'correct-audience' ,
241+ } )
242+ } catch ( e ) {
243+ err = e
244+ }
245+ expect ( err ) . toEqual ( new JwtPayloadRequiresAud ( { iss : 'https://issuer.example' , iat : 1 } ) )
246+ expect ( authorized ) . toBeUndefined ( )
247+ } )
248+
249+ it ( 'JwtTokenAudience(correct string - string)' , async ( ) => {
250+ const tok =
251+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoiY29ycmVjdC1hdWRpZW5jZSIsImlhdCI6MX0.z8T6szX-k66de4xB9OFbpWAOfx0RTqKSUPBcdpSY5nk'
252+ const secret = 'a-secret'
253+ let err
254+ let authorized
255+ try {
256+ authorized = await JWT . verify ( tok , secret , {
257+ alg : AlgorithmTypes . HS256 ,
258+ aud : 'correct-audience' ,
259+ } )
260+ } catch ( e ) {
261+ err = e
262+ }
263+ expect ( err ) . toBeUndefined ( )
264+ expect ( authorized ?. aud ) . toEqual ( 'correct-audience' )
265+ } )
266+
267+ it ( 'JwtTokenAudience(correct string - string[])' , async ( ) => {
268+ const tok =
269+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoiY29ycmVjdC1hdWRpZW5jZSIsImlhdCI6MX0.z8T6szX-k66de4xB9OFbpWAOfx0RTqKSUPBcdpSY5nk'
270+ const secret = 'a-secret'
271+ let err
272+ let authorized
273+ try {
274+ authorized = await JWT . verify ( tok , secret , {
275+ alg : AlgorithmTypes . HS256 ,
276+ aud : [ 'correct-audience' , 'other-audience' ] ,
277+ } )
278+ } catch ( e ) {
279+ err = e
280+ }
281+ expect ( err ) . toBeUndefined ( )
282+ expect ( authorized ?. aud ) . toEqual ( 'correct-audience' )
283+ } )
284+
285+ it ( 'JwtTokenAudience(correct string - RegExp)' , async ( ) => {
286+ const tok =
287+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoiY29ycmVjdC1hdWRpZW5jZSIsImlhdCI6MX0.z8T6szX-k66de4xB9OFbpWAOfx0RTqKSUPBcdpSY5nk'
288+ const secret = 'a-secret'
289+ let err
290+ let authorized
291+ try {
292+ authorized = await JWT . verify ( tok , secret , {
293+ alg : AlgorithmTypes . HS256 ,
294+ aud : / ^ c o r r e c t - a u d i e n c e $ / ,
295+ } )
296+ } catch ( e ) {
297+ err = e
298+ }
299+ expect ( err ) . toBeUndefined ( )
300+ expect ( authorized ?. aud ) . toEqual ( 'correct-audience' )
301+ } )
302+
303+ it ( 'JwtTokenAudience(correct string[] - string)' , async ( ) => {
304+ const tok =
305+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjpbImNvcnJlY3QtYXVkaWVuY2UiLCJvdGhlci1hdWRpZW5jZSJdLCJpYXQiOjF9.l73pNR5zMMAyuoN3f32hKtRJkoxZNzgTcVBZ2A2EsJY'
306+ const secret = 'a-secret'
307+ let err
308+ let authorized
309+ try {
310+ authorized = await JWT . verify ( tok , secret , {
311+ alg : AlgorithmTypes . HS256 ,
312+ aud : 'correct-audience' ,
313+ } )
314+ } catch ( e ) {
315+ err = e
316+ }
317+ expect ( err ) . toBeUndefined ( )
318+ expect ( authorized ?. aud ) . toEqual ( [ 'correct-audience' , 'other-audience' ] )
319+ } )
320+
321+ it ( 'JwtTokenAudience(correct string[] - string[])' , async ( ) => {
322+ const tok =
323+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjpbImNvcnJlY3QtYXVkaWVuY2UiLCJvdGhlci1hdWRpZW5jZSJdLCJpYXQiOjF9.l73pNR5zMMAyuoN3f32hKtRJkoxZNzgTcVBZ2A2EsJY'
324+ const secret = 'a-secret'
325+ let err
326+ let authorized
327+ try {
328+ authorized = await JWT . verify ( tok , secret , {
329+ alg : AlgorithmTypes . HS256 ,
330+ aud : [ 'correct-audience' , 'test' ] ,
331+ } )
332+ } catch ( e ) {
333+ err = e
334+ }
335+ expect ( err ) . toBeUndefined ( )
336+ expect ( authorized ?. aud ) . toEqual ( [ 'correct-audience' , 'other-audience' ] )
337+ } )
338+
339+ it ( 'JwtTokenAudience(correct string[] - RegExp)' , async ( ) => {
340+ const tok =
341+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjpbImNvcnJlY3QtYXVkaWVuY2UiLCJvdGhlci1hdWRpZW5jZSJdLCJpYXQiOjF9.l73pNR5zMMAyuoN3f32hKtRJkoxZNzgTcVBZ2A2EsJY'
342+ const secret = 'a-secret'
343+ let err
344+ let authorized
345+ try {
346+ authorized = await JWT . verify ( tok , secret , {
347+ alg : AlgorithmTypes . HS256 ,
348+ aud : / ^ c o r r e c t - a u d i e n c e $ / ,
349+ } )
350+ } catch ( e ) {
351+ err = e
352+ }
353+ expect ( err ) . toBeUndefined ( )
354+ expect ( authorized ?. aud ) . toEqual ( [ 'correct-audience' , 'other-audience' ] )
355+ } )
356+
357+ it ( 'JwtTokenAudience(wrong string - string)' , async ( ) => {
358+ const tok =
359+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoid3JvbmctYXVkaWVuY2UiLCJpYXQiOjF9.2vTYLiYL5r6qN-iRQ0VSfXh4ioLFtNzo0qc-OoPZmow'
360+ const secret = 'a-secret'
361+ let err
362+ let authorized
363+ try {
364+ authorized = await JWT . verify ( tok , secret , {
365+ alg : AlgorithmTypes . HS256 ,
366+ aud : 'correct-audience' ,
367+ } )
368+ } catch ( e ) {
369+ err = e
370+ }
371+ expect ( err ) . toEqual ( new JwtTokenAudience ( 'correct-audience' , 'wrong-audience' ) )
372+ expect ( authorized ) . toBeUndefined ( )
373+ } )
374+
375+ it ( 'JwtTokenAudience(wrong string - string[])' , async ( ) => {
376+ const tok =
377+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoid3JvbmctYXVkaWVuY2UiLCJpYXQiOjF9.2vTYLiYL5r6qN-iRQ0VSfXh4ioLFtNzo0qc-OoPZmow'
378+ const secret = 'a-secret'
379+ let err
380+ let authorized
381+ try {
382+ authorized = await JWT . verify ( tok , secret , {
383+ alg : AlgorithmTypes . HS256 ,
384+ aud : [ 'correct-audience' , 'other-audience' ] ,
385+ } )
386+ } catch ( e ) {
387+ err = e
388+ }
389+ expect ( err ) . toEqual (
390+ new JwtTokenAudience ( [ 'correct-audience' , 'other-audience' ] , 'wrong-audience' )
391+ )
392+ expect ( authorized ) . toBeUndefined ( )
393+ } )
394+
395+ it ( 'JwtTokenAudience(wrong string - RegExp)' , async ( ) => {
396+ const tok =
397+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoid3JvbmctYXVkaWVuY2UiLCJpYXQiOjF9.2vTYLiYL5r6qN-iRQ0VSfXh4ioLFtNzo0qc-OoPZmow'
398+ const secret = 'a-secret'
399+ let err
400+ let authorized
401+ try {
402+ authorized = await JWT . verify ( tok , secret , {
403+ alg : AlgorithmTypes . HS256 ,
404+ aud : / ^ c o r r e c t - a u d i e n c e $ / ,
405+ } )
406+ } catch ( e ) {
407+ err = e
408+ }
409+ expect ( err ) . toEqual ( new JwtTokenAudience ( / ^ c o r r e c t - a u d i e n c e $ / , 'wrong-audience' ) )
410+ expect ( authorized ) . toBeUndefined ( )
411+ } )
412+
413+ it ( 'JwtTokenAudience(wrong string[] - string)' , async ( ) => {
414+ const tok =
415+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjpbIndyb25nLWF1ZGllbmNlIiwib3RoZXItYXVkaWVuY2UiXSwiaWF0IjoxfQ.YTAM1xtKP4AeEeQSFQ81rcJM1leW_uDayQcTE6LxoP0'
416+ const secret = 'a-secret'
417+ let err
418+ let authorized
419+ try {
420+ authorized = await JWT . verify ( tok , secret , {
421+ alg : AlgorithmTypes . HS256 ,
422+ aud : 'correct-audience' ,
423+ } )
424+ } catch ( e ) {
425+ err = e
426+ }
427+ expect ( err ) . toEqual (
428+ new JwtTokenAudience ( 'correct-audience' , [ 'wrong-audience' , 'other-audience' ] )
429+ )
430+ expect ( authorized ) . toBeUndefined ( )
431+ } )
432+
433+ it ( 'JwtTokenAudience(wrong string[] - string[])' , async ( ) => {
434+ const tok =
435+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjpbIndyb25nLWF1ZGllbmNlIiwib3RoZXItYXVkaWVuY2UiXSwiaWF0IjoxfQ.YTAM1xtKP4AeEeQSFQ81rcJM1leW_uDayQcTE6LxoP0'
436+ const secret = 'a-secret'
437+ let err
438+ let authorized
439+ try {
440+ authorized = await JWT . verify ( tok , secret , {
441+ alg : AlgorithmTypes . HS256 ,
442+ aud : [ 'correct-audience' , 'test' ] ,
443+ } )
444+ } catch ( e ) {
445+ err = e
446+ }
447+ expect ( err ) . toEqual (
448+ new JwtTokenAudience ( [ 'correct-audience' , 'test' ] , [ 'wrong-audience' , 'other-audience' ] )
449+ )
450+ expect ( authorized ) . toBeUndefined ( )
451+ } )
452+
453+ it ( 'JwtTokenAudience(wrong string[] - RegExp)' , async ( ) => {
454+ const tok =
455+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjpbIndyb25nLWF1ZGllbmNlIiwib3RoZXItYXVkaWVuY2UiXSwiaWF0IjoxfQ.YTAM1xtKP4AeEeQSFQ81rcJM1leW_uDayQcTE6LxoP0'
456+ const secret = 'a-secret'
457+ let err
458+ let authorized
459+ try {
460+ authorized = await JWT . verify ( tok , secret , {
461+ alg : AlgorithmTypes . HS256 ,
462+ aud : / ^ c o r r e c t - a u d i e n c e $ / ,
463+ } )
464+ } catch ( e ) {
465+ err = e
466+ }
467+ expect ( err ) . toEqual (
468+ new JwtTokenAudience ( / ^ c o r r e c t - a u d i e n c e $ / , [ 'wrong-audience' , 'other-audience' ] )
469+ )
470+ expect ( authorized ) . toBeUndefined ( )
471+ } )
472+
473+ it ( 'JwtTokenAudience (no aud option and wrong aud in payload)' , async ( ) => {
474+ const tok =
475+ 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2lzc3Vlci5leGFtcGxlIiwiYXVkIjoid3JvbmctYXVkaWVuY2UiLCJpYXQiOjF9.2vTYLiYL5r6qN-iRQ0VSfXh4ioLFtNzo0qc-OoPZmow'
476+ const secret = 'a-secret'
477+ let err
478+ let authorized
479+ try {
480+ authorized = await JWT . verify ( tok , secret , {
481+ alg : AlgorithmTypes . HS256 ,
482+ } )
483+ } catch ( e ) {
484+ err = e
485+ }
486+ expect ( err ) . toBeUndefined ( )
487+ expect ( authorized ?. aud ) . toEqual ( 'wrong-audience' )
488+ } )
489+
229490 it ( 'HS256 sign & verify & decode' , async ( ) => {
230491 const payload = { message : 'hello world' }
231492 const secret = 'a-secret'
0 commit comments