@@ -12,7 +12,6 @@ const Promise = require('bluebird');
1212const promisify = require ( 'promisify-any' ) . use ( Promise ) ;
1313const ServerError = require ( '../errors/server-error' ) ;
1414const isFormat = require ( '@node-oauth/formats' ) ;
15- const util = require ( 'util' ) ;
1615const pkce = require ( '../pkce/pkce' ) ;
1716
1817/**
@@ -113,6 +112,36 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
113112 throw new InvalidGrantError ( 'Invalid grant: `redirect_uri` is not a valid URI' ) ;
114113 }
115114
115+ // optional: PKCE code challenge
116+
117+ if ( code . codeChallenge ) {
118+ if ( ! request . body . code_verifier ) {
119+ throw new InvalidGrantError ( 'Missing parameter: `code_verifier`' ) ;
120+ }
121+
122+ const hash = pkce . getHashForCodeChallenge ( {
123+ method : code . codeChallengeMethod ,
124+ verifier : request . body . code_verifier
125+ } ) ;
126+
127+ if ( ! hash ) {
128+ // notice that we assume that codeChallengeMethod is already
129+ // checked at an earlier stage when being read from
130+ // request.body.code_challenge_method
131+ throw new ServerError ( 'Server error: `getAuthorizationCode()` did not return a valid `codeChallengeMethod` property' ) ;
132+ }
133+
134+ if ( code . codeChallenge !== hash ) {
135+ throw new InvalidGrantError ( 'Invalid grant: code verifier is invalid' ) ;
136+ }
137+ }
138+ else {
139+ if ( request . body . code_verifier ) {
140+ // No code challenge but code_verifier was passed in.
141+ throw new InvalidGrantError ( 'Invalid grant: code verifier is invalid' ) ;
142+ }
143+ }
144+
116145 return code ;
117146 } ) ;
118147 }
@@ -201,4 +230,4 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
201230 * Export constructor.
202231 */
203232
204- module . exports = AuthorizationCodeGrantType ;
233+ module . exports = AuthorizationCodeGrantType ;
0 commit comments