getUsersTable()->newEntity([], ['validate' => false]); $user->setNew(false); $identity = $this->getRequest()->getAttribute('identity'); $identity = $identity ?? []; $userId = $identity['id'] ?? null; if ($userId) { if ($id && $identity['is_superuser'] && Configure::read('Users.Superuser.allowedToChangePasswords')) { // superuser editing any account's password $user->id = $id; $validatePassword = false; $redirect = ['action' => 'index']; } elseif (!$id || $id === $userId) { // normal user editing own password $user->id = $userId; $validatePassword = true; $redirect = Configure::read('Users.Profile.route'); } else { $this->Flash->error( __d('cake_d_c/users', 'Changing another user\'s password is not allowed'), ); $this->redirect(Configure::read('Users.Profile.route')); return; } } else { // password reset $user->id = $this->getRequest()->getSession()->read( Configure::read('Users.Key.Session.resetPasswordUserId'), ); $validatePassword = false; $redirect = $this->Authentication->getConfig('loginAction'); if (!$user->id) { $this->Flash->error(__d('cake_d_c/users', 'User was not found')); $this->redirect($redirect); return; } } $this->set('validatePassword', $validatePassword); if ($this->getRequest()->is(['post', 'put'])) { try { $validator = $this->getUsersTable()->validationPasswordConfirm(new Validator()); if ($validatePassword) { $validator = $this->getUsersTable()->validationCurrentPassword($validator); } $this->getUsersTable()->setValidator('current', $validator); $user = $this->getUsersTable()->patchEntity( $user, $this->getRequest()->getData(), [ 'validate' => 'current', 'accessibleFields' => [ 'current_password' => true, 'password' => true, 'password_confirm' => true, ], ], ); if ($user->getErrors()) { $this->Flash->error(__d('cake_d_c/users', 'Password could not be changed')); } else { $result = $this->getUsersTable()->changePassword($user); if ($result) { $event = $this->dispatchEvent(Plugin::EVENT_AFTER_CHANGE_PASSWORD, ['user' => $result]); $eventResult = $event->getResult(); if (!empty($eventResult) && is_array($eventResult)) { return $this->redirect($event->getResult()); } $this->Flash->success(__d('cake_d_c/users', 'Password has been changed successfully')); return $this->redirect($redirect); } else { $this->Flash->error(__d('cake_d_c/users', 'Password could not be changed')); } } } catch (UserNotFoundException $exception) { $this->Flash->error(__d('cake_d_c/users', 'User was not found')); } catch (WrongPasswordException $wpe) { $this->Flash->error($wpe->getMessage()); } catch (Exception $exception) { $this->Flash->error(__d('cake_d_c/users', 'Password could not be changed')); $this->log($exception->getMessage()); } } $this->set(['user' => $user]); $this->viewBuilder()->setOption('serialize', ['user']); } /** * Reset password * * @param null $token token data. * @return void */ public function resetPassword($token = null) { $this->validate('password', $token); } /** * Reset password * * @return \Cake\Http\Response|void */ public function requestResetPassword() { $this->set('user', $this->getUsersTable()->newEntity([], ['validate' => false])); $this->viewBuilder()->setOption('serialize', ['user']); if (!$this->getRequest()->is('post')) { return; } $reference = $this->getRequest()->getData('reference'); try { $resetUser = $this->getUsersTable()->resetToken($reference, [ 'expiration' => Configure::read('Users.Token.expiration'), 'checkActive' => false, 'sendEmail' => true, 'ensureActive' => Configure::read('Users.Registration.ensureActive'), 'type' => 'password', ]); if ($resetUser) { $msg = __d( 'cake_d_c/users', 'If the account is valid, the system will send an instructional email to the address on record.', ); $this->Flash->success($msg); } else { $msg = __d('cake_d_c/users', 'There was an error please contact Administrator'); $this->Flash->error($msg); } return $this->redirect(['action' => 'login']); } catch (UserNotFoundException | UserNotActiveException $exception) { $msg = __d( 'cake_d_c/users', 'If the account is valid, the system will send an instructional email to the address on record.', ); $this->Flash->success($msg); } catch (Exception $exception) { $msg = __d('cake_d_c/users', 'There was an error please contact Administrator'); $this->Flash->error($msg); $this->log($exception->getMessage()); } } /** * resetOneTimePasswordAuthenticator * * Resets Google Authenticator token by setting secret_verified * to false. * * @param mixed $id of the user record. * @return \Cake\Http\Response|null. */ public function resetOneTimePasswordAuthenticator($id = null): ?Response { if ($this->getRequest()->is('post')) { try { $query = $this->getUsersTable() ->updateQuery() ->set(['secret_verified' => false, 'secret' => null]) ->where(['id' => $id]); $query->execute(); $message = __d('cake_d_c/users', 'Google Authenticator token was successfully reset'); $this->Flash->success($message, 'default'); } catch (\Exception $e) { $this->Flash->error(__d('cake_d_c/users', 'Could not reset Google Authenticator'), 'default'); } } return $this->redirect($this->getRequest()->referer() ?? '/'); } }