I followed this thread here to create a password reset for frontend users.
When the user requested a new password via a frontend form, a token is added to the user’s data and the user receives an email with the url “/token/<the-token”. All good.
However, the almighty impersonate kirby user does not clear the “token” field when this route was accessed. Therefore, this link is valid forever.
Sidenote: Changing the password works.
[
'pattern' => 'token/([a-f0-9]{32})',
'action' => function($token) {
$kirby = kirby();
if ($user = $kirby->user()) {
$user->logout();
}
$kirby->impersonate('kirby');
if ($user = $kirby->users()->findBy('token', $token)) {
$user->update([
'token' => '', // does not work!
'password' => $user->changePassword($token), // works !!
]);
if ($user->login($token)) {
go('/account/password');
} else {
go('error');
}
} else {
go('error');
}
}
],
Thanks, yes I saw the authChallenge and had this on my list already.
I just couldn’t get my head around how to combine the same challenge for different use cases.
But I implemented it now and changed the onboarding flow to:
send a welcome email when a user with a specific role was created with a link to the password reset page (“welcome, please set a new password for your new account”)
Tested it several times and ran into ratelimits a lot, but this thread helped.
Now I am thinking of implementing a janitor button to trigger the removal of the logins file from the panel
With the auth mode “password, code” enabled in the config, the frontend user can request a login code via the panel login form now too.
But I guess there is no way around it (disable the auth challenge for the panel login, but enable it for other cases).
But all in all it feels much safer now. Thanks again for the hint.