@@ -9,8 +9,10 @@ var InvalidArgumentError = require('../../../lib/errors/invalid-argument-error')
99var InvalidGrantError = require ( '../../../lib/errors/invalid-grant-error' ) ;
1010var InvalidRequestError = require ( '../../../lib/errors/invalid-request-error' ) ;
1111var Promise = require ( 'bluebird' ) ;
12+ var crypto = require ( 'crypto' ) ;
1213var Request = require ( '../../../lib/request' ) ;
1314var ServerError = require ( '../../../lib/errors/server-error' ) ;
15+ var stringUtil = require ( '../../../lib/utils/string-util' ) ;
1416var should = require ( 'should' ) ;
1517
1618/**
@@ -361,6 +363,110 @@ describe('AuthorizationCodeGrantType integration', function() {
361363 } ) ;
362364 } ) ;
363365
366+ it ( 'should throw an error if the `code_verifier` is invalid' , function ( ) {
367+ var codeVerifier = stringUtil . base64URLEncode ( crypto . randomBytes ( 32 ) ) ;
368+ var authorizationCode = {
369+ authorizationCode : 12345 ,
370+ client : { id : 'foobar' } ,
371+ expiresAt : new Date ( new Date ( ) * 2 ) ,
372+ user : { } ,
373+ codeChallengeMethod : 'S256' ,
374+ codeChallenge : stringUtil . base64URLEncode ( crypto . createHash ( 'sha256' ) . update ( codeVerifier ) . digest ( ) )
375+ } ;
376+ var client = { id : 'foobar' } ;
377+ var model = {
378+ getAuthorizationCode : function ( ) { return authorizationCode ; } ,
379+ revokeAuthorizationCode : function ( ) { } ,
380+ saveToken : function ( ) { }
381+ } ;
382+ var grantType = new AuthorizationCodeGrantType ( { accessTokenLifetime : 123 , model : model } ) ;
383+ var request = new Request ( { body : { code : 12345 , code_verifier : 'foo' } , headers : { } , method : { } , query : { } } ) ;
384+
385+ return grantType . getAuthorizationCode ( request , client )
386+ . then ( should . fail )
387+ . catch ( function ( e ) {
388+ e . should . be . an . instanceOf ( InvalidGrantError ) ;
389+ e . message . should . equal ( 'Invalid grant: `code_verifier` is invalid' ) ;
390+ } ) ;
391+ } ) ;
392+
393+ it ( 'should throw an error if the `code_verifier` is invalid' , function ( ) {
394+ var authorizationCode = {
395+ authorizationCode : 12345 ,
396+ client : { id : 'foobar' } ,
397+ expiresAt : new Date ( new Date ( ) * 2 ) ,
398+ user : { } ,
399+ codeChallengeMethod : 'plain' ,
400+ codeChallenge : 'baz'
401+ } ;
402+ var client = { id : 'foobar' } ;
403+ var model = {
404+ getAuthorizationCode : function ( ) { return authorizationCode ; } ,
405+ revokeAuthorizationCode : function ( ) { } ,
406+ saveToken : function ( ) { }
407+ } ;
408+ var grantType = new AuthorizationCodeGrantType ( { accessTokenLifetime : 123 , model : model } ) ;
409+ var request = new Request ( { body : { code : 12345 , code_verifier : 'foo' } , headers : { } , method : { } , query : { } } ) ;
410+
411+ return grantType . getAuthorizationCode ( request , client )
412+ . then ( should . fail )
413+ . catch ( function ( e ) {
414+ e . should . be . an . instanceOf ( InvalidGrantError ) ;
415+ e . message . should . equal ( 'Invalid grant: `code_verifier` is invalid' ) ;
416+ } ) ;
417+ } ) ;
418+
419+ it ( 'should return an auth code when `code_verifier` is valid' , function ( ) {
420+ var codeVerifier = stringUtil . base64URLEncode ( crypto . randomBytes ( 32 ) ) ;
421+ var authorizationCode = {
422+ authorizationCode : 12345 ,
423+ client : { id : 'foobar' } ,
424+ expiresAt : new Date ( new Date ( ) * 2 ) ,
425+ user : { } ,
426+ codeChallengeMethod : 'S256' ,
427+ codeChallenge : stringUtil . base64URLEncode ( crypto . createHash ( 'sha256' ) . update ( codeVerifier ) . digest ( ) )
428+ } ;
429+ var client = { id : 'foobar' } ;
430+ var model = {
431+ getAuthorizationCode : function ( ) { return authorizationCode ; } ,
432+ revokeAuthorizationCode : function ( ) { } ,
433+ saveToken : function ( ) { }
434+ } ;
435+ var grantType = new AuthorizationCodeGrantType ( { accessTokenLifetime : 123 , model : model } ) ;
436+ var request = new Request ( { body : { code : 12345 , code_verifier : codeVerifier } , headers : { } , method : { } , query : { } } ) ;
437+
438+ return grantType . getAuthorizationCode ( request , client )
439+ . then ( function ( data ) {
440+ data . should . equal ( authorizationCode ) ;
441+ } )
442+ . catch ( should . fail ) ;
443+ } ) ;
444+
445+ it ( 'should return an auth code when `code_verifier` is valid' , function ( ) {
446+ var authorizationCode = {
447+ authorizationCode : 12345 ,
448+ client : { id : 'foobar' } ,
449+ expiresAt : new Date ( new Date ( ) * 2 ) ,
450+ user : { } ,
451+ codeChallengeMethod : 'plain' ,
452+ codeChallenge : 'baz'
453+ } ;
454+ var client = { id : 'foobar' } ;
455+ var model = {
456+ getAuthorizationCode : function ( ) { return authorizationCode ; } ,
457+ revokeAuthorizationCode : function ( ) { } ,
458+ saveToken : function ( ) { }
459+ } ;
460+ var grantType = new AuthorizationCodeGrantType ( { accessTokenLifetime : 123 , model : model } ) ;
461+ var request = new Request ( { body : { code : 12345 , code_verifier : 'baz' } , headers : { } , method : { } , query : { } } ) ;
462+
463+ return grantType . getAuthorizationCode ( request , client )
464+ . then ( function ( data ) {
465+ data . should . equal ( authorizationCode ) ;
466+ } )
467+ . catch ( should . fail ) ;
468+ } ) ;
469+
364470 it ( 'should return an auth code' , function ( ) {
365471 var authorizationCode = { authorizationCode : 12345 , client : { id : 'foobar' } , expiresAt : new Date ( new Date ( ) * 2 ) , user : { } } ;
366472 var client = { id : 'foobar' } ;
0 commit comments