Remove google recaptcha from code

will be included as plugin. This allows for custom recaptcha's
This commit is contained in:
slawkens
2023-02-07 15:20:24 +01:00
parent 574e361f90
commit 1166ddfe87
15 changed files with 148 additions and 323 deletions

View File

@@ -40,7 +40,6 @@ define('HOOK_ACCOUNT_CREATE_AFTER_ACCOUNT', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_EMAIL', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_COUNTRY', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA', ++$i);
define('HOOK_ACCOUNT_CREATE_BEFORE_CHARACTER_NAME', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_CHARACTER_NAME', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_SEX', ++$i);
@@ -48,11 +47,18 @@ define('HOOK_ACCOUNT_CREATE_AFTER_VOCATION', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_TOWNS', ++$i);
define('HOOK_ACCOUNT_CREATE_BEFORE_SUBMIT_BUTTON', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_FORM', ++$i);
define('HOOK_ACCOUNT_CREATE_AFTER_SUBMIT', ++$i);
define('HOOK_ACCOUNT_CREATE_POST', ++$i);
define('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE', ++$i);
define('HOOK_ACCOUNT_LOGIN_BEFORE_ACCOUNT', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME', ++$i);
define('HOOK_ACCOUNT_LOGIN_AFTER_PAGE', ++$i);
define('HOOK_ACCOUNT_LOGIN_POST', ++$i);
define('HOOK_ADMIN_MENU', ++$i);
define('HOOK_EMAIL_CONFIRMED', ++$i);
define('HOOK_FIRST', HOOK_STARTUP);
define('HOOK_LAST', HOOK_EMAIL_CONFIRMED);
const HOOK_FIRST = HOOK_STARTUP;
const HOOK_LAST = HOOK_EMAIL_CONFIRMED;
require_once LIBS . 'plugins.php';
class Hook

View File

@@ -1,84 +0,0 @@
<?php
class GoogleReCAPTCHA
{
private static $errorMessage = '';
private static $errorType;
const ERROR_MISSING_RESPONSE = 1;
const ERROR_INVALID_ACTION = 2;
const ERROR_LOW_SCORE = 3;
const ERROR_NO_SUCCESS = 4;
public static function verify($action = '')
{
if (!isset($_POST['g-recaptcha-response']) || empty($_POST['g-recaptcha-response'])) {
self::$errorType = self::ERROR_MISSING_RESPONSE;
self::$errorMessage = "Please confirm that you're not a robot.";
return false;
}
$recaptchaApiUrl = 'https://www.google.com/recaptcha/api/siteverify';
$secretKey = config('recaptcha_secret_key');
$recaptchaResponse = $_POST['g-recaptcha-response'];
$ip = $_SERVER['REMOTE_ADDR'];
$params = 'secret='.$secretKey.'&response='.$recaptchaResponse.'&remoteip='.$ip;
if (function_exists('curl_version')) {
$curl_connection = curl_init($recaptchaApiUrl);
curl_setopt($curl_connection, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($curl_connection, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_connection, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl_connection, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($curl_connection, CURLOPT_POSTFIELDS, $params);
$response = curl_exec($curl_connection);
curl_close($curl_connection);
} else {
$response = file_get_contents($recaptchaApiUrl . '?' . $params);
}
$json = json_decode($response);
$recaptchaType = config('recaptcha_type');
if ($recaptchaType === 'v3') { // score based
//log_append('recaptcha.log', 'recaptcha_score: ' . $json->score . ', action:' . $json->action);
if (!isset($json->action) || $json->action !== $action) {
self::$errorType = self::ERROR_INVALID_ACTION;
self::$errorMessage = 'Google ReCaptcha returned invalid action.';
return false;
}
if (!isset($json->score) || $json->score < config('recaptcha_v3_min_score')) {
self::$errorType = self::ERROR_LOW_SCORE;
self::$errorMessage = 'Your Google ReCaptcha score was too low.';
return false;
}
}
if (!isset($json->success) || !$json->success) {
self::$errorType = self::ERROR_NO_SUCCESS;
self::$errorMessage = "Please confirm that you're not a robot.";
return false;
}
return true;
}
/**
* @return string
*/
public static function getErrorMessage() {
return self::$errorMessage;
}
/**
* @return int
*/
public static function getErrorType() {
return self::$errorType;
}
}

View File

@@ -28,124 +28,6 @@ if($current_session !== false)
}
}
// new login with data from form
if(!$logged && isset($_POST['account_login'], $_POST['password_login']))
{
$login_account = $_POST['account_login'];
$login_password = $_POST['password_login'];
$remember_me = isset($_POST['remember_me']);
if(!empty($login_account) && !empty($login_password))
{
if($cache->enabled())
{
$tmp = '';
if($cache->fetch('failed_logins', $tmp))
{
$tmp = unserialize($tmp);
$to_remove = array();
foreach($tmp as $ip => $t)
{
if(time() - $t['last'] >= 5 * 60)
$to_remove[] = $ip;
}
foreach($to_remove as $ip)
unset($tmp[$ip]);
}
else
$tmp = array();
$ip = $_SERVER['REMOTE_ADDR'];
$t = $tmp[$ip] ?? null;
}
if(config('recaptcha_enabled') && !config('account_create_auto_login'))
{
require_once LIBS . 'GoogleReCAPTCHA.php';
if (!GoogleReCAPTCHA::verify('login')) {
$errors[] = GoogleReCAPTCHA::getErrorMessage();
}
}
$account_logged = new OTS_Account();
if (config('account_login_by_email')) {
$account_logged->findByEMail($login_account);
}
if (!config('account_login_by_email') || config('account_login_by_email_fallback')) {
if(USE_ACCOUNT_NAME) {
$account_logged->find($login_account);
} else {
$account_logged->load($login_account, true);
}
}
if($account_logged->isLoaded() && encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword()
&& (!isset($t) || $t['attempts'] < 5)
)
{
setSession('account', $account_logged->getNumber());
setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password));
if($remember_me) {
setSession('remember_me', true);
}
$logged = true;
$logged_flags = $account_logged->getWebFlags();
if(isset($_POST['admin']) && !admin()) {
$errors[] = 'This account has no admin privileges.';
unsetSession('account');
unsetSession('password');
unsetSession('remember_me');
$logged = false;
}
else {
$account_logged->setCustomField('web_lastlogin', time());
}
$hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me));
}
else
{
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
$errorMessage = getAccountLoginByLabel() . ' or password is not correct.';
// temporary solution for blocking failed login attempts
if($cache->enabled())
{
if(isset($t))
{
$t['attempts']++;
$t['last'] = time();
if($t['attempts'] >= 5)
$errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.';
else
$errors[] = $errorMessage;
}
else
{
$t = array('attempts' => 1, 'last' => time());
$errors[] = $errorMessage;
}
$tmp[$ip] = $t;
$cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour
}
else {
$errors[] = $errorMessage;
}
}
}
else {
$errors[] = 'Please enter your ' . getAccountLoginByLabel() . ' and password.';
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
}
}
if($logged) {
$logged_flags = $account_logged->getWebFlags();
$twig->addGlobal('logged', true);

View File

@@ -72,14 +72,6 @@ if($save)
$errors['country'] = 'Country is invalid.';
}
if(config('recaptcha_enabled'))
{
require_once LIBS . 'GoogleReCAPTCHA.php';
if (!GoogleReCAPTCHA::verify('register')) {
$errors['verification'] = GoogleReCAPTCHA::getErrorMessage();
}
}
// password
if(empty($password)) {
$errors['password'] = 'Please enter the password for your new account.';
@@ -149,7 +141,9 @@ if($save)
}
}
$hooks->trigger(HOOK_ACCOUNT_CREATE_AFTER_SUBMIT, $params);
if (!$hooks->trigger(HOOK_ACCOUNT_CREATE_POST, $params)) {
return;
}
if(config('account_create_character_create')) {
$character_name = isset($_POST['name']) ? stripslashes(ucwords(strtolower($_POST['name']))) : null;

View File

@@ -0,0 +1,115 @@
<?php
// new login with data from form
if(!$logged && isset($_POST['account_login'], $_POST['password_login']))
{
$login_account = $_POST['account_login'];
$login_password = $_POST['password_login'];
$remember_me = isset($_POST['remember_me']);
if(!empty($login_account) && !empty($login_password))
{
if($cache->enabled())
{
$tmp = '';
if($cache->fetch('failed_logins', $tmp))
{
$tmp = unserialize($tmp);
$to_remove = array();
foreach($tmp as $ip => $t)
{
if(time() - $t['last'] >= 5 * 60)
$to_remove[] = $ip;
}
foreach($to_remove as $ip)
unset($tmp[$ip]);
}
else
$tmp = array();
$ip = $_SERVER['REMOTE_ADDR'];
$t = $tmp[$ip] ?? null;
}
if (!$hooks->trigger(HOOK_ACCOUNT_LOGIN_POST)) {
return;
}
$account_logged = new OTS_Account();
if (config('account_login_by_email')) {
$account_logged->findByEMail($login_account);
}
if (!config('account_login_by_email') || config('account_login_by_email_fallback')) {
if(USE_ACCOUNT_NAME) {
$account_logged->find($login_account);
} else {
$account_logged->load($login_account, true);
}
}
if($account_logged->isLoaded() && encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password) == $account_logged->getPassword()
&& (!isset($t) || $t['attempts'] < 5)
)
{
setSession('account', $account_logged->getNumber());
setSession('password', encrypt((USE_ACCOUNT_SALT ? $account_logged->getCustomField('salt') : '') . $login_password));
if($remember_me) {
setSession('remember_me', true);
}
$logged = true;
$logged_flags = $account_logged->getWebFlags();
if(isset($_POST['admin']) && !admin()) {
$errors[] = 'This account has no admin privileges.';
unsetSession('account');
unsetSession('password');
unsetSession('remember_me');
$logged = false;
}
else {
$account_logged->setCustomField('web_lastlogin', time());
}
$hooks->trigger(HOOK_LOGIN, array('account' => $account_logged, 'password' => $login_password, 'remember_me' => $remember_me));
}
else
{
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
$errorMessage = getAccountLoginByLabel() . ' or password is not correct.';
// temporary solution for blocking failed login attempts
if($cache->enabled())
{
if(isset($t))
{
$t['attempts']++;
$t['last'] = time();
if($t['attempts'] >= 5)
$errors[] = 'A wrong password has been entered 5 times in a row. You are unable to log into your account for the next 5 minutes. Please wait.';
else
$errors[] = $errorMessage;
}
else
{
$t = array('attempts' => 1, 'last' => time());
$errors[] = $errorMessage;
}
$tmp[$ip] = $t;
$cache->set('failed_logins', serialize($tmp), 60 * 60); // save for 1 hour
}
else {
$errors[] = $errorMessage;
}
}
}
else {
$errors[] = 'Please enter your ' . getAccountLoginByLabel() . ' and password.';
$hooks->trigger(HOOK_LOGIN_ATTEMPT, array('account' => $login_account, 'password' => $login_password, 'remember_me' => $remember_me));
}
}

