diff --git a/common/locales/en/front.json b/common/locales/en/front.json index 6e4dfec28f..99c6437ddd 100644 --- a/common/locales/en/front.json +++ b/common/locales/en/front.json @@ -254,5 +254,6 @@ "onlySocialAttachLocal": "Local authentication can be added to only a social account.", "invalidReqParams": "Invalid request parameters.", "memberIdRequired": "\"member\" must be a valid UUID.", - "heroIdRequired": "\"heroId\" must be a valid UUID." + "heroIdRequired": "\"heroId\" must be a valid UUID.", + "cannotFulfillReq":"Your request cannot be fulfilled. Email admin@habitica.com if this error persists." } diff --git a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js index 47357d3c85..4a3086cbe9 100644 --- a/test/api/v3/integration/user/auth/PUT-user_update_email.test.js +++ b/test/api/v3/integration/user/auth/PUT-user_update_email.test.js @@ -55,6 +55,17 @@ describe('PUT /user/auth/update-email', () => { await user.sync(); expect(user.auth.local.email).to.eql(newEmail); }); + + it('rejects if email is already taken', async () => { + await expect(user.put(ENDPOINT, { + newEmail: user.auth.local.email, + password: oldPassword, + })).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('cannotFulfillReq'), + }); + }); }); context('Social Login User', async () => { diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js index 7863a9f384..74e3663637 100644 --- a/website/server/controllers/api-v3/auth.js +++ b/website/server/controllers/api-v3/auth.js @@ -545,6 +545,9 @@ api.updateEmail = { let validationErrors = req.validationErrors(); if (validationErrors) throw validationErrors; + let emailAlreadyInUse = await User.findOne({'auth.local.email': req.body.newEmail}).select({_id: 1}).lean().exec(); + if (emailAlreadyInUse) throw new NotAuthorized(res.t('cannotFulfillReq')); + let candidatePassword = passwordUtils.encrypt(req.body.password, user.auth.local.salt); if (candidatePassword !== user.auth.local.hashed_password) throw new NotAuthorized(res.t('wrongPassword'));