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) {
|
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 || [];
|
var transports = settings.transports || [];
|
||||||
this.transportsIndex = {};
|
this.transportsIndex = {};
|
||||||
this.transports = [];
|
this.transports = [];
|
||||||
|
|
|
@ -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,
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,8 +76,6 @@
|
||||||
"browser": {
|
"browser": {
|
||||||
"express": "./lib/browser-express.js",
|
"express": "./lib/browser-express.js",
|
||||||
"connect": false,
|
"connect": false,
|
||||||
"passport": false,
|
|
||||||
"passport-local": false,
|
|
||||||
"nodemailer": false
|
"nodemailer": false
|
||||||
},
|
},
|
||||||
"license": {
|
"license": {
|
||||||
|
|
|
@ -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() {
|
||||||
|
@ -236,6 +252,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() {
|
describe('User.logout', function() {
|
||||||
it('Logout a user by providing the current accessToken id (using node)', function(done) {
|
it('Logout a user by providing the current accessToken id (using node)', function(done) {
|
||||||
login(logout);
|
login(logout);
|
||||||
|
|
Loading…
Reference in New Issue