View File

@@ -11,6 +11,7 @@
defined('MYAAC') or die('Direct access not allowed!');
$title = 'Account Management';
require __DIR__ . '/login.php';
require __DIR__ . '/base.php';
if(!$logged) {

View File

@@ -108,28 +108,6 @@
<tr><td></td><td><span id="password2_error" class="FormFieldError">{% if errors.password is defined %}{{ errors.password }}{% endif %}</span></td></tr>
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS') }}
{% if config.recaptcha_enabled %}
{% if config.recaptcha_type == 'v3' %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% elseif config.recaptcha_type == 'v2-invisible' %}
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
{% elseif config.recaptcha_type == 'v2-checkbox' %}
<tr>
<td class="LabelV" style="width: 150px">
<span{% if errors.verification[0] is not null %} class="red"{% endif %}>Verification:</span>
</td>
<td>
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
</td>
</tr>
{% if errors.verification is defined %}
<tr><td></td><td><span class="FormFieldError">{{ errors.verification }}</span></td></tr>
{% endif %}
{% endif %}
{% endif %}
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA') }}
</tbody>
</table>
</div>
@@ -344,11 +322,7 @@
</table>
</form>
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_FORM') }}
<script type="text/javascript" src="tools/check_name.js"></script>
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
{% set action = 'register' %}
{{ include('google_recaptcha_v3.html.twig') }}
{% endif %}
<script type="text/javascript" src="{{ constant('BASE_URL') }}tools/check_name.js"></script>
<style>
#SuggestAccountNumber {
font-size: 7pt;

View File

@@ -1,3 +1,4 @@
{{ hook('HOOK_ACCOUNT_LOGIN_BEFORE_PAGE') }}
Please enter your account {{ account|lower }} and your password.<br/><a href="{{ getLink('account/create') }}">Create an account</a> if you do not have one yet.<br/><br/>
<form action="{{ getLink('account/manage') }}" method="post" >
{% if redirect is not null %}
@@ -22,42 +23,27 @@ Please enter your account {{ account|lower }} and your password.<br/><a href="{{
<td>
<div class="InnerTableContainer">
<table style="width:100%;" >
{{ hook('HOOK_ACCOUNT_LOGIN_BEFORE_PASSWORD') }}
<tr>
<td class="LabelV" >
<span{% if error is not null %} class="red"{% endif %}>{{ account_login_by }}:</span>
</td>
<td style="width:100%;" ><input type="text" name="account_login" size="30" maxlength="30" autofocus/></td>
</tr>
{{ hook('HOOK_ACCOUNT_LOGIN_AFTER_ACCOUNT') }}
<tr>
<td class="LabelV" >
<span{% if error is not null %} class="red"{% endif %}>Password:</span>
</td>
<td><input type="password" name="password_login" size="30" maxlength="29" ></td>
</tr>
{{ hook('HOOK_ACCOUNT_LOGIN_AFTER_PASSWORD') }}
<tr>
<td class="LabelV" ></td>
<td><input type="checkbox" id="remember_me" name="remember_me" value="true" />
<label for="remember_me"> Remember me</label></td>
</tr>
{% if config.recaptcha_enabled %}
{% if config.recaptcha_type == 'v3' %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% elseif config.recaptcha_type == 'v2-invisible' %}
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
{% elseif config.recaptcha_type == 'v2-checkbox' %}
<tr>
<td class="LabelV" style="width: 150px">
<span{% if error is not null %} class="red"{% endif %}>Verification:</span>
</td>
<td>
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
</td>
</tr>
{% endif %}
{% endif %}
{% if error is not null %}
<tr><td></td><td><span class="FormFieldError">{{ error }}</span></td></tr>
{% endif %}
{{ hook('HOOK_ACCOUNT_LOGIN_AFTER_REMEMBER_ME') }}
</table>
</div>
</td>
@@ -90,7 +76,3 @@ Please enter your account {{ account|lower }} and your password.<br/><a href="{{
</td>
</tr>
</table>
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
{% set action = 'login' %}
{{ include('google_recaptcha_v3.html.twig') }}
{% endif %}

View File

@@ -1,11 +0,0 @@
<script>
$(document).ready(function() {
grecaptcha.ready(function() {
grecaptcha.execute('{{ config.recaptcha_site_key }}', {action: '{{ action }}'}).then(function(token) {
if (token) {
document.getElementById('g-recaptcha-response').value = token;
}
});
});
});
</script>

View File

@@ -1,11 +0,0 @@
<script>
$(document).ready(function() {
grecaptcha.ready(function() {
grecaptcha.execute('{{ config.recaptcha_site_key }}', {action: '{{ action }}'}).then(function(token) {
if (token) {
document.getElementById('g-recaptcha-response').value = token;
}
});
});
});
</script>

View File

@@ -16,6 +16,3 @@
Please turn it on, or be aware that some features on this website will not work correctly.
</div>
</noscript>
{% if config.recaptcha_enabled %}
<script src="https://www.google.com/recaptcha/api.js{% if config('recaptcha_type') == 'v3' %}?render={{ config.recaptcha_site_key }}{% endif %}"></script>
{% endif %}