Skip to content

Commit d06190d

Browse files
authored
Merge pull request #2927 from strongloop/backport/require-verification-email-change
Backport/Require verification after email change
2 parents d61e173 + 67e5c6e commit d06190d

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

common/models/user.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ module.exports = function(User) {
667667

668668
// Delete old sessions once email is updated
669669
UserModel.observe('before save', function beforeEmailUpdate(ctx, next) {
670+
var emailChanged;
670671
if (ctx.isNewInstance) return next();
671672
if (!ctx.where && !ctx.instance) return next();
672673
var where = ctx.where || { id: ctx.instance.id };
@@ -675,6 +676,19 @@ module.exports = function(User) {
675676
ctx.hookState.originalUserData = userInstances.map(function(u) {
676677
return { id: u.id, email: u.email };
677678
});
679+
if (ctx.instance) {
680+
emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email;
681+
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
682+
ctx.instance.emailVerified = false;
683+
}
684+
} else {
685+
emailChanged = ctx.hookState.originalUserData.some(function(data) {
686+
return data.email != ctx.data.email;
687+
});
688+
if (emailChanged && ctx.Model.settings.emailVerificationRequired) {
689+
ctx.data.emailVerified = false;
690+
}
691+
}
678692
next();
679693
});
680694
});

test/user.test.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2188,6 +2188,70 @@ describe('User', function() {
21882188
});
21892189
});
21902190

2191+
describe('Verification after updating email', function() {
2192+
var NEW_EMAIL = '[email protected]';
2193+
var userInstance;
2194+
2195+
beforeEach(createOriginalUser);
2196+
2197+
it('sets verification to false after email update if verification is required',
2198+
function(done) {
2199+
User.settings.emailVerificationRequired = true;
2200+
async.series([
2201+
function updateUser(next) {
2202+
userInstance.updateAttribute('email', NEW_EMAIL, function(err, info) {
2203+
if (err) return next(err);
2204+
assert.equal(info.email, NEW_EMAIL);
2205+
next();
2206+
});
2207+
},
2208+
function findUser(next) {
2209+
User.findById(userInstance.id, function(err, info) {
2210+
if (err) return next(err);
2211+
assert.equal(info.email, NEW_EMAIL);
2212+
assert.equal(info.emailVerified, false);
2213+
next();
2214+
});
2215+
},
2216+
], done);
2217+
});
2218+
2219+
it('leaves verification as is after email update if verification is not required',
2220+
function(done) {
2221+
User.settings.emailVerificationRequired = false;
2222+
async.series([
2223+
function updateUser(next) {
2224+
userInstance.updateAttribute('email', NEW_EMAIL, function(err, info) {
2225+
if (err) return next(err);
2226+
assert.equal(info.email, NEW_EMAIL);
2227+
next();
2228+
});
2229+
},
2230+
function findUser(next) {
2231+
User.findById(userInstance.id, function(err, info) {
2232+
if (err) return next(err);
2233+
assert.equal(info.email, NEW_EMAIL);
2234+
assert.equal(info.emailVerified, true);
2235+
next();
2236+
});
2237+
},
2238+
], done);
2239+
});
2240+
2241+
function createOriginalUser(done) {
2242+
var userData = {
2243+
2244+
password: 'bar',
2245+
emailVerified: true,
2246+
};
2247+
User.create(userData, function(err, instance) {
2248+
if (err) return done(err);
2249+
userInstance = instance;
2250+
done();
2251+
});
2252+
}
2253+
});
2254+
21912255
describe('password reset with/without email verification', function() {
21922256
it('allows resetPassword by email if email verification is required and done',
21932257
function(done) {

0 commit comments

Comments
 (0)