|string> */ public function rules(): array { $rules = [ 'email' => ['required', 'string', 'email'], 'password' => ['required', 'string'], ]; if (get_setting('captcha_enabled', false)) { $rules['g-recaptcha-response'] = ['required', 'captcha']; } return $rules; } /** * Attempt to authenticate the request's credentials. * * @throws ValidationException */ public function authenticate(): void { // validasi input $this->ensureIsNotRateLimited(); if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) { $lockoutDuration = get_setting('login_lockout_duration', 15) * 60; // Convert minutes to seconds RateLimiter::hit($this->throttleKey(), $lockoutDuration); throw ValidationException::withMessages([ 'email' => __('The email or password is incorrect.'), ]); } RateLimiter::clear($this->throttleKey()); } public function ensureIsNotRateLimited(): void { $maxAttempts = get_setting('login_max_attempts', 5); if (! RateLimiter::tooManyAttempts($this->throttleKey(), $maxAttempts)) { return; } $seconds = RateLimiter::availableIn($this->throttleKey()); // Trigger lockout event for notification if enabled if (get_setting('login_lockout_notify', true)) { event(new Lockout($this)); } throw ValidationException::withMessages([ 'email' => __('Your account is temporarily locked. Please try again in :seconds seconds.', [ 'seconds' => $seconds, ]), ]); } /** * Get the rate limiting throttle key for the request. */ public function throttleKey(): string { return Str::transliterate(Str::lower($this->string('email')).'|'.$this->ip()); } }