Add an option to honor emailVerified

See https://github.com/strongloop/loopback/pull/215
This commit is contained in:
Raymond Feng 2014-07-07 14:09:45 -07:00
parent 75076c5196
commit 0c67b1e781
2 changed files with 90 additions and 1 deletions

View File

@ -186,6 +186,15 @@ User.login = function (credentials, include, fn) {
debug('An error is reported from User.findOne: %j', err); debug('An error is reported from User.findOne: %j', err);
fn(defaultError); fn(defaultError);
} else if(user) { } else if(user) {
if (self.settings.emailVerificationRequired) {
if (!user.emailVerified) {
// Fail to log in if email verification is not done yet
debug('User email has not been verified');
err = new Error('login failed as the email has not been verified');
err.statusCode = 401;
return fn(err);
}
}
user.hasPassword(credentials.password, function(err, isMatch) { user.hasPassword(credentials.password, function(err, isMatch) {
if(err) { if(err) {
debug('An error is reported from User.hasPassword: %j', err); debug('An error is reported from User.hasPassword: %j', err);
@ -441,6 +450,15 @@ User.setup = function () {
this.$password = bcrypt.hashSync(plain, salt); this.$password = bcrypt.hashSync(plain, salt);
} }
// Make sure emailVerified is not set by creation
UserModel.beforeRemote('create', function(ctx, user, next) {
var body = ctx.req.body;
if (body && body.emailVerified) {
body.emailVerified = false;
}
next();
});
loopback.remoteMethod( loopback.remoteMethod(
UserModel.login, UserModel.login,
{ {

View File

@ -8,6 +8,8 @@ var userMemory = loopback.createDataSource({
describe('User', function(){ describe('User', function(){
var validCredentials = {email: 'foo@bar.com', password: 'bar'}; var validCredentials = {email: 'foo@bar.com', password: 'bar'};
var validCredentialsEmailVerified = {email: 'foo1@bar.com', password: 'bar1', emailVerified: true};
var validCredentialsEmailVerifiedOverREST = {email: 'foo2@bar.com', password: 'bar2', emailVerified: true};
var validCredentialsWithTTL = {email: 'foo@bar.com', password: 'bar', ttl: 3600}; var validCredentialsWithTTL = {email: 'foo@bar.com', password: 'bar', ttl: 3600};
var invalidCredentials = {email: 'foo1@bar.com', password: 'bar1'}; var invalidCredentials = {email: 'foo1@bar.com', password: 'bar1'};
var incompleteCredentials = {password: 'bar1'}; var incompleteCredentials = {password: 'bar1'};
@ -30,7 +32,9 @@ describe('User', function(){
app.use(loopback.rest()); app.use(loopback.rest());
app.model(User); app.model(User);
User.create(validCredentials, done); User.create(validCredentials, function(err, user) {
User.create(validCredentialsEmailVerified, done);
});
}); });
afterEach(function (done) { afterEach(function (done) {
@ -105,6 +109,18 @@ describe('User', function(){
var u = new User({username: 'foo', password: 'bar'}); var u = new User({username: 'foo', password: 'bar'});
assert(u.password !== 'bar'); assert(u.password !== 'bar');
}); });
it('Create a user over REST should remove emailVerified property', function(done) {
request(app)
.post('/users')
.expect('Content-Type', /json/)
.expect(200)
.send(validCredentialsEmailVerifiedOverREST)
.end(function(err, res){
assert(!res.body.emailVerified);
done();
});
});
}); });
describe('User.login', function() { describe('User.login', function() {
@ -156,6 +172,26 @@ describe('User', function(){
}); });
}); });
it('Login a user by without email verification', function(done) {
User.settings.emailVerificationRequired = true;
User.login(validCredentials, function (err, accessToken) {
assert(err);
User.settings.emailVerificationRequired = false;
done();
});
});
it('Login a user by with email verification', function(done) {
User.settings.emailVerificationRequired = true;
User.login(validCredentialsEmailVerified, function (err, accessToken) {
assert(accessToken.userId);
assert(accessToken.id);
assert.equal(accessToken.id.length, 64);
User.settings.emailVerificationRequired = false;
done();
});
});
it('Login a user over REST by providing credentials', function(done) { it('Login a user over REST by providing credentials', function(done) {
request(app) request(app)
.post('/users/login') .post('/users/login')
@ -175,6 +211,41 @@ describe('User', function(){
}); });
}); });
it('Login a user over REST when email verification is required', function(done) {
User.settings.emailVerificationRequired = true;
request(app)
.post('/users/login')
.expect('Content-Type', /json/)
.expect(200)
.send(validCredentialsEmailVerified)
.end(function(err, res){
if(err) return done(err);
var accessToken = res.body;
assert(accessToken.userId);
assert(accessToken.id);
assert.equal(accessToken.id.length, 64);
assert(accessToken.user === undefined);
User.settings.emailVerificationRequired = false;
done();
});
});
it('Login a user over REST without email verification when it is required', function(done) {
User.settings.emailVerificationRequired = true;
request(app)
.post('/users/login')
.expect('Content-Type', /json/)
.expect(401)
.send(validCredentials)
.end(function(err, res){
User.settings.emailVerificationRequired = false;
done();
});
});
it('Login a user over REST by providing invalid credentials', function(done) { it('Login a user over REST by providing invalid credentials', function(done) {
request(app) request(app)
.post('/users/login') .post('/users/login')