Repository: auth0/node-auth0
Pull request #533 (2020-09-14 04:11:58)

Adding support for prompts and custom texts
### Changes

Adding support for prompts and prompts custom texts.

GET 	/api/v2/prompts
PATCH	/api/v2/prompts
GET	/api/v2/prompts/{prompt}/custom-text/{language}
PUT	/api/v2/prompts/{prompt}/custom-text/{language}

Closes https://github.com/auth0/node-auth0/issues/525
Closes https://github.com/auth0/node-auth0/issues/526


### References

Please include relevant links supporting this change such as a:

- support ticket
- community post
- StackOverflow post
- support forum thread

### Testing

Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors. 

- [x] This change adds unit test coverage
- [x] This change adds integration test coverage

### Checklist

- [x] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)
- [x] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)
- [x] All existing and new tests complete without errors



Patch:
diff --git a/src/management/PromptsManager.js b/src/management/PromptsManager.js
index e170489b7..5a253da78 100644
--- a/src/management/PromptsManager.js
+++ b/src/management/PromptsManager.js
@@ -51,6 +51,23 @@ var PromptsManager = function(options) {
     options.tokenProvider
   );
   this.resource = new RetryRestClient(auth0RestClient, options.retry);
+
+  /**
+   * Retrieve custom text for a specific prompt and language.
+   * {@link https://auth0.com/docs/api/management/v2#!/Prompts/get_custom_text_by_language Custom Text endpoint}
+   *
+   *
+   * @type {external:RestClient}
+   */
+  var customTextByLanguageAuth0RestClient = new Auth0RestClient(
+    options.baseUrl + '/prompts/:prompt/custom-text/:language',
+    clientOptions,
+    options.tokenProvider
+  );
+  this.customTextByLanguage = new RetryRestClient(
+    customTextByLanguageAuth0RestClient,
+    options.retry
+  );
 };
 
 /**
@@ -101,4 +118,93 @@ utils.wrapPropertyMethod(PromptsManager, 'updateSettings', 'resource.patch');
  */
 utils.wrapPropertyMethod(PromptsManager, 'getSettings', 'resource.get');
 
+/**
+ * Retrieve custom text for a specific prompt and language.
+ *
+ * @method    getCustomTextByLanguage
+ * @memberOf  module:management.PromptsManager.prototype
+ *
+ * @example
+ * var params = { prompt: PROMPT_NAME, language: LANGUAGE };
+ *
+ * management.prompts.getCustomTextByLanguage(params, function (err, customText) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ *
+ *   console.log('CustomText', customText);
+ * });
+ *
+ * @param   {Object}    params            Data object.
+ * @param   {String}    params.prompt     Name of the prompt.
+ * @param   {String}    params.language   Language to retrieve.
+ * @param   {Function}  [cb]              Callback function
+ *
+ * @return  {Promise|undefined}
+ */
+PromptsManager.prototype.getCustomTextByLanguage = function(params, cb) {
+  params = params || {};
+
+  if (!params.prompt || typeof params.prompt !== 'string') {
+    throw new ArgumentError('The prompt parameter must be a string');
+  }
+
+  if (!params.language || typeof params.language !== 'string') {
+    throw new ArgumentError('The language parameter must be a string');
+  }
+
+  if (cb && cb instanceof Function) {
+    return this.customTextByLanguage.get(params, cb);
+  }
+
+  return this.customTextByLanguage.get(params);
+};
+
+/**
+ * Set custom text for a specific prompt.
+ *
+ * @method    updateCustomTextByLanguage
+ * @memberOf  module:management.PromptsManager.prototype
+ *
+ * @example
+ * var params = { prompt: PROMPT_NAME, language: LANGUAGE, body: BODY_OBJECT };
+ *
+ * management.prompts.updateCustomTextByLanguage(params, function (err, customText) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ *
+ *   console.log('CustomText', customText);
+ * });
+ *
+ * @param   {Object}    params            Data object.
+ * @param   {String}    params.prompt     Name of the prompt.
+ * @param   {String}    params.language   Language to retrieve.
+ * @param   {Object}    params.body       An object containing custom dictionaries for a group of screens.
+ * @param   {Function}  [cb]              Callback function
+ *
+ * @return  {Promise|undefined}
+ */
+PromptsManager.prototype.updateCustomTextByLanguage = function(params, cb) {
+  params = params || {};
+
+  if (!params.prompt || typeof params.prompt !== 'string') {
+    throw new ArgumentError('The prompt parameter must be a string');
+  }
+
+  if (!params.language || typeof params.language !== 'string') {
+    throw new ArgumentError('The language parameter must be a string');
+  }
+
+  if (!params.body || typeof params.body !== 'object') {
+    throw new ArgumentError('The body parameter must be an object');
+  }
+
+  if (cb && cb instanceof Function) {
+    return this.customTextByLanguage.update(params, params.body, cb);
+  }
+
+  return this.customTextByLanguage.update(params, params.body);
+};
+
 module.exports = PromptsManager;
diff --git a/src/management/index.js b/src/management/index.js
index 9d53813c5..c8955c23f 100644
--- a/src/management/index.js
+++ b/src/management/index.js
@@ -34,6 +34,7 @@ var RolesManager = require('./RolesManager');
 var HooksManager = require('./HooksManager');
 var BrandingManager = require('./BrandingManager');
 var MigrationsManager = require('./MigrationsManager');
+var PromptsManager = require('./PromptsManager');
 
 var BASE_URL_FORMAT = 'https://%s/api/v2';
 var MANAGEMENT_API_AUD_FORMAT = 'https://%s/api/v2/';
@@ -343,6 +344,13 @@ var ManagementClient = function(options) {
    * @type {MigrationsManager}
    */
   this.migrations = new MigrationsManager(managerOptions);
+
+  /**
+   * Prompts Manager
+   *
+   * @type {PromptsManager}
+   */
+  this.prompts = new PromptsManager(managerOptions);
 };
 
 /**
@@ -3548,4 +3556,110 @@ utils.wrapPropertyMethod(ManagementClient, 'updateMigrations', 'migrations.updat
  */
 utils.wrapPropertyMethod(ManagementClient, 'getMigrations', 'migrations.getMigrations');
 
+/**
+ * Get prompts settings..
+ *
+ * @method    getPromptsSettings
+ * @memberOf  module:management.ManagementClient.prototype
+ *
+ * @example
+ * management.getPromptsSettings(function (err, settings) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ *
+ *   console.log(settings);
+ * });
+ *
+ * @param   {Function}  [cb]  Callback function.
+ *
+ * @return  {Promise|undefined}
+ */
+
+utils.wrapPropertyMethod(ManagementClient, 'getPromptsSettings', 'prompts.getSettings');
+
+/**
+ * Update prompts settings.
+ *
+ * @method    updatePromptsSettings
+ * @memberOf  module:management.ManagementClient.prototype
+ *
+ * @example
+ * management.updatePromptsSettings(data, function (err) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ * });
+ *
+ * @param   {Object}    data  The new prompts settings.
+ * @param   {Function}  [cb]  Callback function.
+ *
+ * @return  {Promise|undefined}
+ */
+
+utils.wrapPropertyMethod(ManagementClient, 'updatePromptsSettings', 'prompts.updateSettings');
+
+/**
+ * Retrieve custom text for a specific prompt and language.
+ *
+ * @method    getCustomTextByLanguage
+ * @memberOf  module:management.PromptsManager.prototype
+ *
+ * @example
+ * var params = { prompt: PROMPT_NAME, language: LANGUAGE };
+ *
+ * management.prompts.getCustomTextByLanguage(params, function (err, customText) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ *
+ *   console.log('CustomText', customText);
+ * });
+ *
+ * @param   {Object}    params            Data object.
+ * @param   {String}    params.prompt     Name of the prompt.
+ * @param   {String}    params.language   Language to retrieve.
+ * @param   {Function}  [cb]              Callback function
+ *
+ * @return  {Promise|undefined}
+ */
+
+utils.wrapPropertyMethod(
+  ManagementClient,
+  'getCustomTextByLanguage',
+  'prompts.getCustomTextByLanguage'
+);
+
+/**
+ * Set custom text for a specific prompt.
+ *
+ * @method    updateCustomTextByLanguage
+ * @memberOf  module:management.PromptsManager.prototype
+ *
+ * @example
+ * var params = { prompt: PROMPT_NAME, language: LANGUAGE, body: BODY_OBJECT };
+ *
+ * management.prompts.updateCustomTextByLanguage(params, function (err, customText) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ *
+ *   console.log('CustomText', customText);
+ * });
+ *
+ * @param   {Object}    params            Data object.
+ * @param   {String}    params.prompt     Name of the prompt.
+ * @param   {String}    params.language   Language to retrieve.
+ * @param   {Object}    params.body       An object containing custom dictionaries for a group of screens.
+ * @param   {Function}  [cb]              Callback function
+ *
+ * @return  {Promise|undefined}
+ */
+
+utils.wrapPropertyMethod(
+  ManagementClient,
+  'updateCustomTextByLanguage',
+  'prompts.updateCustomTextByLanguage'
+);
+
 module.exports = ManagementClient;


