Reorganize CAPTCHA handling classes #2112

This commit is contained in:
Kijin Sung 2023-06-19 22:27:25 +09:00
parent eb79a5c66f
commit ef77af5a39
6 changed files with 94 additions and 84 deletions

View file

@ -1,6 +1,11 @@
<?php
class spamfilter_captcha
namespace Rhymix\Modules\Spamfilter\Captcha;
use Context;
use Rhymix\Framework\Exception;
class reCAPTCHA
{
protected static $verify_url = 'https://www.google.com/recaptcha/api/siteverify';
protected static $config = null;
@ -19,7 +24,7 @@ class spamfilter_captcha
$response = Context::get('g-recaptcha-response');
if (!$response)
{
throw new Rhymix\Framework\Exception('msg_recaptcha_invalid_response');
throw new Exception('msg_recaptcha_invalid_response');
}
try
@ -32,17 +37,17 @@ class spamfilter_captcha
}
catch (\Requests_Exception $e)
{
throw new Rhymix\Framework\Exception('msg_recaptcha_connection_error');
throw new Exception('msg_recaptcha_connection_error');
}
$verify = @json_decode($verify_request->body, true);
if (!$verify || !$verify['success'])
{
throw new Rhymix\Framework\Exception('msg_recaptcha_server_error');
throw new Exception('msg_recaptcha_server_error');
}
if ($verify && isset($verify['error-codes']) && in_array('invalid-input-response', $verify['error-codes']))
{
throw new Rhymix\Framework\Exception('msg_recaptcha_invalid_response');
throw new Exception('msg_recaptcha_invalid_response');
}
$_SESSION['recaptcha_authenticated'] = true;

View file

@ -1,6 +1,11 @@
<?php
class spamfilter_captcha
namespace Rhymix\Modules\Spamfilter\Captcha;
use Context;
use Rhymix\Framework\Exception;
class Turnstile
{
protected static $verify_url = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
protected static $config = null;
@ -19,7 +24,7 @@ class spamfilter_captcha
$response = Context::get('g-recaptcha-response');
if (!$response)
{
throw new Rhymix\Framework\Exception('msg_recaptcha_invalid_response');
throw new Exception('msg_recaptcha_invalid_response');
}
try
@ -32,17 +37,17 @@ class spamfilter_captcha
}
catch (\Requests_Exception $e)
{
throw new Rhymix\Framework\Exception('msg_recaptcha_connection_error');
throw new Exception('msg_recaptcha_connection_error');
}
$verify = @json_decode($verify_request->body, true);
if (!$verify || !$verify['success'])
{
throw new Rhymix\Framework\Exception('msg_recaptcha_server_error');
throw new Exception('msg_recaptcha_server_error');
}
if ($verify && isset($verify['error-codes']) && in_array('invalid-input-response', $verify['error-codes']))
{
throw new Rhymix\Framework\Exception('msg_recaptcha_invalid_response');
throw new Exception('msg_recaptcha_invalid_response');
}
$_SESSION['recaptcha_authenticated'] = true;
@ -73,6 +78,6 @@ class spamfilter_captcha
public function __toString()
{
return sprintf('<div id="recaptcha-instance-%d" class="g-recaptcha"></div>', self::$instances_inserted++);
return sprintf('<div id="turnstile-instance-%d" class="turnstile-captcha"></div>', self::$instances_inserted++);
}
}

View file

@ -64,7 +64,7 @@ $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_connection_error = 'An error occurred while connecting to the reCAPTCHA verification server.';
$lang->msg_recaptcha_server_error = 'An error occurred while verifying your reCAPTCHA response.';
$lang->msg_recaptcha_invalid_response = 'Please check reCAPTCHA.';
$lang->msg_recaptcha_keys_not_set = 'Please fill in your reCAPTCHA Site Key and Secret Key.';
$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.';

View file

@ -64,7 +64,7 @@ $lang->recaptcha_target_everyone = '모든 사용자';
$lang->recaptcha_target_frequency = '캡챠 사용 빈도';
$lang->recaptcha_target_first_time_only = '최초 1회만 사용';
$lang->recaptcha_target_every_time = '매번 사용';
$lang->msg_recaptcha_connection_error = 'reCAPTCHA 스팸방지 서버에 접속하는 도중 오류가 발생했습니다.';
$lang->msg_recaptcha_server_error = 'reCAPTCHA 스팸방지 서버와 통신하는 도중 오류가 발생했습니다.';
$lang->msg_recaptcha_invalid_response = 'reCAPTCHA 스팸방지 기능을 체크해 주십시오.';
$lang->msg_recaptcha_keys_not_set = 'reCAPTCHA Site Key 및 Secret Key를 입력하여 주십시오.';
$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를 입력하여 주십시오.';

View file

