CMS Password Reset flow Broken with Eloquent driver
Bug description
I migrated my users in Statamic 5 to use the eloquent driver, as described in the docs. When using the "Forgot Password" form on the CMS login form, I got an error after submitting
Route [password.reset] not defined.
How to reproduce
- Use the eloquent driver for your users and follow the documentation on https://statamic.dev/tips/storing-users-in-a-database
- Go to
/cpand click "Forgot password?" - Fill out the form and submit
Logs
Environment
Environment
Application Name: Kwetta
Laravel Version: 12.15.0
PHP Version: 8.4.3
Composer Version: 2.8.5
Environment: staging
Debug Mode: ENABLED
URL: kwetta.gil.testsite.kiwi.nz
Maintenance Mode: OFF
Timezone: UTC
Locale: en
Cache
Config: CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED
Drivers
Broadcasting: log
Cache: file
Database: mysql
Logs: stack / single
Mail: log
Queue: sync
Session: file
Storage
public/storage: LINKED
Statamic
Addons: 2
Sites: 1
Stache Watcher: Disabled (auto)
Static Caching: Disabled
Version: 5.56.0 PRO
Statamic Addons
statamic/eloquent-driver: 4.21.2
statamic/ssg: 3.1.1
Statamic Eloquent Driver
Asset Containers: eloquent
Assets: eloquent
Blueprints: file
Collection Trees: eloquent
Collections: eloquent
Entries: eloquent
Forms: eloquent
Global Sets: eloquent
Global Variables: eloquent
Navigation Trees: eloquent
Navigations: eloquent
Revisions: eloquent
Sites: eloquent
Taxonomies: eloquent
Terms: eloquent
Tokens: eloquent
Installation
Fresh statamic/statamic site via CLI
Additional details
No response
Can you provide your config/auth.php and config/statamic/users.php config files?
auth.php
<?php
use App\Models\User;
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option defines the default authentication "guard" and password
| reset "broker" for your application. You may change these values
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => env('AUTH_GUARD', 'web'),
'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| which utilizes session storage plus the Eloquent user provider.
|
| All authentication guards have a user provider, which defines how the
| users are actually retrieved out of your database or other storage
| system used by the application. Typically, Eloquent is utilized.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication guards have a user provider, which defines how the
| users are actually retrieved out of your database or other storage
| system used by the application. Typically, Eloquent is utilized.
|
| If you have multiple user tables or models you may configure multiple
| providers to represent the model / table. These providers may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "statamic", "database", "eloquent"
|
*/
'providers' => [
// 'users' => [
// 'driver' => 'statamic',
// ],
'users' => [
'driver' => 'eloquent',
'model' => env('AUTH_MODEL', User::class),
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| These configuration options specify the behavior of Laravel's password
| reset functionality, including the table utilized for token storage
| and the user provider that is invoked to actually retrieve users.
|
| The expiry time is the number of minutes that each reset token will be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
| The throttle setting is the number of seconds a user must wait before
| generating more password reset tokens. This prevents the user from
| quickly generating a very large amount of password reset tokens.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'),
'expire' => 60,
'throttle' => 60,
],
'activations' => [
'provider' => 'users',
'table' => env('AUTH_ACTIVATION_TOKEN_TABLE', 'password_activation_tokens'),
'expire' => 4320,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| window expires and users are asked to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800),
];
users.php
<?php
return [
/*
|--------------------------------------------------------------------------
| User Repository
|--------------------------------------------------------------------------
|
| Statamic uses a repository to get users, roles, groups, and their
| relationships from specified storage locations. The file driver
| gets it from disk, while the eloquent driver gets from a DB.
|
| Supported: "file", "eloquent"
|
*/
'repository' => 'eloquent',
'repositories' => [
'file' => [
'driver' => 'file',
'paths' => [
'roles' => resource_path('users/roles.yaml'),
'groups' => resource_path('users/groups.yaml'),
],
],
'eloquent' => [
'driver' => 'eloquent',
],
],
/*
|--------------------------------------------------------------------------
| Avatars
|--------------------------------------------------------------------------
|
| User avatars are initials by default, with custom options for services
| like Gravatar.com.
|
| Supported: "initials", "gravatar", or a custom class name.
|
*/
'avatars' => 'initials',
/*
|--------------------------------------------------------------------------
| New User Roles
|--------------------------------------------------------------------------
|
| When registering new users through the user:register_form tag, these
| roles will automatically be applied to your newly created users.
|
*/
'new_user_roles' => [
//
],
/*
|--------------------------------------------------------------------------
| New User Groups
|--------------------------------------------------------------------------
|
| When registering new users through the user:register_form tag, these
| groups will automatically be applied to your newly created users.
|
*/
'new_user_groups' => [
//
],
/*
|--------------------------------------------------------------------------
| Registration form honeypot field
|--------------------------------------------------------------------------
|
| When registering new users through the user:register_form tag,
| specify the field to act as a honeypot for bots
|
*/
'registration_form_honeypot_field' => null,
/*
|--------------------------------------------------------------------------
| User Wizard Invitation Email
|--------------------------------------------------------------------------
|
| When creating new users through the wizard in the control panel,
| you may choose whether to be able to send an invitation email.
| Setting to true will give the user the option. But setting
| it to false will disable the invitation option entirely.
|
*/
'wizard_invitation' => true,
/*
|--------------------------------------------------------------------------
| Password Brokers
|--------------------------------------------------------------------------
|
| When resetting passwords, Statamic uses an appropriate password broker.
| Here you may define which broker should be used for each situation.
| You may want a longer expiry for user activations, for example.
|
*/
'passwords' => [
'resets' => 'users',
'activations' => 'activations',
],
/*
|--------------------------------------------------------------------------
| Database
|--------------------------------------------------------------------------
|
| Here you may configure the database connection and its table names.
|
*/
'database' => config('database.default'),
'tables' => [
'users' => 'users',
'role_user' => 'role_user',
'roles' => false,
'group_user' => 'group_user',
'groups' => false,
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| By default, Statamic will use the `web` authentication guard. However,
| if you want to run Statamic alongside the default Laravel auth
| guard, you can configure that for your cp and/or frontend.
|
*/
'guards' => [
'cp' => 'web',
'web' => 'web',
],
/*
|--------------------------------------------------------------------------
| Impersonation
|--------------------------------------------------------------------------
|
| Here you can configure if impersonation is available, and what URL to
| redirect to after impersonation begins.
|
*/
'impersonate' => [
'enabled' => env('STATAMIC_IMPERSONATE_ENABLED', true),
'redirect' => env('STATAMIC_IMPERSONATE_REDIRECT', null),
],
/*
|--------------------------------------------------------------------------
| Default Sorting
|--------------------------------------------------------------------------
|
| Here you may configure the default sort behavior for user listings.
|
*/
'sort_field' => 'email',
'sort_direction' => 'asc',
];
@SuryaWebfox Have you followed step 12 of the linked documentation page? We had this issue of a missing route, but it was caused by us skipping the last step of adding a notification method to your User model. Once you add that, you should be fine.
public function sendPasswordResetNotification($token)
{
$this->notify(new \Statamic\Notifications\PasswordReset($token));
}
That's a good point. I since did add that method (a custom version) but I probably missed that step somewhere.
Just to clarify… is this resolved now that you’ve added the method to your User model?
Yes, sorry