@@ -18,7 +18,7 @@ const Request = require('../request');
18
18
const Response = require ( '../response' ) ;
19
19
const ServerError = require ( '../errors/server-error' ) ;
20
20
const UnauthorizedClientError = require ( '../errors/unauthorized-client-error' ) ;
21
- const is = require ( '../validator/is ' ) ;
21
+ const isFormat = require ( '@node-oauth/formats ' ) ;
22
22
const tokenUtil = require ( '../utils/token-util' ) ;
23
23
const url = require ( 'url' ) ;
24
24
@@ -96,6 +96,12 @@ AuthorizeHandler.prototype.handle = function(request, response) {
96
96
let ResponseType ;
97
97
98
98
return Promise . bind ( this )
99
+ . then ( function ( ) {
100
+ state = this . getState ( request ) ;
101
+ if ( request . query . allowed === 'false' ) {
102
+ throw new AccessDeniedError ( 'Access denied: user denied access to application' ) ;
103
+ }
104
+ } )
99
105
. then ( function ( ) {
100
106
const requestedScope = this . getScope ( request ) ;
101
107
@@ -107,7 +113,6 @@ AuthorizeHandler.prototype.handle = function(request, response) {
107
113
return this . generateAuthorizationCode ( client , user , scope ) ;
108
114
} )
109
115
. then ( function ( authorizationCode ) {
110
- state = this . getState ( request ) ;
111
116
ResponseType = this . getResponseType ( request ) ;
112
117
113
118
return this . saveAuthorizationCode ( authorizationCode , expiresAt , scope , client , uri , user ) ;
@@ -160,19 +165,20 @@ AuthorizeHandler.prototype.getAuthorizationCodeLifetime = function() {
160
165
*/
161
166
162
167
AuthorizeHandler . prototype . getClient = function ( request ) {
168
+ const self = this ;
163
169
const clientId = request . body . client_id || request . query . client_id ;
164
170
165
171
if ( ! clientId ) {
166
172
throw new InvalidRequestError ( 'Missing parameter: `client_id`' ) ;
167
173
}
168
174
169
- if ( ! is . vschar ( clientId ) ) {
175
+ if ( ! isFormat . vschar ( clientId ) ) {
170
176
throw new InvalidRequestError ( 'Invalid parameter: `client_id`' ) ;
171
177
}
172
178
173
179
const redirectUri = request . body . redirect_uri || request . query . redirect_uri ;
174
180
175
- if ( redirectUri && ! is . uri ( redirectUri ) ) {
181
+ if ( redirectUri && ! isFormat . uri ( redirectUri ) ) {
176
182
throw new InvalidRequestError ( 'Invalid request: `redirect_uri` is not a valid URI' ) ;
177
183
}
178
184
return promisify ( this . model . getClient , 2 ) . call ( this . model , clientId , null )
@@ -193,10 +199,17 @@ AuthorizeHandler.prototype.getClient = function(request) {
193
199
throw new InvalidClientError ( 'Invalid client: missing client `redirectUri`' ) ;
194
200
}
195
201
196
- if ( redirectUri && ! client . redirectUris . includes ( redirectUri ) ) {
197
- throw new InvalidClientError ( 'Invalid client: `redirect_uri` does not match client value' ) ;
202
+ if ( redirectUri ) {
203
+ return self . validateRedirectUri ( redirectUri , client )
204
+ . then ( function ( valid ) {
205
+ if ( ! valid ) {
206
+ throw new InvalidClientError ( 'Invalid client: `redirect_uri` does not match client value' ) ;
207
+ }
208
+ return client ;
209
+ } ) ;
210
+ } else {
211
+ return client ;
198
212
}
199
- return client ;
200
213
} ) ;
201
214
} ;
202
215
@@ -225,7 +238,7 @@ AuthorizeHandler.prototype.validateScope = function(user, client, scope) {
225
238
AuthorizeHandler . prototype . getScope = function ( request ) {
226
239
const scope = request . body . scope || request . query . scope ;
227
240
228
- if ( ! is . nqschar ( scope ) ) {
241
+ if ( ! isFormat . nqschar ( scope ) ) {
229
242
throw new InvalidScopeError ( 'Invalid parameter: `scope`' ) ;
230
243
}
231
244
@@ -238,13 +251,14 @@ AuthorizeHandler.prototype.getScope = function(request) {
238
251
239
252
AuthorizeHandler . prototype . getState = function ( request ) {
240
253
const state = request . body . state || request . query . state ;
241
-
242
- if ( ! this . allowEmptyState && ! state ) {
243
- throw new InvalidRequestError ( 'Missing parameter: `state`' ) ;
244
- }
245
-
246
- if ( ! is . vschar ( state ) ) {
247
- throw new InvalidRequestError ( 'Invalid parameter: `state`' ) ;
254
+ const stateExists = state && state . length > 0 ;
255
+ const stateIsValid = stateExists
256
+ ? isFormat . vschar ( state )
257
+ : this . allowEmptyState ;
258
+
259
+ if ( ! stateIsValid ) {
260
+ const message = ( ! stateExists ) ? 'Missing' : 'Invalid' ;
261
+ throw new InvalidRequestError ( `${ message } parameter: \`state\`` ) ;
248
262
}
249
263
250
264
return state ;
@@ -289,6 +303,14 @@ AuthorizeHandler.prototype.saveAuthorizationCode = function(authorizationCode, e
289
303
return promisify ( this . model . saveAuthorizationCode , 3 ) . call ( this . model , code , client , user ) ;
290
304
} ;
291
305
306
+
307
+ AuthorizeHandler . prototype . validateRedirectUri = function ( redirectUri , client ) {
308
+ if ( this . model . validateRedirectUri ) {
309
+ return promisify ( this . model . validateRedirectUri , 2 ) . call ( this . model , redirectUri , client ) ;
310
+ }
311
+
312
+ return Promise . resolve ( client . redirectUris . includes ( redirectUri ) ) ;
313
+ } ;
292
314
/**
293
315
* Get response type.
294
316
*/
0 commit comments