diff --git a/src/controllers/accounts/edit.js b/src/controllers/accounts/edit.js index 9c298f18cc..de5cf391f5 100644 --- a/src/controllers/accounts/edit.js +++ b/src/controllers/accounts/edit.js @@ -77,10 +77,24 @@ editController.username = async function (req, res, next) { await renderRoute('username', req, res, next); }; -editController.email = async function (req, res) { +editController.email = async function (req, res, next) { + const targetUid = await user.getUidByUserslug(req.params.userslug); + if (!targetUid) { + return next(); + } + + const [isAdminOrGlobalMod, canEdit] = await Promise.all([ + user.isAdminOrGlobalMod(req.uid), + privileges.users.canEdit(req.uid, targetUid), + ]); + + if (!isAdminOrGlobalMod && !canEdit) { + return next(); + } + req.session.registration = req.session.registration || {}; req.session.registration.updateEmail = true; - req.session.registration.uid = req.uid; + req.session.registration.uid = targetUid; helpers.redirect(res, '/register/complete'); }; diff --git a/src/user/index.js b/src/user/index.js index f1172e7553..c7151c49de 100644 --- a/src/user/index.js +++ b/src/user/index.js @@ -259,10 +259,22 @@ User.addInterstitials = function (callback) { throw new Error('[[error:email-nochange]]'); } - await User.email.sendValidationEmail(userData.uid, { - email: formData.email, - force: true, - }); + const [isAdminOrGlobalMod, canEdit] = await Promise.all([ + User.isAdminOrGlobalMod(data.req.uid), + privileges.users.canEdit(data.req.uid, userData.uid), + ]); + if (isAdminOrGlobalMod) { + await User.setUserField(userData.uid, 'email', formData.email); + await User.email.confirmByUid(userData.uid); + } else if (canEdit) { + await User.email.sendValidationEmail(userData.uid, { + email: formData.email, + force: true, + }); + } else { + // User attempting to edit another user's email -- not allowed + throw new Error('[[error:no-privileges]]'); + } } else { // New registrants have the confirm email sent from user.create() userData.email = formData.email;