@@ -8,8 +8,6 @@ const AbstractGrantType = require('./abstract-grant-type');
88const InvalidArgumentError = require ( '../errors/invalid-argument-error' ) ;
99const InvalidGrantError = require ( '../errors/invalid-grant-error' ) ;
1010const InvalidRequestError = require ( '../errors/invalid-request-error' ) ;
11- const Promise = require ( 'bluebird' ) ;
12- const promisify = require ( 'promisify-any' ) . use ( Promise ) ;
1311const ServerError = require ( '../errors/server-error' ) ;
1412const isFormat = require ( '@node-oauth/formats' ) ;
1513const pkce = require ( '../pkce/pkce' ) ;
@@ -45,7 +43,7 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
4543 * @see https://tools.ietf.org/html/rfc6749#section-4.1.3
4644 */
4745
48- handle ( request , client ) {
46+ async handle ( request , client ) {
4947 if ( ! request ) {
5048 throw new InvalidArgumentError ( 'Missing parameter: `request`' ) ;
5149 }
@@ -54,96 +52,87 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
5452 throw new InvalidArgumentError ( 'Missing parameter: `client`' ) ;
5553 }
5654
57- return Promise . bind ( this )
58- . then ( function ( ) {
59- return this . getAuthorizationCode ( request , client ) ;
60- } )
61- . tap ( function ( code ) {
62- return this . validateRedirectUri ( request , code ) ;
63- } )
64- . tap ( function ( code ) {
65- return this . revokeAuthorizationCode ( code ) ;
66- } )
67- . then ( function ( code ) {
68- return this . saveToken ( code . user , client , code . authorizationCode , code . scope ) ;
69- } ) ;
55+ const code = await this . getAuthorizationCode ( request , client ) ;
56+ await this . validateRedirectUri ( request , code ) ;
57+ await this . revokeAuthorizationCode ( code ) ;
58+ 59+ return this . saveToken ( code . user , client , code . authorizationCode , code . scope ) ;
7060 }
7161
7262 /**
7363 * Get the authorization code.
7464 */
7565
76- getAuthorizationCode ( request , client ) {
66+ async getAuthorizationCode ( request , client ) {
7767 if ( ! request . body . code ) {
7868 throw new InvalidRequestError ( 'Missing parameter: `code`' ) ;
7969 }
8070
8171 if ( ! isFormat . vschar ( request . body . code ) ) {
8272 throw new InvalidRequestError ( 'Invalid parameter: `code`' ) ;
8373 }
84- return promisify ( this . model . getAuthorizationCode , 1 )
85- . call ( this . model , request . body . code )
86- . then ( ( code ) => {
87- if ( ! code ) {
88- throw new InvalidGrantError ( 'Invalid grant: authorization code is invalid' ) ;
89- }
90- 91- if ( ! code . client ) {
92- throw new ServerError ( 'Server error: `getAuthorizationCode()` did not return a `client` object' ) ;
93- }
94- 95- if ( ! code . user ) {
96- throw new ServerError ( 'Server error: `getAuthorizationCode()` did not return a `user` object' ) ;
97- }
98- 99- if ( code . client . id !== client . id ) {
100- throw new InvalidGrantError ( 'Invalid grant: authorization code is invalid' ) ;
101- }
102- 103- if ( ! ( code . expiresAt instanceof Date ) ) {
104- throw new ServerError ( 'Server error: `expiresAt` must be a Date instance' ) ;
105- }
106- 107- if ( code . expiresAt < new Date ( ) ) {
108- throw new InvalidGrantError ( 'Invalid grant: authorization code has expired' ) ;
109- }
110- 111- if ( code . redirectUri && ! isFormat . uri ( code . redirectUri ) ) {
112- throw new InvalidGrantError ( 'Invalid grant: `redirect_uri` is not a valid URI' ) ;
113- }
114- 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- 145- return code ;
74+ 75+ const code = await this . model . getAuthorizationCode ( request . body . code ) ;
76+ 77+ if ( ! code ) {
78+ throw new InvalidGrantError ( 'Invalid grant: authorization code is invalid' ) ;
79+ }
80+ 81+ if ( ! code . client ) {
82+ throw new ServerError ( 'Server error: `getAuthorizationCode()` did not return a `client` object' ) ;
83+ }
84+ 85+ if ( ! code . user ) {
86+ throw new ServerError ( 'Server error: `getAuthorizationCode()` did not return a `user` object' ) ;
87+ }
88+ 89+ if ( code . client . id !== client . id ) {
90+ throw new InvalidGrantError ( 'Invalid grant: authorization code is invalid' ) ;
91+ }
92+ 93+ if ( ! ( code . expiresAt instanceof Date ) ) {
94+ throw new ServerError ( 'Server error: `expiresAt` must be a Date instance' ) ;
95+ }
96+ 97+ if ( code . expiresAt < new Date ( ) ) {
98+ throw new InvalidGrantError ( 'Invalid grant: authorization code has expired' ) ;
99+ }
100+ 101+ if ( code . redirectUri && ! isFormat . uri ( code . redirectUri ) ) {
102+ throw new InvalidGrantError ( 'Invalid grant: `redirect_uri` is not a valid URI' ) ;
103+ }
104+ 105+ // optional: PKCE code challenge
106+ 107+ if ( code . codeChallenge ) {
108+ if ( ! request . body . code_verifier ) {
109+ throw new InvalidGrantError ( 'Missing parameter: `code_verifier`' ) ;
110+ }
111+ 112+ const hash = pkce . getHashForCodeChallenge ( {
113+ method : code . codeChallengeMethod ,
114+ verifier : request . body . code_verifier
146115 } ) ;
116+ 117+ if ( ! hash ) {
118+ // notice that we assume that codeChallengeMethod is already
119+ // checked at an earlier stage when being read from
120+ // request.body.code_challenge_method
121+ throw new ServerError ( 'Server error: `getAuthorizationCode()` did not return a valid `codeChallengeMethod` property' ) ;
122+ }
123+ 124+ if ( code . codeChallenge !== hash ) {
125+ throw new InvalidGrantError ( 'Invalid grant: code verifier is invalid' ) ;
126+ }
127+ }
128+ else {
129+ if ( request . body . code_verifier ) {
130+ // No code challenge but code_verifier was passed in.
131+ throw new InvalidGrantError ( 'Invalid grant: code verifier is invalid' ) ;
132+ }
133+ }
134+ 135+ return code ;
147136 }
148137
149138 /**
@@ -183,46 +172,38 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
183172 * @see https://tools.ietf.org/html/rfc6749#section-4.1.2
184173 */
185174
186- revokeAuthorizationCode ( code ) {
187- return promisify ( this . model . revokeAuthorizationCode , 1 )
188- . call ( this . model , code )
189- . then ( ( status ) => {
190- if ( ! status ) {
191- throw new InvalidGrantError ( 'Invalid grant: authorization code is invalid' ) ;
192- }
175+ async revokeAuthorizationCode ( code ) {
176+ const status = await this . model . revokeAuthorizationCode ( code ) ;
193177
194- return code ;
195- } ) ;
178+ if ( ! status ) {
179+ throw new InvalidGrantError ( 'Invalid grant: authorization code is invalid' ) ;
180+ }
181+ 182+ return code ;
196183 }
197184
198185
199186 /**
200187 * Save token.
201188 */
202189
203- saveToken ( user , client , authorizationCode , scope ) {
204- const fns = [
205- this . validateScope ( user , client , scope ) ,
206- this . generateAccessToken ( client , user , scope ) ,
207- this . generateRefreshToken ( client , user , scope ) ,
208- this . getAccessTokenExpiresAt ( ) ,
209- this . getRefreshTokenExpiresAt ( ) ,
210- ] ;
211- 212- return Promise . all ( fns )
213- . bind ( this )
214- . spread ( function ( scope , accessToken , refreshToken , accessTokenExpiresAt , refreshTokenExpiresAt ) {
215- const token = {
216- accessToken : accessToken ,
217- authorizationCode : authorizationCode ,
218- accessTokenExpiresAt : accessTokenExpiresAt ,
219- refreshToken : refreshToken ,
220- refreshTokenExpiresAt : refreshTokenExpiresAt ,
221- scope : scope ,
222- } ;
223- 224- return promisify ( this . model . saveToken , 3 ) . call ( this . model , token , client , user ) ;
225- } ) ;
190+ async saveToken ( user , client , authorizationCode , scope ) {
191+ const validatedScope = await this . validateScope ( user , client , scope ) ;
192+ const accessToken = await this . generateAccessToken ( client , user , scope ) ;
193+ const refreshToken = await this . generateRefreshToken ( client , user , scope ) ;
194+ const accessTokenExpiresAt = await this . getAccessTokenExpiresAt ( ) ;
195+ const refreshTokenExpiresAt = await this . getRefreshTokenExpiresAt ( ) ;
196+ 197+ const token = {
198+ accessToken : accessToken ,
199+ authorizationCode : authorizationCode ,
200+ accessTokenExpiresAt : accessTokenExpiresAt ,
201+ refreshToken : refreshToken ,
202+ refreshTokenExpiresAt : refreshTokenExpiresAt ,
203+ scope : validatedScope ,
204+ } ;
205+ 206+ return this . model . saveToken ( token , client , user ) ;
226207 }
227208}
228209
0 commit comments