'Willkommen zurück', 'eyebrow' => 'Anmeldung im Publisher-Hub', 'topRightLabel' => 'Noch kein Konto?', 'topRightLinkText' => 'Konto erstellen', 'topRightLinkHref' => '/register'])] class extends Component { #[Validate('required|string|email')] public string $email = ''; #[Validate('required|string')] public string $password = ''; public bool $remember = false; /** * Handle an incoming authentication request. */ public function login(): void { $this->validate(); $this->ensureIsNotRateLimited(); // Zugangsdaten prüfen, OHNE schon einzuloggen – sonst würde die // Fortify-2FA-Pipeline umgangen (2FA-Bypass). Legacy-User ohne Passwort // (password = null) scheitern hier korrekt und nutzen Magic-Link/Reset. $user = User::query()->where('email', $this->email)->first(); if (! $user || ! $user->password || ! Hash::check($this->password, $user->password)) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages([ 'email' => __('auth.failed'), ]); } RateLimiter::clear($this->throttleKey()); // 2FA aktiv: nicht einloggen, sondern in Fortifys Challenge übergeben // (Session-Vertrag login.id/login.remember wie RedirectIfTwoFactorAuthenticatable). if ($user->hasEnabledTwoFactorAuthentication()) { Session::put([ 'login.id' => $user->getKey(), 'login.remember' => $this->remember, ]); $this->redirect(route('two-factor.challenge')); return; } Auth::login($user, $this->remember); // Unverifizierte Selbst-Registrierer → Notice-Seite. if (! $user->hasVerifiedEmail()) { Session::regenerate(); $this->redirect(route('verification.notice', absolute: false)); return; } // Verifiziert, aber deaktiviert: Login zentral blockieren. if (! $user->is_active) { Auth::logout(); throw ValidationException::withMessages([ 'email' => __('Ihr Konto ist nicht aktiv. Bitte wenden Sie sich an den Support.'), ]); } $user->update([ 'last_login_at' => now(), 'last_login_ip' => request()->ip(), ]); Session::regenerate(); // Rollengerechter, 403-sicherer Redirect. Ohne navigate:true, weil das // Portal ein anderes Vite-Bundle nutzt als das Hub-Auth-Layout. $this->redirect(LoginRedirect::safeTarget( $user, Session::pull('url.intended'), LoginRedirect::homeFor($user), )); } /** * Ensure the authentication request is not rate limited. */ protected function ensureIsNotRateLimited(): void { if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { return; } event(new Lockout(request())); $seconds = RateLimiter::availableIn($this->throttleKey()); throw ValidationException::withMessages([ 'email' => __('auth.throttle', [ 'seconds' => $seconds, 'minutes' => ceil($seconds / 60), ]), ]); } /** * Get the authentication rate limiting throttle key. */ protected function throttleKey(): string { return Str::transliterate(Str::lower($this->email).'|'.request()->ip()); } }; ?>