Repository: auth0/node-auth0
Pull request #218 (2017-10-25 19:14:10)

Added support for /users-by-email method.
The ```/users-by-email``` API is preferred over using the Search API when working in the Authentication workflow. This is because the Search API uses Elastic Search and is less reliable than the single-index lookup provided by ```/users-by-email```

This new API allows you to use a simplified API:

```
auth0.getUsersByEmail('someone@somewhere.com')
````


I copied the ```getUsers``` method style, and did separate testing of my own to verify this works. Feel free to make any suggestions or improve.

luisrudge: Thanks for the PR. Can you also add a test so we make sure we don't add bugs in the future? Thanks!
kopertop: Sure thing, I just added in the tests that were used by getAll, so hopefully that's OK!

Patch:
diff --git a/src/management/UsersManager.js b/src/management/UsersManager.js
index 4f1ed8bf0..090867dbc 100644
--- a/src/management/UsersManager.js
+++ b/src/management/UsersManager.js
@@ -68,6 +68,13 @@ var UsersManager = function (options){
    * @type {external:RestClient}
    */
   this.enrollments = new Auth0RestClient(options.baseUrl + '/users/:id/enrollments', clientOptions, options.tokenProvider);
+
+  /**
+   * Provides an abstraction layer for the new "users-by-email" API
+   *
+   * @type {external:RestClient}
+   */
+  this.usersByEmail = new Auth0RestClient(options.baseUrl + '/users-by-email', clientOptions, options.tokenProvider);
 };
 
 
@@ -132,6 +139,30 @@ UsersManager.prototype.getAll = function (params) {
   return this.users.getAll.apply(this.users, arguments);
 };
 
+/**
+ * Get Users by an Email Address
+ *
+ * @method    getByEmail
+ * @memberOf  module:management.UsersManager.prototype
+ *
+ * @example <caption>
+ *   This method takes a first argument as the Email address to look for
+ *   users, and uses the /users-by-email API, not the search API
+ * </caption>
+ *
+ * management.users.getByEmail('email@address', function (err, users) {
+ *   console.log(users);
+ * });
+ *
+ * @param   {String}    [email]           Email address of user(s) to find
+ * @param   {Function}  [cb]              Callback function.
+ *
+ * @return  {Promise|undefined}
+ */
+UsersManager.prototype.getByEmail = function (email, callback) {
+  return this.usersByEmail.getAll({ email }, callback);
+};
+
 
 /**
  * Get a user by its id.
diff --git a/src/management/index.js b/src/management/index.js
index 68b22c7db..2c65d96a6 100644
--- a/src/management/index.js
+++ b/src/management/index.js
@@ -806,6 +806,29 @@ utils.wrapPropertyMethod(ManagementClient, 'updateRule', 'rules.update');
  */
 utils.wrapPropertyMethod(ManagementClient, 'getUsers', 'users.getAll');
 
+/**
+ * Get users for a given email address
+ *
+ * @method    getUsersByEmail
+ * @memberOf  module:management.ManagementClient.prototype
+ *
+ * @example <caption>
+ *   This method takes an email address as the first argument,
+ *   and returns all users with that email address
+ * </caption>
+ *
+ * auth0.getUsersByEmail(email, function (err, users) {
+ *   console.log(users);
+ * });
+ *
+ * @param   {String}    [email]           Email Address of users to locate
+ * @param   {Function}  [cb]              Callback function.
+ *
+ * @return  {Promise|undefined}
+ */
+utils.wrapPropertyMethod(ManagementClient, 'getUsersByEmail', 'users.getByEmail');
+
+
 
 /**
  * Get a user by its id.


Test patch:
diff --git a/test/management/users.tests.js b/test/management/users.tests.js
index 9d20dcd7d..75905e49d 100644
--- a/test/management/users.tests.js
+++ b/test/management/users.tests.js
@@ -199,6 +199,136 @@ describe('UsersManager', function () {
     });
   });
 
+  describe('#getByEmail', function () {
+    beforeEach(function () {
+      this.request = nock(API_URL)
+        .get('/users-by-email')
+        .reply(200);
+    })
+
+
+    it('should accept a callback', function (done) {
+      this
+        .users
+        .getByEmail('someone@example.com', function () {
+          done();
+        });
+    });
+
+
+    it('should return a promise if no callback is given', function (done) {
+      this
+        .users
+        .getByEmail()
+        .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('/users-by-email')
+        .reply(500);
+
+      this
+        .users
+        .getByEmail()
+        .catch(function (err) {
+          expect(err)
+            .to.exist;
+
+          done();
+        });
+    });
+
+
+    it('should pass the body of the response to the "then" handler', function (done) {
+      nock.cleanAll();
+
+      var data = [{ test: true }];
+      var request = nock(API_URL)
+        .get('/users-by-email')
+        .reply(200, data);
+
+      this
+        .users
+        .getByEmail()
+        .then(function (users) {
+          expect(users)
+            .to.be.an.instanceOf(Array);
+
+          expect(users.length)
+            .to.equal(data.length);
+
+          expect(users[0].test)
+            .to.equal(data[0].test);
+
+          done();
+        });
+    });
+
+
+    it('should perform a GET request to /api/v2/users-by-email', function (done) {
+      var request = this.request;
+
+      this
+        .users
+        .getByEmail()
+        .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('/users-by-email')
+        .matchHeader('Authorization', 'Bearer ' + this.token)
+        .reply(200);
+
+      this
+        .users
+        .getByEmail()
+        .then(function () {
+          expect(request.isDone())
+            .to.be.true;
+
+          done();
+        });
+    });
+
+
+    it('should pass an email in as a query string', function (done) {
+      nock.cleanAll();
+
+      var params = {
+        email: 'email@example.com'
+      };
+      var request = nock(API_URL)
+        .get('/users-by-email')
+        .query(params)
+        .reply(200);
+
+      this
+        .users
+        .getByEmail(params.email)
+        .then(function () {
+          expect(request.isDone())
+            .to.be.true;
+
+          done();
+        });
+    });
+  });
+
+
 
   describe('#get', function () {
     beforeEach(function () {