Skip to content

Commit

Permalink
refactor: added user.email.remove method, updated email interstitial …
Browse files Browse the repository at this point in the history
…to handle email removal
  • Loading branch information
julianlam committed Jul 30, 2021
1 parent 414d733 commit ccf004f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 22 deletions.
32 changes: 23 additions & 9 deletions src/user/email.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ UserEmail.available = async function (email) {
return !exists;
};

UserEmail.remove = async function (uid) {
const email = await user.getUserField(uid, 'email');
if (!email) {
return;
}

await Promise.all([
user.setUserFields(uid, {
email: '',
'email:confirmed': 0,
}),
db.sortedSetRemove('email:uid', email.toLowerCase()),
db.sortedSetRemove('email:sorted', `${email.toLowerCase()}:${uid}`),
user.email.expireValidation(uid),
user.auth.revokeAllSessions(uid),
events.log({ type: 'email-change', email, newEmail: '' }),
]);
};

UserEmail.isValidationPending = async (uid, email) => {
const code = await db.get(`confirm:byUid:${uid}`);

Expand Down Expand Up @@ -124,21 +143,16 @@ UserEmail.confirmByCode = async function (code) {
throw new Error('[[error:invalid-data]]');
}

let oldEmail = await user.getUserField(confirmObj.uid, 'email');
if (oldEmail) {
oldEmail = oldEmail || '';
if (oldEmail !== confirmObj.email) {
await db.sortedSetRemove('email:uid', oldEmail.toLowerCase());
await db.sortedSetRemove('email:sorted', `${oldEmail.toLowerCase()}:${confirmObj.uid}`);
await user.auth.revokeAllSessions(confirmObj.uid);
await events.log('email-change', { oldEmail, newEmail: confirmObj.email });
}
const oldEmail = await user.getUserField(confirmObj.uid, 'email');
if (oldEmail && confirmObj.email !== oldEmail) {
UserEmail.remove(confirmObj.uid);
}

await user.setUserField(confirmObj.uid, 'email', confirmObj.email);
await Promise.all([
UserEmail.confirmByUid(confirmObj.uid),
db.delete(`confirm:${code}`),
events.log({ type: 'email-change', oldEmail, newEmail: confirmObj.email }),
]);
};

Expand Down
28 changes: 15 additions & 13 deletions src/user/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,23 +248,22 @@ User.addInterstitials = function (callback) {
data: { email },
callback: async (userData, formData) => {
// Validate and send email confirmation
if (formData.email && formData.email.length) {
if (!utils.isEmailValid(formData.email)) {
throw new Error('[[error:invalid-email]]');
}
if (userData.uid) {
const [isAdminOrGlobalMod, canEdit] = await Promise.all([
User.isAdminOrGlobalMod(data.req.uid),
privileges.users.canEdit(data.req.uid, userData.uid),
]);

if (formData.email && formData.email.length) {
if (!utils.isEmailValid(formData.email)) {
throw new Error('[[error:invalid-email]]');
}

if (userData.uid) {
const current = await User.getUserField(userData.uid, 'email');
if (formData.email === current) {
throw new Error('[[error:email-nochange]]');
}

const [isAdminOrGlobalMod, canEdit] = await Promise.all([
User.isAdminOrGlobalMod(data.req.uid),
privileges.users.canEdit(data.req.uid, userData.uid),

]);

// Admins editing will auto-confirm, unless editing their own email
if (isAdminOrGlobalMod && userData.uid !== data.req.uid) {
await User.setUserField(userData.uid, 'email', formData.email);
Expand All @@ -279,9 +278,12 @@ User.addInterstitials = function (callback) {
throw new Error('[[error:no-privileges]]');
}
} else {
// New registrants have the confirm email sent from user.create()
userData.email = formData.email;
// User explicitly clearing their email
await User.email.remove(userData.uid);
}
} else {
// New registrants have the confirm email sent from user.create()
userData.email = formData.email;
}

delete userData.updateEmail;
Expand Down

0 comments on commit ccf004f

Please sign in to comment.