From eb640d8da0cadfbb88171bb823a3af0f60ef5cd9 Mon Sep 17 00:00:00 2001 From: Loay Date: Tue, 20 Sep 2016 11:10:18 -0400 Subject: [PATCH] Require verification after email change When the User model is configured to require email verification, then any change of the email address should trigger re-verification. --- common/models/user.js | 13 +++++++++ test/user.test.js | 64 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/common/models/user.js b/common/models/user.js index bfc5607a..5d24bcea 100644 --- a/common/models/user.js +++ b/common/models/user.js @@ -683,6 +683,19 @@ module.exports = function(User) { ctx.hookState.originalUserData = userInstances.map(function(u) { return { id: u.id, email: u.email }; }); + if (ctx.instance) { + var emailChanged = ctx.instance.email !== ctx.hookState.originalUserData[0].email; + if (emailChanged && ctx.Model.settings.emailVerificationRequired) { + ctx.instance.emailVerified = false; + } + } else { + var emailChanged = ctx.hookState.originalUserData.some(function(data) { + return data.email != ctx.data.email; + }); + if (emailChanged && ctx.Model.settings.emailVerificationRequired) { + ctx.data.emailVerified = false; + } + } next(); }); }); diff --git a/test/user.test.js b/test/user.test.js index 37534a72..25004daf 100644 --- a/test/user.test.js +++ b/test/user.test.js @@ -2193,6 +2193,70 @@ describe('User', function() { }); }); + describe('Verification after updating email', function() { + var NEW_EMAIL = 'updated@example.com'; + var userInstance; + + beforeEach(createOriginalUser); + + it('sets verification to false after email update if verification is required', + function(done) { + User.settings.emailVerificationRequired = true; + async.series([ + function updateUser(next) { + userInstance.updateAttribute('email', NEW_EMAIL, function(err, info) { + if (err) return next (err); + assert.equal(info.email, NEW_EMAIL); + next(); + }); + }, + function findUser(next) { + User.findById(userInstance.id, function(err, info) { + if (err) return next (err); + assert.equal(info.email, NEW_EMAIL); + assert.equal(info.emailVerified, false); + next(); + }); + }, + ], done); + }); + + it('leaves verification as is after email update if verification is not required', + function(done) { + User.settings.emailVerificationRequired = false; + async.series([ + function updateUser(next) { + userInstance.updateAttribute('email', NEW_EMAIL, function(err, info) { + if (err) return next (err); + assert.equal(info.email, NEW_EMAIL); + next(); + }); + }, + function findUser(next) { + User.findById(userInstance.id, function(err, info) { + if (err) return next (err); + assert.equal(info.email, NEW_EMAIL); + assert.equal(info.emailVerified, true); + next(); + }); + }, + ], done); + }); + + function createOriginalUser(done) { + var userData = { + email: 'original@example.com', + password: 'bar', + emailVerified: true, + }; + User.create(userData, function(err, instance) { + if (err) return done(err); + userInstance = instance; + done(); + }); + } + }); + describe('password reset with/without email verification', function() { it('allows resetPassword by email if email verification is required and done', function(done) {