From d1308aa14cbc144298ed434efabe0b813cf8859e Mon Sep 17 00:00:00 2001 From: Tankred Hase Date: Fri, 19 Sep 2014 18:59:13 +0200 Subject: [PATCH] Add SMS validation --- src/js/controller/add-account.js | 34 +++++++++++++-- src/js/dao/admin-dao.js | 27 +++++++++++- src/sass/views/_login.scss | 8 ++-- src/tpl/add-account.html | 29 +++++++++++-- test/unit/add-account-ctrl-test.js | 48 ++++++++++++++++++++- test/unit/admin-dao-test.js | 69 ++++++++++++++++++++++++++++-- 6 files changed, 198 insertions(+), 17 deletions(-) diff --git a/src/js/controller/add-account.js b/src/js/controller/add-account.js index ac1e982..8668278 100644 --- a/src/js/controller/add-account.js +++ b/src/js/controller/add-account.js @@ -29,12 +29,38 @@ define(function(require) { appCtrl._adminDao.createUser({ emailAddress: $scope.emailAddress, password: $scope.pass, - //phone: $scope.phone, - //betaCode: $scope.betaCode + phone: $scope.phone, + betaCode: $scope.betaCode.toUpperCase() + }, function(err) { + $scope.busy = false; + + if (err) { + $scope.errMsg = err.errMsg || err.message; + $scope.$apply(); + return; + } + + $scope.goTo(3); + $scope.$apply(); + }); + }; + + $scope.validateUser = function() { + if ($scope.formValidate.$invalid) { + return; + } + + $scope.busyValidate = true; + $scope.errMsgValidate = undefined; // reset error msg + + // verify user to REST api + appCtrl._adminDao.validateUser({ + emailAddress: $scope.emailAddress, + token: $scope.token.toUpperCase() }, function(err) { if (err) { - $scope.busy = false; - $scope.errMsg = err.errMsg || err.message; + $scope.busyValidate = false; + $scope.errMsgValidate = err.errMsg || err.message; $scope.$apply(); return; } diff --git a/src/js/dao/admin-dao.js b/src/js/dao/admin-dao.js index 79ded1b..dfd7d4f 100644 --- a/src/js/dao/admin-dao.js +++ b/src/js/dao/admin-dao.js @@ -15,7 +15,7 @@ define(function() { AdminDAO.prototype.createUser = function(options, callback) { var uri; - if (!options.emailAddress || !options.password /* || !options.phone*/ ) { + if (!options.emailAddress || !options.password || !options.phone) { callback(new Error('Incomplete arguments!')); return; } @@ -34,5 +34,30 @@ define(function() { }); }; + /** + * Verify a user's phone number by confirming a token to the server. + * @param {String} options.emailAddress The desired email address + * @param {String} options.token The validation token. + * @param {Function} callback(error) + */ + AdminDAO.prototype.validateUser = function(options, callback) { + var uri; + + if (!options.emailAddress || !options.token) { + callback(new Error('Incomplete arguments!')); + return; + } + + uri = '/user/validate'; + this._restDao.post(options, uri, function(err) { + if (!err || (err && err.code === 202)) { + // success + callback(); + } else { + callback(new Error('Validation failed!')); + } + }); + }; + return AdminDAO; }); \ No newline at end of file diff --git a/src/sass/views/_login.scss b/src/sass/views/_login.scss index bbdd69f..e600ace 100644 --- a/src/sass/views/_login.scss +++ b/src/sass/views/_login.scss @@ -78,6 +78,10 @@ width: 100%; } + input.token { + width: auto; + } + input[type=file] { width: 100%; background-color: white; @@ -142,10 +146,6 @@ margin-top: 20px; } - input.token { - width: auto; - } - .code { max-width: 240px; margin: 0 auto; diff --git a/src/tpl/add-account.html b/src/tpl/add-account.html index fd4e764..236d935 100644 --- a/src/tpl/add-account.html +++ b/src/tpl/add-account.html @@ -13,7 +13,7 @@

Login to IMAP account. Connect Whiteout Mail to any existing email account via IMAP.

- +
@@ -29,7 +29,7 @@
- + @wmail.io
@@ -51,7 +51,30 @@ -
+
+ + +
+

Validate phone number. We have sent you a validation code via SMS. Please enter this code to confirm your phone number.

+
+ +
+ + +
+ +
+ +
+ +
+
+
+
+ +

Select account

    diff --git a/test/unit/add-account-ctrl-test.js b/test/unit/add-account-ctrl-test.js index 31639e2..89288e1 100644 --- a/test/unit/add-account-ctrl-test.js +++ b/test/unit/add-account-ctrl-test.js @@ -25,6 +25,7 @@ define(function(require) { scope = $rootScope.$new(); scope.state = {}; scope.form = {}; + scope.formValidate = {}; sinon.stub(location, 'path').returns(location); sinon.stub(location, 'search').returns(location); @@ -58,6 +59,7 @@ define(function(require) { it('should fail to error creating user', function(done) { scope.form.$invalid = false; + scope.betaCode = 'asfd'; adminStub.createUser.yieldsAsync(new Error('asdf')); scope.$apply = function() { @@ -73,11 +75,13 @@ define(function(require) { it('should work', function(done) { scope.form.$invalid = false; + scope.betaCode = 'asfd'; adminStub.createUser.yieldsAsync(); - scope.login = function() { - expect(scope.busy).to.be.true; + scope.$apply = function() { + expect(scope.busy).to.be.false; expect(scope.errMsg).to.be.undefined; + expect(scope.step).to.equal(3); expect(adminStub.createUser.calledOnce).to.be.true; done(); }; @@ -87,6 +91,46 @@ define(function(require) { }); }); + describe('validateUser', function() { + it('should return early for invalid form', function() { + scope.formValidate.$invalid = true; + scope.validateUser(); + expect(adminStub.validateUser.called).to.be.false; + }); + + it('should fail to error creating user', function(done) { + scope.formValidate.$invalid = false; + scope.token = 'asfd'; + adminStub.validateUser.yieldsAsync(new Error('asdf')); + + scope.$apply = function() { + expect(scope.busyValidate).to.be.false; + expect(scope.errMsgValidate).to.equal('asdf'); + expect(adminStub.validateUser.calledOnce).to.be.true; + done(); + }; + + scope.validateUser(); + expect(scope.busyValidate).to.be.true; + }); + + it('should work', function(done) { + scope.formValidate.$invalid = false; + scope.token = 'asfd'; + adminStub.validateUser.yieldsAsync(); + + scope.login = function() { + expect(scope.busyValidate).to.be.true; + expect(scope.errMsgValidate).to.be.undefined; + expect(adminStub.validateUser.calledOnce).to.be.true; + done(); + }; + + scope.validateUser(); + expect(scope.busyValidate).to.be.true; + }); + }); + describe('login', function() { it('should work', function() { scope.form.$invalid = false; diff --git a/test/unit/admin-dao-test.js b/test/unit/admin-dao-test.js index 708b1b5..06811b2 100644 --- a/test/unit/admin-dao-test.js +++ b/test/unit/admin-dao-test.js @@ -33,7 +33,8 @@ define(function(require) { it('should fail if user already exists', function(done) { var opt = { emailAddress: emailAddress, - password: password + password: password, + phone: '12345' }; restDaoStub.post.withArgs(opt, '/user').yields({ @@ -50,7 +51,8 @@ define(function(require) { it('should fail due to unknown error', function(done) { var opt = { emailAddress: emailAddress, - password: password + password: password, + phone: '12345' }; restDaoStub.post.withArgs(opt, '/user').yields(new Error()); @@ -65,7 +67,8 @@ define(function(require) { it('should work', function(done) { var opt = { emailAddress: emailAddress, - password: password + password: password, + phone: '12345' }; restDaoStub.post.withArgs(opt, '/user').yields(); @@ -78,6 +81,66 @@ define(function(require) { }); }); + describe('validateUser', function() { + it('should fail due to incomplete args', function(done) { + var opt = { + emailAddress: emailAddress + }; + + adminDao.validateUser(opt, function(err) { + expect(err).to.exist; + done(); + }); + }); + + it('should fail due to error in rest api', function(done) { + var opt = { + emailAddress: emailAddress, + token: 'H45Z6D' + }; + + restDaoStub.post.withArgs(opt, '/user/validate').yields(new Error()); + + adminDao.validateUser(opt, function(err) { + expect(err).to.exist; + expect(restDaoStub.post.calledOnce).to.be.true; + done(); + }); + }); + + it('should work with no error object', function(done) { + var opt = { + emailAddress: emailAddress, + token: 'H45Z6D' + }; + + restDaoStub.post.withArgs(opt, '/user/validate').yields(); + + adminDao.validateUser(opt, function(err) { + expect(err).to.not.exist; + expect(restDaoStub.post.calledOnce).to.be.true; + done(); + }); + }); + + it('should work with 202', function(done) { + var opt = { + emailAddress: emailAddress, + token: 'H45Z6D' + }; + + restDaoStub.post.withArgs(opt, '/user/validate').yields({ + code: 202 + }); + + adminDao.validateUser(opt, function(err) { + expect(err).to.not.exist; + expect(restDaoStub.post.calledOnce).to.be.true; + done(); + }); + }); + }); + }); }); \ No newline at end of file