app->singleton(LoginResponse::class, RoleAwareLoginResponse::class); $this->app->singleton(TwoFactorLoginResponse::class, RoleAwareLoginResponse::class); // Fortifys Default leitet auf die nicht registrierte Route // `two-factor.login` (views => false) – zurück zur Livewire-Challenge. $this->app->singleton(FailedTwoFactorLoginResponse::class, FailedTwoFactorChallengeResponse::class); $this->app->singleton(PasskeyLoginResponseContract::class, PasskeyLoginResponse::class); } /** * Bootstrap any application services. */ public function boot(): void { // Nur die notwendigen Fortify-Aktionen behalten Fortify::createUsersUsing(CreateNewUser::class); Fortify::updateUserPasswordsUsing(UpdateUserPassword::class); Fortify::resetUserPasswordsUsing(ResetUserPassword::class); Fortify::redirectUserForTwoFactorAuthenticationUsing(RedirectIfTwoFactorAuthenticatable::class); // Keine View-Definitionen, die Auth-Seiten sind Livewire-Komponenten RateLimiter::for('login', function (Request $request) { $throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip()); return Limit::perMinute(5)->by($throttleKey); }); RateLimiter::for('two-factor', function (Request $request) { return Limit::perMinute(5)->by($request->session()->get('login.id')); }); RateLimiter::for('passkeys', function (Request $request) { return Limit::perMinute(10)->by($request->user()?->getAuthIdentifier() ?? $request->ip()); }); // Passkey-Login (Entscheidung 5, 07.10.2026): nur aktive, verifizierte // Konten — wie die übrigen Anmeldewege. Passkeys::authorizeLoginUsing(function (Request $request, PasskeyUser $user, Passkey $passkey): bool { return $user instanceof User && $user->is_active && $user->hasVerifiedEmail(); }); } }