diff --git a/admin/pages/login.php b/admin/pages/login.php index 76d25d49..32d8e8b0 100644 --- a/admin/pages/login.php +++ b/admin/pages/login.php @@ -10,6 +10,12 @@ defined('MYAAC') or die('Direct access not allowed!'); $title = 'Login'; +require PAGES . 'account/login.php'; +if ($logged) { + header('Location: ' . ADMIN_URL); + return; +} + $twig->display('admin.login.html.twig', [ 'logout' => (ACTION == 'logout' ? 'You have been logged out!' : ''), 'account' => USE_ACCOUNT_NAME ? 'Name' : 'Number', diff --git a/config.php b/config.php index 0b6a3c96..2e54562a 100644 --- a/config.php +++ b/config.php @@ -142,18 +142,6 @@ $config = array( 'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook) 'smtp_debug' => false, // set true to debug (you will see more info in error.log) - // Google reCAPTCHA (prevent spam bots) - 'recaptcha_enabled' => false, // enable recaptcha verification code - 'recaptcha_type' => 'v3', // 'v2-checkbox', 'v2-invisible', 'v3' - 'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha - 'recaptcha_secret_key' => '', - // following option apply only for ReCaptcha v2-checkbox - 'recaptcha_v2_theme' => 'light', // light, dark - // following option apply only for ReCaptcha v3 - // min score for validation, between 0 - 1.0 - // https://developers.google.com/recaptcha/docs/v3#interpreting_the_score - 'recaptcha_v3_min_score' => 0.5, - // 'generate_new_reckey' => true, // let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key) 'generate_new_reckey_price' => 20, // price for new recovery key diff --git a/plugins/account-create-hint/hint.html.twig b/plugins/account-create-hint/hint.html.twig index d6069d56..5c31dfb1 100644 --- a/plugins/account-create-hint/hint.html.twig +++ b/plugins/account-create-hint/hint.html.twig @@ -1,3 +1,3 @@ To play on {{ config.lua.serverName }} you need an account. -All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.recaptcha_enabled %}, confirm reCAPTCHA{% endif %}{% if config.account_country %}, country{% endif %} and your email address. +All you have to do to create your new account is to enter an account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %}, password{% if config.account_country %}, country{% endif %} and your email address. Also you have to agree to the terms presented below. If you have done so, your account {% if constant('USE_ACCOUNT_NAME') %}name{% else %}number{% endif %} will be shown on the following page and your account password will be sent to your email address along with further instructions. If you do not receive the email with your password, please check your spam filter.

diff --git a/system/hooks.php b/system/hooks.php index 3f510d79..73f8e630 100644 --- a/system/hooks.php +++ b/system/hooks.php @@ -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 diff --git a/system/libs/GoogleReCAPTCHA.php b/system/libs/GoogleReCAPTCHA.php deleted file mode 100644 index 3dd18b28..00000000 --- a/system/libs/GoogleReCAPTCHA.php +++ /dev/null @@ -1,84 +0,0 @@ -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; - } -} diff --git a/system/login.php b/system/login.php index 4e372b75..5d55cd18 100644 --- a/system/login.php +++ b/system/login.php @@ -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); diff --git a/system/pages/account/create.php b/system/pages/account/create.php index 4b927eb6..551d6d1e 100644 --- a/system/pages/account/create.php +++ b/system/pages/account/create.php @@ -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; diff --git a/system/pages/account/login.php b/system/pages/account/login.php new file mode 100644 index 00000000..3fe92c50 --- /dev/null +++ b/system/pages/account/login.php @@ -0,0 +1,115 @@ +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)); + } +} diff --git a/system/pages/account/manage.php b/system/pages/account/manage.php index 10aea0ce..dead01bc 100644 --- a/system/pages/account/manage.php +++ b/system/pages/account/manage.php @@ -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) { diff --git a/system/templates/account.create.html.twig b/system/templates/account.create.html.twig index b5dfc2e2..8e885b43 100644 --- a/system/templates/account.create.html.twig +++ b/system/templates/account.create.html.twig @@ -108,28 +108,6 @@ {% if errors.password is defined %}{{ errors.password }}{% endif %} {{ hook('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS') }} - - {% if config.recaptcha_enabled %} - {% if config.recaptcha_type == 'v3' %} - - {% elseif config.recaptcha_type == 'v2-invisible' %} -
- {% elseif config.recaptcha_type == 'v2-checkbox' %} - - - Verification: - - -
- - - {% if errors.verification is defined %} - {{ errors.verification }} - {% endif %} - {% endif %} - {% endif %} - - {{ hook('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA') }} @@ -344,11 +322,7 @@ {{ hook('HOOK_ACCOUNT_CREATE_AFTER_FORM') }} - -{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %} - {% set action = 'register' %} - {{ include('google_recaptcha_v3.html.twig') }} -{% endif %} +