form->getState(); $email = (string) ($data['email'] ?? ''); $throttleKey = $this->throttleKey($email); if (RateLimiter::tooManyAttempts($throttleKey, 10)) { $this->audit(status: 'failure', email: $email, actor: null, reason: 'throttled'); $seconds = RateLimiter::availableIn($throttleKey); throw ValidationException::withMessages([ 'data.email' => __('auth.throttle', [ 'seconds' => $seconds, 'minutes' => (int) ceil($seconds / 60), ]), ]); } try { $response = parent::authenticate(); } catch (ValidationException $exception) { RateLimiter::hit($throttleKey, 60); $this->audit(status: 'failure', email: $email, actor: null, reason: 'invalid_credentials'); throw $exception; } if (! $response) { return null; } /** @var PlatformUser|null $user */ $user = auth('platform')->user(); if (! ($user instanceof PlatformUser)) { return $response; } if (! $user->is_active) { auth('platform')->logout(); RateLimiter::hit($throttleKey, 60); $this->audit(status: 'failure', email: $email, actor: null, reason: 'inactive'); throw ValidationException::withMessages([ 'data.email' => __('filament-panels::auth/pages/login.messages.failed'), ]); } RateLimiter::clear($throttleKey); $user->forceFill(['last_login_at' => now()])->saveQuietly(); $this->audit(status: 'success', email: $email, actor: $user); return $response; } private function throttleKey(string $email): string { $ip = (string) request()->ip(); $normalizedEmail = mb_strtolower(trim($email)); return "system-login:{$ip}:{$normalizedEmail}"; } private function audit(string $status, string $email, ?PlatformUser $actor, ?string $reason = null): void { $tenant = Tenant::query()->where('external_id', 'platform')->first(); if (! $tenant) { return; } app(AuditLogger::class)->log( tenant: $tenant, action: 'platform.auth.login', context: [ 'attempted_email' => $email, 'ip' => request()->ip(), 'user_agent' => request()->userAgent(), 'reason' => $reason, ], actorId: $actor?->getKey(), actorEmail: $actor?->email ?? ($email ?: null), actorName: $actor?->name, status: $status, resourceType: 'platform_user', resourceId: $actor ? (string) $actor->getKey() : null, ); } }