Repository: auth0/auth0.js
Pull request #895 (2019-01-18 02:24:01)

Trim `username`, `email` and `phoneNumber` params in every request
This is in reference to issue #872

It's possible there are additional places that username/email should be trimmed. If so, you can consider this a WIP 😉; but as I'm still getting used to the code base, I wanted to get this in to make sure I'm on the right track.

luisrudge: Thanks @ScottRudiger! that's amazing! I left a couple of comments of things that I think are missing.
luisrudge: Thanks, that's perfect 🎉 

Patch:
diff --git a/src/helper/object.js b/src/helper/object.js
index c16228e..f34e83f 100644
--- a/src/helper/object.js
+++ b/src/helper/object.js
@@ -147,6 +147,22 @@ function getOriginFromUrl(url) {
   return origin;
 }
 
+function trim(options, key) {
+  var trimmed = extend(options);
+  if (options[key]) {
+    trimmed[key] = options[key].trim();
+  }
+  return trimmed;
+}
+
+function trimMultiple(options, keys) {
+  return keys.reduce(trim, options);
+}
+
+function trimUserDetails(options) {
+  return trimMultiple(options, ['username', 'email', 'phoneNumber']);
+}
+
 export default {
   toSnakeCase: toSnakeCase,
   toCamelCase: toCamelCase,
@@ -156,5 +172,6 @@ export default {
   getKeysNotIn: getKeysNotIn,
   extend: extend,
   getOriginFromUrl: getOriginFromUrl,
-  getLocationFromUrl: getLocationFromUrl
+  getLocationFromUrl: getLocationFromUrl,
+  trimUserDetails: trimUserDetails
 };
diff --git a/src/helper/request-builder.js b/src/helper/request-builder.js
index 8c73e7c..f405b86 100644
--- a/src/helper/request-builder.js
+++ b/src/helper/request-builder.js
@@ -2,6 +2,7 @@
 import request from 'superagent';
 import base64Url from './base64_url';
 import version from '../version';
+import objectHelper from './object';
 
 // ------------------------------------------------ RequestWrapper
 
@@ -45,7 +46,7 @@ RequestObj.prototype.set = function(key, value) {
 };
 
 RequestObj.prototype.send = function(body) {
-  this.request = this.request.send(body);
+  this.request = this.request.send(objectHelper.trimUserDetails(body));
   return this;
 };
 


Test patch:
diff --git a/test/helper/object.test.js b/test/helper/object.test.js
index 42462da..76a0115 100644
--- a/test/helper/object.test.js
+++ b/test/helper/object.test.js
@@ -102,7 +102,7 @@ describe('helpers', function() {
   });
 
   describe('extend', function() {
-    it('shold merge objects attributes', function() {
+    it('should merge objects attributes', function() {
       var object1 = {
         attr1: 'attribute_1',
         attr2: 'attribute_2'
@@ -305,7 +305,7 @@ describe('helpers', function() {
       });
     });
 
-    it('shold merge picking attributes of both objects', function() {
+    it('should merge picking attributes of both objects', function() {
       var object1 = {
         attr1: 'attribute_1',
         attr2: 'attribute_2',
@@ -580,4 +580,80 @@ describe('helpers', function() {
       });
     }
   });
+  describe('trimUserDetails', function() {
+    var options;
+    function getTrimmed() {
+      return objectHelper.trimUserDetails(options);
+    }
+    beforeEach(function() {
+      options = {
+        email: '   me@example.com   ',
+        phoneNumber: '   +16505555555   ',
+        username: '   johndoe   '
+      };
+    });
+    it('should trim the username, email, and phoneNumber in an options object', function() {
+      expect(getTrimmed()).to.eql({
+        email: 'me@example.com',
+        phoneNumber: '+16505555555',
+        username: 'johndoe'
+      });
+    });
+    it('should not mutate the original options object', function() {
+      expect(options)
+        .to.not.equal(getTrimmed())
+        .and.eql({
+          email: '   me@example.com   ',
+          phoneNumber: '   +16505555555   ',
+          username: '   johndoe   '
+        });
+    });
+    it('should only trim username & email--not other properties', function() {
+      options.otherAttribute = '   stay untrimmed my friend   ';
+      expect(getTrimmed()).to.eql({
+        email: 'me@example.com',
+        otherAttribute: '   stay untrimmed my friend   ',
+        phoneNumber: '+16505555555',
+        username: 'johndoe'
+      });
+    });
+    it('should not fail when username, email, and/or phoneNumber are absent', function() {
+      options = {
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        attr3: 'attribute_3'
+      };
+      expect(getTrimmed()).to.eql(options);
+      options = {
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        username: '   johndoe   '
+      };
+      expect(getTrimmed()).to.eql({
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        username: 'johndoe'
+      });
+      options = {
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        email: '   email@example.com   '
+      };
+      expect(getTrimmed()).to.eql({
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        email: 'email@example.com'
+      });
+      options = {
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        phoneNumber: '   +16505555555   '
+      };
+      expect(getTrimmed()).to.eql({
+        attr1: 'attribute_1',
+        attr2: 'attribute_2',
+        phoneNumber: '+16505555555'
+      });
+    });
+  });
 });
diff --git a/test/helper/request-builder.test.js b/test/helper/request-builder.test.js
index 4ec8669..20cfdb4 100644
--- a/test/helper/request-builder.test.js
+++ b/test/helper/request-builder.test.js
@@ -7,6 +7,7 @@ import RequestMock from '../mock/request-mock';
 import RequestBuilder from '../../src/helper/request-builder';
 import base64url from '../../src/helper/base64_url';
 import version from '../../src/version';
+import objectHelper from '../../src/helper/object';
 
 var telemetryInfo = new RequestBuilder({}).getTelemetryData();
 
@@ -140,6 +141,9 @@ describe('helpers requestBuilder', function() {
 
     it('should post stuff', function() {
       var req = new RequestBuilder({});
+      var trimUserDetailsStub = stub(objectHelper, 'trimUserDetails', function(obj) {
+        return obj;
+      });
       var handler = req
         .post('https://test.com')
         .send({
@@ -148,6 +152,8 @@ describe('helpers requestBuilder', function() {
         })
         .end(function(err, data) {});
 
+      expect(trimUserDetailsStub).to.be.called;
+      trimUserDetailsStub.restore();
       expect(handler.getMethod()).to.eql('POST');
       expect(handler.getUrl()).to.eql('https://test.com');
       expect(handler.getBody()).to.eql({
@@ -286,6 +292,9 @@ describe('helpers requestBuilder', function() {
 
     it('should post stuff', function() {
       var req = new RequestBuilder({});
+      var trimUserDetailsStub = stub(objectHelper, 'trimUserDetails', function(obj) {
+        return obj;
+      });
       var handler = req
         .post('https://test.com', { noHeaders: true })
         .send({
@@ -294,6 +303,8 @@ describe('helpers requestBuilder', function() {
         })
         .end(function(err, data) {});
 
+      expect(trimUserDetailsStub).to.be.called;
+      trimUserDetailsStub.restore();
       expect(handler.getMethod()).to.eql('POST');
       expect(handler.getUrl()).to.eql('https://test.com');
       expect(handler.getBody()).to.eql({