diff --git a/modules/spamfilter/captcha/recaptcha.php b/modules/spamfilter/captcha/recaptcha.php index f3e2b9775..f53c2797d 100644 --- a/modules/spamfilter/captcha/recaptcha.php +++ b/modules/spamfilter/captcha/recaptcha.php @@ -20,9 +20,12 @@ class reCAPTCHA self::$config = $config; } - public static function check() + public static function check($response = null) { - $response = Context::get('g-recaptcha-response'); + if (!$response) + { + $response = Context::get('g-recaptcha-response'); + } if (!$response) { throw new Exception('msg_recaptcha_invalid_response'); diff --git a/modules/spamfilter/captcha/turnstile.php b/modules/spamfilter/captcha/turnstile.php index 2f3dad337..3098582ad 100644 --- a/modules/spamfilter/captcha/turnstile.php +++ b/modules/spamfilter/captcha/turnstile.php @@ -20,9 +20,12 @@ class Turnstile self::$config = $config; } - public static function check() + public static function check($response = null) { - $response = Context::get('g-recaptcha-response'); + if (!$response) + { + $response = Context::get('g-recaptcha-response'); + } if (!$response) { throw new Exception('msg_recaptcha_invalid_response'); diff --git a/modules/spamfilter/conf/module.xml b/modules/spamfilter/conf/module.xml index 00440ac48..8bef3c6f9 100644 --- a/modules/spamfilter/conf/module.xml +++ b/modules/spamfilter/conf/module.xml @@ -6,6 +6,7 @@ + @@ -15,6 +16,7 @@ + diff --git a/modules/spamfilter/lang/en.php b/modules/spamfilter/lang/en.php index 8d09bb889..53d905804 100644 --- a/modules/spamfilter/lang/en.php +++ b/modules/spamfilter/lang/en.php @@ -2,7 +2,8 @@ $lang->cmd_denied_ip = 'IP Address Blacklist'; $lang->cmd_denied_word = 'Keyword Blacklist'; $lang->cmd_config_block = 'Automatic Blocking'; -$lang->cmd_captcha_config = 'CAPTCHA'; +$lang->cmd_captcha_config = 'CAPTCHA Settings'; +$lang->cmd_captcha_test = 'CAPTCHA Test'; $lang->add_denied_ip = 'Add IP address or range'; $lang->add_denied_word = 'Add keyword'; $lang->spamfilter = 'Spam Filter'; @@ -69,7 +70,9 @@ $lang->recaptcha_target_everyone = 'Everyone'; $lang->recaptcha_target_frequency = 'Frequency'; $lang->recaptcha_target_first_time_only = 'First Time Only'; $lang->recaptcha_target_every_time = 'Every Time'; +$lang->msg_recaptcha_not_configured = 'Your CAPTCHA is not properly configured.'; $lang->msg_recaptcha_connection_error = 'An error occurred while connecting to the CAPTCHA verification server.'; $lang->msg_recaptcha_server_error = 'An error occurred while verifying your CAPTCHA response.'; $lang->msg_recaptcha_invalid_response = 'Please check the CAPTCHA.'; $lang->msg_recaptcha_keys_not_set = 'Please fill in your CAPTCHA Site Key and Secret Key.'; +$lang->msg_recaptcha_test_success = 'You passed the CAPTCHA test successfully.'; diff --git a/modules/spamfilter/lang/ko.php b/modules/spamfilter/lang/ko.php index 3b2e1dfb6..a7f16d0ae 100644 --- a/modules/spamfilter/lang/ko.php +++ b/modules/spamfilter/lang/ko.php @@ -3,6 +3,7 @@ $lang->cmd_denied_ip = '스팸 IP 목록'; $lang->cmd_denied_word = '스팸 키워드 목록'; $lang->cmd_config_block = '자동 차단 설정'; $lang->cmd_captcha_config = '캡챠 설정'; +$lang->cmd_captcha_test = '캡챠 테스트'; $lang->add_denied_ip = '스팸 IP 추가'; $lang->add_denied_word = '스팸 키워드 추가'; $lang->spamfilter = '스팸필터'; @@ -69,7 +70,9 @@ $lang->recaptcha_target_everyone = '모든 사용자'; $lang->recaptcha_target_frequency = '캡챠 사용 빈도'; $lang->recaptcha_target_first_time_only = '최초 1회만 사용'; $lang->recaptcha_target_every_time = '매번 사용'; +$lang->msg_recaptcha_not_configured = '스팸방지 CAPTCHA가 올바르게 설정되지 않았습니다.'; $lang->msg_recaptcha_connection_error = '스팸방지 CAPTCHA 서버에 접속하는 도중 오류가 발생했습니다.'; $lang->msg_recaptcha_server_error = '스팸방지 CAPTCHA 서버와 통신하는 도중 오류가 발생했습니다.'; $lang->msg_recaptcha_invalid_response = '스팸방지 기능을 체크해 주십시오.'; $lang->msg_recaptcha_keys_not_set = 'CAPTCHA Site Key 및 Secret Key를 입력하여 주십시오.'; +$lang->msg_recaptcha_test_success = 'CAPTCHA 테스트를 성공적으로 통과했습니다.'; diff --git a/modules/spamfilter/spamfilter.admin.controller.php b/modules/spamfilter/spamfilter.admin.controller.php index 38e99cab0..eaf4d79f1 100644 --- a/modules/spamfilter/spamfilter.admin.controller.php +++ b/modules/spamfilter/spamfilter.admin.controller.php @@ -115,6 +115,23 @@ class SpamfilterAdminController extends Spamfilter $this->setRedirectUrl($returnUrl); } + public function procSpamfilterAdminSubmitCaptchaTest() + { + $response = Context::get('g-recaptcha-response') ?? Context::get('cf-turnstile-response'); + + try + { + SpamfilterModel::checkCaptchaResponse($response); + } + catch (Exception $e) + { + return new BaseObject(-1, $e->getMessage()); + } + + $this->setMessage('msg_recaptcha_test_success'); + $this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispSpamfilterAdminConfigCaptchaTest')); + } + public function procSpamfilterAdminInsertDeniedIP() { //스팸IP 추가 diff --git a/modules/spamfilter/spamfilter.admin.view.php b/modules/spamfilter/spamfilter.admin.view.php index 1e2f1e72f..402d7ba3e 100644 --- a/modules/spamfilter/spamfilter.admin.view.php +++ b/modules/spamfilter/spamfilter.admin.view.php @@ -86,6 +86,20 @@ class SpamfilterAdminView extends Spamfilter $this->setTemplateFile('config_captcha'); } + + /** + * @brief CAPTCHA Test + */ + public function dispSpamfilterAdminConfigCaptchaTest() + { + $config = ModuleModel::getModuleConfig('spamfilter'); + Context::set('config', $config); + + $captcha = SpamfilterModel::getCaptcha(); + Context::set('captcha', $captcha); + + $this->setTemplateFile('captcha_test'); + } } /* End of file spamfilter.admin.view.php */ /* Location: ./modules/spamfilter/spamfilter.admin.view.php */ diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index dcd23d6cb..c7f73f217 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -218,7 +218,7 @@ class SpamfilterModel extends Spamfilter { $config = ModuleModel::getModuleConfig('spamfilter'); $user = Context::get('logged_info'); - if (!isset($config) || !isset($config->captcha) || !in_array($config->captcha->type, ['recaptcha', 'turnstile']) || !$config->captcha->site_key || !$config->captcha->secret_key) + if (!isset($config) || empty($config->captcha) || empty($config->captcha->type) || empty($config->captcha->site_key) || empty($config->captcha->secret_key)) { return false; } @@ -248,20 +248,58 @@ class SpamfilterModel extends Spamfilter /** * Get a CAPTCHA instance. * - * @return object + * @return ?object */ - public static function getCaptcha($target_action) + public static function getCaptcha($target_action = null) { $config = ModuleModel::getModuleConfig('spamfilter'); - $captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type; - $captcha_class::init($config->captcha); + if (!isset($config) || empty($config->captcha) || empty($config->captcha->type) || empty($config->captcha->site_key) || empty($config->captcha->secret_key)) + { + return null; + } + $captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type; + if (!class_exists($captcha_class)) + { + return null; + } + + $captcha_class::init($config->captcha); $captcha = new $captcha_class(); - $captcha->setTargetActions([$target_action => true]); + if ($target_action) + { + $captcha->setTargetActions([$target_action => true]); + } $captcha->addScripts(); return $captcha; } + /** + * Check the CAPTCHA. + * + * This method will throw an exception if the CAPTCHA is invalid. + * + * @param ?string $response + * @return void + */ + public static function checkCaptchaResponse(?string $response = null): void + { + $config = ModuleModel::getModuleConfig('spamfilter'); + if (!isset($config) || empty($config->captcha) || empty($config->captcha->type) || empty($config->captcha->site_key) || empty($config->captcha->secret_key)) + { + throw new Exception('msg_recaptcha_not_configured'); + } + + $captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type; + if (!class_exists($captcha_class)) + { + throw new Exception('msg_recaptcha_not_configured'); + } + + $captcha_class::init($config->captcha); + $captcha_class::check($response); + } + /** * @brief Check if the trackbacks have already been registered to a particular article */ diff --git a/modules/spamfilter/tpl/captcha_test.html b/modules/spamfilter/tpl/captcha_test.html new file mode 100644 index 000000000..20afe9a9f --- /dev/null +++ b/modules/spamfilter/tpl/captcha_test.html @@ -0,0 +1,32 @@ + + +
+
+ + + +
+

{$XE_VALIDATOR_MESSAGE}

+
+ +
+ +
+ {$captcha|noescape} +
+
+
+
+ +
+
+ +
+

{$lang->msg_recaptcha_not_configured}

+
+ +
+
+ + + diff --git a/modules/spamfilter/tpl/header.html b/modules/spamfilter/tpl/header.html index e7ba69a19..95206b739 100644 --- a/modules/spamfilter/tpl/header.html +++ b/modules/spamfilter/tpl/header.html @@ -11,4 +11,5 @@
  • {$lang->cmd_denied_word}
  • {$lang->cmd_config_block}
  • {$lang->cmd_captcha_config}
  • +
  • {$lang->cmd_captcha_test}