diff --git a/src/user/email.js b/src/user/email.js index 8e422ac2f1..e7c03584b5 100644 --- a/src/user/email.js +++ b/src/user/email.js @@ -126,14 +126,12 @@ UserEmail.confirmByCode = async function (code) { let oldEmail = await user.getUserField(confirmObj.uid, 'email'); if (oldEmail) { oldEmail = oldEmail || ''; - if (oldEmail === confirmObj.email) { - return; + 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 }); } - - 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 }); } await Promise.all([ diff --git a/src/user/invite.js b/src/user/invite.js index 84db5cef3e..9df3731975 100644 --- a/src/user/invite.js +++ b/src/user/invite.js @@ -42,7 +42,8 @@ module.exports = function (User) { const email_exists = await User.getUidByEmail(email); if (email_exists) { - throw new Error('[[error:email-taken]]'); + // Silently drop the invitation if the invited email already exists locally + return true; } const invitation_exists = await db.exists(`invitation:uid:${uid}:invited:${email}`); diff --git a/test/user.js b/test/user.js index d1b0c3ffc3..4c9a61cd86 100644 --- a/test/user.js +++ b/test/user.js @@ -975,11 +975,10 @@ describe('User', () => { const uid = await User.create({ username: longName }); await socketUser.changeUsernameEmail({ uid: uid }, { uid: uid, username: longName, email: 'verylong@name.com' }); const userData = await db.getObject(`user:${uid}`); - assert.strictEqual(userData.username, longName); + const awaitingValidation = await User.email.isValidationPending(uid, 'verylong@name.com'); - const event = (await events.getEvents('email-confirmation-sent', 0, 0)).pop(); - assert.strictEqual(parseInt(event.uid, 10), uid); - assert.strictEqual(event.email, 'verylong@name.com'); + assert.strictEqual(userData.username, longName); + assert.strictEqual(awaitingValidation, true); }); it('should not update a user\'s username if it did not change', (done) => { @@ -2048,6 +2047,7 @@ describe('User', () => { async.apply(groups.create, { name: OWN_PRIVATE_GROUP, ownerUid: inviterUid, private: 1 }), async.apply(groups.join, 'administrators', adminUid), async.apply(groups.join, 'cid:0:privileges:invite', inviterUid), + async.apply(User.email.confirmByUid, inviterUid), ], done); }); }); @@ -2181,10 +2181,12 @@ describe('User', () => { assert.strictEqual(numInvites, 0); }); - it('should error if email exists', async () => { + it('should succeed if email exists but not actually send an invite', async () => { const { res } = await helpers.invite({ emails: 'inviter@nodebb.org', groupsToJoin: [] }, inviterUid, jar, csrf_token); - assert.strictEqual(res.statusCode, 400); - assert.strictEqual(res.body.status.message, 'Email taken'); + const numInvites = await User.getInvitesNumber(adminUid); + + assert.strictEqual(res.statusCode, 200); + assert.strictEqual(numInvites, 0); }); });