forked from leftypol/leftypol
Add hcaptcha support (#166)
Co-authored-by: RealAngeleno <angeleno@screamer.wiki> Reviewed-on: https://git.leftypol.org/leftypol/leftypol/pulls/166 Co-authored-by: Zankaria <zankaria.auxa@skiff.com> Co-committed-by: Zankaria <zankaria.auxa@skiff.com>
This commit is contained in:
parent
25089f5cbb
commit
d8c5c600a8
5 changed files with 107 additions and 19 deletions
|
@ -302,6 +302,7 @@
|
|||
'raw',
|
||||
'embed',
|
||||
'g-recaptcha-response',
|
||||
'h-captcha-response',
|
||||
'cf-turnstile-response',
|
||||
'spoiler',
|
||||
'page',
|
||||
|
@ -343,10 +344,17 @@
|
|||
$config['recaptcha_public'] = '6LcXTcUSAAAAAKBxyFWIt2SO8jwx4W7wcSMRoN3f';
|
||||
$config['recaptcha_private'] = '6LcXTcUSAAAAAOGVbVdhmEM1_SyRF4xTKe8jbzf_';
|
||||
|
||||
// Enable hCaptcha.
|
||||
$config['hcaptcha'] = false;
|
||||
|
||||
// Public and private key pair for using hCaptcha.
|
||||
$config['hcaptcha_public'] = '7a4b21e0-dc53-46f2-a9f8-91d2e74b63a0';
|
||||
$config['hcaptcha_private'] = '0x4e9A01bE637b51dC41a7Ea9865C3fDe4aB72Cf17';
|
||||
|
||||
// Enable Cloudflare's Turnstile captcha.
|
||||
$config['turnstile'] = false;
|
||||
|
||||
// Public and private key pair.
|
||||
// Public and private key pair for turnstile.
|
||||
$config['turnstile_public'] = '';
|
||||
$config['turnstile_private'] = '';
|
||||
|
||||
|
|
52
post.php
52
post.php
|
@ -92,6 +92,44 @@ function check_recaptcha($secret, $response, $remote_ip)
|
|||
return !!$resp['success'];
|
||||
}
|
||||
|
||||
function check_hcaptcha($secret, $response, $remote_ip, $public_key)
|
||||
{
|
||||
$data = [
|
||||
'secret' => $secret,
|
||||
'response' => $response,
|
||||
'sitekey' => $public_key,
|
||||
];
|
||||
|
||||
if ($remote_ip !== null) {
|
||||
$data['remoteip'] = $remote_ip;
|
||||
}
|
||||
|
||||
$c = curl_init();
|
||||
curl_setopt_array($c, [
|
||||
CURLOPT_URL => 'https://api.hcaptcha.com/siteverify',
|
||||
CURLOPT_CUSTOMREQUEST => "POST",
|
||||
CURLOPT_POSTFIELDS => $data,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
]);
|
||||
$c_ret = curl_exec($c);
|
||||
if ($c_ret === false) {
|
||||
$err_no = curl_errno($c);
|
||||
$err_str = curl_error($c);
|
||||
|
||||
curl_close($c);
|
||||
error_log("hCaptcha call failed. Curl returned: $err_no ($err_str)");
|
||||
return false;
|
||||
}
|
||||
curl_close($c);
|
||||
|
||||
$json_ret = json_decode($c_ret, true);
|
||||
if ($json_ret === null) {
|
||||
error_log("hCaptcha call failed. Malformed json: $c_ret");
|
||||
return false;
|
||||
}
|
||||
return $json_ret['success'] === true;
|
||||
}
|
||||
|
||||
function check_turnstile($secret, $response, $remote_ip, $expected_action)
|
||||
{
|
||||
$data = [
|
||||
|
@ -736,6 +774,13 @@ function handle_post()
|
|||
if (!check_recaptcha($config['recaptcha_private'], $_POST['g-recaptcha-response'], null)) {
|
||||
error($config['error']['captcha']);
|
||||
}
|
||||
} elseif ($config['hcaptcha']) {
|
||||
if (!isset($_POST['h-captcha-response'])) {
|
||||
error($config['error']['bot']);
|
||||
}
|
||||
if (!check_hcaptcha($config['hcaptcha_private'], $_POST['h-captcha-response'], null, $config['hcaptcha_public'])) {
|
||||
error($config['error']['captcha']);
|
||||
}
|
||||
} elseif ($config['turnstile']) {
|
||||
if (!isset($_POST['cf-turnstile-response'])) {
|
||||
error($config['error']['bot']);
|
||||
|
@ -755,6 +800,13 @@ function handle_post()
|
|||
if (!check_recaptcha($config['recaptcha_private'], $_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR'])) {
|
||||
error($config['error']['captcha']);
|
||||
}
|
||||
} elseif ($config['hcaptcha']) {
|
||||
if (!isset($_POST['h-captcha-response'])) {
|
||||
error($config['error']['bot']);
|
||||
}
|
||||
if (!check_hcaptcha($config['hcaptcha_private'], $_POST['h-captcha-response'], $_SERVER['REMOTE_ADDR'], $config['hcaptcha_public'])) {
|
||||
error($config['error']['captcha']);
|
||||
}
|
||||
} elseif ($config['turnstile']) {
|
||||
if (!isset($_POST['cf-turnstile-response'])) {
|
||||
error($config['error']['bot']);
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
{% if config.hcaptcha %}
|
||||
<script src="https://js.hcaptcha.com/1/api.js?recaptchacompat=off&render=explicit&onload=onCaptchaLoadHcaptcha" async defer></script>
|
||||
{% endif %}
|
||||
{% if config.turnstile %}
|
||||
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=onCaptchaLoadTurnstile_{{ form_action_type }}" async defer></script>
|
||||
{% endif %}
|
||||
|
|
|
@ -245,11 +245,39 @@ function getCookie(cookie_name) {
|
|||
{% endraw %}
|
||||
|
||||
/* BEGIN CAPTCHA REGION */
|
||||
|
||||
{% if config.turnstile %}
|
||||
{% if config.hcaptcha or config.turnstile %} // If any captcha
|
||||
// Global captcha object. Assigned by `onCaptchaLoad()`.
|
||||
var captcha_renderer = null;
|
||||
|
||||
{% if config.hcaptcha %} // If hcaptcha
|
||||
function onCaptchaLoadHcaptcha() {
|
||||
if (captcha_renderer === null) {
|
||||
let renderer = {
|
||||
renderOn: (container) => hcaptcha.render(container, {
|
||||
sitekey: "{{ config.hcaptcha_public }}",
|
||||
}),
|
||||
remove: (widgetId) => { /* Not supported */ },
|
||||
reset: (widgetId) => hcaptcha.reset(widgetId)
|
||||
};
|
||||
|
||||
onCaptchaLoad(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
function initCaptchaImpl() {
|
||||
/*
|
||||
* hcaptcha is set but the captcha_renderer is null? hcaptcha loaded before main.js could set up the callbacks.
|
||||
* Init now.
|
||||
*/
|
||||
if (hcaptcha && captcha_renderer === null) {
|
||||
if (active_page === 'index' || active_page === 'catalog' || active_page === 'thread') {
|
||||
onCaptchaLoadHcaptcha();
|
||||
}
|
||||
}
|
||||
}
|
||||
{% endif %} // End if hcaptcha
|
||||
{% if config.turnstile %} // If turnstile
|
||||
|
||||
// Wrapper function to be called from thread.html
|
||||
window.onCaptchaLoadTurnstile_post_reply = function() {
|
||||
onCaptchaLoadTurnstile('post-reply');
|
||||
|
@ -265,7 +293,7 @@ function onCaptchaLoadTurnstile(action) {
|
|||
if (captcha_renderer === null) {
|
||||
let renderer = {
|
||||
renderOn: function(container) {
|
||||
let widgetId = turnstile.render(container, {
|
||||
let widgetId = turnstile.render('#' + container, {
|
||||
sitekey: "{{ config.turnstile_public }}",
|
||||
action: action,
|
||||
});
|
||||
|
@ -274,12 +302,8 @@ function onCaptchaLoadTurnstile(action) {
|
|||
}
|
||||
return widgetId;
|
||||
},
|
||||
remove: function(widgetId) {
|
||||
turnstile.remove(widgetId);
|
||||
},
|
||||
reset: function(widgetId) {
|
||||
turnstile.reset(widgetId);
|
||||
}
|
||||
remove: (widgetId) => turnstile.remove(widgetId),
|
||||
reset: (widgetId) => turnstile.reset(widgetId)
|
||||
};
|
||||
|
||||
onCaptchaLoad(renderer);
|
||||
|
@ -299,12 +323,12 @@ function initCaptchaImpl() {
|
|||
}
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
{% endif %} // End if turnstile
|
||||
|
||||
function onCaptchaLoad(renderer) {
|
||||
captcha_renderer = renderer;
|
||||
|
||||
let widgetId = renderer.renderOn('#captcha-container');
|
||||
let widgetId = renderer.renderOn('captcha-container');
|
||||
if (widgetId === null) {
|
||||
console.error('Could not render captcha!');
|
||||
}
|
||||
|
@ -314,23 +338,24 @@ function onCaptchaLoad(renderer) {
|
|||
});
|
||||
}
|
||||
|
||||
{% if config.dynamic_captcha %}
|
||||
{% if config.dynamic_captcha %} // If dynamic captcha
|
||||
function isDynamicCaptchaEnabled() {
|
||||
let cookie = getCookie('captcha-required');
|
||||
return cookie === '1';
|
||||
}
|
||||
|
||||
function initDynamicCaptcha() {
|
||||
function initCaptcha() {
|
||||
if (isDynamicCaptchaEnabled()) {
|
||||
let captcha_hook = document.getElementById('captcha');
|
||||
captcha_hook.style = "";
|
||||
initCaptchaImpl();
|
||||
}
|
||||
}
|
||||
{% else %}
|
||||
{% endif %} // End if dynamic captcha
|
||||
{% else %} // Else if any captcha
|
||||
// No-op for `init()`.
|
||||
function initDynamicCaptcha() {}
|
||||
{% endif %}
|
||||
function initCaptcha() {}
|
||||
{% endif %} // End if any captcha
|
||||
|
||||
/* END CAPTCHA REGION */
|
||||
|
||||
|
@ -500,7 +525,7 @@ var script_settings = function(script_name) {
|
|||
|
||||
function init() {
|
||||
initStyleChooser();
|
||||
initDynamicCaptcha();
|
||||
initCaptcha();
|
||||
|
||||
{% endraw %}
|
||||
{% if config.allow_delete %}
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% if config.turnstile %}
|
||||
{% if config.hcaptcha or config.turnstile %}
|
||||
{% if config.dynamic_captcha %}
|
||||
<tr id="captcha" style="display: none;">
|
||||
{% else %}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue