From ff9e4228d9ad2fd734503c14c2b7f337efd7a1e9 Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Tue, 3 Apr 2018 21:52:59 -0400 Subject: [PATCH] feat(oauth): make server compatible with AppAuth (#534) r=@rfk Ref: https://appauth.io/ --- lib/routes/token.js | 4 ++- lib/validators.js | 4 +++ test/api.js | 64 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/lib/routes/token.js b/lib/routes/token.js index 7e768e0..6c4a13f 100644 --- a/lib/routes/token.js +++ b/lib/routes/token.js @@ -84,6 +84,8 @@ const PAYLOAD_SCHEMA = Joi.object({ then: Joi.forbidden() }), + redirect_uri: validators.redirectUri.optional(), + grant_type: Joi.string() .valid(GRANT_AUTHORIZATION_CODE, GRANT_REFRESH_TOKEN, GRANT_JWT) .default(GRANT_AUTHORIZATION_CODE) @@ -98,7 +100,7 @@ const PAYLOAD_SCHEMA = Joi.object({ scope: Joi.alternatives().when('grant_type', { is: GRANT_REFRESH_TOKEN, then: validators.scope, - otherwise: Joi.forbidden() + otherwise: Joi.optional() }), code: Joi.string() diff --git a/lib/validators.js b/lib/validators.js index dd06ca2..6c36b74 100644 --- a/lib/validators.js +++ b/lib/validators.js @@ -32,6 +32,10 @@ exports.scope = Joi.string() .max(256) .regex(/^[a-zA-Z0-9 _\/.:]+$/); +exports.redirectUri = Joi.string() + .max(256) + .regex(/^[a-zA-Z0-9\-_\/.:]+$/); + // taken from mozilla/persona/lib/validate.js exports.assertion = Joi.string() .min(50) diff --git a/test/api.js b/test/api.js index 3cae144..788eb33 100644 --- a/test/api.js +++ b/test/api.js @@ -1899,6 +1899,70 @@ describe('/v1', function() { }); + describe('?redirect_uri', () => { + function getCode(clientId) { + mockAssertion().reply(200, VERIFY_GOOD); + return Server.api.post({ + url: '/authorization', + payload: authParams({ + client_id: clientId + }) + }).then((res) => { + return url.parse(res.result.redirect, true).query.code; + }); + } + it('works with https redirect_uri', () => { + return getCode(clientId).then((code) => { + return Server.api.post({ + url: '/token', + payload: { + client_id: clientId, + client_secret: secret, + code: code, + redirect_uri: 'https://2aa95473a5115d5f3deb36bb6875cf76f05e4c4d.extensions.allizom.org/' + } + }); + }).then((res) => { + assert.equal(res.statusCode, 200); + }); + }); + + it('works with app redirect_uri', () => { + return getCode(clientId).then((code) => { + return Server.api.post({ + url: '/token', + payload: { + client_id: clientId, + client_secret: secret, + code: code, + redirect_uri: 'testpilot-notes://redirect.android' + } + }); + }).then((res) => { + assert.equal(res.statusCode, 200); + }); + }); + + it('is validated', () => { + return getCode(clientId).then((code) => { + return Server.api.post({ + url: '/token', + payload: { + client_id: clientId, + client_secret: secret, + code: code, + redirect_uri: 'https://foo\n\n<>\n\r' + } + }); + }).then((res) => { + assert.equal(res.statusCode, 400); + assertInvalidRequestParam(res.result, 'redirect_uri'); + assertSecurityHeaders(res); + }); + }); + + }); + }); describe('/client', function() {