From e14d907e61f4c6a3aa262b16a39b4f8802634409 Mon Sep 17 00:00:00 2001 From: ousid Date: Mon, 1 Apr 2024 02:16:42 +0100 Subject: [PATCH] add reset captcha event --- README.md | 69 +++++++++++++++++++ .../views/components/turnstile.blade.php | 14 ++++ tests/Fixtures/ContactUs.php | 6 ++ tests/TurnstileTest.php | 20 ++++++ 4 files changed, 109 insertions(+) diff --git a/README.md b/README.md index 81fd6d5..a1e512a 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,67 @@ For a list of supported languages, refer to the [supported languages section](ht The `Turnstile` field offers various options; you can learn more about them in [the Cloudflare configuration section](https://developers.cloudflare.com/turnstile/get-started/client-side-rendering/#configurations). +## Turnstile Events + +The Turnstile package provides events that you can leverage to manage the behavior of the captcha in various scenarios. + +**Reset Event** + +The `reset-captcha` event allows you to programmatically reset the captcha challenge. This can be useful when you want to: + +- **Clear the challenge after a successful form submission:** This ensures a fresh captcha for the next user. +- **Reset the challenge upon validation errors:** Prevents users from being stuck with a previously solved captcha after encountering errors during form submission. + +**Dispatching the Reset Event:** + +There are two primary ways to dispatch the `reset-captcha` event: + +**1. Using `onValidationError` Method:** + +Filament provides the `onValidationError` method within your form's Livewire component. This method is automatically triggered whenever form [validation fails](https://filamentphp.com/docs/3.x/forms/validation#sending-validation-notifications). Here's how to utilize it: + +```php +protected function onValidationError(ValidationException $exception): void +{ + $this->dispatch('reset-captcha'); + + // Perform additional actions as necessary (e.g., display error messages) +} +``` + +In this example, the `reset-captcha` event is dispatched upon validation errors, ensuring the captcha is reset for the user's next attempt. + +**2. Manual Dispatching:** + +For scenarios where resetting the captcha is not directly tied to validation, you can manually dispatch the event using Filament's event dispatcher: + +```php +$this->dispatch('reset-captcha'); +``` + +**Using Reset Event in Login Page:** + +To automatically reset the captcha on a failed login attempt in your login form's Livewire component, leverage the `throwFailureValidationException` method: + +```php +protected function authenticate(): void +{ + // Perform authentication logic + // ... + + if (! Auth::attempt($this->data)) { + $this->throwFailureValidationException( + [ + 'email' => 'Invalid email or password.', + ] + ); + } + + // Redirect to success page or perform other actions +} +``` + +By throwing a validation exception with appropriate error messages, you trigger the `onValidationError` method, which in turn dispatches the `reset-captcha` event, effectively resetting the captcha for the next login attempt. ## Real-Life Example: @@ -97,6 +158,14 @@ class Login extends AuthLogin ), ]; } + + // if you want to reset the captcha in case of validation error + protected function throwFailureValidationException(): never + { + $this->dispatch('reset-captcha'); + + parent::throwFailureValidationException(); + } } ``` diff --git a/resources/views/components/turnstile.blade.php b/resources/views/components/turnstile.blade.php index 8131218..9f1319c 100644 --- a/resources/views/components/turnstile.blade.php +++ b/resources/views/components/turnstile.blade.php @@ -27,6 +27,10 @@ window.onloadTurnstileCallback = () => { turnstile.render($refs.turnstile, options) } + + resetCaptcha = () => { + turnstile.reset($refs.turnstile) + } })()" >
+ + @push('scripts') + + @endpush \ No newline at end of file diff --git a/tests/Fixtures/ContactUs.php b/tests/Fixtures/ContactUs.php index 3081880..065f74f 100644 --- a/tests/Fixtures/ContactUs.php +++ b/tests/Fixtures/ContactUs.php @@ -7,6 +7,7 @@ use Filament\Forms; use Filament\Forms\Form; use Filament\Forms\FormsComponent; +use Illuminate\Validation\ValidationException; class ContactUs extends FormsComponent { @@ -55,4 +56,9 @@ public function render() { return 'fixtures.contact-us'; } + + protected function onValidationError(ValidationException $exception): void + { + $this->dispatch('reset-captcha'); + } } diff --git a/tests/TurnstileTest.php b/tests/TurnstileTest.php index 50d5c8a..18ea29b 100644 --- a/tests/TurnstileTest.php +++ b/tests/TurnstileTest.php @@ -4,6 +4,7 @@ use Coderflex\FilamentTurnstile\Tests\Models\Contact; use Coderflex\LaravelTurnstile\Facades\LaravelTurnstile; use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Event; use function Pest\Livewire\livewire; @@ -94,3 +95,22 @@ expect(Contact::get()) ->toHaveCount(0); }); + +it('reset captcha event sent, on validation error ', function () { + Event::fake(); + + Config::set('turnstile', [ + 'turnstile_site_key' => '2x00000000000000000000AB', + 'turnstile_secret_key' => '2x0000000000000000000000000000000AA', + ]); + + livewire(ContactUs::class) + ->fillForm([ + 'name' => null, + 'email' => 'john@example.com', + 'content' => 'This is a simple message', + ]) + ->call('send') + ->assertHasFormErrors(['name']) + ->assertDispatched('reset-captcha'); +});