Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fortify routes already been assigned #6628

Closed
MattiaMarchiorato opened this issue Dec 20, 2024 · 9 comments
Closed

fortify routes already been assigned #6628

MattiaMarchiorato opened this issue Dec 20, 2024 · 9 comments
Assignees
Labels
bug Verified bug by the Nova team fix incoming A fix is in review

Comments

@MattiaMarchiorato
Copy link

  • Laravel Version: 11
  • Nova Version: 5.0.4
  • PHP Version: 8.3
  • Database Driver & Version: mysql
  • Operating System and Version: Sail

Description:

With artisan route:cache
Unable to prepare route [email/verify/{id}/{hash}] for serialization. Another route has already been assigned name [verification.verify].

Detailed steps to reproduce the issue on a fresh Nova installation:

We are using fortify in our app and we published fortify.php routes under routes folder. Since we updated to nova 5.* we receive this error.

@crynobone
Copy link
Member

Hi there,

We need to see how Fortify is being setup on your app before we can replicate the issue. If you looked at src/PendingRouteRegistration.php line 276 we already have some condition in place to avoid duplicate routes which clearly isn't working for you.

@MattiaMarchiorato
Copy link
Author

Hello,

Just create fortify.php in routes and add the content of fortify/routes/routes.php, then register the route in the RouteServiceProvider

Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/fortify.php'));

you will notice the issue with php artisan route:cache

@MattiaMarchiorato
Copy link
Author

In PendingRouteRegistration.php line 276 Route::has('verification.verify') return false, but with tinker
Route::has('verification.verify') return true.

@MattiaMarchiorato
Copy link
Author

The issue seems because of the order of the Service providers

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,
        App\Providers\TelescopeServiceProvider::class,
        App\Providers\FortifyServiceProvider::class,
        App\Providers\NovaServiceProvider::class,
        App\Providers\JetstreamServiceProvider::class,
        App\Providers\ViewServiceProvider::class,

We changed the order including NovaServiceProvider above FortifyServiceProvider, after was above, and now seems is working properly, anyway is quite strange.

@MattiaMarchiorato

This comment was marked as off-topic.

@crynobone
Copy link
Member

@MattiaMarchiorato Please keep the issue to a specific error so we can have a single reproducing step.


Can you share the content of config/fortify.php and App\Providers\FortifyServiceProvider

@MattiaMarchiorato
Copy link
Author

Yes sure

<?php

use App\Providers\RouteServiceProvider;
use Laravel\Fortify\Features;

return [

    /*
    |--------------------------------------------------------------------------
    | Fortify Guard
    |--------------------------------------------------------------------------
    |
    | Here you may specify which authentication guard Fortify will use while
    | authenticating users. This value should correspond with one of your
    | guards that is already present in your "auth" configuration file.
    |
    */

    'guard' => 'web',

    /*
    |--------------------------------------------------------------------------
    | Fortify Password Broker
    |--------------------------------------------------------------------------
    |
    | Here you may specify which password broker Fortify can use when a user
    | is resetting their password. This configured value should match one
    | of your password brokers setup in your "auth" configuration file.
    |
    */

    'passwords' => 'users',

    /*
    |--------------------------------------------------------------------------
    | Username / Email
    |--------------------------------------------------------------------------
    |
    | This value defines which model attribute should be considered as your
    | application's "username" field. Typically, this might be the email
    | address of the users but you are free to change this value here.
    |
    | Out of the box, Fortify expects forgot password and reset password
    | requests to have a field named 'email'. If the application uses
    | another name for the field you may define it below as needed.
    |
    */

    'username' => 'email',

    'email' => 'email',

    /*
    |--------------------------------------------------------------------------
    | Home Path
    |--------------------------------------------------------------------------
    |
    | Here you may configure the path where users will get redirected during
    | authentication or password reset when the operations are successful
    | and the user is authenticated. You are free to change this value.
    |
    */

    'home' => RouteServiceProvider::HOME,

    /*
    |--------------------------------------------------------------------------
    | Fortify Routes Middleware
    |--------------------------------------------------------------------------
    |
    | Here you may specify which middleware Fortify will assign to the routes
    | that it registers with the application. If necessary, you may change
    | these middleware but typically this provided default is preferred.
    |
    */

    'middleware' => ['web'],

    /*
    |--------------------------------------------------------------------------
    | Rate Limiting
    |--------------------------------------------------------------------------
    |
    | By default, Fortify will throttle logins to five requests per minute for
    | every email and IP address combination. However, if you would like to
    | specify a custom rate limiter to call then you may specify it here.
    |
    */

    'limiters' => [
        'login' => null,
    ],

    /*
    |--------------------------------------------------------------------------
    | Features
    |--------------------------------------------------------------------------
    |
    | Some of the Fortify features are optional. You may disable the features
    | by removing them from this array. You're free to only remove some of
    | these features or you can even remove all of these if you need to.
    |
    */

    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        Features::emailVerification(),
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        // Features::twoFactorAuthentication([
        //     'confirmPassword' => true,
        // ]),
    ],

];
<?php

namespace App\Providers;

use Laravel\Fortify\Fortify;
use App\Actions\Fortify\CreateNewUser;
use Illuminate\Support\ServiceProvider;
use App\Actions\Fortify\ResetUserPassword;
use App\Actions\Fortify\UpdateUserPassword;
use Laravel\Fortify\Contracts\LoginResponse;
use Laravel\Fortify\Contracts\LogoutResponse;
use Laravel\Fortify\Contracts\RegisterResponse;
use App\Actions\Fortify\UpdateUserProfileInformation;

class FortifyServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {       
        Fortify::ignoreRoutes();

        $this->app->instance(LogoutResponse::class, new class implements LogoutResponse
        {
            public function toResponse($request)
            {
                return redirect(route('index'));
            }
        });
        $this->app->instance(RegisterResponse::class, new class implements RegisterResponse
        {
            public function toResponse($request)
            {
                return redirect(route('dashboard', ['is_new' => 1]));
            }
        });

        $this->app->instance(LoginResponse::class, new class implements LoginResponse
        {
            public function toResponse($request)
            {   
                $qrcode = $request->session()->get('qrcode');
                if($qrcode) {
                    $request->session()->forget('qrcode');
                    return redirect(route('scan-campaign', ['qrcode' => $qrcode]));
                }
                return redirect(route('dashboard'));
            }
        });

    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {   
        Fortify::createUsersUsing(CreateNewUser::class);
        Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
        Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
        Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
    }
}

@crynobone crynobone self-assigned this Dec 22, 2024
@crynobone crynobone added pending Issues that are pending triage bug Verified bug by the Nova team fix incoming A fix is in review and removed pending Issues that are pending triage labels Dec 22, 2024
@crynobone
Copy link
Member

This is now fixed in 5.0.5, add the following to App\Providers\NovaServiceProvider:

    /**
     * Register the Nova routes.
     */
    protected function routes(): void
    {
        Nova::routes()
            ->withAuthenticationRoutes(default: true)
            ->withPasswordResetRoutes()
+           ->withoutEmailVerificationRoutes()
            ->register();
    }

@MattiaMarchiorato
Copy link
Author

For the moment, we solved by disabling in fortify

'features' => [
        //Features::registration(),
        Features::resetPasswords(),
        //Features::emailVerification(),
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        // Features::twoFactorAuthentication([
        //     'confirmPassword' => true,
        // ]),
    ],

delete Fortify::ignoreRoutes(); from FortifyServiceProvider and using our custom fortify routes.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified bug by the Nova team fix incoming A fix is in review
Projects
None yet
Development

No branches or pull requests

2 participants