Update code to use the v2 api from Friendy-Captcha#10
Conversation
|
@KRMM2025 Would that mean that the package would then become incompatible with https://github.com/FriendlyCaptcha/friendly-lite-server ? |
@wi-wissen I'm not familiar with the "friendly-lite-server" repository and can't say for sure that the v2 puzzle can be solved by the lite server. However, you could make this pull request a major release so that people with the v1 lite server can simply continue using an older version of this package. |
|
@wi-wissen what do you think ? |
|
@ossycodes Thank you for the follow-up. I have only been a minor contributor to https://github.com/FriendlyCaptcha/friendly-lite-server and here. 😊 I fully understand that @KRMM2025 wants to use the new API though. Perhaps we could address this cleanly by introducing two major versions on Packagist — keeping the current v1.x for those using the self-hosted Lite server like me, and releasing a v2.x that targets the new cloud API. That way both use cases are supported without breaking existing installations. |
|
@KRMM2025 did you properly test this please ? Overall review body (REQUEST_CHANGES): Thanks for this contribution — the direction is correct, and the v2 API changes look well thought out. However, two critical bugs would break the package at runtime, plus a few smaller
Inline comments:
|
|
Thanks for your reply. I will look on it and make some fixes in the next days. 👍 |
|
Hi, is there some news about this PR? Thank you. |
ossycodes
left a comment
There was a problem hiding this comment.
Thanks for this contribution — migrating to the v2 API is the right direction and the overall structure is solid. However a thorough review found 2 crash-on-use bugs and 6 additional issues that need to be fixed before this can be merged.
🔴 Critical — crashes at runtime
1. Fatal TypeError when captcha field is empty — src/Rules/FriendlyCaptcha.php:24
verifyResponse() returns false (a bool) when $solution is empty. passes() then calls $response->isSuccess() on that false:
$response = $this->friendlyCaptchaClient->verifyResponse($value); // can return false
if ($response->isSuccess()) { // fatal: "Call to a member function isSuccess() on bool"Any form submission where the captcha field is missing (the most common spam scenario) causes a 500 error instead of a validation failure.
Fix: Change verifyResponse() to always return $this — set $this->isSuccess = false instead of return false. Or guard the call in passes():
if (!$response || !$response->isSuccess()) { ... }2. bootLang() silently overwrites bootMacro() — src/FriendlyCaptchaServiceProvider.php
boot() calls bootMacro() then bootLang(). Both call Rule::macro('friendlycaptcha', ...). Laravel's Macroable::macro is a plain array write — the second registration silently wins. The surviving closure calls $this->loadTranslationsFrom(...) where $this is the Rule class, which has no such method → fatal "Call to undefined method". Rule::friendlycaptcha() never returns a rule object, breaking all captcha validation.
Fix: Remove the Rule::macro call from bootLang(). Load translations directly in boot():
public function boot()
{
// ...
$this->loadTranslationsFrom(__DIR__.'/../lang', 'friendlycaptcha');
$this->bootMacro();
// ...
}🟠 High
3. $this->errors vs declared $this->error — src/FriendlyCaptcha.php
The class declares protected $error = [] (singular) but all reads/writes use $this->errors (plural). Dynamic undeclared property — deprecated in PHP 8.2, fatal in PHP 9. More critically: on the success path $this->errors is never assigned, so getErrors() returns null. The foreach ($response->getErrors() as ...) in Rules/FriendlyCaptcha.php then throws "foreach argument must be of type array|object, null given" on every successful captcha verification.
Fix: Rename the declared property to protected $errors = [].
4. Illuminate\Contracts\Validation\Rule removed in Laravel 12 — src/Rules/FriendlyCaptcha.php
use Illuminate\Contracts\Validation\Rule;
class FriendlyCaptcha implements RuleThis interface was removed in Laravel 12. The package's composer.json supports illuminate/support ^12.0|^13.0, so on Laravel 12+ this class fails to load with "Interface not found", making the validation rule completely unusable.
Fix: Implement Illuminate\Contracts\Validation\ValidationRule instead, replacing passes() + message() with:
public function validate(string $attribute, mixed $value, \Closure $fail): void
{
$response = $this->friendlyCaptchaClient->verifyResponse($value);
if (!$response->isSuccess()) {
foreach ($response->getErrors() as $code) {
$fail($this->mapErrorCodeToMessage($code));
}
}
}5. form_params sends form-encoded but v2 endpoint expects JSON — src/FriendlyCaptcha.php
The config now defaults to https://global.frcapi.com/api/v2/captcha/siteverify. Guzzle's form_params sends Content-Type: application/x-www-form-urlencoded. The FriendlyCaptcha v2 API is a JSON REST API, so this will cause every verification to fail.
Fix: Replace form_params with json:
$response = $this->http->request('POST', $this->verify, [
'headers' => $headers,
'json' => $data,
]);🟡 Medium
6. Tests use @test annotation — tests/FriendlyCaptchaTest.php
PHPUnit 11 (pulled in by testbench 9+ for Laravel 11+) removed the @test docblock annotation. Both test methods are invisible to PHPUnit — the suite exits with "no tests found" (exit code 2), breaking CI.
Fix: Rename methods to use the test_ prefix and drop the annotations:
public function test_it_can_render_jsdelivr_widget_script_correctly()
public function test_it_can_render_widget_correctly()7. SDK version inconsistency — CHANGELOG.md vs source files
src/FriendlyCaptcha.php and src/FriendlyCaptchaServiceProvider.php both hardcode @friendlycaptcha/sdk@0.1.36, but CHANGELOG.md documents @0.2.0. Please align these — use @0.2.0 consistently across all files.
8. Translations never loaded
Even after fixing issue #2, the lang files won't be registered unless loadTranslationsFrom is called directly in boot() (not inside a macro closure). The fix for #2 above handles this correctly.
Once these are addressed this will be ready to merge as a major release (v4.0.0). Happy to review a follow-up — thanks again for the contribution.
I have updated this repository to support FriendlyCaptcha API Version 2.
This is a breaking change, i recommend this as a part of a major update.
As part of this update:
I removed the use of unpkg, because the FriendlyCaptcha SDK (@friendlycaptcha/sdk@0.1.36) is only available via jsdelivr.net.
I updated the tests accordingly to use the FriendlyCaptcha SDK.
I removed the option to select a puzzle, as the current @friendlycaptcha/sdk package does not support that functionality.
I updated the API requests to use the correct URL and request structure required by FriendlyCaptcha API V2.
I also adjusted the error messages in validation.php to align with the new API response format.