@ -225,7 +225,7 @@ class spamfilterController extends spamfilter
function triggerCheckCaptcha(&$obj)
{
$config = ModuleModel::getModuleConfig('spamfilter');
if (!isset($config) || !isset($config->captcha) || !in_array($config->captcha->type, ['recaptcha','turnstile']) || !$config->captcha->site_key || !$config->captcha->secret_key)
if (!isset($config) || !isset($config->captcha) || !in_array($config->captcha->type, ['recaptcha', 'turnstile']) || !$config->captcha->site_key || !$config->captcha->secret_key)
{
return;
}
@ -260,16 +260,16 @@ class spamfilterController extends spamfilter
if (count($target_actions))
{
include_once __DIR__ . '/captcha/' . $config->captcha->type . '.php';
spamfilter_captcha::init($config->captcha);
$captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type;
$captcha_class::init($config->captcha);
if (strncasecmp('proc', $obj->act, 4) === 0)
{
spamfilter_captcha::check();
$captcha_class::check();
}
else
{
$captcha = new spamfilter_captcha();
$captcha = new $captcha_class();
$captcha->setTargetActions($target_actions);
$captcha->addScripts();
Context::set('captcha', $captcha);

View file

@ -1,60 +1,60 @@
function turnstileCallback() {
var recaptcha_config = $("#recaptcha-config");
var recaptcha_instances = $(".g-recaptcha");
var recaptcha_instance_id = 1;
var recaptcha_targets = String(recaptcha_config.data("targets")).split(",");
if (recaptcha_instances.length === 0) {
var autoinsert_candidates = $("form").filter(function() {
var actinput = $("input[name='act']", this);
if (actinput.length && actinput.val()) {
var act = String(actinput.val());
if (act.match(/^procMemberInsert$/i) && recaptcha_targets.indexOf("signup") > -1) {
return true;
}
if (act.match(/^procMemberLogin$/i) && recaptcha_targets.indexOf("login") > -1) {
return true;
}
if (act.match(/^procMember(FindAccount|ResendAuthMail)$/i) && recaptcha_targets.indexOf("recovery") > -1) {
return true;
}
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertDocument$/i) && recaptcha_targets.indexOf("document") > -1) {
return true;
}
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertComment$/i) && recaptcha_targets.indexOf("comment") > -1) {
return true;
}
}
var procfilter = $(this).attr("onsubmit");
if (procfilter && procfilter.match(/procFilter\b.+\binsert/i) && (recaptcha_targets.indexOf("document") > -1 || recaptcha_targets.indexOf("comment") > -1)) {
return true;
}
return false;
});
autoinsert_candidates.each(function() {
var new_instance = $('<div class="g-recaptcha"></div>');
new_instance.attr("id", "recaptcha-instance-" + recaptcha_instance_id++);
var autoinsert_point = $(this).find("button[type='submit'],input[type='submit']").parent();
if (autoinsert_point.size()) {
new_instance.insertBefore(autoinsert_point);
} else {
new_instance.appendTo($(this));
}
});
var recaptcha_instances = $(".g-recaptcha");
}
recaptcha_instances.each(function() {
var instance = $(this);
var theme = recaptcha_config.data("theme");
if (theme === 'auto') {
theme = getColorScheme();
}
grecaptcha.render(`#${instance.attr("id")}`, {
sitekey: recaptcha_config.data("sitekey"),
size: recaptcha_config.data("size"),
theme: theme
});
});
}
function turnstileCallback() {
var recaptcha_config = $("#recaptcha-config");
var recaptcha_instances = $(".turnstile-captcha");
var recaptcha_instance_id = 1;
var recaptcha_targets = String(recaptcha_config.data("targets")).split(",");
if (recaptcha_instances.length === 0) {
var autoinsert_candidates = $("form").filter(function() {
var actinput = $("input[name='act']", this);
if (actinput.length && actinput.val()) {
var act = String(actinput.val());
if (act.match(/^procMemberInsert$/i) && recaptcha_targets.indexOf("signup") > -1) {
return true;
}
if (act.match(/^procMemberLogin$/i) && recaptcha_targets.indexOf("login") > -1) {
return true;
}
if (act.match(/^procMember(FindAccount|ResendAuthMail)$/i) && recaptcha_targets.indexOf("recovery") > -1) {
return true;
}
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertDocument$/i) && recaptcha_targets.indexOf("document") > -1) {
return true;
}
if (act.match(/^proc[A-Z][a-zA-Z0-9_]+InsertComment$/i) && recaptcha_targets.indexOf("comment") > -1) {
return true;
}
}
var procfilter = $(this).attr("onsubmit");
if (procfilter && procfilter.match(/procFilter\b.+\binsert/i) && (recaptcha_targets.indexOf("document") > -1 || recaptcha_targets.indexOf("comment") > -1)) {
return true;
}
return false;
});
autoinsert_candidates.each(function() {
var new_instance = $('<div class="turnstile-captcha"></div>');
new_instance.attr("id", "turnstile-instance-" + recaptcha_instance_id++);
var autoinsert_point = $(this).find("button[type='submit'],input[type='submit']").parent();
if (autoinsert_point.size()) {
new_instance.insertBefore(autoinsert_point);
} else {
new_instance.appendTo($(this));
}
});
var recaptcha_instances = $(".turnstile-captcha");
}
recaptcha_instances.each(function() {
var instance = $(this);
var theme = recaptcha_config.data("theme");
if (theme === 'auto') {
theme = getColorScheme();
}
grecaptcha.render(`#${instance.attr("id")}`, {
sitekey: recaptcha_config.data("sitekey"),
size: recaptcha_config.data("size"),
theme: theme
});
});
}