From 050a4b8c0e97868d962cac9113ef73b87415aca2 Mon Sep 17 00:00:00 2001 From: Frederik Prijck Date: Wed, 20 Jan 2021 23:37:15 +0100 Subject: [PATCH] [SDK-2261] Add forwardFor support to passwordless calls (#576) --- src/auth/PasswordlessAuthenticator.js | 44 +++++++++++--- test/auth/passwordless.tests.js | 88 +++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 10 deletions(-) diff --git a/src/auth/PasswordlessAuthenticator.js b/src/auth/PasswordlessAuthenticator.js index 38e1122ad..13bf6df1e 100644 --- a/src/auth/PasswordlessAuthenticator.js +++ b/src/auth/PasswordlessAuthenticator.js @@ -2,6 +2,20 @@ var extend = require('util')._extend; var ArgumentError = require('rest-facade').ArgumentError; var RestClient = require('rest-facade').Client; +var sanitizeArguments = require('../utils').sanitizeArguments; + +function getParamsFromOptions(options) { + const params = {}; + if (!options || typeof options !== 'object') { + return params; + } + if (options.forwardedFor) { + params._requestCustomizer = function(req) { + req.set('auth0-forwarded-for', options.forwardedFor); + }; + } + return params; +} /** * @class @@ -93,11 +107,14 @@ var PasswordlessAuthenticator = function(options, oauth) { * @param {String} userData.username The user's phone number if realm=sms, or the user's email if realm=email * @param {String} userData.password [DEPRECATED] Password. * @param {String} [userData.connection=sms] [DEPRECATED] Connection string: "sms" or "email". + * @param {Object} [options] Additional options. + * @param {String} [options.forwardedFor] Value to be used for auth0-forwarded-for header * @param {Function} [cb] Method callback. * * @return {Promise|undefined} */ -PasswordlessAuthenticator.prototype.signIn = function(userData, cb) { +PasswordlessAuthenticator.prototype.signIn = function(userData, options, cb) { + var { options, cb } = sanitizeArguments(options, cb); var defaultFields = { client_id: this.clientId, client_secret: this.clientSecret @@ -118,7 +135,7 @@ PasswordlessAuthenticator.prototype.signIn = function(userData, cb) { data.realm = 'sms'; } data.grant_type = 'http://auth0.com/oauth/grant-type/passwordless/otp'; - return this.oauth.signIn(data, { type: 'token' }, cb); + return this.oauth.signIn(data, extend({ type: 'token' }, options), cb); } // Don't let the user override the connection nor the grant type. @@ -134,8 +151,7 @@ PasswordlessAuthenticator.prototype.signIn = function(userData, cb) { console.warn( 'The oauth/ro endpoint has been deprecated. Please use the realm and otp parameters in this function.' ); - - return this.oauth.signIn(data, cb); + return this.oauth.signIn(data, options, cb); }; /** @@ -179,15 +195,19 @@ PasswordlessAuthenticator.prototype.signIn = function(userData, cb) { * @param {Object} userData User account data. * @param {String} userData.email User email address. * @param {String} userData.send The type of email to be sent. + * @param {Object} [options] Additional options. + * @param {String} [options.forwardedFor] Value to be used for auth0-forwarded-for header * @param {Function} [cb] Method callback. * * @return {Promise|undefined} */ -PasswordlessAuthenticator.prototype.sendEmail = function(userData, cb) { +PasswordlessAuthenticator.prototype.sendEmail = function(userData, options, cb) { + var { options, cb } = sanitizeArguments(options, cb); var defaultFields = { client_id: this.clientId, client_secret: this.clientSecret }; + var params = getParamsFromOptions(options); var data = extend(defaultFields, userData); // Don't let the user override the connection nor the grant type. @@ -206,10 +226,10 @@ PasswordlessAuthenticator.prototype.sendEmail = function(userData, cb) { } if (cb && cb instanceof Function) { - return this.passwordless.create(data, cb); + return this.passwordless.create(params, data, cb); } - return this.passwordless.create(data); + return this.passwordless.create(params, data); }; /** @@ -237,15 +257,19 @@ PasswordlessAuthenticator.prototype.sendEmail = function(userData, cb) { * * @param {Object} userData User account data. * @param {String} userData.phone_number User phone number. + * @param {Object} [options] Additional options. + * @param {String} [options.forwardedFor] Value to be used for auth0-forwarded-for header * @param {Function} [cb] Method callback. * * @return {Promise|undefined} */ -PasswordlessAuthenticator.prototype.sendSMS = function(userData, cb) { +PasswordlessAuthenticator.prototype.sendSMS = function(userData, options, cb) { + var { options, cb } = sanitizeArguments(options, cb); var defaultFields = { client_id: this.clientId, client_secret: this.clientSecret }; + var params = getParamsFromOptions(options); var data = extend(defaultFields, userData); // Don't let the user override the connection nor the grant type. @@ -260,10 +284,10 @@ PasswordlessAuthenticator.prototype.sendSMS = function(userData, cb) { } if (cb && cb instanceof Function) { - return this.passwordless.create(data, cb); + return this.passwordless.create(params, data, cb); } - return this.passwordless.create(data); + return this.passwordless.create(params, data); }; module.exports = PasswordlessAuthenticator; diff --git a/test/auth/passwordless.tests.js b/test/auth/passwordless.tests.js index c694ad545..4a4a1fb3f 100644 --- a/test/auth/passwordless.tests.js +++ b/test/auth/passwordless.tests.js @@ -54,6 +54,9 @@ describe('PasswordlessAuthenticator', function() { username: 'username', password: 'pwd' }; + var options = { + forwardedFor: '0.0.0.0' + }; beforeEach(function() { var oauth = new OAuth(validOptions); @@ -246,6 +249,25 @@ describe('PasswordlessAuthenticator', function() { }) .catch(done); }); + + it('should make it possible to pass auth0-forwarded-for header', function(done) { + nock.cleanAll(); + + var request = nock(API_URL) + .post(path, function() { + return this.getHeader('auth0-forwarded-for') === options.forwardedFor; + }) + .reply(200); + + this.authenticator + .signIn(userData, options) + .then(function() { + expect(request.isDone()).to.be.true; + + done(); + }) + .catch(done); + }); }); describe('/oauth/token', function() { @@ -254,6 +276,9 @@ describe('PasswordlessAuthenticator', function() { username: 'username', otp: '000000' }; + var options = { + forwardedFor: '0.0.0.0' + }; beforeEach(function() { var oauth = new OAuth(validOptions); @@ -446,6 +471,25 @@ describe('PasswordlessAuthenticator', function() { }) .catch(done); }); + + it('should make it possible to pass auth0-forwarded-for header', function(done) { + nock.cleanAll(); + + var request = nock(API_URL) + .post(path, function() { + return this.getHeader('auth0-forwarded-for') === options.forwardedFor; + }) + .reply(200); + + this.authenticator + .signIn(userData, options) + .then(function() { + expect(request.isDone()).to.be.true; + + done(); + }) + .catch(done); + }); }); }); @@ -455,6 +499,9 @@ describe('PasswordlessAuthenticator', function() { email: 'email@domain.com', send: 'link' }; + var options = { + forwardedFor: '0.0.0.0' + }; beforeEach(function() { var oauth = new OAuth(validOptions); @@ -612,6 +659,25 @@ describe('PasswordlessAuthenticator', function() { }) .catch(done); }); + + it('should make it possible to pass auth0-forwarded-for header', function(done) { + nock.cleanAll(); + + var request = nock(API_URL) + .post(path, function() { + return this.getHeader('auth0-forwarded-for') === options.forwardedFor; + }) + .reply(200); + + this.authenticator + .sendEmail(userData, options) + .then(function() { + expect(request.isDone()).to.be.true; + + done(); + }) + .catch(done); + }); }); describe('#sendSMS', function() { @@ -619,6 +685,9 @@ describe('PasswordlessAuthenticator', function() { var userData = { phone_number: '12345678' }; + var options = { + forwardedFor: '0.0.0.0' + }; beforeEach(function() { var oauth = new OAuth(validOptions); @@ -746,5 +815,24 @@ describe('PasswordlessAuthenticator', function() { }) .catch(done); }); + + it('should make it possible to pass auth0-forwarded-for header', function(done) { + nock.cleanAll(); + + var request = nock(API_URL) + .post(path, function() { + return this.getHeader('auth0-forwarded-for') === options.forwardedFor; + }) + .reply(200); + + this.authenticator + .sendSMS(userData, options) + .then(function() { + expect(request.isDone()).to.be.true; + + done(); + }) + .catch(done); + }); }); });