diff --git a/errors.js b/errors.js index 37f42f4ff..da1287dd3 100644 --- a/errors.js +++ b/errors.js @@ -371,6 +371,14 @@ class ErrParentDoesNotVisible extends TalkError { } } +class ErrPasswordIncorrect extends TalkError { + constructor() { + super('Your current password was entered incorrectly', { + translation_key: 'PASSWORD_INCORRECT', + }); + } +} + module.exports = { TalkError, ErrAlreadyExists, @@ -395,6 +403,7 @@ module.exports = { ErrNotFound, ErrNotVerified, ErrParentDoesNotVisible, + ErrPasswordIncorrect, ErrPasswordResetToken, ErrPasswordTooShort, ErrPermissionUpdateUsername, diff --git a/graph/mutators/user.js b/graph/mutators/user.js index 8657905d9..1f43ca838 100644 --- a/graph/mutators/user.js +++ b/graph/mutators/user.js @@ -1,4 +1,8 @@ -const { ErrNotFound, ErrNotAuthorized } = require('../../errors'); +const { + ErrNotFound, + ErrNotAuthorized, + ErrPasswordIncorrect, +} = require('../../errors'); const Users = require('../../services/users'); const migrationHelpers = require('../../services/migration/helpers'); const { @@ -170,7 +174,7 @@ const changeUserPassword = async (ctx, oldPassword, newPassword) => { // Verify the old password. const validPassword = await user.verifyPassword(oldPassword); if (!validPassword) { - throw new ErrNotAuthorized(); + throw new ErrPasswordIncorrect(); } // Change the users password now. diff --git a/locales/en.yml b/locales/en.yml index 3d2fe88c7..e293fb40b 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -225,6 +225,7 @@ en: embedlink: copy: "Copy to Clipboard" error: + PASSWORD_INCORRECT: "Your current password was entered incorrectly" COMMENT_PARENT_NOT_VISIBLE: "The comment that you're replying to has been removed or doesn't exist." EMAIL_VERIFICATION_TOKEN_INVALID: "Email verification token is invalid." EMAIL_ALREADY_VERIFIED: "Email address already verified." diff --git a/middleware/trace.js b/middleware/trace.js index 24cbf38f4..6ac6f4b2c 100644 --- a/middleware/trace.js +++ b/middleware/trace.js @@ -3,5 +3,9 @@ const uuid = require('uuid/v1'); // Trace middleware attaches a request id to each incoming request. module.exports = (req, res, next) => { req.id = uuid(); + + // Add the context ID to the request as an HTTP header. + res.set('X-Talk-Trace-ID', req.id); + next(); }; diff --git a/plugins/talk-plugin-local-auth/client/components/ChangePassword.js b/plugins/talk-plugin-local-auth/client/components/ChangePassword.js index 1ceb1b9f5..010df0826 100644 --- a/plugins/talk-plugin-local-auth/client/components/ChangePassword.js +++ b/plugins/talk-plugin-local-auth/client/components/ChangePassword.js @@ -127,12 +127,11 @@ class ChangePassword extends React.Component { 'success', t('talk-plugin-local-auth.change_password.changed_password_msg') ); + this.clearForm(); + this.disableEditing(); } catch (err) { this.props.notify('error', getErrorMessages(err)); } - - this.clearForm(); - this.disableEditing(); }; onForgotPassword = async () => { diff --git a/plugins/talk-plugin-local-auth/server/mutators.js b/plugins/talk-plugin-local-auth/server/mutators.js index 389574d2d..147d06cd2 100644 --- a/plugins/talk-plugin-local-auth/server/mutators.js +++ b/plugins/talk-plugin-local-auth/server/mutators.js @@ -35,16 +35,24 @@ async function updateUserEmailAddress(ctx, email, confirmPassword) { email = email.toLowerCase().trim(); // Update the Users email address. - await User.update( - { - id: user.id, - profiles: { $elemMatch: { provider: 'local' } }, - }, - { - $set: { 'profiles.$.id': email }, - $unset: { 'profiles.$.metadata.confirmed_at': 1 }, + try { + await User.update( + { + id: user.id, + profiles: { $elemMatch: { provider: 'local' } }, + }, + { + $set: { 'profiles.$.id': email }, + $unset: { 'profiles.$.metadata.confirmed_at': 1 }, + } + ); + } catch (err) { + if (err.code === 11000) { + throw new ErrEmailTaken(); } - ); + + throw err; + } // Get some context for the email to be sent. const { organizationContactEmail } = await Settings.load([