From b04e3fbddbdd2c8b5a7fae811a0d18d6690a93be Mon Sep 17 00:00:00 2001 From: aleclerc7 <66482588+aleclerc7@users.noreply.github.com> Date: Fri, 1 Apr 2022 17:22:25 -0400 Subject: [PATCH] Add hCaptcha support This will add hCaptcha support. - The user only needs to select the provider, set the keys. - This is a drop-in replacement of reCaptcha. PHP code on server side could be optimized. Tested to be working. No error cases were tested. --- blueprints.yaml | 10 +++- form.php | 60 +++++++++++++------ languages.yaml | 2 + .../forms/fields/captcha/captcha.html.twig | 18 +++--- 4 files changed, 63 insertions(+), 27 deletions(-) diff --git a/blueprints.yaml b/blueprints.yaml index c0bc31c..e5becc9 100644 --- a/blueprints.yaml +++ b/blueprints.yaml @@ -170,6 +170,14 @@ form: title: PLUGIN_FORM.RECAPTCHA fields: + recaptcha.provider: + type: select + label: PLUGIN_FORM.RECAPTCHA_PROVIDER + help: PLUGIN_FORM.RECAPTCHA_PROVIDER_HELP + default: reCaptcha + options: + reCaptcha: reCaptcha (Google) + hCaptcha: hCaptcha (Intuition Machines) recaptcha.version: type: select label: PLUGIN_FORM.RECAPTCHA_VERSION @@ -189,10 +197,8 @@ form: recaptcha.site_key: type: text label: PLUGIN_FORM.RECAPTCHA_SITE_KEY - help: PLUGIN_FORM.RECAPTCHA_SITE_KEY_HELP default: '' recaptcha.secret_key: type: text label: PLUGIN_FORM.RECAPTCHA_SECRET_KEY - help: PLUGIN_FORM.RECAPTCHA_SECRET_KEY_HELP default: '' diff --git a/form.php b/form.php index 86c182a..4075d66 100644 --- a/form.php +++ b/form.php @@ -465,26 +465,52 @@ public function onFormProcessed(Event $event): void $recaptcha = new ReCaptcha($secret, new CurlPost()); } - // get captcha version - $captcha_version = $captcha_config['version'] ?? 2; - - // Add version 3 specific options - if ($captcha_version == 3) { - $token = $form->value('token'); - $resp = $recaptcha - ->setExpectedHostname($hostname) - ->setExpectedAction($action) - ->setScoreThreshold(0.5) - ->verify($token, $ip); + $success = true; + $errors = ''; + + if ($this->config->get('plugins.form.recaptcha.provider','reCaptcha') == 'hCaptcha') { + // Use hCaptcha as provider: https://docs.hcaptcha.com/switch (see bottom of page for PHP code) + $data = array( + 'secret' => $secret, + 'response' => $_POST['h-captcha-response'] + ); + $verify = curl_init(); + curl_setopt($verify, CURLOPT_URL, "https://hcaptcha.com/siteverify"); + curl_setopt($verify, CURLOPT_POST, true); + curl_setopt($verify, CURLOPT_POSTFIELDS, http_build_query($data)); + curl_setopt($verify, CURLOPT_RETURNTRANSFER, true); + $response = curl_exec($verify); + $responseData = json_decode($response); + if(!$responseData->success) { + $success = false; + $errors = $responseData; + } } else { - $token = $form->value('g-recaptcha-response', true); - $resp = $recaptcha - ->setExpectedHostname($hostname) - ->verify($token, $ip); + // get captcha version + $captcha_version = $captcha_config['version'] ?? 2; + + // Add version 3 specific options + if ($captcha_version == 3) { + $token = $form->value('token'); + $resp = $recaptcha + ->setExpectedHostname($hostname) + ->setExpectedAction($action) + ->setScoreThreshold(0.5) + ->verify($token, $ip); + } else { + $token = $form->value('g-recaptcha-response', true); + $resp = $recaptcha + ->setExpectedHostname($hostname) + ->verify($token, $ip); + } + + if (!$resp->isSuccess()) { + $success = false; + $errors = $resp->getErrorCodes(); + } } - if (!$resp->isSuccess()) { - $errors = $resp->getErrorCodes(); + if (!$success) { $message = $this->grav['language']->translate('PLUGIN_FORM.ERROR_VALIDATING_CAPTCHA'); $fields = $form->value()->blueprints()->get('form/fields'); diff --git a/languages.yaml b/languages.yaml index 4b2f06d..819214e 100644 --- a/languages.yaml +++ b/languages.yaml @@ -14,6 +14,8 @@ en: DATA_SUMMARY: "Here is the summary of what you wrote to us:" NO_FORM_DATA: "No form data available" RECAPTCHA: "reCAPTCHA" + RECAPTCHA_PROVIDER: "Captcha Provider" + RECAPTCHA_PROVIDER_HELP: "reCaptcha (Google): For more info visit https://developers.google.com/recaptcha\nhCaptcha (Intuition Machines): For more info visit https://docs.hcaptcha.com" RECAPTCHA_VERSION: "Version" RECAPTCHA_VERSION_V2_CHECKBOX: "v2 - Checkbox" RECAPTCHA_VERSION_V2_INVISIBLE: "v2 - Invisible" diff --git a/templates/forms/fields/captcha/captcha.html.twig b/templates/forms/fields/captcha/captcha.html.twig index 75a4bee..7a89d9f 100644 --- a/templates/forms/fields/captcha/captcha.html.twig +++ b/templates/forms/fields/captcha/captcha.html.twig @@ -5,6 +5,8 @@ {% set action = (page.route|trim('/') ~ '-' ~ form.name)|underscorize %} {% set formName = form.name|underscorize %} {% set theme = config.plugins.form.recaptcha.theme ?? 'light' %} +{% set _captchaURL = config.plugins.form.recaptcha.provider == 'hCaptcha' ? 'https://js.hcaptcha.com/1/api.js' : 'https://www.google.com/recaptcha/api.js' %} +{% set _captchaName = config.plugins.form.recaptcha.provider == 'hCaptcha' ? 'h-captcha' : 'g-recaptcha' %} {% block label %}{% endblock %} @@ -12,7 +14,7 @@ {% if not site_key %} {% elseif config.plugins.form.recaptcha.version == 3 %} - {% do assets.addJs('https://www.google.com/recaptcha/api.js?render='~site_key~'&theme=' ~ theme) %} + {% do assets.addJs(_captchaURL ~ '?render=' ~ site_key ~ '&theme=' ~ theme) %} {##} - {% else %} - -
+ {% endif %} {% endblock %}