Password Reset Direct link

Is there anyway to get direct access to the password reset page?
Currently you have to visit the login page and click ‘Forgot your password’ first. I’m just wanting to remove a step for the user.
I thought /panel/reset-password/ would go directly to it but that’s a different process.

Is that for a frontend login?

No for Panel access.
I’m sending an email to the new admin user via a hook when I’ve created their account.
Ideally wanted them to create a new password without having to send them one, hense the need for a link to the ‘forgot your password’ form/page.

A direct link to the password reset form is currently not available, but what you could do is to build a custom route like so (untested):

<?php

use Kirby\Http\Response;

return [
  'routes' => [
    [
      'pattern' => 'reset-password/(:any)',
      'action'  => function ($email) {
        try {
          kirby()->auth()->createChallenge($email, false, 'password-reset');
        } catch (\Exception $e) {
          return new Response($e->getMessage(), 'text/plain', 400);
        }

        return Response::redirect('panel/login');
      }
    ]
  ]
];

Then you can send users a link like https://example.com/reset-password/your@email.com and they will be sent directly to the entry form for the password reset code.

2 Likes

Thanks for the suggestion @lukasbestle I’ll give it ago.

This a very useful - thank you! Is it possible to extend your suggestion by adding further logic to first check if the email address is a registered user before creating the authentication challenge?
Trying to check the email throws an error (Call to a member function exists() on null)
`

    [
        'pattern' => 'user-confirmation/(:any)',
        'action'  => function ($email) {
            if(kirby()->user($email)->exists()) {
                try {
                    kirby()->auth()->createChallenge($email, false, 'password-reset');
                } catch (\Exception $e) {
                    return new Response($e->getMessage(), 'text/plain', 400);
                }
                return Response::redirect('password-reset');
            } else {
                return go('error');
            }
        }
      ] 

`

kirby()->user($email)->exists() is not a method, but kirby()->user($email) will return null if the user does not exist. So you can just do

if (kirby()->user($email)) {

Ah, of course! Thank you so much

I wouldn’t recommend this though. With such a check, you would introduce a user enumeration vulnerability, i.e. attackers would be able to go through a list of email addresses and verify for each one whether a user with this email address exists. This could then be used to perform an attack on your site.

If you use the example code from my post, Kirby will protect against this vulnerability. Even if the email address was invalid, a challenge will still be created and Kirby will behave the same on the outside, which hides the fact whether a user exists or not.

If you need to create different behavior or an error message when a password reset was requested for an invalid user, you should protect against user enumeration in a different way, such as by protecting the password reset mechanism with an additional token or password.

Thank you Lukas, this makes total sense. In my case the client admin has the ability to add members who have access to restricted front end content without panel access. To avoid having to issue passwords by email, the client emails them a link, such as https://example.com/reset-password/your@email.com which generates the authentication challenge, emails them a login code and redirects them to the login code form. Once they enter the correct code, they’re effectively logged in and directed to a password update form where they can set or change their password. Is that sufficient protection of the password reset mechanism or would you recommend a different approach?

The workflow itself sounds really sensible. Letting people choose their own passwords is much more secure than sending them default passwords in unencrypted emails.

The risk for a user enumeration attack depends on your threat model. If it’s not viable for an attacker to check the existence of email addresses or if the fact whether a user with a specific email address exists won’t be sensitive information that could be abused, you are good to go. But it’s worth considering whether there is a risk. If you cannot rule it out, it’s safer to use Kirby’s default logic that hides whether the email address belongs to a user.

1 Like