Merge pull request #365 from strongloop/feature/login-email-verification
Add an option to honor emailVerified
This commit is contained in:
commit
f8ffd978cf
|
@ -18,7 +18,7 @@ module.exports = MailConnector;
|
|||
*/
|
||||
|
||||
function MailConnector(settings) {
|
||||
assert(typeof settings === 'object', 'cannot initiaze MailConnector without a settings object');
|
||||
assert(typeof settings === 'object', 'cannot initialize MailConnector without a settings object');
|
||||
var transports = settings.transports || [];
|
||||
this.transportsIndex = {};
|
||||
this.transports = [];
|
||||
|
|
|
@ -186,6 +186,15 @@ User.login = function (credentials, include, fn) {
|
|||
debug('An error is reported from User.findOne: %j', err);
|
||||
fn(defaultError);
|
||||
} 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) {
|
||||
if(err) {
|
||||
debug('An error is reported from User.hasPassword: %j', err);
|
||||
|
@ -441,6 +450,15 @@ User.setup = function () {
|
|||
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(
|
||||
UserModel.login,
|
||||
{
|
||||
|
|
|
@ -76,8 +76,6 @@
|
|||
"browser": {
|
||||
"express": "./lib/browser-express.js",
|
||||
"connect": false,
|
||||
"passport": false,
|
||||
"passport-local": false,
|
||||
"nodemailer": false
|
||||
},
|
||||
"license": {
|
||||
|
|
|
@ -8,6 +8,8 @@ var userMemory = loopback.createDataSource({
|
|||
|
||||
describe('User', function(){
|
||||
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 invalidCredentials = {email: 'foo1@bar.com', password: 'bar1'};
|
||||
var incompleteCredentials = {password: 'bar1'};
|
||||
|
@ -30,7 +32,9 @@ describe('User', function(){
|
|||
app.use(loopback.rest());
|
||||
app.model(User);
|
||||
|
||||
User.create(validCredentials, done);
|
||||
User.create(validCredentials, function(err, user) {
|
||||
User.create(validCredentialsEmailVerified, done);
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
|
@ -105,6 +109,18 @@ describe('User', function(){
|
|||
var u = new User({username: 'foo', 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() {
|
||||
|
@ -155,7 +171,7 @@ describe('User', function(){
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('Login a user over REST by providing credentials', function(done) {
|
||||
request(app)
|
||||
.post('/users/login')
|
||||
|
@ -235,6 +251,63 @@ describe('User', function(){
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('User.login requiring email verification', function() {
|
||||
beforeEach(function() {
|
||||
User.settings.emailVerificationRequired = true;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
User.settings.emailVerificationRequired = false;
|
||||
});
|
||||
|
||||
it('Login a user by without email verification', function(done) {
|
||||
User.login(validCredentials, function (err, accessToken) {
|
||||
assert(err);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Login a user by with email verification', function(done) {
|
||||
User.login(validCredentialsEmailVerified, function (err, accessToken) {
|
||||
assert(accessToken.userId);
|
||||
assert(accessToken.id);
|
||||
assert.equal(accessToken.id.length, 64);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Login a user over REST when email verification is required', function(done) {
|
||||
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);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Login a user over REST without email verification when it is required', function(done) {
|
||||
request(app)
|
||||
.post('/users/login')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(401)
|
||||
.send(validCredentials)
|
||||
.end(function(err, res) {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('User.logout', function() {
|
||||
it('Logout a user by providing the current accessToken id (using node)', function(done) {
|
||||
|
|
Loading…
Reference in New Issue