From 92ac717fffcd313a67142f3079b4119098babda2 Mon Sep 17 00:00:00 2001 From: Kai Rohrpasser Date: Fri, 30 Jan 2026 10:20:11 +0100 Subject: [PATCH 1/2] Update code to use the v2 api from Friendy-Captcha --- lang/de/validation.php | 15 +++++---- lang/en/validation.php | 15 +++++---- src/FriendlyCaptcha.php | 44 ++++++++++---------------- src/FriendlyCaptchaServiceProvider.php | 15 ++------- src/Rules/FriendlyCaptcha.php | 32 ++++++++----------- tests/FriendlyCaptchaTest.php | 26 ++++----------- 6 files changed, 55 insertions(+), 92 deletions(-) diff --git a/lang/de/validation.php b/lang/de/validation.php index e336be3..235b427 100644 --- a/lang/de/validation.php +++ b/lang/de/validation.php @@ -7,12 +7,13 @@ */ return [ - 'secret_missing' => 'Sie haben vergessen, den Parameter secret (=API-Schlüssel) hinzuzufügen.', - 'secret_invalid' => 'Der von Ihnen angegebene API-Schlüssel war ungültig.', - 'solution_missing' => 'Sie haben vergessen, den Parameter secret (=API-Schlüssel) hinzuzufügen.', - 'secret_missing' => 'Sie haben vergessen, den Lösungsparameter hinzuzufügen.', 'bad_request' => 'Mit Ihrer Anfrage ist etwas anderes nicht in Ordnung, z. B. ist Ihr Anfragekörper leer.', - 'solution_invalid' => 'Die von Ihnen angegebene Lösung war ungültig (vielleicht wurde versucht, das Rätsel zu manipulieren).', - 'solution_timeout_or_duplicate' => 'Das Rätsel, für das Sie die Lösung angegeben haben, ist abgelaufen oder wurde bereits verwendet.', + 'auth_required' => 'Authentifizierung erforderlich.', + 'auth_invalid' => 'Authentifizierung fehlgeschlagen.', + 'sitekey_invalid' => 'Der Sitekey ist ungültig.', + 'response_missing' => 'Die Captcha-Lösung fehlt.', + 'response_invalid' => 'Die Captcha-Lösung ist falsch.', + 'response_timeout' => 'Anfrage abgelaufen.', + 'response_duplicate' => 'Diese Lösung wurde bereits verwendet.', 'unexpected' => 'Ein unerwarteter Fehler ist aufgetreten.' -]; \ No newline at end of file +]; diff --git a/lang/en/validation.php b/lang/en/validation.php index ae73955..f0d2b49 100644 --- a/lang/en/validation.php +++ b/lang/en/validation.php @@ -7,12 +7,13 @@ */ return [ - 'secret_missing' => 'You forgot to add the secret (=API key) parameter.', - 'secret_invalid' => 'The API key you provided was invalid.', - 'solution_missing' => 'You forgot to add the secret (=API key) parameter.', - 'secret_missing' => 'You forgot to add the solution parameter.', 'bad_request' => 'Something else is wrong with your request, e.g. your request body is empty.', - 'solution_invalid' => 'The solution you provided was invalid (perhaps the user tried to tamper with the puzzle).', - 'solution_timeout_or_duplicate' => 'The puzzle that the solution was for has expired or has already been used.', + 'auth_required' => 'Authentification required.', + 'auth_invalid' => 'Authentification failed.', + 'sitekey_invalid' => 'The sitekey is invalid.', + 'response_missing' => 'The captcha solution is missing.', + 'response_invalid' => 'The captcha solution is invalid.', + 'response_timeout' => 'Connection timed out.', + 'response_duplicate' => 'This solution has already been used.', 'unexpected' => 'An unexpected error occurred.' -]; \ No newline at end of file +]; diff --git a/src/FriendlyCaptcha.php b/src/FriendlyCaptcha.php index e52b25f..ed3b41c 100755 --- a/src/FriendlyCaptcha.php +++ b/src/FriendlyCaptcha.php @@ -20,11 +20,6 @@ class FriendlyCaptcha */ protected $sitekey; - /** - * FriendlyCaptcha Puzzle endpoint - */ - protected $puzzle; - /** * FriendlyCaptcha verify endpoint */ @@ -44,27 +39,19 @@ class FriendlyCaptcha */ protected $http; - public function __construct($secret, $sitekey, $puzzle, $verify, $options = []) + public function __construct($secret, $sitekey, $verify, $options = []) { $this->secret = $secret; $this->sitekey = $sitekey; - $this->puzzle = $puzzle; $this->verify = $verify; $this->http = new Client($options); } - public function renderWidgetScripts($option = 'unpkg') + public function renderWidgetScripts(): string { - if ($option == 'unpkg') { - return << - - EOF; - } - return << - + + EOF; } @@ -83,8 +70,6 @@ public function renderWidget($attributes = []) */ protected function prepareAttributes(array $attributes) { - $attributes['data-puzzle-endpoint'] = $this->puzzle; - $attributes['data-sitekey'] = $this->sitekey; if (isset($attributes['dark-theme'])) { @@ -130,7 +115,7 @@ protected function buildAttributes(array $attributes) * * @return bool */ - public function verifyRequest($solution) + public function verifyRequest(string $solution) { return $this->verifyResponse( $solution, @@ -144,17 +129,19 @@ public function verifyRequest($solution) * * @return self */ - public function verifyResponse($solution) + public function verifyResponse(string $solution) { if (empty($solution)) { return false; } - $verifyResponse = $this->sendRequestVerify([ - 'solution' => $solution, - 'secret' => $this->secret, - 'sitekey' => $this->sitekey, - ]); + $verifyResponse = $this->sendRequestVerify( + ['X-API-Key' => $this->secret], + [ + 'response' => $solution, + 'sitekey' => $this->sitekey, + ] + ); if (isset($verifyResponse['success']) && $verifyResponse['success'] === true) { $this->isSuccess = true; @@ -178,13 +165,14 @@ public function verifyResponse($solution) /** * Send verify request. * + * @param array $headers * @param array $data - * * @return array */ - protected function sendRequestVerify(array $data = []) + protected function sendRequestVerify(array $headers = [], array $data = []): array { $response = $this->http->request('POST', $this->verify, [ + 'headers' => $headers, 'form_params' => $data, ]); diff --git a/src/FriendlyCaptchaServiceProvider.php b/src/FriendlyCaptchaServiceProvider.php index bef41b8..21691dd 100644 --- a/src/FriendlyCaptchaServiceProvider.php +++ b/src/FriendlyCaptchaServiceProvider.php @@ -49,19 +49,10 @@ protected function bootConfig() */ public function bootBladeDirectives() { - Blade::directive('friendlyCaptchaRenderWidgetScripts', function ($option) { - $option = trim($option, "'"); - - if (empty($option) || $option == 'unpkg') { - return << - - EOF; - } - + Blade::directive('friendlyCaptchaRenderWidgetScripts', function () { return << - + + EOF; }); } diff --git a/src/Rules/FriendlyCaptcha.php b/src/Rules/FriendlyCaptcha.php index 06040b8..932d9bc 100644 --- a/src/Rules/FriendlyCaptcha.php +++ b/src/Rules/FriendlyCaptcha.php @@ -45,24 +45,20 @@ public function message() protected function mapErrorCodeToMessage(string $code): string { switch ($code) { - case "secret_missing": - return __('validation.secret_missing'); - break; - case "secret_invalid": - return __('validation.secret_invalid'); - break; - case "solution_missing": - return __('validation.solution_missing'); - break; - case "bad_request": - return __('validation.bad_request'); - break; - case "solution_invalid": - return __('validation.solution_invalid'); - break; - case "solution_timeout_or_duplicate": - return __('validation.solution_timeout_or_duplicate'); - break; + case "auth_required": + return __('validation.auth_required'); + case "auth_invalid": + return __('validation.auth_invalid'); + case "sitekey_invalid": + return __('validation.sitekey_invalid'); + case "response_missing": + return __('validation.response_missing'); + case "response_invalid": + return __('validation.response_invalid'); + case "response_timeout": + return __('validation.response_timeout'); + case "response_duplicate": + return __('validation.response_duplicate'); default: return __('validation.unexpected'); } diff --git a/tests/FriendlyCaptchaTest.php b/tests/FriendlyCaptchaTest.php index f6686d6..7c29740 100644 --- a/tests/FriendlyCaptchaTest.php +++ b/tests/FriendlyCaptchaTest.php @@ -22,37 +22,23 @@ public function setUp(): void { parent::setUp(); - $this->captcha = new FriendlyCaptcha('{secret-key}', '{site-key}', 'https://api.friendlycaptcha.com/api/v1/puzzle', 'https://api.friendlycaptcha.com/api/v1/siteverify'); + $this->captcha = new FriendlyCaptcha('{secret-key}', '{site-key}', 'https://global.frcapi.com/api/v2/captcha/siteverify'); } /** * @test */ - public function it_can_render_unpkg_widget_script_correctly() + public function it_can_render_jsdelivr_widget_script_correctly() { $this->assertTrue($this->captcha instanceof FriendlyCaptcha); - $expectedScriptOne = ''; - $expectedScriptTwo = ''; + $expectedScriptOne = ''; + $expectedScriptTwo = ''; $this->assertStringContainsString($expectedScriptOne, $this->captcha->renderWidgetScripts()); $this->assertStringContainsString($expectedScriptTwo, $this->captcha->renderWidgetScripts()); } - /** - * @test - */ - public function it_can_render_jsdelivr_widget_script_correctly() - { - $this->assertTrue($this->captcha instanceof FriendlyCaptcha); - - $expectedScriptOne = ''; - $expectedScriptTwo = ''; - - $this->assertStringContainsString($expectedScriptOne, $this->captcha->renderWidgetScripts('jsdelivr')); - $this->assertStringContainsString($expectedScriptTwo, $this->captcha->renderWidgetScripts('jsdelivr')); - } - /** * @test */ @@ -60,8 +46,8 @@ public function it_can_render_widget_correctly() { $this->assertTrue($this->captcha instanceof FriendlyCaptcha); - $expectedWidget = '
'; - $expectedWidgetWithCustomAttributes = '
'; + $expectedWidget = '
'; + $expectedWidgetWithCustomAttributes = '
'; $this->assertEquals($expectedWidget, $this->captcha->renderWidget()); $this->assertEquals($expectedWidgetWithCustomAttributes, $this->captcha->renderWidget(['dark-theme' => true])); From 56acdaea2822bba911d47b87d405ba83d59471d8 Mon Sep 17 00:00:00 2001 From: Kai Rohrpasser Date: Wed, 8 Apr 2026 18:05:09 +0200 Subject: [PATCH 2/2] Update changelog; fix spelling and constructor --- CHANGELOG.md | 16 ++++++++++++++++ lang/en/validation.php | 4 ++-- src/FriendlyCaptcha.php | 6 +++++- src/FriendlyCaptchaServiceProvider.php | 1 - src/Rules/FriendlyCaptcha.php | 2 ++ src/config/friendlycaptcha.php | 3 +-- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa54ca2..19f47ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to `ossycodes/friendlycaptcha` will be documented in this file +## 2.0.0 - 2026-04.08 +- Replace the friendly-challenge scripts +```html + + +``` +with the new @friendlycaptcha/sdk scripts +```html + + +``` + +For more information visit: https://developer.friendlycaptcha.com/docs/v2/guides/upgrading-from-v1/script + ## 1.0.0 - 2021-10-21 - initial release diff --git a/lang/en/validation.php b/lang/en/validation.php index f0d2b49..0ab2631 100644 --- a/lang/en/validation.php +++ b/lang/en/validation.php @@ -8,8 +8,8 @@ return [ 'bad_request' => 'Something else is wrong with your request, e.g. your request body is empty.', - 'auth_required' => 'Authentification required.', - 'auth_invalid' => 'Authentification failed.', + 'auth_required' => 'Authentication required.', + 'auth_invalid' => 'Authentication failed.', 'sitekey_invalid' => 'The sitekey is invalid.', 'response_missing' => 'The captcha solution is missing.', 'response_invalid' => 'The captcha solution is invalid.', diff --git a/src/FriendlyCaptcha.php b/src/FriendlyCaptcha.php index ed3b41c..4c33c78 100755 --- a/src/FriendlyCaptcha.php +++ b/src/FriendlyCaptcha.php @@ -3,6 +3,7 @@ namespace Ossycodes\FriendlyCaptcha; use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; class FriendlyCaptcha { @@ -35,7 +36,7 @@ class FriendlyCaptcha public $isSuccess = false; /** - * @var \GuzzleHttp\Client + * @var Client */ protected $http; @@ -114,6 +115,7 @@ protected function buildAttributes(array $attributes) * @param string $solution * * @return bool + * @throws GuzzleException */ public function verifyRequest(string $solution) { @@ -128,6 +130,7 @@ public function verifyRequest(string $solution) * @param string $solution * * @return self + * @throws GuzzleException */ public function verifyResponse(string $solution) { @@ -168,6 +171,7 @@ public function verifyResponse(string $solution) * @param array $headers * @param array $data * @return array + * @throws GuzzleException */ protected function sendRequestVerify(array $headers = [], array $data = []): array { diff --git a/src/FriendlyCaptchaServiceProvider.php b/src/FriendlyCaptchaServiceProvider.php index 21691dd..f49238f 100644 --- a/src/FriendlyCaptchaServiceProvider.php +++ b/src/FriendlyCaptchaServiceProvider.php @@ -90,7 +90,6 @@ public function register() return new FriendlyCaptcha( $app['config']['friendlycaptcha.secret'], $app['config']['friendlycaptcha.sitekey'], - $app['config']['friendlycaptcha.puzzle_endpoint'], $app['config']['friendlycaptcha.verify_endpoint'], $app['config']['friendlycaptcha.options'] ); diff --git a/src/Rules/FriendlyCaptcha.php b/src/Rules/FriendlyCaptcha.php index 932d9bc..54e6ca0 100644 --- a/src/Rules/FriendlyCaptcha.php +++ b/src/Rules/FriendlyCaptcha.php @@ -59,6 +59,8 @@ protected function mapErrorCodeToMessage(string $code): string return __('validation.response_timeout'); case "response_duplicate": return __('validation.response_duplicate'); + case "bad_request": + return __('validation.bad_request'); default: return __('validation.unexpected'); } diff --git a/src/config/friendlycaptcha.php b/src/config/friendlycaptcha.php index 9dcce25..456d908 100644 --- a/src/config/friendlycaptcha.php +++ b/src/config/friendlycaptcha.php @@ -3,8 +3,7 @@ return [ 'secret' => env('FRIENDLY_CAPTCHA_SECRET'), 'sitekey' => env('FRIENDLY_CAPTCHA_SITEKEY'), - 'puzzle_endpoint' => env('FRIENDLY_CAPTCHA_PUZZLE_ENDPOINT', 'https://api.friendlycaptcha.com/api/v1/puzzle'), - 'verify_endpoint' => env('FRIENDLY_CAPTCHA_VERIFY_ENDPOINT', 'https://api.friendlycaptcha.com/api/v1/siteverify'), + 'verify_endpoint' => env('FRIENDLY_CAPTCHA_VERIFY_ENDPOINT', 'https://global.frcapi.com/api/v2/captcha/siteverify'), //see https://developer.friendlycaptcha.com/docs/v2/guides/upgrading-from-v1/backend-integration 'options' => [ 'timeout' => 30, 'http_errors' => false,