diff --git a/application/Espo/Controllers/User.php b/application/Espo/Controllers/User.php index 45b823de40..888da75932 100644 --- a/application/Espo/Controllers/User.php +++ b/application/Espo/Controllers/User.php @@ -53,7 +53,10 @@ class User extends \Espo\Core\Controllers\Record if (!$request->isPost()) { throw new BadRequest(); } - return $this->getService('User')->changePassword($this->getUser()->id, $data['password']); + if (!array_key_exists('password', $data) || !array_key_exists('currentPassword', $data)) { + throw new BadRequest(); + } + return $this->getService('User')->changePassword($this->getUser()->id, $data['password'], true, $data['currentPassword']); } public function actionChangePasswordByRequest($params, $data, $request) diff --git a/application/Espo/Resources/i18n/en_US/User.json b/application/Espo/Resources/i18n/en_US/User.json index f7dd0df6d2..9b6d09decc 100644 --- a/application/Espo/Resources/i18n/en_US/User.json +++ b/application/Espo/Resources/i18n/en_US/User.json @@ -10,6 +10,7 @@ "roles": "Roles", "teamRole": "Position", "password": "Password", + "currentPassword": "Current Password", "passwordConfirm": "Confirm Password", "newPassword": "New Password", "newPasswordConfirm": "Confirm New Password", diff --git a/application/Espo/Services/User.php b/application/Espo/Services/User.php index 285ef08387..6095bf9089 100644 --- a/application/Espo/Services/User.php +++ b/application/Espo/Services/User.php @@ -79,7 +79,7 @@ class User extends Record return $result; } - public function changePassword($userId, $password) + public function changePassword($userId, $password, $checkCurrentPassword = false, $currentPassword) { $user = $this->getEntityManager()->getEntity('User', $userId); if (!$user) { @@ -90,6 +90,17 @@ class User extends Record throw new Error('Password can\'t be empty.'); } + if ($checkCurrentPassword) { + $passwordHash = new \Espo\Core\Utils\PasswordHash($this->getConfig()); + $u = $this->getEntityManager()->getRepository('User')->where(array( + 'id' => $user->id, + 'password' => $passwordHash->hash($currentPassword) + ))->findOne(); + if (!$u) { + throw new Forbidden(); + } + } + $user->set('password', $this->hashPassword($password)); $this->getEntityManager()->saveEntity($user); diff --git a/frontend/client/res/templates/modals/change-password.tpl b/frontend/client/res/templates/modals/change-password.tpl index 561c9d1c8a..f92d9716bb 100644 --- a/frontend/client/res/templates/modals/change-password.tpl +++ b/frontend/client/res/templates/modals/change-password.tpl @@ -1,4 +1,8 @@ +
+ +
{{{currentPassword}}}
+
{{{password}}}
diff --git a/frontend/client/src/views/modals/change-password.js b/frontend/client/src/views/modals/change-password.js index f0968a4ca2..51489f340e 100644 --- a/frontend/client/src/views/modals/change-password.js +++ b/frontend/client/src/views/modals/change-password.js @@ -54,6 +54,18 @@ Espo.define('Views.Modals.ChangePassword', 'Views.Modal', function (Dep) { this.getModelFactory().create('User', function (user) { this.model = user; + this.createView('currentPassword', 'Fields.Password', { + model: user, + mode: 'edit', + el: this.options.el + ' .field-currentPassword', + defs: { + name: 'currentPassword', + params: { + required: true, + } + } + }); + this.createView('password', 'Fields.Password', { model: user, mode: 'edit', @@ -84,10 +96,13 @@ Espo.define('Views.Modals.ChangePassword', 'Views.Modal', function (Dep) { changePassword: function () { + this.getView('currentPassword').fetchToModel(); this.getView('password').fetchToModel(); this.getView('passwordConfirm').fetchToModel(); - var notValid = this.getView('password').validate() || this.getView('passwordConfirm').validate(); + var notValid = this.getView('currentPassword').validate() || + this.getView('password').validate() || + this.getView('passwordConfirm').validate(); if (notValid) { return; @@ -99,6 +114,7 @@ Espo.define('Views.Modals.ChangePassword', 'Views.Modal', function (Dep) { url: 'User/action/changeOwnPassword', type: 'POST', data: JSON.stringify({ + currentPassword: this.model.get('currentPassword'), password: this.model.get('password') }), error: function () {