diff --git a/lib/tx.js b/lib/tx.js index 037e1a9963..4829c64bed 100644 --- a/lib/tx.js +++ b/lib/tx.js @@ -7,7 +7,8 @@ var AuthPollStopError = require('./errors/AuthPollStopError'); var config = require('./config'); function addStateToken(res, options) { - var builtArgs = util.clone(options) || {}; + var builtArgs = {}; + util.extend(builtArgs, options || {}); // Add the stateToken if one isn't passed and we have one if (!builtArgs.stateToken && res.stateToken) { @@ -76,11 +77,12 @@ function getPollFn(sdk, res, ref) { // Get the poll function var pollLink = util.getLink(res, 'next', 'poll'); function pollFn() { - var opts = { - 'autoPush': autoPush - }; + var opts = {}; + if (autoPush !== undefined && autoPush !== null) { + opts.autoPush = (typeof autoPush === 'function') ? autoPush() : !!autoPush; + } if (rememberDevice) { - opts.rememberDevice = rememberDevice; + opts.rememberDevice = true; } var href = pollLink.href + util.toQueryParams(opts); return http.post(sdk, href, getStateToken(res), { @@ -187,20 +189,22 @@ function link2fn(sdk, res, obj, link, ref) { var params = {}; if (data.autoPush !== undefined) { - params.autoPush = data.autoPush; + if (data.autoPush !== null) { + params.autoPush = (typeof data.autoPush === 'function') ? data.autoPush() : !!data.autoPush; + } data = util.omit(data, 'autoPush'); } if (data.rememberDevice !== undefined) { if (data.rememberDevice) { - params.rememberDevice = data.rememberDevice; + params.rememberDevice = true; } data = util.omit(data, 'rememberDevice'); } else if (data.profile && data.profile.updatePhone !== undefined) { if (data.profile.updatePhone) { - params.updatePhone = data.profile.updatePhone; + params.updatePhone = true; } data.profile = util.omit(data.profile, 'updatePhone'); } diff --git a/okta-okta-auth-js-1.12.0.tgz b/okta-okta-auth-js-1.12.0.tgz new file mode 100644 index 0000000000..d6365e68b8 Binary files /dev/null and b/okta-okta-auth-js-1.12.0.tgz differ diff --git a/test/spec/mfa-challenge.js b/test/spec/mfa-challenge.js index b8b88399ef..271e84cfd5 100644 --- a/test/spec/mfa-challenge.js +++ b/test/spec/mfa-challenge.js @@ -108,6 +108,29 @@ define(function(require) { } }); + util.itMakesCorrectRequestResponse({ + title: 'allows verification with autoPush as a function', + setup: { + status: 'mfa-challenge-sms', + request: { + uri: '/api/v1/authn/factors/smsigwDlH85L9FyQK0g3/verify?autoPush=true', + data: { + stateToken: '00rt1IY9c6Q3RVc4a2jJPbS2uAtFNWJz_d8A26KTdF', + passCode: '123456' + } + }, + response: 'success' + }, + execute: function (test) { + return test.trans.verify({ + passCode: '123456', + autoPush: function () { + return true; + } + }); + } + }); + util.itMakesCorrectRequestResponse({ title: 'allows verification with autoPush as undefined', setup: { @@ -129,6 +152,27 @@ define(function(require) { } }); + util.itMakesCorrectRequestResponse({ + title: 'allows verification with autoPush as null', + setup: { + status: 'mfa-challenge-sms', + request: { + uri: '/api/v1/authn/factors/smsigwDlH85L9FyQK0g3/verify', + data: { + stateToken: '00rt1IY9c6Q3RVc4a2jJPbS2uAtFNWJz_d8A26KTdF', + passCode: '123456' + } + }, + response: 'success' + }, + execute: function (test) { + return test.trans.verify({ + passCode: '123456', + autoPush: null + }); + } + }); + util.itMakesCorrectRequestResponse({ title: 'allows verification with autoPush and rememberDevice true', setup: { @@ -194,6 +238,28 @@ define(function(require) { }); } }); + + util.itMakesCorrectRequestResponse({ + title: 'allows verification with autoPush null and rememberDevice true', + setup: { + status: 'mfa-challenge-sms', + request: { + uri: '/api/v1/authn/factors/smsigwDlH85L9FyQK0g3/verify?rememberDevice=true', + data: { + stateToken: '00rt1IY9c6Q3RVc4a2jJPbS2uAtFNWJz_d8A26KTdF', + passCode: '123456' + } + }, + response: 'success' + }, + execute: function (test) { + return test.trans.verify({ + passCode: '123456', + autoPush: null, + rememberDevice: true + }); + } + }); }); describe('trans.poll', function () { @@ -362,6 +428,50 @@ define(function(require) { } }); + util.itMakesCorrectRequestResponse({ + title: 'allows polling for push with autoPush as a function', + setup: { + status: 'mfa-challenge-push', + calls: [ + { + request: { + uri: '/api/v1/authn/factors/opf492vmb3s1blLTs0h7/verify?autoPush=true', + data: { + stateToken: '00T4jcVNRzJy5dkWJ4P7c9051dY3FUYY9O2zvbU_vI' + } + }, + response: 'mfa-challenge-push' + }, + { + request: { + uri: '/api/v1/authn/factors/opf492vmb3s1blLTs0h7/verify?autoPush=true', + data: { + stateToken: '00T4jcVNRzJy5dkWJ4P7c9051dY3FUYY9O2zvbU_vI' + } + }, + response: 'mfa-challenge-push' + }, + { + request: { + uri: '/api/v1/authn/factors/opf492vmb3s1blLTs0h7/verify?autoPush=true', + data: { + stateToken: '00T4jcVNRzJy5dkWJ4P7c9051dY3FUYY9O2zvbU_vI' + } + }, + response: 'success' + } + ] + }, + execute: function (test) { + return test.trans.poll({ + delay: 0, + autoPush: function () { + return true; + } + }); + } + }); + util.itMakesCorrectRequestResponse({ title: 'does not include autoPush for polling for push if autoPush undefined', setup: { @@ -404,6 +514,48 @@ define(function(require) { } }); + util.itMakesCorrectRequestResponse({ + title: 'does not include autoPush for polling for push if autoPush null', + setup: { + status: 'mfa-challenge-push', + calls: [ + { + request: { + uri: '/api/v1/authn/factors/opf492vmb3s1blLTs0h7/verify', + data: { + stateToken: '00T4jcVNRzJy5dkWJ4P7c9051dY3FUYY9O2zvbU_vI' + } + }, + response: 'mfa-challenge-push' + }, + { + request: { + uri: '/api/v1/authn/factors/opf492vmb3s1blLTs0h7/verify', + data: { + stateToken: '00T4jcVNRzJy5dkWJ4P7c9051dY3FUYY9O2zvbU_vI' + } + }, + response: 'mfa-challenge-push' + }, + { + request: { + uri: '/api/v1/authn/factors/opf492vmb3s1blLTs0h7/verify', + data: { + stateToken: '00T4jcVNRzJy5dkWJ4P7c9051dY3FUYY9O2zvbU_vI' + } + }, + response: 'success' + } + ] + }, + execute: function (test) { + return test.trans.poll({ + delay: 0, + autoPush: null + }); + } + }); + util.itMakesCorrectRequestResponse({ title: 'allows polling for push with autoPush and rememberDevice', setup: { diff --git a/test/spec/mfa-required.js b/test/spec/mfa-required.js index cdafa2c5b7..98b2124544 100644 --- a/test/spec/mfa-required.js +++ b/test/spec/mfa-required.js @@ -149,6 +149,29 @@ define(function(require) { }); } }); + util.itMakesCorrectRequestResponse({ + title: 'passes autoPush as a query param if function returns true', + setup: { + status: 'mfa-required', + request: { + uri: '/api/v1/authn/factors/uftigiEmYTPOmvqTS0g3/verify?autoPush=true', + data: { + stateToken: '004KscPNUS2LswGp26qiu4Hetqt_zcgz-PcQhPseVP', + passCode: '123456' + } + }, + response: 'success' + }, + execute: function (test) { + var factor = _.find(test.trans.factors, {id: 'uftigiEmYTPOmvqTS0g3'}); + return factor.verify({ + 'passCode': '123456', + 'autoPush': function() { + return true; + } + }); + } + }); util.itMakesCorrectRequestResponse({ title: 'doesn\'t pass autoPush as a query param if undefined', setup: { @@ -170,6 +193,27 @@ define(function(require) { }); } }); + util.itMakesCorrectRequestResponse({ + title: 'doesn\'t pass autoPush as a query param if null', + setup: { + status: 'mfa-required', + request: { + uri: '/api/v1/authn/factors/uftigiEmYTPOmvqTS0g3/verify', + data: { + stateToken: '004KscPNUS2LswGp26qiu4Hetqt_zcgz-PcQhPseVP', + passCode: '123456' + } + }, + response: 'success' + }, + execute: function (test) { + var factor = _.find(test.trans.factors, {id: 'uftigiEmYTPOmvqTS0g3'}); + return factor.verify({ + passCode: '123456', + autoPush: null + }); + } + }); util.itMakesCorrectRequestResponse({ title: 'passes autoPush and rememberDevice as a query param if true', setup: { @@ -236,6 +280,28 @@ define(function(require) { }); } }); + util.itMakesCorrectRequestResponse({ + title: 'passes rememberDevice as a query param if autoPush is null and rememberDevice is true', + setup: { + status: 'mfa-required', + request: { + uri: '/api/v1/authn/factors/uftigiEmYTPOmvqTS0g3/verify?rememberDevice=true', + data: { + stateToken: '004KscPNUS2LswGp26qiu4Hetqt_zcgz-PcQhPseVP', + passCode: '123456' + } + }, + response: 'success' + }, + execute: function (test) { + var factor = _.find(test.trans.factors, {id: 'uftigiEmYTPOmvqTS0g3'}); + return factor.verify({ + passCode: '123456', + autoPush: null, + rememberDevice: true + }); + } + }); util.itErrorsCorrectly({ title: 'returns correct error when invalid answer provided (403)', setup: {