Test patch:
diff --git a/test/management/management-client.tests.js b/test/management/management-client.tests.js
index 35e03b741..51582eacd 100644
--- a/test/management/management-client.tests.js
+++ b/test/management/management-client.tests.js
@@ -912,7 +912,9 @@ describe('ManagementClient', function() {
       'unblockUser',
       'getUserBlocksByIdentifier',
       'unblockUserByIdentifier',
-      'getAccessToken'
+      'getAccessToken',
+      'getPromptsSettings',
+      'updatePromptsSettings'
     ];
 
     before(function() {
diff --git a/test/management/prompts.tests.js b/test/management/prompts.tests.js
index 48c9bd9ab..a8a8c5292 100644
--- a/test/management/prompts.tests.js
+++ b/test/management/prompts.tests.js
@@ -219,4 +219,174 @@ describe('PromptsManager', function() {
       });
     });
   });
+
+  describe('#getCustomTextByLanguage', function() {
+    var data = {};
+    var params = {
+      prompt: 'test',
+      language: 'english'
+    };
+
+    beforeEach(function() {
+      this.request = nock(API_URL)
+        .get('/prompts/test/custom-text/english')
+        .reply(200);
+    });
+
+    it('should validate empty prompt parameter', function() {
+      var _this = this;
+      expect(function() {
+        _this.prompts.getCustomTextByLanguage({}, _this.body, function() {});
+      }).to.throw('The prompt parameter must be a string');
+    });
+
+    it('should validate empty language parameter', function() {
+      var _this = this;
+      expect(function() {
+        _this.prompts.getCustomTextByLanguage({ prompt: 'test' }, _this.body, function() {});
+      }).to.throw('The language parameter must be a string');
+    });
+
+    it('should accept a callback', function(done) {
+      this.prompts.getCustomTextByLanguage(params, function() {
+        done();
+      });
+    });
+
+    it('should return a promise if no callback is given', function(done) {
+      this.prompts
+        .getCustomTextByLanguage(params)
+        .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)
+        .get('/prompts/test/custom-text/english')
+        .reply(500);
+
+      this.prompts.getCustomTextByLanguage(params).catch(function(err) {
+        expect(err).to.exist;
+
+        done();
+      });
+    });
+
+    it('should perform a GET request to /api/v2/prompts/test/custom-text/english', function(done) {
+      var request = this.request;
+
+      this.prompts.getCustomTextByLanguage(params).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)
+        .get('/prompts/test/custom-text/english')
+        .matchHeader('Authorization', 'Bearer ' + this.token)
+        .reply(200);
+
+      this.prompts.getCustomTextByLanguage(params).then(function() {
+        expect(request.isDone()).to.be.true;
+
+        done();
+      });
+    });
+  });
+
+  describe('#updateCustomTextByLanguage', function() {
+    var data = {};
+    var params = {
+      prompt: 'test',
+      language: 'english',
+      body: {}
+    };
+
+    beforeEach(function() {
+      this.request = nock(API_URL)
+        .put('/prompts/test/custom-text/english')
+        .reply(200);
+    });
+
+    it('should validate empty prompt parameter', function() {
+      var _this = this;
+      expect(function() {
+        _this.prompts.updateCustomTextByLanguage({}, _this.body, function() {});
+      }).to.throw('The prompt parameter must be a string');
+    });
+
+    it('should validate empty language parameter', function() {
+      var _this = this;
+      expect(function() {
+        _this.prompts.updateCustomTextByLanguage({ prompt: 'test' }, _this.body, function() {});
+      }).to.throw('The language parameter must be a string');
+    });
+
+    it('should validate empty body parameter', function() {
+      var _this = this;
+      expect(function() {
+        _this.prompts.updateCustomTextByLanguage(
+          { prompt: 'test', language: 'english' },
+          _this.body,
+          function() {}
+        );
+      }).to.throw('The body parameter must be an object');
+    });
+
+    it('should accept a callback', function(done) {
+      this.prompts.updateCustomTextByLanguage(params, function() {
+        done();
+      });
+    });
+
+    it('should return a promise if no callback is given', function(done) {
+      this.prompts
+        .updateCustomTextByLanguage(params)
+        .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)
+        .put('/prompts/test/custom-text/english')
+        .reply(500);
+
+      this.prompts.updateCustomTextByLanguage(params).catch(function(err) {
+        expect(err).to.exist;
+
+        done();
+      });
+    });
+
+    it('shoushould perform a GET request to /api/v2/prompts/test/custom-text/english', function(done) {
+      var request = this.request;
+
+      this.prompts.updateCustomTextByLanguage(params).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)
+        .put('/prompts/test/custom-text/english')
+        .matchHeader('Authorization', 'Bearer ' + this.token)
+        .reply(200);
+
+      this.prompts.updateCustomTextByLanguage(params).then(function() {
+        expect(request.isDone()).to.be.true;
+
+        done();
+      });
+    });
+  });
 });