diff --git a/Panel/CHANGELOG.md b/Panel/CHANGELOG.md index bd6962af..a183c2fa 100644 --- a/Panel/CHANGELOG.md +++ b/Panel/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 2026-05-18 +- **Panel registration stability + captcha fallback hardening:** Fixed a fatal syntax error in `modules/register/register-exec.php`, removed hardcoded/legacy registration redirects, added structured registration logging to `modules/register/logs/register.log` (auto-creates missing log dir), added duplicate username checks, added optional `users_pass_hash` write for PHP 8.3-compatible auth upgrades, and implemented graceful reCAPTCHA fallback when keys are missing/legacy-invalid or the widget reports an error so the themed registration flow no longer crashes with raw PHP errors. + ## 2026-05-13 - **Root Apache vhost template for split Panel/Website layout:** Added `SITES_AVAILABLE_EXAMPLE.conf` at repo root with ready-to-copy `sites-available` examples for both `Panel/` and `Website/`, covering HTTP→HTTPS redirects, SSL vhosts, example domains/paths, required Apache modules, Certbot (`--apache` and `--webroot`) commands, and verification/reload steps. - **Per-site Apache examples for direct deployment:** Added `examples/apache/panel.example.com.conf` and `examples/apache/website.example.com.conf` so each site can be copied directly into `/etc/apache2/sites-available/` with minimal edits. diff --git a/Panel/docs/COPILOT_TODO.md b/Panel/docs/COPILOT_TODO.md index f758df5d..738af1ed 100644 --- a/Panel/docs/COPILOT_TODO.md +++ b/Panel/docs/COPILOT_TODO.md @@ -14,3 +14,4 @@ - Add an automated end-to-end check that verifies `create_servers.php` skips already-installed homes while still retrying existing-home orders with missing executable/IP-port/mod prerequisites. - Add a repeatable QA fixture that exercises `modules/billing/logs/provisioning_trace.log` writability failures and verifies payment success pages surface the traced provision result for paid and free orders. - Add an admin/serverlist UI badge that shows detected service OS variant (Windows/Linux/Any) from XML metadata next to each purchasable service row. +- Add a panel settings health check that validates reCAPTCHA site/secret keys against active panel/storefront domains and warns admins before registration users see widget errors. diff --git a/Panel/includes/database_mysqli.php b/Panel/includes/database_mysqli.php index 46d39b73..e61632d9 100644 --- a/Panel/includes/database_mysqli.php +++ b/Panel/includes/database_mysqli.php @@ -432,7 +432,7 @@ class OGPDatabaseMySQL extends OGPDatabase $user_id = mysqli_insert_id($this->link); if( !$user_id ) { - echo mysqli_errno($this->link) . ": " . mysqli_error($this->link); + error_log("OGP addUser failed: " . mysqli_errno($this->link) . ": " . mysqli_error($this->link)); return false; } else diff --git a/Panel/index.php b/Panel/index.php index 87350ed1..280f2098 100644 --- a/Panel/index.php +++ b/Panel/index.php @@ -316,6 +316,8 @@ function ogpHome() $_SESSION['users_lang'] = isset( $_GET['lang'] ) ? $_GET['lang'] : $userInfo['users_lang']; $_SESSION['users_theme'] = $userInfo['users_theme']; $_SESSION['users_api_key'] = $db->getApiToken($userInfo['user_id']); + require_once('modules/register/register_helpers.php'); + register_log_event('login_succeeded', array('username' => $userInfo['users_login'], 'user_id' => $userInfo['user_id'])); print_success( get_lang("logging_in") ."..."); $db->logger( get_lang("logging_in") ."..."); $db->query("DELETE FROM `OGP_DB_PREFIXban_list` WHERE client_ip='$client_ip';"); @@ -474,4 +476,3 @@ function ogpHome() ?> - diff --git a/Panel/modules/register/register-exec.php b/Panel/modules/register/register-exec.php index 6f098320..863309ee 100644 --- a/Panel/modules/register/register-exec.php +++ b/Panel/modules/register/register-exec.php @@ -34,9 +34,11 @@ function checkEmail($email) { } require_once("includes/functions.php"); +require_once(dirname(__FILE__) . '/register_helpers.php'); function exec_ogp_module() { global $db,$view,$settings; + startSession(); $adminEmailList = ''; // Get email address of all admins to inform him when a user has registered. @@ -68,14 +70,16 @@ function exec_ogp_module() } //Sanitize the POST values - $users_fname = sanitizeInputStr($_POST['users_fname']); - $users_lname = sanitizeInputStr($_POST['users_lname']); - $users_login = sanitizeInputStr($_POST['login_name']); - $users_passwd = clean($_POST['users_passwd']); - $users_cpasswd = clean($_POST['users_cpasswd']); - $users_email = clean($_POST['users_email']); - $users_comment = clean($_POST['users_comment']); - $gRecaptchaResponse = clean($_POST['g-recaptcha-response']); + $users_fname = sanitizeInputStr(isset($_POST['users_fname']) ? $_POST['users_fname'] : ''); + $users_lname = sanitizeInputStr(isset($_POST['users_lname']) ? $_POST['users_lname'] : ''); + $users_login = sanitizeInputStr(isset($_POST['login_name']) ? $_POST['login_name'] : ''); + $users_passwd = clean(isset($_POST['users_passwd']) ? $_POST['users_passwd'] : ''); + $users_cpasswd = clean(isset($_POST['users_cpasswd']) ? $_POST['users_cpasswd'] : ''); + $users_email = clean(isset($_POST['users_email']) ? $_POST['users_email'] : ''); + $users_comment = clean(isset($_POST['users_comment']) ? $_POST['users_comment'] : ''); + $gRecaptchaResponse = clean(isset($_POST['g-recaptcha-response']) ? $_POST['g-recaptcha-response'] : ''); + $recaptcha_widget_error = clean(isset($_POST['recaptcha_widget_error']) ? $_POST['recaptcha_widget_error'] : '0'); + register_log_event('registration_started', array('username' => $users_login, 'email' => $users_email)); if( !empty($users_fname) ) { $input['users_fname'] = $users_fname; @@ -115,6 +119,12 @@ function exec_ogp_module() $errmsg_arr[] = get_lang('err_login_name'); $errflag = true; } + elseif($db->getUser($users_login) != FALSE) + { + $errmsg_arr[] = get_lang('err_login_name'); + $errflag = true; + register_log_event('registration_validation_failed', array('reason' => 'duplicate_username', 'username' => $users_login)); + } if($users_passwd == '') { $errmsg_arr[] = get_lang('err_password'); $errflag = true; @@ -137,21 +147,33 @@ function exec_ogp_module() $errflag = true; } - if(!empty($settings['recaptcha_site_key']) && !empty($settings['recaptcha_secret_key'])){ - $sitekey = $settings['recaptcha_site_key']; - $secretkey = $settings['recaptcha_secret_key']; - }else{ - require_once('captchakeys.php'); - } - - require('includes/classes/recaptcha/autoload.php'); - $recaptcha = new \ReCaptcha\ReCaptcha($secretkey); - $resp = $recaptcha->verify($gRecaptchaResponse, $_SERVER["REMOTE_ADDR"]); - - if (empty($gRecaptchaResponse) || !$resp->isSuccess()) + $recaptcha = register_get_recaptcha_config($settings); + if($recaptcha['enabled'] && $recaptcha_widget_error !== '1') { - $errmsg_arr[] = get_lang('err_captcha'); - $errflag = true; + require_once('includes/classes/recaptcha/autoload.php'); + try { + $captcha = new \ReCaptcha\ReCaptcha($recaptcha['secretkey']); + $resp = $captcha->verify($gRecaptchaResponse, isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : ''); + if (empty($gRecaptchaResponse) || !$resp->isSuccess()) + { + $errmsg_arr[] = get_lang('err_captcha'); + $errflag = true; + register_log_event('registration_captcha_failed', array('username' => $users_login)); + } + else + { + register_log_event('registration_captcha_validated', array('username' => $users_login)); + } + } + catch (Exception $e) + { + register_log_event('registration_captcha_exception', array('error' => $e->getMessage())); + register_log_event('registration_captcha_skipped', array('reason' => 'verification_exception')); + } + } + else + { + register_log_event('registration_captcha_skipped', array('reason' => $recaptcha['reason'], 'widget_error' => $recaptcha_widget_error)); } //Create INSERT query @@ -161,11 +183,23 @@ function exec_ogp_module() { $errmsg_arr[] = get_lang('err_login_name'); $errflag = true; + register_log_event('registration_db_insert_failed', array('username' => $users_login)); } else { $user = $db->getUser($users_login); $user_id = $user['user_id']; + register_log_event('registration_db_insert_succeeded', array('username' => $users_login, 'user_id' => $user_id)); + + $users_pass_hash = password_hash($users_passwd, PASSWORD_DEFAULT); + if($users_pass_hash !== false) + { + $hash_column = $db->resultQuery("SHOW COLUMNS FROM `OGP_DB_PREFIXusers` LIKE 'users_pass_hash';"); + if($hash_column) + { + $db->query("UPDATE `OGP_DB_PREFIXusers` SET `users_pass_hash` = '".$db->realEscapeSingle($users_pass_hash)."' WHERE `user_id` = ".(int)$user_id." LIMIT 1;"); + } + } $fields['users_fname'] = $users_fname; $fields['users_lname'] = $users_lname; @@ -195,19 +229,21 @@ function exec_ogp_module() if($mail) { print_success(get_lang_f('your_account_details_has_been_sent_by_email_to',$users_email)); - $view->refresh("http://xpgame.host,8); + $view->refresh("index.php",8); }else{ - $view->refresh("http://xpgame.host",8); print_success(get_lang('account_created')); + $view->refresh("index.php",8); } + register_log_event('registration_completed', array('username' => $users_login, 'user_id' => $user_id)); } else { $user = $db->getUser($users_login); $user_id = $user['user_id']; $db->delUser($user_id); - print_failure('FAILURE: Unable to set user details, try again.'); + print_failure('Unable to complete registration details. Please try again.'); $view->refresh("index.php?m=register&p=form&".$lang_switch,8); + register_log_event('registration_profile_update_failed', array('username' => $users_login, 'user_id' => $user_id)); } } } @@ -215,8 +251,8 @@ function exec_ogp_module() if($errflag) { $_SESSION['ERRMSG_ARR'] = $errmsg_arr; $_SESSION['INPUT'] = $input; + register_log_event('registration_validation_failed', array('username' => $users_login, 'errors' => $errmsg_arr)); $view->refresh("index.php?m=register&p=form&".$lang_switch,0); } } ?> - diff --git a/Panel/modules/register/register.php b/Panel/modules/register/register.php index c9f5bdf1..549869aa 100644 --- a/Panel/modules/register/register.php +++ b/Panel/modules/register/register.php @@ -25,8 +25,7 @@ //Open Game Panel Free User Registration Add On By // MarkDogg18769 -define("RECAPTCHA_API_SERVER", "http://www.google.com/recaptcha/api"); -define("RECAPTCHA_API_SECURE_SERVER", "https://www.google.com/recaptcha/api"); +require_once(dirname(__FILE__) . '/register_helpers.php'); function exec_ogp_module() { @@ -83,14 +82,22 @@ function exec_ogp_module() $ft->add_field_hidden('users_comment',get_lang_f('registered_on', date("d/m/Y")) ); echo "