From f90a7ed7c236b96e4d9242612184c609546af985 Mon Sep 17 00:00:00 2001
From: Alexkurd <7689609+Alexkurd@users.noreply.github.com>
Date: Thu, 9 Apr 2020 13:11:45 +0300
Subject: [PATCH] Hcaptcha support
---
.../jquery-wa/wa-settings/settings.captcha.js | 2 +-
wa-system/autoload/system_classes.php | 1 +
.../captcha/hcaptcha/templates/hcaptcha.html | 35 +++++++
.../templates/hcaptcha_invisible.html | 38 ++++++++
.../captcha/hcaptcha/waHCaptcha.class.php | 95 +++++++++++++++++++
wa-system/captcha/waCaptcha.class.php | 2 +-
...webasystSettingsCaptchaSave.controller.php | 3 +
7 files changed, 174 insertions(+), 2 deletions(-)
create mode 100644 wa-system/captcha/hcaptcha/templates/hcaptcha.html
create mode 100644 wa-system/captcha/hcaptcha/templates/hcaptcha_invisible.html
create mode 100644 wa-system/captcha/hcaptcha/waHCaptcha.class.php
diff --git a/wa-content/js/jquery-wa/wa-settings/settings.captcha.js b/wa-content/js/jquery-wa/wa-settings/settings.captcha.js
index 674f67163..c4494ae01 100644
--- a/wa-content/js/jquery-wa/wa-settings/settings.captcha.js
+++ b/wa-content/js/jquery-wa/wa-settings/settings.captcha.js
@@ -42,7 +42,7 @@ var WASettingsCaptcha = ( function($) {
var that = this;
that.$form.find(':input[name="captcha"]').on('change', function(){
- if (this.value == 'waReCaptcha') {
+ if (this.value === 'waReCaptcha' || this.value === 'waHCaptcha') {
that.$form.find('div.js-captcha-adapter-settings').slideDown();
} else {
that.$form.find('div.js-captcha-adapter-settings').slideUp();
diff --git a/wa-system/autoload/system_classes.php b/wa-system/autoload/system_classes.php
index 91eafe62a..345d74126 100644
--- a/wa-system/autoload/system_classes.php
+++ b/wa-system/autoload/system_classes.php
@@ -62,6 +62,7 @@
'waCaptcha' => 'captcha/waCaptcha.class.php',
'waReCaptcha' => 'captcha/recaptcha/waReCaptcha.class.php',
+ 'waHCaptcha' => 'captcha/hcaptcha/waHCaptcha.class.php',
'waPHPCaptcha' => 'captcha/phpcaptcha/waPHPCaptcha.class.php',
'waModel' => 'database/waModel.class.php',
diff --git a/wa-system/captcha/hcaptcha/templates/hcaptcha.html b/wa-system/captcha/hcaptcha/templates/hcaptcha.html
new file mode 100644
index 000000000..2af76e800
--- /dev/null
+++ b/wa-system/captcha/hcaptcha/templates/hcaptcha.html
@@ -0,0 +1,35 @@
+
+
diff --git a/wa-system/captcha/hcaptcha/templates/hcaptcha_invisible.html b/wa-system/captcha/hcaptcha/templates/hcaptcha_invisible.html
new file mode 100644
index 000000000..ac6a58bec
--- /dev/null
+++ b/wa-system/captcha/hcaptcha/templates/hcaptcha_invisible.html
@@ -0,0 +1,38 @@
+
+
diff --git a/wa-system/captcha/hcaptcha/waHCaptcha.class.php b/wa-system/captcha/hcaptcha/waHCaptcha.class.php
new file mode 100644
index 000000000..24b4fef01
--- /dev/null
+++ b/wa-system/captcha/hcaptcha/waHCaptcha.class.php
@@ -0,0 +1,95 @@
+options, 'wrapper_class', 'wa-captcha');
+ $sitekey = ifset($this->options['sitekey']);
+ $invisible = ifset($this->options['invisible']);
+
+ $view = wa('webasyst')->getView();
+ $view->assign(array(
+ 'wrapper_class' => $wrapper_class,
+ 'sitekey' => $sitekey,
+ ));
+
+ $template = wa()->getConfig()->getRootPath() .'/wa-system/captcha/hcaptcha/templates/hcaptcha.html';
+ if ($invisible) {
+ $template = wa()->getConfig()->getRootPath() .'/wa-system/captcha/hcaptcha/templates/hcaptcha_invisible.html';
+ }
+ return $view->fetch($template);
+ }
+
+ public function isValid($code = null, &$error = '')
+ {
+ if ($code === null) {
+ $code = waRequest::post('h-captcha-response');
+ }
+ $handle = curl_init(self::SITE_VERIFY_URL);
+ $options = array(
+ CURLOPT_POST => true,
+ CURLOPT_POSTFIELDS => http_build_query(array(
+ 'secret' => $this->options['secret'],
+ 'response' => $code,
+ 'remoteip' => waRequest::getIp(),
+ )),
+ CURLOPT_HTTPHEADER => array(
+ 'Content-Type: application/x-www-form-urlencoded'
+ ),
+ CURLINFO_HEADER_OUT => false,
+ CURLOPT_HEADER => false,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_SSL_VERIFYPEER => true
+ );
+ curl_setopt_array($handle, $options);
+ $response = curl_exec($handle);
+ curl_close($handle);
+ if ($response) {
+ $response = json_decode($response, true);
+ if (isset($response['success']) && $response['success'] === true) {
+ return true;
+ }
+
+ if (isset($response['error-codes'])) {
+ $errors = [];
+ foreach ($response['error-codes'] as $error_code) {
+ switch ($error_code) {
+ case 'missing-input-secret':
+ $errors[] = _ws('The secret parameter is missing.');
+ break;
+ case 'invalid-input-secret':
+ $errors[] = _ws('The secret parameter is invalid or malformed.');
+ break;
+ case 'missing-input-response':
+ $errors[] = _ws('The response parameter is missing.');
+ break;
+ case 'invalid-input-response':
+ $errors[] = _ws('The response parameter is invalid or malformed.');
+ break;
+ case 'bad-request':
+ $errors[] = _wa('The request is invalid or malformed.');
+ break;
+ default:
+ $errors[] = $error_code;
+ }
+ $error = implode('
', $errors);
+ }
+ }
+ }
+ return false;
+ }
+
+ public function display()
+ {
+
+ }
+}
diff --git a/wa-system/captcha/waCaptcha.class.php b/wa-system/captcha/waCaptcha.class.php
index e00cbe4fb..05e90c2fb 100644
--- a/wa-system/captcha/waCaptcha.class.php
+++ b/wa-system/captcha/waCaptcha.class.php
@@ -85,7 +85,7 @@ protected function readCaptchaConfig()
if (file_exists($captcha_config_path)) {
$config = include($captcha_config_path);
$class = ifset($config, 'captcha', 0, 'waPHPCaptcha');
- $options = ifset($config, 'captcha', 1, array());
+ $options = ifset($config, 'captcha', 1, $class, array());
return array($class, $options);
}
return array(null, null);
diff --git a/wa-system/webasyst/lib/actions/settings/captcha/webasystSettingsCaptchaSave.controller.php b/wa-system/webasyst/lib/actions/settings/captcha/webasystSettingsCaptchaSave.controller.php
index de3908ec6..4ae0ee376 100644
--- a/wa-system/webasyst/lib/actions/settings/captcha/webasystSettingsCaptchaSave.controller.php
+++ b/wa-system/webasyst/lib/actions/settings/captcha/webasystSettingsCaptchaSave.controller.php
@@ -8,6 +8,9 @@ public function execute()
$captcha_config_path = wa()->getConfig()->getConfigPath('config.php', true, 'webasyst');
if (file_exists($captcha_config_path)) {
$captcha_config = include ($captcha_config_path);
+ if (!is_array($captcha_config)) {
+ $captcha_config = null;
+ }
}
$captcha_config['captcha'][0] = waRequest::post('captcha', 'waPHPCaptcha', waRequest::TYPE_STRING);