mirror of
https://github.com/phpbb/phpbb.git
synced 2025-03-13 20:28:44 +01:00
[ticket/15937] Google reCAPTCHA v3 Plugin
PHPBB3-15937
This commit is contained in:
parent
b732b4d8c8
commit
0c63f03db4
15
phpBB/adm/style/captcha_recaptcha_v3.html
Normal file
15
phpBB/adm/style/captcha_recaptcha_v3.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% if S_RECAPTCHA_AVAILABLE %}
|
||||
<dl>
|
||||
<dt> </dt>
|
||||
<dd>
|
||||
<noscript>
|
||||
<div class="warningbox">{{ lang('RECAPTCHA_NOSCRIPT') }}</div>
|
||||
</noscript>
|
||||
|
||||
{{ lang('RECAPTCHA_INVISIBLE') }}
|
||||
<script src="{{ U_RECAPTCHA_SCRIPT }}" async defer></script>
|
||||
</dd>
|
||||
</dl>
|
||||
{% else %}
|
||||
{{ lang('RECAPTCHA_NOT_AVAILABLE') }}
|
||||
{% endif %}
|
111
phpBB/adm/style/captcha_recaptcha_v3_acp.html
Normal file
111
phpBB/adm/style/captcha_recaptcha_v3_acp.html
Normal file
@ -0,0 +1,111 @@
|
||||
{% include 'overall_header.html' %}
|
||||
|
||||
<a id="maincontent"></a>
|
||||
|
||||
<h1>{{ lang('ACP_VC_SETTINGS') }}</h1>
|
||||
<p>{{ lang('ACP_VC_SETTINGS_EXPLAIN') }}</p>
|
||||
|
||||
<form id="acp_captcha" method="post" action="{{ U_ACTION }}">
|
||||
<fieldset>
|
||||
<legend>{{ lang('GENERAL_OPTIONS') }}</legend>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<label for="recaptcha_v3_key">{{ lang('RECAPTCHA_PUBLIC') ~ lang('COLON') }}</label>
|
||||
<br><span>{{ lang('RECAPTCHA_V3_PUBLIC_EXPLAIN') }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
<input id="recaptcha_v3_key" name="recaptcha_v3_key" type="text" value="{{ RECAPTCHA_V3_KEY }}" size="50">
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<label for="recaptcha_v3_secret">{{ lang('RECAPTCHA_PRIVATE') ~ lang('COLON') }}</label>
|
||||
<br><span>{{ lang('RECAPTCHA_V3_PRIVATE_EXPLAIN') }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
<input id="recaptcha_v3_secret" name="recaptcha_v3_secret" type="text" value="{{ RECAPTCHA_V3_SECRET }}" size="50">
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<label>{{ lang('RECAPTCHA_V3_DOMAIN') ~ lang('COLON') }}</label>
|
||||
<br><span>{{ lang('RECAPTCHA_V3_DOMAIN_EXPLAIN') }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
{% for domain in RECAPTCHA_V3_DOMAINS %}
|
||||
<label>
|
||||
<input class="radio" name="recaptcha_v3_domain" type="radio" value="{{ domain }}"{{ domain == RECAPTCHA_V3_DOMAIN ? ' checked' }}>
|
||||
<span>{{ domain }}</span>
|
||||
</label>
|
||||
{% endfor %}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>
|
||||
<label>{{ lang('RECAPTCHA_V3_METHOD') ~ lang('COLON') }}</label>
|
||||
<br><span>{{ lang('RECAPTCHA_V3_METHOD_EXPLAIN') }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
{% for method, constant in RECAPTCHA_V3_METHODS %}
|
||||
<label>
|
||||
{% set disabled = not attribute(_context, 'S_RECAPTCHA_V3_' ~ method) ? ' disabled' %}
|
||||
{% set checked = constant == RECAPTCHA_V3_METHOD ? ' checked' %}
|
||||
|
||||
<input class="radio" name="recaptcha_v3_method" type="radio" value="{{ constant }}"{{ checked ~ disabled }}>
|
||||
<span>{{ lang('RECAPTCHA_V3_METHOD_' ~ method) }}</span>
|
||||
</label>
|
||||
{% endfor %}
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{ lang('RECAPTCHA_V3_THRESHOLDS') }}</legend>
|
||||
<p>{{ lang('RECAPTCHA_V3_THRESHOLDS_EXPLAIN') }}</p>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<label for="recaptcha_v3_threshold">{{ lang('RECAPTCHA_V3_THRESHOLD') ~ lang('COLON') }}</label>
|
||||
<br><span class="explain">{{ lang('RECAPTCHA_V3_THRESHOLD_EXPLAIN') }}</span>
|
||||
</dt>
|
||||
<dd><input id="recaptcha_v3_threshold" name="recaptcha_v3_threshold" type="number" value="{{ RECAPTCHA_V3_THRESHOLD }}" min="0" max="1" step="0.1"></dd>
|
||||
</dl>
|
||||
|
||||
{% for threshold in thresholds %}
|
||||
<dl>
|
||||
<dt><label for="{{ threshold.key }}">{{ lang(threshold.key|upper) ~ lang('COLON') }}</label></dt>
|
||||
<dd><input id="{{ threshold.key }}" name="{{ threshold.key }}" type="number" value="{{ threshold.value }}" min="0" max="1" step="0.1"></dd>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{ lang('PREVIEW') }}</legend>
|
||||
|
||||
{% if PREVIEW %}
|
||||
<div class="successbox">
|
||||
<h3>{{ lang('WARNING') }}</h3>
|
||||
<p>{{ lang('CAPTCHA_PREVIEW_MSG') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% include CAPTCHA_PREVIEW %}
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
|
||||
|
||||
<p class="submit-buttons">
|
||||
<input class="button1" id="submit" name="submit" type="submit" value="{{ lang('SUBMIT') }}">
|
||||
<input class="button2" id="reset" name="reset" type="reset" value="{{ lang('RESET') }}">
|
||||
|
||||
<input name="select_captcha" type="hidden" value="{{ CAPTCHA_NAME }}">
|
||||
<input name="configure" type="hidden" value="1">
|
||||
{{ S_FORM_TOKEN }}
|
||||
</p>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
{% include 'overall_footer.html' %}
|
@ -1745,49 +1745,81 @@ phpbb.lazyLoadAvatars = function loadAvatars() {
|
||||
});
|
||||
};
|
||||
|
||||
var recaptchaForm = $('.g-recaptcha').parents('form');
|
||||
var submitButton = null;
|
||||
var programaticallySubmitted = false;
|
||||
phpbb.recaptcha = {
|
||||
button: null,
|
||||
ready: false,
|
||||
|
||||
phpbb.recaptchaOnLoad = function () {
|
||||
// Listen to submit buttons in order to know which one was pressed
|
||||
$('input[type="submit"]').each(function () {
|
||||
$(this).on('click', function () {
|
||||
submitButton = this;
|
||||
token: $('input[name="recaptcha_token"]'),
|
||||
form: $('.g-recaptcha').parents('form'),
|
||||
v3: $('[data-recaptcha-v3]'),
|
||||
|
||||
load: function() {
|
||||
phpbb.recaptcha.bindButton();
|
||||
phpbb.recaptcha.bindForm();
|
||||
},
|
||||
bindButton: function() {
|
||||
phpbb.recaptcha.form.find('input[type="submit"]').on('click', function() {
|
||||
// Listen to all the submit buttons for the form that has reCAPTCHA protection,
|
||||
// and store it so we can click the exact same button later on when we are ready.
|
||||
phpbb.recaptcha.button = this;
|
||||
});
|
||||
});
|
||||
},
|
||||
bindForm: function() {
|
||||
phpbb.recaptcha.form.on('submit', function(e) {
|
||||
// If ready is false, it means the user pressed a submit button.
|
||||
// And the form was not submitted by us, after the token was loaded.
|
||||
if (!phpbb.recaptcha.ready) {
|
||||
// If version 3 is used, we need to make a different execution,
|
||||
// including the action and the site key.
|
||||
if (phpbb.recaptcha.v3.length) {
|
||||
grecaptcha.execute(
|
||||
phpbb.recaptcha.v3.data('recaptcha-v3'),
|
||||
{action: phpbb.recaptcha.v3.val()}
|
||||
).then(function(token) {
|
||||
// Place the token inside the form
|
||||
phpbb.recaptcha.token.val(token);
|
||||
|
||||
recaptchaForm.on('submit', function (e) {
|
||||
if (!programaticallySubmitted) {
|
||||
grecaptcha.execute();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
// And now we submit the form.
|
||||
phpbb.recaptcha.submitForm();
|
||||
});
|
||||
} else {
|
||||
// Regular version 2 execution
|
||||
grecaptcha.execute();
|
||||
}
|
||||
|
||||
phpbb.recaptchaOnSubmit = function () {
|
||||
programaticallySubmitted = true;
|
||||
// If concrete button was clicked (e.g. preview instead of submit),
|
||||
// let's trigger the same action
|
||||
if (submitButton) {
|
||||
submitButton.click();
|
||||
} else {
|
||||
// Rename input[name="submit"] so that we can submit the form
|
||||
if (typeof recaptchaForm.submit !== 'function') {
|
||||
recaptchaForm.submit.name = 'submit_btn';
|
||||
// Do not submit the form
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
submitForm: function() {
|
||||
// Now we are ready, so set it to true.
|
||||
// so the 'submit' event doesn't run multiple times.
|
||||
phpbb.recaptcha.ready = true;
|
||||
|
||||
if (phpbb.recaptcha.button) {
|
||||
// If there was a specific button pressed initially, trigger the same button
|
||||
phpbb.recaptcha.button.click();
|
||||
} else {
|
||||
if (typeof phpbb.recaptcha.form.submit !== 'function') {
|
||||
// Rename input[name="submit"] so that we can submit the form
|
||||
phpbb.recaptcha.form.submit.name = 'submit_btn';
|
||||
}
|
||||
|
||||
phpbb.recaptcha.form.submit();
|
||||
}
|
||||
recaptchaForm.submit();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// reCAPTCHA doesn't accept callback functions nested inside objects
|
||||
// reCAPTCHA v2 doesn't accept callback functions nested inside objects
|
||||
// so we need to make this helper functions here
|
||||
window.phpbbRecaptchaOnLoad = function() {
|
||||
phpbb.recaptchaOnLoad();
|
||||
}
|
||||
phpbb.recaptcha.load();
|
||||
};
|
||||
|
||||
window.phpbbRecaptchaOnSubmit = function() {
|
||||
phpbb.recaptchaOnSubmit();
|
||||
}
|
||||
phpbb.recaptcha.submitForm();
|
||||
};
|
||||
|
||||
$(window).on('load', phpbb.lazyLoadAvatars);
|
||||
|
||||
@ -1795,6 +1827,11 @@ $(window).on('load', phpbb.lazyLoadAvatars);
|
||||
* Apply code editor to all textarea elements with data-bbcode attribute
|
||||
*/
|
||||
$(function() {
|
||||
// reCAPTCHA v3 needs to be initialized
|
||||
if (phpbb.recaptcha.v3.length) {
|
||||
phpbb.recaptcha.load();
|
||||
}
|
||||
|
||||
$('textarea[data-bbcode]').each(function() {
|
||||
phpbb.applyCodeEditor(this);
|
||||
});
|
||||
|
@ -57,3 +57,11 @@ services:
|
||||
- [set_name, [core.captcha.plugins.recaptcha]]
|
||||
tags:
|
||||
- { name: captcha.plugins }
|
||||
|
||||
core.captcha.plugins.recaptcha_v3:
|
||||
class: phpbb\captcha\plugins\recaptcha_v3
|
||||
shared: false
|
||||
calls:
|
||||
- ['set_name', ['core.captcha.plugins.recaptcha_v3']]
|
||||
tags:
|
||||
- { name: captcha.plugins }
|
||||
|
@ -37,16 +37,39 @@ if (empty($lang) || !is_array($lang))
|
||||
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
|
||||
|
||||
$lang = array_merge($lang, array(
|
||||
'RECAPTCHA_LANG' => 'en-GB', // Find the language/country code on https://developers.google.com/recaptcha/docs/language - If no code exists for your language you can use "en" or leave the string empty
|
||||
'RECAPTCHA_NOT_AVAILABLE' => 'In order to use reCaptcha, you must create an account on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
|
||||
'CAPTCHA_RECAPTCHA' => 'reCaptcha',
|
||||
// Find the language/country code on https://developers.google.com/recaptcha/docs/language
|
||||
// If no code exists for your language you can use "en" or leave the string empty
|
||||
'RECAPTCHA_LANG' => 'en-GB',
|
||||
|
||||
'CAPTCHA_RECAPTCHA' => 'reCaptcha v2',
|
||||
'CAPTCHA_RECAPTCHA_V3' => 'reCaptcha v3',
|
||||
|
||||
'RECAPTCHA_INCORRECT' => 'The solution you provided was incorrect',
|
||||
'RECAPTCHA_NOSCRIPT' => 'Please enable JavaScript in your browser to load the challenge.',
|
||||
'RECAPTCHA_NOT_AVAILABLE' => 'In order to use reCaptcha, you must create an account on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>.',
|
||||
|
||||
'RECAPTCHA_PUBLIC' => 'Site key',
|
||||
'RECAPTCHA_PUBLIC_EXPLAIN' => 'Your site reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v2 > Invisible reCAPTCHA badge type.',
|
||||
'RECAPTCHA_V3_PUBLIC_EXPLAIN' => 'Your site reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v3.',
|
||||
'RECAPTCHA_PRIVATE' => 'Secret key',
|
||||
'RECAPTCHA_PRIVATE_EXPLAIN' => 'Your secret reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v2 > Invisible reCAPTCHA badge type.',
|
||||
'RECAPTCHA_V3_PRIVATE_EXPLAIN' => 'Your secret reCAPTCHA key. Keys can be obtained on <a href="http://www.google.com/recaptcha">www.google.com/recaptcha</a>. Please, use reCAPTCHA v3.',
|
||||
|
||||
'RECAPTCHA_INVISIBLE' => 'This CAPTCHA is actually invisible. To verify that it works, a small icon should appear in right bottom corner of this page.',
|
||||
|
||||
'RECAPTCHA_V3_DOMAIN' => 'Request domain',
|
||||
'RECAPTCHA_V3_DOMAIN_EXPLAIN' => 'The domain to fetch the script from and to use when verifying the request.<br>Use <samp>recaptcha.net</samp> when <samp>google.com</samp> is not accessible.',
|
||||
'RECAPTCHA_V3_METHOD' => 'Request method',
|
||||
'RECAPTCHA_V3_METHOD_EXPLAIN' => 'The method to use when verifying the request.<br>Disabled options are not available within your setup.',
|
||||
'RECAPTCHA_V3_METHOD_CURL' => 'cURL',
|
||||
'RECAPTCHA_V3_METHOD_POST' => 'POST',
|
||||
'RECAPTCHA_V3_METHOD_SOCKET' => 'Socket',
|
||||
'RECAPTCHA_V3_THRESHOLD' => 'Default threshold',
|
||||
'RECAPTCHA_V3_THRESHOLD_EXPLAIN' => 'Used when none of the other actions are applicable.',
|
||||
'RECAPTCHA_V3_THRESHOLD_LOGIN' => 'Login threshold',
|
||||
'RECAPTCHA_V3_THRESHOLD_POST' => 'Post threshold',
|
||||
'RECAPTCHA_V3_THRESHOLD_REGISTER' => 'Register threshold',
|
||||
'RECAPTCHA_V3_THRESHOLD_REPORT' => 'Report threshold',
|
||||
'RECAPTCHA_V3_THRESHOLDS' => 'Thresholds',
|
||||
'RECAPTCHA_V3_THRESHOLDS_EXPLAIN' => 'reCAPTCHA v3 returns a score (<samp>1.0</samp> is very likely a good interaction, <samp>0.0</samp> is very likely a bot). Here you can set the minimum score per action.',
|
||||
));
|
||||
|
263
phpBB/phpbb/captcha/plugins/recaptcha_v3.php
Normal file
263
phpBB/phpbb/captcha/plugins/recaptcha_v3.php
Normal file
@ -0,0 +1,263 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* This file is part of the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*
|
||||
* For full copyright and license information, please see
|
||||
* the docs/CREDITS.txt file.
|
||||
*
|
||||
*/
|
||||
|
||||
namespace phpbb\captcha\plugins;
|
||||
|
||||
/**
|
||||
* Google reCaptcha v3 plugin.
|
||||
*/
|
||||
class recaptcha_v3 extends captcha_abstract
|
||||
{
|
||||
const CURL = 'curl';
|
||||
const POST = 'post';
|
||||
const SOCKET = 'socket';
|
||||
|
||||
const GOOGLE = 'google.com';
|
||||
const RECAPTCHA = 'recaptcha.net';
|
||||
|
||||
static protected $action = 'default';
|
||||
static protected $actions = [
|
||||
CONFIRM_REG => 'register',
|
||||
CONFIRM_LOGIN => 'login',
|
||||
CONFIRM_POST => 'post',
|
||||
CONFIRM_REPORT => 'report',
|
||||
];
|
||||
|
||||
public function execute()
|
||||
{
|
||||
}
|
||||
|
||||
public function execute_demo()
|
||||
{
|
||||
}
|
||||
|
||||
public function get_generator_class()
|
||||
{
|
||||
throw new \Exception('No generator class given.');
|
||||
}
|
||||
|
||||
public function get_name()
|
||||
{
|
||||
return 'CAPTCHA_RECAPTCHA_V3';
|
||||
}
|
||||
|
||||
public function has_config()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function init($type)
|
||||
{
|
||||
/**
|
||||
* @var \phpbb\language\language $language Language object
|
||||
*/
|
||||
global $language;
|
||||
|
||||
$language->add_lang('captcha_recaptcha');
|
||||
|
||||
parent::init($type);
|
||||
}
|
||||
|
||||
public function is_available()
|
||||
{
|
||||
/**
|
||||
* @var \phpbb\config\config $config Config object
|
||||
* @var \phpbb\language\language $language Language object
|
||||
*/
|
||||
global $config, $language;
|
||||
|
||||
$language->add_lang('captcha_recaptcha');
|
||||
|
||||
return ($config->offsetGet('recaptcha_v3_key') ?? false)
|
||||
&& ($config->offsetGet('recaptcha_v3_secret') ?? false);
|
||||
}
|
||||
|
||||
public function acp_page($id, $module)
|
||||
{
|
||||
/**
|
||||
* @var \phpbb\config\config $config Config object
|
||||
* @var \phpbb\language\language $language Language object
|
||||
* @var \phpbb\log\log $phpbb_log Log object
|
||||
* @var \phpbb\request\request $request Request object
|
||||
* @var \phpbb\template\template $template Template object
|
||||
* @var \phpbb\user $user User object
|
||||
*/
|
||||
global $config, $language, $phpbb_log, $request, $template, $user;
|
||||
|
||||
$module->tpl_name = 'captcha_recaptcha_v3_acp';
|
||||
$module->page_title = 'ACP_VC_SETTINGS';
|
||||
|
||||
$form_key = 'acp_captcha';
|
||||
add_form_key($form_key);
|
||||
|
||||
if ($request->is_set_post('submit'))
|
||||
{
|
||||
if (!check_form_key($form_key))
|
||||
{
|
||||
trigger_error($language->lang('FORM_INVALID') . adm_back_link($module->u_action), E_USER_WARNING);
|
||||
}
|
||||
|
||||
$config->set('recaptcha_v3_key', $request->variable('recaptcha_v3_key', '', true));
|
||||
$config->set('recaptcha_v3_secret', $request->variable('recaptcha_v3_secret', '', true));
|
||||
$config->set('recaptcha_v3_domain', $request->variable('recaptcha_v3_domain', '', true));
|
||||
$config->set('recaptcha_v3_method', $request->variable('recaptcha_v3_method', '', true));
|
||||
$config->set('recaptcha_v3_threshold', $request->variable('recaptcha_v3_threshold', 0.50));
|
||||
|
||||
foreach (self::$actions as $action)
|
||||
{
|
||||
$config->set("recaptcha_v3_threshold_{$action}", $request->variable("recaptcha_v3_threshold_{$action}", 0.50));
|
||||
}
|
||||
|
||||
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_VISUAL');
|
||||
|
||||
trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($module->u_action));
|
||||
}
|
||||
|
||||
foreach (self::$actions as $action)
|
||||
{
|
||||
$template->assign_block_vars('thresholds', [
|
||||
'key' => "recaptcha_v3_threshold_{$action}",
|
||||
'value' => $config["recaptcha_v3_threshold_{$action}"] ?? 0.5,
|
||||
]);
|
||||
}
|
||||
|
||||
$template->assign_vars([
|
||||
'CAPTCHA_NAME' => $this->get_service_name(),
|
||||
'CAPTCHA_PREVIEW' => $this->get_demo_template($id),
|
||||
|
||||
'RECAPTCHA_V3_KEY' => $config['recaptcha_v3_key'] ?? '',
|
||||
'RECAPTCHA_V3_SECRET' => $config['recaptcha_v3_secret'] ?? '',
|
||||
'RECAPTCHA_V3_THRESHOLD' => $config['recaptcha_v3_threshold'] ?? 0.5,
|
||||
|
||||
'RECAPTCHA_V3_DOMAIN' => $config['recaptcha_v3_domain'] ?? self::GOOGLE,
|
||||
'RECAPTCHA_V3_DOMAINS' => [self::GOOGLE, self::RECAPTCHA],
|
||||
|
||||
'RECAPTCHA_V3_METHOD' => $config['recaptcha_v3_method'] ?? self::POST,
|
||||
'RECAPTCHA_V3_METHODS' => [
|
||||
'POST' => self::POST,
|
||||
'CURL' => self::CURL,
|
||||
'SOCKET' => self::SOCKET,
|
||||
],
|
||||
|
||||
'S_RECAPTCHA_V3_CURL' => extension_loaded('curl') && function_exists('curl_init'),
|
||||
'S_RECAPTCHA_V3_POST' => ini_get('allow_url_fopen') && function_exists('file_get_contents'),
|
||||
'S_RECAPTCHA_V3_SOCKET' => function_exists('fsockopen'),
|
||||
|
||||
'U_ACTION' => $module->u_action,
|
||||
]);
|
||||
}
|
||||
|
||||
public function get_demo_template($id)
|
||||
{
|
||||
return $this->get_template();
|
||||
}
|
||||
|
||||
public function get_template()
|
||||
{
|
||||
/**
|
||||
* @var \phpbb\config\config $config Config object
|
||||
* @var \phpbb\language\language $language Language object
|
||||
* @var \phpbb\template\template $template Template object
|
||||
* @var string $phpbb_root_path phpBB root path
|
||||
* @var string $phpEx php File extensions
|
||||
*/
|
||||
global $config, $language, $template, $phpbb_root_path, $phpEx;
|
||||
|
||||
if ($this->is_solved())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$contact = phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx);
|
||||
$explain = $this->type !== CONFIRM_POST ? 'CONFIRM_EXPLAIN' : 'POST_CONFIRM_EXPLAIN';
|
||||
|
||||
$domain = $config['recaptcha_v3_domain'] ?? self::GOOGLE;
|
||||
$render = $config['recaptcha_v3_key'] ?? '';
|
||||
|
||||
$template->assign_vars([
|
||||
'CONFIRM_EXPLAIN' => $language->lang($explain, '<a href="' . $contact . '">', '</a>'),
|
||||
|
||||
'RECAPTCHA_ACTION' => self::$actions[$this->type] ?? self::$action,
|
||||
'RECAPTCHA_KEY' => $config['recaptcha_v3_key'] ?? '',
|
||||
'U_RECAPTCHA_SCRIPT' => sprintf('//%s/recaptcha/api.js?render=%s', $domain, $render),
|
||||
|
||||
'S_CONFIRM_CODE' => true,
|
||||
'S_RECAPTCHA_AVAILABLE' => $this->is_available(),
|
||||
'S_TYPE' => $this->type,
|
||||
]);
|
||||
|
||||
return 'captcha_recaptcha_v3.html';
|
||||
}
|
||||
|
||||
function validate()
|
||||
{
|
||||
if (!parent::validate())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->recaptcha_check_answer();
|
||||
}
|
||||
|
||||
function recaptcha_check_answer()
|
||||
{
|
||||
/**
|
||||
* @var \phpbb\config\config $config Config object
|
||||
* @var \phpbb\language\language $language Language object
|
||||
* @var \phpbb\request\request $request Request object
|
||||
* @var \phpbb\user $user User object
|
||||
*/
|
||||
global $config, $language, $request, $user;
|
||||
|
||||
$action = $request->variable('recaptcha_action', self::$action, true);
|
||||
$token = $request->variable('recaptcha_token', '', true);
|
||||
$threshold = (double) $config["recaptcha_v3_threshold_{$action}"] ?? $config['recaptcha_v3_threshold'] ?? 0.5;
|
||||
|
||||
// Discard spam submissions
|
||||
if (empty($token))
|
||||
{
|
||||
return $language->lang('RECAPTCHA_INCORRECT');
|
||||
}
|
||||
|
||||
switch ($config['recaptcha_v3_method'] ?? '')
|
||||
{
|
||||
case self::CURL:
|
||||
$method = new \ReCaptcha\RequestMethod\CurlPost();
|
||||
break;
|
||||
|
||||
case self::SOCKET:
|
||||
$method = new \ReCaptcha\RequestMethod\SocketPost();
|
||||
break;
|
||||
|
||||
case self::POST:
|
||||
default:
|
||||
$method = new \ReCaptcha\RequestMethod\Post();
|
||||
break;
|
||||
}
|
||||
|
||||
$recaptcha = new \ReCaptcha\ReCaptcha($config['recaptcha_v3_secret'], $method);
|
||||
|
||||
$result = $recaptcha->setExpectedAction($action)
|
||||
->setScoreThreshold($threshold)
|
||||
->verify($token, $user->ip);
|
||||
|
||||
if ($result->isSuccess())
|
||||
{
|
||||
$this->solved = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $language->lang('RECAPTCHA_INCORRECT');
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
<div>{L_RECAPTCHA_NOSCRIPT}</div>
|
||||
</noscript>
|
||||
{% INCLUDEJS RECAPTCHA_SERVER ~ '.js?onload=phpbbRecaptchaOnLoad&hl=' ~ lang('RECAPTCHA_LANG') %}
|
||||
{# The g-recaptcha class is used in JavaScript #}
|
||||
<div class="g-recaptcha" data-sitekey="{RECAPTCHA_PUBKEY}" data-callback="phpbbRecaptchaOnSubmit" data-size="invisible" data-tabindex="<!-- IF $CAPTCHA_TAB_INDEX -->{$CAPTCHA_TAB_INDEX}<!-- ELSE -->10<!-- ENDIF -->"></div>
|
||||
<!-- ELSE -->
|
||||
{L_RECAPTCHA_NOT_AVAILABLE}
|
||||
|
13
phpBB/styles/prosilver/template/captcha_recaptcha_v3.html
Normal file
13
phpBB/styles/prosilver/template/captcha_recaptcha_v3.html
Normal file
@ -0,0 +1,13 @@
|
||||
{% if S_RECAPTCHA_AVAILABLE %}
|
||||
<noscript>
|
||||
<div>{{ lang('RECAPTCHA_NOSCRIPT') }}</div>
|
||||
</noscript>
|
||||
|
||||
<script src="{{ U_RECAPTCHA_SCRIPT }}" async defer></script>
|
||||
|
||||
{# The g-recaptcha class is used in JavaScript #}
|
||||
<input class="g-recaptcha" type="hidden" name="recaptcha_action" value="{{ RECAPTCHA_ACTION }}" data-recaptcha-v3="{{ RECAPTCHA_KEY }}">
|
||||
<input type="hidden" name="recaptcha_token" value="">
|
||||
{% else %}
|
||||
{{ lang('RECAPTCHA_NOT_AVAILABLE') }}
|
||||
{% endif %}
|
Loading…
x
Reference in New Issue
Block a user