mirror of
https://github.com/moparisthebest/mail
synced 2025-02-20 04:41:52 -05:00
Add SMS validation
This commit is contained in:
parent
7c7d650cf2
commit
d1308aa14c
@ -29,12 +29,38 @@ define(function(require) {
|
|||||||
appCtrl._adminDao.createUser({
|
appCtrl._adminDao.createUser({
|
||||||
emailAddress: $scope.emailAddress,
|
emailAddress: $scope.emailAddress,
|
||||||
password: $scope.pass,
|
password: $scope.pass,
|
||||||
//phone: $scope.phone,
|
phone: $scope.phone,
|
||||||
//betaCode: $scope.betaCode
|
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) {
|
}, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
$scope.busy = false;
|
$scope.busyValidate = false;
|
||||||
$scope.errMsg = err.errMsg || err.message;
|
$scope.errMsgValidate = err.errMsg || err.message;
|
||||||
$scope.$apply();
|
$scope.$apply();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ define(function() {
|
|||||||
AdminDAO.prototype.createUser = function(options, callback) {
|
AdminDAO.prototype.createUser = function(options, callback) {
|
||||||
var uri;
|
var uri;
|
||||||
|
|
||||||
if (!options.emailAddress || !options.password /* || !options.phone*/ ) {
|
if (!options.emailAddress || !options.password || !options.phone) {
|
||||||
callback(new Error('Incomplete arguments!'));
|
callback(new Error('Incomplete arguments!'));
|
||||||
return;
|
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;
|
return AdminDAO;
|
||||||
});
|
});
|
@ -78,6 +78,10 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input.token {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
input[type=file] {
|
input[type=file] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
@ -142,10 +146,6 @@
|
|||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.token {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.code {
|
.code {
|
||||||
max-width: 240px;
|
max-width: 240px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<hr>
|
<hr>
|
||||||
<div class="choice">
|
<div class="choice">
|
||||||
<p><b>Login to IMAP account.</b> Connect Whiteout Mail to any existing email account via IMAP.</p>
|
<p><b>Login to IMAP account.</b> Connect Whiteout Mail to any existing email account via IMAP.</p>
|
||||||
<button class="btn btn-alt" wo-touch="goTo(3)">Login to existing</button>
|
<button class="btn btn-alt" wo-touch="goTo(4)">Login to existing</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
<label class="input-error-message" ng-show="errMsg">{{errMsg}}</label>
|
<label class="input-error-message" ng-show="errMsg">{{errMsg}}</label>
|
||||||
<label class="input-error-message" ng-show="form.$invalid">Please fill out all required fields!</label>
|
<label class="input-error-message" ng-show="form.$invalid">Please fill out all required fields!</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<input class="input-text wmail" ng-model="user" required type="text" pattern='^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))' placeholder="User name">
|
<input class="input-text wmail" ng-model="user" required type="text" pattern='^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))' placeholder="User name" focus-me="step === 2">
|
||||||
<span class="domain">@wmail.io</span>
|
<span class="domain">@wmail.io</span>
|
||||||
</div>
|
</div>
|
||||||
<input class="input-text" type="text" ng-model="realname" placeholder="Full name (optional)"></input>
|
<input class="input-text" type="text" ng-model="realname" placeholder="Full name (optional)"></input>
|
||||||
@ -51,7 +51,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="providers" ng-show="step === 3">
|
<div ng-show="step === 3">
|
||||||
|
<div class="logo">
|
||||||
|
<img src="img/whiteout_logo.svg" alt="whiteout.io">
|
||||||
|
</div><!--/logo-->
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<p><b>Validate phone number.</b> We have sent you a validation code via SMS. Please enter this code to confirm your phone number.</p>
|
||||||
|
<form name="formValidate">
|
||||||
|
<label class="input-error-message" ng-show="errMsgValidate">{{errMsgValidate}}</label>
|
||||||
|
<br>
|
||||||
|
<input type="text" class="input-text token" size="6" maxlength="6" ng-model="token" placeholder="Code" focus-me="step === 3" required pattern="([a-zA-Z0-9]*)">
|
||||||
|
|
||||||
|
<div class="working" ng-show="busyValidate">
|
||||||
|
<span class="spinner"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button class="btn" type="submit" ng-click="validateUser()">Confirm code</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="providers" ng-show="step === 4">
|
||||||
<h1>Select account</h1>
|
<h1>Select account</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -25,6 +25,7 @@ define(function(require) {
|
|||||||
scope = $rootScope.$new();
|
scope = $rootScope.$new();
|
||||||
scope.state = {};
|
scope.state = {};
|
||||||
scope.form = {};
|
scope.form = {};
|
||||||
|
scope.formValidate = {};
|
||||||
|
|
||||||
sinon.stub(location, 'path').returns(location);
|
sinon.stub(location, 'path').returns(location);
|
||||||
sinon.stub(location, 'search').returns(location);
|
sinon.stub(location, 'search').returns(location);
|
||||||
@ -58,6 +59,7 @@ define(function(require) {
|
|||||||
|
|
||||||
it('should fail to error creating user', function(done) {
|
it('should fail to error creating user', function(done) {
|
||||||
scope.form.$invalid = false;
|
scope.form.$invalid = false;
|
||||||
|
scope.betaCode = 'asfd';
|
||||||
adminStub.createUser.yieldsAsync(new Error('asdf'));
|
adminStub.createUser.yieldsAsync(new Error('asdf'));
|
||||||
|
|
||||||
scope.$apply = function() {
|
scope.$apply = function() {
|
||||||
@ -73,11 +75,13 @@ define(function(require) {
|
|||||||
|
|
||||||
it('should work', function(done) {
|
it('should work', function(done) {
|
||||||
scope.form.$invalid = false;
|
scope.form.$invalid = false;
|
||||||
|
scope.betaCode = 'asfd';
|
||||||
adminStub.createUser.yieldsAsync();
|
adminStub.createUser.yieldsAsync();
|
||||||
|
|
||||||
scope.login = function() {
|
scope.$apply = function() {
|
||||||
expect(scope.busy).to.be.true;
|
expect(scope.busy).to.be.false;
|
||||||
expect(scope.errMsg).to.be.undefined;
|
expect(scope.errMsg).to.be.undefined;
|
||||||
|
expect(scope.step).to.equal(3);
|
||||||
expect(adminStub.createUser.calledOnce).to.be.true;
|
expect(adminStub.createUser.calledOnce).to.be.true;
|
||||||
done();
|
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() {
|
describe('login', function() {
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
scope.form.$invalid = false;
|
scope.form.$invalid = false;
|
||||||
|
@ -33,7 +33,8 @@ define(function(require) {
|
|||||||
it('should fail if user already exists', function(done) {
|
it('should fail if user already exists', function(done) {
|
||||||
var opt = {
|
var opt = {
|
||||||
emailAddress: emailAddress,
|
emailAddress: emailAddress,
|
||||||
password: password
|
password: password,
|
||||||
|
phone: '12345'
|
||||||
};
|
};
|
||||||
|
|
||||||
restDaoStub.post.withArgs(opt, '/user').yields({
|
restDaoStub.post.withArgs(opt, '/user').yields({
|
||||||
@ -50,7 +51,8 @@ define(function(require) {
|
|||||||
it('should fail due to unknown error', function(done) {
|
it('should fail due to unknown error', function(done) {
|
||||||
var opt = {
|
var opt = {
|
||||||
emailAddress: emailAddress,
|
emailAddress: emailAddress,
|
||||||
password: password
|
password: password,
|
||||||
|
phone: '12345'
|
||||||
};
|
};
|
||||||
|
|
||||||
restDaoStub.post.withArgs(opt, '/user').yields(new Error());
|
restDaoStub.post.withArgs(opt, '/user').yields(new Error());
|
||||||
@ -65,7 +67,8 @@ define(function(require) {
|
|||||||
it('should work', function(done) {
|
it('should work', function(done) {
|
||||||
var opt = {
|
var opt = {
|
||||||
emailAddress: emailAddress,
|
emailAddress: emailAddress,
|
||||||
password: password
|
password: password,
|
||||||
|
phone: '12345'
|
||||||
};
|
};
|
||||||
|
|
||||||
restDaoStub.post.withArgs(opt, '/user').yields();
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
Loading…
x
Reference in New Issue
Block a user