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);