1 | <?php |
||||
2 | |||||
3 | namespace Backend\Modules\Authentication\Actions; |
||||
4 | |||||
5 | use Backend\Core\Engine\Base\ActionAdd as BackendBaseActionAdd; |
||||
6 | use Backend\Core\Engine\Authentication as BackendAuthentication; |
||||
7 | use Backend\Core\Engine\Form as BackendForm; |
||||
8 | use Backend\Core\Engine\Model as BackendModel; |
||||
9 | use Backend\Core\Language\Language as BL; |
||||
10 | use Backend\Core\Engine\User as BackendUser; |
||||
11 | use Backend\Modules\Users\Engine\Model as BackendUsersModel; |
||||
12 | |||||
13 | /** |
||||
14 | * This is the reset password action, it will display a form that allows the user to reset his/her password. |
||||
15 | */ |
||||
16 | class ResetPassword extends BackendBaseActionAdd |
||||
17 | { |
||||
18 | /** |
||||
19 | * User email |
||||
20 | * |
||||
21 | * @var string $email |
||||
22 | */ |
||||
23 | private $email; |
||||
24 | |||||
25 | /** |
||||
26 | * Reset password key |
||||
27 | * |
||||
28 | * @var string $key |
||||
29 | */ |
||||
30 | private $key; |
||||
31 | |||||
32 | /** |
||||
33 | * User record |
||||
34 | * |
||||
35 | * @var BackendUser |
||||
36 | */ |
||||
37 | private $user; |
||||
38 | |||||
39 | public function execute(): void |
||||
40 | { |
||||
41 | parent::execute(); |
||||
42 | |||||
43 | // the user email and key provided match |
||||
44 | if (!$this->isThePasswordResetKeyCorrect()) { |
||||
45 | $this->redirect(BackendModel::createUrlForAction('Index')); |
||||
46 | } |
||||
47 | |||||
48 | $this->loadForm(); |
||||
49 | $this->validateForm(); |
||||
50 | $this->parse(); |
||||
51 | $this->display(); |
||||
52 | } |
||||
53 | |||||
54 | private function isThePasswordResetKeyCorrect(): bool |
||||
55 | { |
||||
56 | // catch the key and e-mail address from GET |
||||
57 | $this->email = urldecode($this->getRequest()->query->get('email', '')); |
||||
58 | $this->key = $this->getRequest()->query->get('key', ''); |
||||
59 | |||||
60 | // if the email or the key aren't set, redirect the user |
||||
61 | if ($this->email !== '' && $this->key !== '') { |
||||
62 | // fetch the user |
||||
63 | $userId = BackendUsersModel::getIdByEmail($this->email); |
||||
64 | $this->user = new BackendUser($userId); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
65 | $requestTime = $this->user->getSetting('reset_password_timestamp'); |
||||
66 | |||||
67 | // check if the request was made within 24 hours |
||||
68 | if ((time() - $requestTime) > 86400) { |
||||
69 | // remove the reset_password_key and reset_password_timestamp usersettings |
||||
70 | BackendUsersModel::deleteResetPasswordSettings($userId); |
||||
0 ignored issues
–
show
It seems like
$userId can also be of type false ; however, parameter $id of Backend\Modules\Users\En...ResetPasswordSettings() does only seem to accept integer , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
71 | |||||
72 | // redirect to the login form, with a timeout error |
||||
73 | $this->redirect(BackendModel::createUrlForAction('Index', null, null, ['reset' => 'timeout'])); |
||||
74 | } |
||||
75 | |||||
76 | // check if the provided key matches the one in the user record |
||||
77 | if ($this->key === $this->user->getSetting('reset_password_key')) { |
||||
78 | return true; |
||||
79 | } |
||||
80 | } |
||||
81 | |||||
82 | // if we made it here the user is not allowed to access this page |
||||
83 | return false; |
||||
84 | } |
||||
85 | |||||
86 | private function loadForm(): void |
||||
87 | { |
||||
88 | $this->form = new BackendForm(); |
||||
89 | $this->form->addPassword('backend_new_password'); |
||||
90 | $this->form->addPassword('backend_new_password_repeated'); |
||||
91 | |||||
92 | $this->form->getField('backend_new_password')->setAttributes(['autocomplete' => 'new-password']); |
||||
93 | $this->form->getField('backend_new_password_repeated')->setAttributes(['autocomplete' => 'new-password']); |
||||
94 | } |
||||
95 | |||||
96 | private function validateForm(): void |
||||
97 | { |
||||
98 | if ($this->form->isSubmitted()) { |
||||
99 | // shorten fields |
||||
100 | $newPassword = $this->form->getField('backend_new_password'); |
||||
101 | $newPasswordRepeated = $this->form->getField('backend_new_password_repeated'); |
||||
102 | |||||
103 | // required fields |
||||
104 | $newPassword->isFilled(BL::err('PasswordIsRequired')); |
||||
105 | $newPasswordRepeated->isFilled(BL::err('PasswordRepeatIsRequired')); |
||||
106 | |||||
107 | // all fields are ok? |
||||
108 | if ($newPassword->isFilled() && $newPasswordRepeated->isFilled()) { |
||||
109 | // the passwords entered match |
||||
110 | if ($newPassword->getValue() !== $newPasswordRepeated->getValue()) { |
||||
111 | // add error |
||||
112 | $this->form->addError(BL::err('PasswordsDontMatch')); |
||||
113 | |||||
114 | // show error |
||||
115 | $this->template->assign('error', BL::err('PasswordsDontMatch')); |
||||
116 | } |
||||
117 | } |
||||
118 | |||||
119 | if ($this->form->isCorrect()) { |
||||
120 | // change the users password |
||||
121 | BackendUsersModel::updatePassword($this->user, $newPassword->getValue()); |
||||
122 | |||||
123 | // attempt to login the user |
||||
124 | if (!BackendAuthentication::loginUser($this->user->getEmail(), $newPassword->getValue())) { |
||||
125 | // redirect to the login form with an error |
||||
126 | $this->redirect(BackendModel::createUrlForAction('Index', null, null, ['login' => 'failed'])); |
||||
127 | } |
||||
128 | |||||
129 | // redirect to the login form |
||||
130 | $this->redirect( |
||||
131 | BackendModel::createUrlForAction('Index', 'Dashboard', null, ['password_reset' => 'success']) |
||||
132 | ); |
||||
133 | } |
||||
134 | } |
||||
135 | } |
||||
136 | } |
||||
137 |