Befund (Review 16.06.): Der Volt-Login machte direkt Auth::attempt() und umging Fortifys 2FA-Pipeline (2FA-Bypass); zusätzlich existierte der Fortify-POST /login parallel mit schwächeren Post-Login-Regeln. Fix (Volt-nativ): - Volt-Login prüft Credentials ohne sofortiges Login; bei aktivem 2FA wird der Session-Vertrag login.id/login.remember gesetzt und auf eine neue Volt- 2FA-Challenge-Seite (/two-factor-challenge) geleitet, die an Fortifys bestehenden Controller postet (TOTP + Recovery-Code). - Gemeinsame Post-Login-Logik in App\Support\LoginRedirect (rollengerechtes Home + 403-sicherer intended-Redirect), genutzt von Volt-Login UND Response. - RoleAwareLoginResponse implementiert jetzt LoginResponse UND TwoFactorLoginResponse und erzwingt einheitlich: unverifiziert → Notice, verifiziert-inaktiv → Logout+Fehler, sonst 403-sicherer Redirect. Damit ist auch der direkte Fortify-POST-Pfad gehärtet. Tests: 2FA-Übergabe, Challenge-Guard, voller TOTP-Flow, Fortify-POST blockt inaktive User und hält Customer aus dem Admin-Bereich. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
49 lines
1.7 KiB
PHP
49 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Responses;
|
|
|
|
use App\Support\LoginRedirect;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
|
|
use Laravel\Fortify\Contracts\TwoFactorLoginResponse as TwoFactorLoginResponseContract;
|
|
|
|
/**
|
|
* Einheitliche Antwort für den Fortify-POST-Login UND den Abschluss der
|
|
* 2FA-Challenge. Spiegelt dieselbe Policy wie der Volt-Login:
|
|
* - unverifiziert → Verifizierungs-Notice
|
|
* - verifiziert, aber inaktiv → Login blockiert (Logout + Fehler)
|
|
* - sonst rollengerechter, 403-sicherer Redirect (intended nur wenn erreichbar)
|
|
*/
|
|
class RoleAwareLoginResponse implements LoginResponseContract, TwoFactorLoginResponseContract
|
|
{
|
|
public function toResponse($request): RedirectResponse|JsonResponse
|
|
{
|
|
if ($request instanceof Request && $request->wantsJson()) {
|
|
return new JsonResponse('', 204);
|
|
}
|
|
|
|
$user = $request->user();
|
|
|
|
if ($user && ! $user->hasVerifiedEmail()) {
|
|
return redirect()->route('verification.notice');
|
|
}
|
|
|
|
if ($user && ! $user->is_active) {
|
|
Auth::guard('web')->logout();
|
|
$request->session()->invalidate();
|
|
$request->session()->regenerateToken();
|
|
|
|
return redirect()->route('login')->withErrors([
|
|
'email' => __('Ihr Konto ist nicht aktiv. Bitte wenden Sie sich an den Support.'),
|
|
]);
|
|
}
|
|
|
|
$default = LoginRedirect::homeFor($user);
|
|
$intended = $request->session()->pull('url.intended');
|
|
|
|
return redirect(LoginRedirect::safeTarget($user, $intended, $default));
|
|
}
|
|
}
|