Skip to content

Commit 98a9d19

Browse files
better implementation of validateRedirectUri
1 parent 0a86e69 commit 98a9d19

File tree

4 files changed

+85
-15
lines changed

4 files changed

+85
-15
lines changed

docs/model/spec.rst

+7-7
Original file line numberDiff line numberDiff line change
@@ -989,12 +989,12 @@ Returns ``true`` if the access token passes, ``false`` otherwise.
989989

990990
.. _Model#validateRedirectUri:
991991

992-
``validateRedirectUri(redirect_uri, redirect_uris, [callback])``
992+
``validateRedirectUri(redirectUri, client, [callback])``
993993
================================================================
994994

995-
Invoked to check if the provided ``redirect_uri`` is valid for a particular ``client``.
995+
Invoked to check if the provided ``redirectUri`` is valid for a particular ``client``.
996996

997-
This model function is **optional**. If not implemented, the redirect_uri should be included in the provided redirect_uris of the client.
997+
This model function is **optional**. If not implemented, the ``redirectUri`` should be included in the provided ``redirectUris`` of the client.
998998

999999
**Invoked during:**
10001000

@@ -1007,18 +1007,18 @@ This model function is **optional**. If not implemented, the redirect_uri should
10071007
+=================+==========+=====================================================================+
10081008
| redirect_uri | String | The redirect URI to validate. |
10091009
+-----------------+----------+---------------------------------------------------------------------+
1010-
| redirect_uris | Array | The list of redirect URIs configured for the client. |
1010+
| client | Object | The associated client. |
10111011
+-----------------+----------+---------------------------------------------------------------------+
10121012

10131013
**Return value:**
10141014

1015-
Returns ``true`` if the ``redirect_uri`` is valid, ``false`` otherwise.
1015+
Returns ``true`` if the ``redirectUri`` is valid, ``false`` otherwise.
10161016

10171017
**Remarks:**
10181018

10191019
::
10201020

1021-
function validateRedirectUri(redirect_uri, redirect_uris) {
1022-
return redirect_uris.includes(redirect_uri);
1021+
function validateRedirectUri(redirectUri, client) {
1022+
return client.redirectUris.includes(redirectUri);
10231023
}
10241024

lib/handlers/authorize-handler.js

+18-7
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,17 @@ AuthorizeHandler.prototype.getClient = function(request) {
194194
throw new InvalidClientError('Invalid client: missing client `redirectUri`');
195195
}
196196

197-
if (redirectUri && typeof self.model.validateRedirectUri === 'function') {
198-
if (!self.model.validateRedirectUri(redirectUri, client.redirectUris)) {
199-
throw new InvalidClientError('Invalid client: `redirect_uri` does not match client value');
200-
}
201-
} else if (redirectUri && !client.redirectUris.includes(redirectUri)) {
202-
throw new InvalidClientError('Invalid client: `redirect_uri` does not match client value');
197+
if (redirectUri) {
198+
return self.validateRedirectUri(redirectUri, client)
199+
.then(function(valid) {
200+
if (!valid) {
201+
throw new InvalidClientError('Invalid client: `redirect_uri` does not match client value');
202+
}
203+
return client;
204+
});
205+
} else {
206+
return client;
203207
}
204-
return client;
205208
});
206209
};
207210

@@ -294,6 +297,14 @@ AuthorizeHandler.prototype.saveAuthorizationCode = function(authorizationCode, e
294297
return promisify(this.model.saveAuthorizationCode, 3).call(this.model, code, client, user);
295298
};
296299

300+
301+
AuthorizeHandler.prototype.validateRedirectUri = function(redirectUri, client) {
302+
if (this.model.validateRedirectUri) {
303+
return promisify(this.model.validateRedirectUri, 2).call(this.model, redirectUri, client);
304+
}
305+
306+
return Promise.resolve(client.redirectUris.includes(redirectUri));
307+
};
297308
/**
298309
* Get response type.
299310
*/

test/integration/handlers/authorize-handler_test.js

+59
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,65 @@ describe('AuthorizeHandler integration', function() {
634634
});
635635
});
636636

637+
describe('validateRedirectUri()', function() {
638+
it('should support empty model', function() {
639+
const model = {
640+
getAccessToken: function() {},
641+
getClient: function() {},
642+
saveAuthorizationCode: function() {}
643+
};
644+
645+
const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
646+
647+
handler.validateRedirectUri('http://example.com/a', { redirectUris: ['http://example.com/a'] }).should.be.an.instanceOf(Promise);
648+
});
649+
650+
it('should support promises', function() {
651+
const model = {
652+
getAccessToken: function() {},
653+
getClient: function() {},
654+
saveAuthorizationCode: function() {},
655+
validateRedirectUri: function() {
656+
return Promise.resolve(true);
657+
}
658+
};
659+
660+
const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
661+
662+
handler.validateRedirectUri('http://example.com/a', { }).should.be.an.instanceOf(Promise);
663+
});
664+
665+
it('should support non-promises', function() {
666+
const model = {
667+
getAccessToken: function() {},
668+
getClient: function() {},
669+
saveAuthorizationCode: function() {},
670+
validateRedirectUri: function() {
671+
return true;
672+
}
673+
};
674+
675+
const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
676+
677+
handler.validateRedirectUri('http://example.com/a', { }).should.be.an.instanceOf(Promise);
678+
});
679+
680+
it('should support callbacks', function() {
681+
const model = {
682+
getAccessToken: function() {},
683+
getClient: function() {},
684+
saveAuthorizationCode: function() {},
685+
validateRedirectUri: function(redirectUri, client, callback) {
686+
callback(null, false);
687+
}
688+
};
689+
690+
const handler = new AuthorizeHandler({ authorizationCodeLifetime: 120, model: model });
691+
692+
handler.validateRedirectUri('http://example.com/a', { }).should.be.an.instanceOf(Promise);
693+
});
694+
});
695+
637696
describe('getClient()', function() {
638697
it('should throw an error if `client_id` is missing', function() {
639698
const model = {

test/unit/handlers/authorize-handler_test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('AuthorizeHandler', function() {
123123
model.validateRedirectUri.callCount.should.equal(1);
124124
model.validateRedirectUri.firstCall.args.should.have.length(2);
125125
model.validateRedirectUri.firstCall.args[0].should.equal(redirect_uri);
126-
model.validateRedirectUri.firstCall.args[1].should.equal(client.redirectUris);
126+
model.validateRedirectUri.firstCall.args[1].should.equal(client);
127127
model.validateRedirectUri.firstCall.thisValue.should.equal(model);
128128
})
129129
.catch(should.fail);

0 commit comments

Comments
 (0)