Users cannot reset their password using reset link with latest Kirby version

Hi there!

I’ve been using the userskit from starckio for the past months with no issues on multiple websites, in order to manage simple membership.

After updating the Kirby version of those websites, something is not working anymore: users who forgot their password and who click the reset link sent by email get an error saying "You are not allowed to change the password for the user “Member name”.

public static function changePassword(User $user, string $password): bool {
  if ($user->permissions()->changePassword() !== true) {
    throw new PermissionException([
      'key'  => 'user.changePassword.permission',
      'data' => ['name' => $user->username()]
    ]);
  }
  return static::validPassword($user, $password);
}

The link sent by email looks like mysite.com/token/9eced87154adfeaf76652838687d206d.
Here is the route I am using:

[
        'pattern' => 'token/([a-f0-9]{32})',
        'action'  => function($token) {
            $kirby   = kirby();
            $kirby->impersonate('kirby');
            if ($user = $kirby->user()) {
                $user->logout();
            }
            if ($user = $kirby->users()->findBy('token', $token)) {
                $user->update([
                    'token'    => '',
                    'password' => $user->changePassword($token),
                ]);
                if ($user->login($token)) {
                    go('/professionnels/mot-de-passe');
                } else {
                    go('error');
                } 
            } else {
                go('error');
            }
        }
    ],

And here is my member.yml blueprint:

title: Member
permissions:
  access:
    panel: false
    users: false
    site: false
user:
  changePassword: true

Do you know what I should do to make it work again? Something related to the Kirby impersonate? With the blueprint?

Thank you for your help :slight_smile:

1 Like

From which version did you update?

Version 3.2.5

The problem might be this line. Try and change it to:

  $user = $user->update([
                    'token'    => '',
                    'password' => $user->changePassword($token),
                ]);

But I wonder why you get the permission error… :thinking:

Same issue :pensive:

Maybe intend issue? user option should be inside of permissions option:

title: Member
permissions:
  access:
    panel: false
    users: false
    site: false
  user:
    changePassword: true

The indentation is exactly like you wrote it in my blueprint. I just mistyped it in the post above.

This drives me nuts, I think I’ll have to stay with Kirby 3.2.5 forever :joy:

Don’t despair, there is a solution.

I’ll try and look into it.

Thanks Sonja :pray:

Can you try using the $kirby->impersonate() method just before the $user->update() method? :thinking:

$kirby->impersonate('kirby');
$user->update([
    ...
]);
4 Likes

Yeeaaaaaaaaah!!! That’s working!
Thanks byybora! :heart_eyes:
I didn’t expect the solution to be so… obvious.

1 Like

You used the impersonate() method in your code before the user logout(). We made some corrections in these parts after 3.2.5 versions.

You’re wellcome. Just mark it as solution and move to solved please :wink:

Thanks again!

Like I said in the recent survey: this community is awseome!

1 Like

Could you please create an issue in the userskit repo, please?

I am doing it right now :wink:

Looks like the kit also still comes with an outdated Kirby version. It should ideally not contain the kirby folder at all…

You’re totally right. This should come as a plugin, or be part of future Kirby official releases.

(I just discovered BTW that the issue is already listed in the repo)

True, that was filed two months ago…

Hello,

I discover this code from @starckio which is just exceptional to be able to manage front-end sites.

I grabbed the latest version (but kirby’s version is old 3.x)

I updated to kirby 3.6.6. Full of errors because kirby made some changes in the meantime.

But nothing serious !

Here are the changes I made and everything seems to be working fine:

snippets/menu.php
$pages->visible() to $pages->listed()

controllers/account.php
$error = null;
add next:

$data = null;
$success = null;
$failed = null;

controllers/password.php
$error = null;
add next:
$success = null;

controllers/delete.php
$error = null;
add next:
$success = null;

controllers/signup.php
$error = null;
add next:
$success = null;

controllers/registrationbyemail.php
$error = null;
add next:
$success = null;

controllers/reset.php
$error = null;
add next:
$success = null;

template/login.php
<?= esc(get['username']) ?> to <?= $data['username'] ?? '' ?>

template/signup.php
template/registrationbyemail.php
<?= esc(get['name']) ?> to <?= $data['name'] ?? '' ?>
<?= esc(get['email']) ?> to <?= $data['email'] ?? '' ?>

template/reset.php
<?= esc(get['email']) ?> to <?= $data['email'] ?? '' ?>

for the email account creation page I moved $kirby->impersonate('kirby'); because it crashed.

config/config.php

    [
      'pattern' => 'token/([a-f0-9]{32})',
      'action'  => function($token) {
        $kirby   = kirby();
        //$kirby->impersonate('kirby');
        if ($user = $kirby->user()) {
          $user->logout();
        }
        $kirby->impersonate('kirby');
        if ($user = $kirby->users()->findBy('token', $token)) {
          $user->update([
            'token'    => '',
            'password' => $user->changePassword($token),
          ]);
          if ($user->login($token)) {
            go('/account/password');
          } else {
            go('error');
          } 
        } else {
          go('error');
        }
      }
    ],

I think that’s all.

I hope my edits are correct. Anyway it works.

Note:
For the mail sending part I put my own SMTP information.