5

In my application, user's will have their accounts created for them by other people, so I want to send a password reset email to them so they can set their password and log in. The problem is I don't want these links to expire after 60 minutes like the default password reset emails. Now I could change the expiry time, but I want regular password resets to stay at 60 minutes, but the welcome email link to either never expire or expire after some long amount of time.

How can I go about doing this without implementing a second token system, I can't seem to find anything about this.

I suppose I could also just allow the user to re-send the welcome email if their token expires, but that is kind of annoying.

Matthew Weeks
  • 705
  • 7
  • 23

1 Answers1

7

The expiration duration is defined in auth.php. You can simply define another configuration with a different expiration time:

'passwords' => [
    'users' => [
        'provider' => 'users',
        'table' => 'password_resets',
        'expire' => 60,
    ],
    'users_welcome' => [
        'provider' => 'users',
        'table' => 'password_resets',
        'expire' => 120,
    ],
],

And when you're generating the mail you can use that new broker:

\Illuminate\Support\Facades\Password::broker('users_welcome')->sendResetLink($user->email);

To check whether the token is expired, Laravel uses the created_at of the reset and the defined expiration duration:

    /**
     * Determine if the token has expired.
     *
     * @param  string  $createdAt
     * @return bool
     */
    protected function tokenExpired($createdAt)
    {
        return Carbon::parse($createdAt)->addSeconds($this->expires)->isPast();
    }

https://github.com/laravel/framework/blob/5.8/src/Illuminate/Auth/Passwords/DatabaseTokenRepository.php#L139

Thomas
  • 6,550
  • 1
  • 23
  • 42
  • So I thought I had this working, but I discovered that when using the reset password form it is still using the default password broker. Is there a way I can use the same form and the same controller action, but use the different broker for those users that had a token generated with the `users_welcome` broker? – Matthew Weeks Apr 29 '19 at 21:17
  • I thought you didn't want to change the default password reset. If you can somehow differentiate between normal users and those created by someone else (maybe you need an additional user property), you can override the `broker()` method on the `ForgotPasswordController` and return the `users_welcome` broker. – Thomas Apr 30 '19 at 16:51
  • I did not want to change the default password. My issue just comes up because I didn't want to change the functionality of password resets, they are exactly the same whether the user forgot their password, or needs to set their password via the welcome email. I could make a second controller and view and override the broker, but the issue is that since both brokers use the users model, tokens are valid for both brokers even if they were generated by the opposite (I tested this out). This could mean a user could copy their token to the other url and it still be valid. Any ideas? Thanks! – Matthew Weeks Apr 30 '19 at 17:00
  • I'm afraid I don't understand the problem. You're right that Laravel only checks whether the token exists for a user, not with which broker it was generated. But the check whether it is expired uses the `expire` settings in the config. So, the ones you generate with your custom broker are valid for longer. – Thomas Apr 30 '19 at 17:18
  • Sorry I may not have explained it enough. So I've got ResetPasswordController which uses the default password broker. It has the route `password/reset/{token}`. Now I can't use this same route for the welcome tokens because it uses the default password broker. I could create say WelcomeController which would also use the `Illuminate\Foundation\Auth\ResetsPasswords` trait, and have the route `/password/set/{token}`, and override the `broker()` method. The issue is a user (or hacker) who has a token could just paste the token into the `password/set/{token}` route, so it would use the new broker. – Matthew Weeks Apr 30 '19 at 17:26