diff --git a/docs/management_JobsManager.js.html b/docs/management_JobsManager.js.html
index f7e52792c..7bb900673 100644
--- a/docs/management_JobsManager.js.html
+++ b/docs/management_JobsManager.js.html
@@ -235,7 +235,8 @@
management/JobsManager.js
*
* @example
* var params = {
- * user_id: '{USER_ID}'
+ * user_id: '{USER_ID}',
+ * client_id: '{CLIENT_ID}'
* };
*
* management.jobs.verifyEmail(function (err) {
@@ -246,6 +247,7 @@ management/JobsManager.js
*
* @param {Object} data User data object.
* @param {String} data.user_id ID of the user to be verified.
+ * @param {String} data.client_id ID of the client for which the verification email will be sent.
* @param {Function} [cb] Callback function.
*
* @return {Promise|undefined}
diff --git a/src/auth/OAuthAuthenticator.js b/src/auth/OAuthAuthenticator.js
index 0d2b33d81..d8df93582 100644
--- a/src/auth/OAuthAuthenticator.js
+++ b/src/auth/OAuthAuthenticator.js
@@ -179,6 +179,60 @@ OAuthAuthenticator.prototype.passwordGrant = function(userData, cb) {
return this.oauthWithIDTokenValidation.create(params, data);
};
+/**
+ * Sign in using a refresh token
+ *
+ * @method refreshToken
+ * @memberOf module:auth.OAuthAuthenticator.prototype
+ *
+ * @example
+ * Given a refresh token from a previous authentication request
+ * it will return a JSON with the access_token and id_token.
+ * More information in the
+ *
+ * API Docs
+ * .
+ *
+ *
+ * var data = {
+ * client_id: '{CLIENT_ID}', // Optional field.
+ * refresh_token: '{REFRESH_TOKEN}',
+ * };
+ *
+ * auth0.oauth.refreshToken(data, function (err, userData) {
+ * if (err) {
+ * // Handle error.
+ * }
+ *
+ * console.log(userData);
+ * });
+ *
+ * @param {Object} userData User credentials object.
+ * @param {String} userData.refresh_token Refresh token.
+ *
+ * @return {Promise|undefined}
+ */
+OAuthAuthenticator.prototype.refreshToken = function(userData, cb) {
+ var params = {
+ type: 'token'
+ };
+ var defaultFields = {
+ client_id: this.clientId,
+ grant_type: 'refresh_token'
+ };
+ var data = extend(defaultFields, userData);
+ if (!userData || typeof userData !== 'object') {
+ throw new ArgumentError('Missing user data object');
+ }
+ if (typeof data.refresh_token !== 'string' || data.refresh_token.split().length === 0) {
+ throw new ArgumentError('refresh_token is required');
+ }
+ if (cb && cb instanceof Function) {
+ return this.oauthWithIDTokenValidation.create(params, data, cb);
+ }
+ return this.oauthWithIDTokenValidation.create(params, data);
+};
+
/**
* Sign in using a social provider access token.
*
diff --git a/src/auth/index.js b/src/auth/index.js
index fa410aa9c..acb70f253 100644
--- a/src/auth/index.js
+++ b/src/auth/index.js
@@ -543,4 +543,39 @@ utils.wrapPropertyMethod(
*/
utils.wrapPropertyMethod(AuthenticationClient, 'passwordGrant', 'oauth.passwordGrant');
+/**
+ * Sign in using a refresh token
+ *
+ * @method refreshToken
+ * @memberOf module:auth.AuthenticationClient.prototype
+ *
+ * @example
+ * Given a refresh token from a previous authentication request,
+ * it will return a JSON with the access_token and id_token.
+ * More information in the
+ *
+ * API Docs
+ * .
+ *
+ *
+ * var data = {
+ * client_id: '{CLIENT_ID}', // Optional field.
+ * refresh_token: '{REFRESH_TOKEN}',
+ * };
+ *
+ * auth0.refreshToken(data, function (err, userData) {
+ * if (err) {
+ * // Handle error.
+ * }
+ *
+ * console.log(userData);
+ * });
+ *
+ * @param {Object} userData User credentials object.
+ * @param {String} userData.refresh_token Refresh token.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(AuthenticationClient, 'refreshToken', 'oauth.refreshToken');
+
module.exports = AuthenticationClient;
diff --git a/src/management/GuardianManager.js b/src/management/GuardianManager.js
index eede511d2..c1f516ca1 100644
--- a/src/management/GuardianManager.js
+++ b/src/management/GuardianManager.js
@@ -1,4 +1,5 @@
var ArgumentError = require('rest-facade').ArgumentError;
+var utils = require('../utils');
var Auth0RestClient = require('../Auth0RestClient');
var RetryRestClient = require('../RetryRestClient');
@@ -49,6 +50,60 @@ var GuardianManager = function(options) {
options.tokenProvider
);
this.enrollments = new RetryRestClient(guardianEnrollmentsAuth0RestClient, options.retry);
+
+ /**
+ * Provides an abstraction layer for retrieving Guardian tickets.
+ *
+ * @type {external:RestClient}
+ */
+ var guardianTicketsAuth0RestClient = new Auth0RestClient(
+ options.baseUrl + '/guardian/enrollments/ticket',
+ clientOptions,
+ options.tokenProvider
+ );
+ this.tickets = new RetryRestClient(guardianTicketsAuth0RestClient, options.retry);
+
+ /**
+ * Provides an abstraction layer for retrieving Guardian factors.
+ *
+ * @type {external:RestClient}
+ */
+ var guardianFactorsAuth0RestClient = new Auth0RestClient(
+ options.baseUrl + '/guardian/factors/:name',
+ clientOptions,
+ options.tokenProvider
+ );
+ this.factors = new RetryRestClient(guardianFactorsAuth0RestClient, options.retry);
+
+ /**
+ * Provides an abstraction layer for retrieving Guardian factors.
+ *
+ * @type {external:RestClient}
+ */
+ var guardianFactorsTemplatesAuth0RestClient = new Auth0RestClient(
+ options.baseUrl + '/guardian/factors/:name/templates',
+ clientOptions,
+ options.tokenProvider
+ );
+ this.factorsTemplates = new RetryRestClient(
+ guardianFactorsTemplatesAuth0RestClient,
+ options.retry
+ );
+
+ /**
+ * Provides an abstraction layer for retrieving Guardian factor providers.
+ *
+ * @type {external:RestClient}
+ */
+ var guardianFactorsProvidersAuth0RestClient = new Auth0RestClient(
+ options.baseUrl + '/guardian/factors/:name/providers/:provider',
+ clientOptions,
+ options.tokenProvider
+ );
+ this.factorsProviders = new RetryRestClient(
+ guardianFactorsProvidersAuth0RestClient,
+ options.retry
+ );
};
/**
@@ -58,7 +113,7 @@ var GuardianManager = function(options) {
* @memberOf module:management.GuardianManager.prototype
*
* @example
- * management.users.getGuardianEnrollment({ id: ENROLLMENT_ID }, function (err, enrollment) {
+ * management.guardian.getGuardianEnrollment({ id: ENROLLMENT_ID }, function (err, enrollment) {
* console.log(enrollment);
* });
*
@@ -68,9 +123,7 @@ var GuardianManager = function(options) {
*
* @return {Promise|undefined}
*/
-GuardianManager.prototype.getGuardianEnrollment = function(params, cb) {
- return this.enrollments.get(params, cb);
-};
+utils.wrapPropertyMethod(GuardianManager, 'getGuardianEnrollment', 'enrollments.get');
/**
* Delete a Guardian enrollment.
@@ -79,7 +132,7 @@ GuardianManager.prototype.getGuardianEnrollment = function(params, cb) {
* @memberOf module:management.GuardianManager.prototype
*
* @example
- * management.users.deleteGuardianEnrollment({ id: ENROLLMENT_ID }, function (err, enrollments) {
+ * management.guardian.deleteGuardianEnrollment({ id: ENROLLMENT_ID }, function (err, enrollments) {
* console.log(enrollments);
* });
*
@@ -89,8 +142,136 @@ GuardianManager.prototype.getGuardianEnrollment = function(params, cb) {
*
* @return {Promise|undefined}
*/
-GuardianManager.prototype.deleteGuardianEnrollment = function(params, cb) {
- return this.enrollments.delete(params, cb);
-};
+utils.wrapPropertyMethod(GuardianManager, 'deleteGuardianEnrollment', 'enrollments.delete');
+
+/**
+ * Create a Guardian enrollment ticket.
+ *
+ * @method createEnrollmentTicket
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * @example
+ * management.guardian.createEnrollmentTicket(function (err, ticket) {
+ * console.log(ticket);
+ * });
+ *
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'createEnrollmentTicket', 'tickets.create');
+
+/**
+ * Get a list of factors and statuses.
+ *
+ * @method getFactors
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.guardian.getFactors(function (err, factors) {
+ * console.log(factors.length);
+ * });
+ *
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'getFactors', 'factors.getAll');
+
+/**
+ * Get Guardian factor provider configuration
+ *
+ * @method getFactorProvider
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.guardian.getFactorProvider({ name: 'sms', provider: 'twilio'}, function (err, provider) {
+ * console.log(provider);
+ * });
+ *
+ * @param {Object} params Factor provider parameters.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'getFactorProvider', 'factorsProviders.get');
+
+/**
+ * Update Guardian's factor provider
+ *
+ * @method updateFactorProvider
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.guardian.updateFactorProvider({ name: 'sms', provider: 'twilio' }, {
+ * messaging_service_sid: 'XXXXXXXXXXXXXX',
+ * auth_token: 'XXXXXXXXXXXXXX',
+ * sid: 'XXXXXXXXXXXXXX'
+ * }, function(err, provider) {
+ * console.log(provider);
+ * });
+ *
+ * @param {Object} params Factor provider parameters.
+ * @param {Object} data Updated Factor provider data.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'updateFactorProvider', 'factorsProviders.update');
+
+/**
+ * Get Guardian enrollment and verification factor templates
+ *
+ * @method getFactorTemplates
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.guardian.getFactorTemplates({ name: 'sms' }, function (err, templates) {
+ * console.log(templates);
+ * });
+ *
+ * @param {Object} params Factor parameters.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'getFactorTemplates', 'factorsTemplates.get');
+
+/**
+ * Update Guardian enrollment and verification factor templates
+ *
+ * @method updateFactorTemplates
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.guardian.updateFactorProvider({ name: 'sms' }, {
+ * enrollment_message: "{{code}} is your verification code for {{tenant.friendly_name}}. Please enter this code to verify your enrollment.",
+ * verification_message: "{{code}} is your verification code for {{tenant.friendly_name}}"
+ * }, function(err, templates) {
+ * console.log(templates);
+ * });
+ *
+ * @param {Object} params Factor parameters.
+ * @param {Object} data Updated factor templates data.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'updateFactorTemplates', 'factorsTemplates.update');
+
+/**
+ * Update Guardian Factor
+ *
+ * @method updateFactor
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.guardian.updateFactor({ name: 'sms' }, {
+ * enabled: true
+ * }, function(err, factor) {
+ * console.log(factor);
+ * });
+ *
+ * @param {Object} params Factor parameters.
+ * @param {Object} data Updated factor data.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(GuardianManager, 'updateFactor', 'factors.update');
module.exports = GuardianManager;
diff --git a/src/management/index.js b/src/management/index.js
index 842b953c4..b9bce9cf0 100644
--- a/src/management/index.js
+++ b/src/management/index.js
@@ -2044,4 +2044,154 @@ utils.wrapPropertyMethod(ManagementClient, 'verifyCustomDomain', 'customDomains.
*/
utils.wrapPropertyMethod(ManagementClient, 'deleteCustomDomain', 'customDomains.delete');
+/**
+ * Create a Guardian enrollment ticket.
+ *
+ * @method createGuardianEnrollmentTicket
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * @example
+ * management.createGuardianEnrollmentTicket(function (err, ticket) {
+ * console.log(ticket);
+ * });
+ *
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(
+ ManagementClient,
+ 'createGuardianEnrollmentTicket',
+ 'guardian.tickets.create'
+);
+
+/**
+ * Get a list of Guardian factors and statuses.
+ *
+ * @method getGuardianFactors
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.getGuardianFactors(function (err, factors) {
+ * console.log(factors.length);
+ * });
+ *
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(ManagementClient, 'getGuardianFactors', 'guardian.factors.getAll');
+
+/**
+ * Get Guardian factor provider configuration
+ *
+ * @method getGuardianFactorProvider
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.getFactorProvider({ name: 'sms', provider: 'twilio'}, function (err, provider) {
+ * console.log(provider);
+ * });
+ *
+ * @param {Object} params Factor provider parameters.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(
+ ManagementClient,
+ 'getGuardianFactorProvider',
+ 'guardian.factorsProviders.get'
+);
+
+/**
+ * Update Guardian's factor provider
+ *
+ * @method updateFactorProvider
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.updateGuardianFactorProvider({ name: 'sms', provider: 'twilio' }, {
+ * messaging_service_sid: 'XXXXXXXXXXXXXX',
+ * auth_token: 'XXXXXXXXXXXXXX',
+ * sid: 'XXXXXXXXXXXXXX'
+ * }, function(err, provider) {
+ * console.log(provider);
+ * });
+ *
+ * @param {Object} params Factor provider parameters.
+ * @param {Object} data Updated Factor provider data.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(
+ ManagementClient,
+ 'updateGuardianFactorProvider',
+ 'guardian.factorsProviders.update'
+);
+
+/**
+ * Get Guardian enrollment and verification factor templates
+ *
+ * @method getGuardianFactorTemplates
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.getGuardianFactorTemplates({ name: 'sms' }, function (err, templates) {
+ * console.log(templates);
+ * });
+ *
+ * @param {Object} params Factor parameters.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(
+ ManagementClient,
+ 'getGuardianFactorTemplates',
+ 'guardian.factorsTemplates.get'
+);
+
+/**
+ * Update Guardian enrollment and verification factor templates
+ *
+ * @method updateGuardianFactorTemplates
+ * @memberOf module:management.GuardianManager.prototype
+ *
+ * management.updateGuardianFactorTemplates({ name: 'sms' }, {
+ * enrollment_message: "{{code}} is your verification code for {{tenant.friendly_name}}. Please enter this code to verify your enrollment.",
+ * verification_message: "{{code}} is your verification code for {{tenant.friendly_name}}"
+ * }, function(err, templates) {
+ * console.log(templates);
+ * });
+ *
+ * @param {Object} params Factor parameters.
+ * @param {Object} data Updated factor templates data.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(
+ ManagementClient,
+ 'updateGuardianFactorTemplates',
+ 'guardian.factorsTemplates.update'
+);
+
+/**
+ * Update Guardian Factor
+ *
+ * @method updateGuardianFactor
+ * @memberOf module.GuardianManager.prototype
+ *
+ * management.updateGuardianFactor({ name: 'sms' }, {
+ * enabled: true
+ * }, function(err, factor) {
+ * console.log(factor);
+ * });
+ *
+ * @param {Object} params Factor parameters.
+ * @param {Object} data Updated factor data.
+ * @param {Function} [cb] Callback function.
+ *
+ * @return {Promise|undefined}
+ */
+utils.wrapPropertyMethod(ManagementClient, 'updateGuardianFactor', 'guardian.factors.update');
+
module.exports = ManagementClient;
diff --git a/test/auth/oauth.tests.js b/test/auth/oauth.tests.js
index 3dcb436a2..f91d4104e 100644
--- a/test/auth/oauth.tests.js
+++ b/test/auth/oauth.tests.js
@@ -44,7 +44,13 @@ describe('OAuthAuthenticator', function() {
});
describe('instance', function() {
- var methods = ['signIn', 'socialSignIn', 'passwordGrant', 'authorizationCodeGrant'];
+ var methods = [
+ 'signIn',
+ 'socialSignIn',
+ 'passwordGrant',
+ 'authorizationCodeGrant',
+ 'refreshToken'
+ ];
var authenticator = new Authenticator(validOptions);
methods.forEach(function(method) {
@@ -405,6 +411,96 @@ describe('OAuthAuthenticator', function() {
});
});
+ describe('#refreshToken', function() {
+ var path = '/oauth/token';
+ var userData = {
+ refresh_token: 'refresh_token'
+ };
+ beforeEach(function() {
+ this.authenticator = new Authenticator(validOptions);
+ this.request = nock(API_URL)
+ .post(path)
+ .reply(200);
+ });
+ it('should require an object as first argument', function() {
+ expect(this.authenticator.refreshToken).to.throw(ArgumentError, 'Missing user data object');
+ });
+ it('should require a refreshToken', function() {
+ var auth = this.authenticator;
+ var refresh = auth.refreshToken.bind(auth, {});
+ expect(refresh).to.throw(ArgumentError, 'refresh_token is required');
+ });
+ it('should accept a callback', function(done) {
+ this.authenticator.refreshToken(userData, done.bind(null, null));
+ });
+ it('should return a promise when no callback is provided', function(done) {
+ this.authenticator
+ .refreshToken(userData)
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+ it('should perform a POST request to ' + path, function(done) {
+ var request = this.request;
+ this.authenticator
+ .refreshToken(userData)
+ .then(function() {
+ expect(request.isDone()).to.be.true;
+ done();
+ })
+ .catch(done);
+ });
+ it('should include the user data in the request', function(done) {
+ nock.cleanAll();
+ var request = nock(API_URL)
+ .post(path, function(body) {
+ for (var property in userData) {
+ if (userData[property] !== body[property]) {
+ return false;
+ }
+ }
+ return true;
+ })
+ .reply(200);
+ this.authenticator
+ .refreshToken(userData)
+ .then(function() {
+ expect(request.isDone()).to.be.true;
+ done();
+ })
+ .catch(done);
+ });
+ it('should include the Auth0 client ID in the request', function(done) {
+ nock.cleanAll();
+ var request = nock(API_URL)
+ .post(path, function(body) {
+ return body.client_id === CLIENT_ID;
+ })
+ .reply(200);
+ this.authenticator
+ .refreshToken(userData)
+ .then(function() {
+ expect(request.isDone()).to.be.true;
+ done();
+ })
+ .catch(done);
+ });
+ it('should use refresh_token as default grant type', function(done) {
+ nock.cleanAll();
+ var request = nock(API_URL)
+ .post(path, function(body) {
+ return body.grant_type === 'refresh_token';
+ })
+ .reply(200);
+ this.authenticator
+ .refreshToken(userData)
+ .then(function() {
+ expect(request.isDone()).to.be.true;
+ done();
+ })
+ .catch(done);
+ });
+ });
+
describe('#socialSignIn', function() {
var path = '/oauth/access_token';
var userData = {
diff --git a/test/management/guardian.tests.js b/test/management/guardian.tests.js
index 75f7e2bac..b3fd95731 100644
--- a/test/management/guardian.tests.js
+++ b/test/management/guardian.tests.js
@@ -17,7 +17,16 @@ describe('GuardianManager', function() {
});
describe('instance', function() {
- var methods = ['getGuardianEnrollment', 'deleteGuardianEnrollment'];
+ var methods = [
+ 'getGuardianEnrollment',
+ 'deleteGuardianEnrollment',
+ 'getFactors',
+ 'getFactorProvider',
+ 'updateFactorProvider',
+ 'getFactorTemplates',
+ 'updateFactorTemplates',
+ 'updateFactor'
+ ];
methods.forEach(function(method) {
it('should have a ' + method + ' method', function() {
@@ -186,4 +195,512 @@ describe('GuardianManager', function() {
});
});
});
+
+ describe('#createEnrollmentTicket', function() {
+ var data = {
+ user_id: '',
+ email: '',
+ send_mail: false
+ };
+
+ beforeEach(function() {
+ this.request = nock(API_URL)
+ .post('/guardian/enrollments/ticket')
+ .reply(200);
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.createEnrollmentTicket(data, function() {
+ done();
+ });
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .createEnrollmentTicket(data)
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .post('/guardian/enrollments/ticket')
+ .reply(500);
+
+ this.guardian.createEnrollmentTicket(data).catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should perform a POST request to /api/v2/guardian/enrollments/ticket', function(done) {
+ var request = this.request;
+
+ this.guardian.createEnrollmentTicket(data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass the data in the body of the request', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .post('/guardian/enrollments/ticket', data)
+ .reply(200);
+
+ this.guardian.createEnrollmentTicket(data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .post('/guardian/enrollments/ticket')
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.createEnrollmentTicket(data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
+
+ describe('#getFactors', function() {
+ beforeEach(function() {
+ this.data = [
+ { name: 'sms', enabled: true, trial_expired: false },
+ { name: 'push-notification', enabled: false, trial_expired: false },
+ { name: 'otp', enabled: false, trial_expired: false },
+ { name: 'email', enabled: false, trial_expired: false },
+ { name: 'duo', enabled: false, trial_expired: false }
+ ];
+
+ this.request = nock(API_URL)
+ .get('/guardian/factors')
+ .reply(200, this.data);
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.getFactors(done.bind(null, null));
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .getFactors()
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should perform a POST request to /api/v2/guardian/factors', function(done) {
+ var request = this.request;
+
+ this.guardian.getFactors().then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .get('/guardian/factors')
+ .reply(500);
+
+ this.guardian.getFactors().catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .get('/guardian/factors')
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.getFactors().then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
+
+ describe('#getFactorProvider', function() {
+ beforeEach(function() {
+ this.params = { name: 'sms', provider: 'twilio' };
+ this.data = {
+ from: '+1223323',
+ messaging_service_sid: '5dEkAiHLPCuQ1uJj4qNXcAnERFAL6cpq',
+ auth_token: 'zw5Ku6z2sxhd0ZVXto5SDHX6KPDByJPU',
+ sid: 'wywA2BH4VqTpfywiDuyDAYZL3xQjoO40'
+ };
+
+ this.request = nock(API_URL)
+ .get('/guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .reply(200, this.data);
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.getFactorProvider(this.params, done.bind(null, null));
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .getFactorProvider(this.params)
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should perform a POST request to /api/v2/guardian/factors/sms/twilio', function(done) {
+ var request = this.request;
+
+ this.guardian.getFactorProvider(this.params).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .get('guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .reply(500);
+
+ this.guardian.getFactorProvider(this.params).catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .get('/guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.getFactorProvider(this.params).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
+
+ describe('#updateFactorProvider', function() {
+ beforeEach(function() {
+ this.params = { name: 'sms', provider: 'twilio' };
+ this.data = {
+ from: '+1223323',
+ messaging_service_sid: '5dEkAiHLPCuQ1uJj4qNXcAnERFAL6cpq',
+ auth_token: 'zw5Ku6z2sxhd0ZVXto5SDHX6KPDByJPU',
+ sid: 'wywA2BH4VqTpfywiDuyDAYZL3xQjoO40'
+ };
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.updateFactorProvider({ id: 5 }, {}, done.bind(null, null));
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .updateFactorProvider(this.params, {})
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should perform a PUT request to /api/v2/guardian/factors/sms/providers/twilio', function(done) {
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .reply(200, this.data);
+
+ this.guardian.updateFactorProvider(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should include the new data in the body of the request', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .reply(200);
+
+ this.guardian.updateFactorProvider(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .reply(500);
+
+ this.guardian.updateFactorProvider(this.params, this.data).catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/providers/' + this.params.provider)
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.updateFactorProvider(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
+
+ describe('#getFactorTemplates', function() {
+ beforeEach(function() {
+ this.params = { name: 'sms' };
+
+ this.data = {
+ enrollment_message:
+ '{{code}} is your verification code for {{tenant.friendly_name}}. Please enter this code to verify your enrollment.',
+ verification_message: '{{code}} is your verification code for {{tenant.friendly_name}}'
+ };
+
+ this.request = nock(API_URL)
+ .get('/guardian/factors/sms/templates')
+ .reply(200, this.data);
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.getFactorTemplates(this.params, done.bind(null, null));
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .getFactorTemplates(this.params)
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should perform a POST request to /api/v2/guardian/factors/sms/templates', function(done) {
+ var request = this.request;
+
+ this.guardian.getFactorTemplates(this.params).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .get('/guardian/factors/sms/templates')
+ .reply(500);
+
+ this.guardian.getFactorTemplates(this.params).catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .get('/guardian/factors/sms/templates')
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.getFactorTemplates(this.params).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
+
+ describe('#updateFactorTemplates', function() {
+ beforeEach(function() {
+ this.params = { name: 'sms' };
+ this.data = {
+ enrollment_message:
+ '{{code}} is your verification code for {{tenant.friendly_name}}. Please enter this code to verify your enrollment.',
+ verification_message: '{{code}} is your verification code for {{tenant.friendly_name}}'
+ };
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.updateFactorTemplates(this.params, {}, done.bind(null, null));
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .updateFactorTemplates(this.params, this.data)
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should perform a PUT request to /api/v2/guardian/factors/sms/templates', function(done) {
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/templates')
+ .reply(200, this.data);
+
+ this.guardian.updateFactorTemplates(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should include the new data in the body of the request', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/templates')
+ .reply(200);
+
+ this.guardian.updateFactorTemplates(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/templates')
+ .reply(500);
+
+ this.guardian.updateFactorTemplates(this.params, this.data).catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name + '/templates')
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.updateFactorTemplates(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
+
+ describe('#updateFactor', function() {
+ beforeEach(function() {
+ this.params = { name: 'sms' };
+ this.data = {
+ enabled: true
+ };
+ });
+
+ it('should accept a callback', function(done) {
+ this.guardian.updateFactor(this.params, {}, done.bind(null, null));
+ });
+
+ it('should return a promise if no callback is given', function(done) {
+ this.guardian
+ .updateFactor(this.params, this.data)
+ .then(done.bind(null, null))
+ .catch(done.bind(null, null));
+ });
+
+ it('should perform a PUT request to /api/v2/guardian/factors/sms', function(done) {
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name)
+ .reply(200, this.data);
+
+ this.guardian.updateFactor(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should include the new data in the body of the request', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name)
+ .reply(200);
+
+ this.guardian.updateFactor(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+
+ it('should pass any errors to the promise catch handler', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name)
+ .reply(500);
+
+ this.guardian.updateFactor(this.params, this.data).catch(function(err) {
+ expect(err).to.exist;
+
+ done();
+ });
+ });
+
+ it('should include the token in the Authorization header', function(done) {
+ nock.cleanAll();
+
+ var request = nock(API_URL)
+ .put('/guardian/factors/' + this.params.name)
+ .matchHeader('Authorization', 'Bearer ' + this.token)
+ .reply(200);
+
+ this.guardian.updateFactor(this.params, this.data).then(function() {
+ expect(request.isDone()).to.be.true;
+
+ done();
+ });
+ });
+ });
});