Merge pull request #149 from GameServerPanel/copilot/fix-user-registration-issues
This commit is contained in:
commit
651c935fa7
7 changed files with 163 additions and 46 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
|||
?>
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
|
|
|
|||
|
|
@ -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 "<tr><td> </td><td align='right'>";
|
||||
|
||||
if(!empty($settings['recaptcha_site_key']) && !empty($settings['recaptcha_secret_key'])){
|
||||
$sitekey = $settings['recaptcha_site_key'];
|
||||
$secretkey = $settings['recaptcha_secret_key'];
|
||||
$recaptcha = register_get_recaptcha_config($settings);
|
||||
if($recaptcha['enabled']){
|
||||
echo recaptcha_get_html($recaptcha['sitekey']);
|
||||
echo '<input type="hidden" id="recaptcha_widget_error" name="recaptcha_widget_error" value="0" />';
|
||||
echo '<script type="text/javascript">
|
||||
function registerRecaptchaWidgetError() {
|
||||
var flag = document.getElementById("recaptcha_widget_error");
|
||||
if (flag) flag.value = "1";
|
||||
}
|
||||
</script>';
|
||||
register_log_event('registration_form_captcha_enabled');
|
||||
}else{
|
||||
require_once('captchakeys.php');
|
||||
echo "<div style='color:#f8e58c;font-size:12px;'>Captcha is temporarily unavailable. Registration is still available.</div>";
|
||||
echo '<input type="hidden" id="recaptcha_widget_error" name="recaptcha_widget_error" value="1" />';
|
||||
register_log_event('registration_form_captcha_disabled', array('reason' => $recaptcha['reason']));
|
||||
}
|
||||
$use_ssl = ( isset($_SERVER['HTTPS']) and get_true_boolean($_SERVER['HTTPS']) ) ? true : false;
|
||||
echo recaptcha_get_html($sitekey,null,$use_ssl);
|
||||
echo "</td></tr>";
|
||||
$ft->end_table();
|
||||
$ft->add_button("submit","Submit",get_lang('register_a_new_user'));
|
||||
|
|
@ -100,13 +107,7 @@ function exec_ogp_module()
|
|||
function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
|
||||
{
|
||||
if ($pubkey == null || $pubkey == '') {
|
||||
die ("To use reCAPTCHA you must get an API key from <a href='https://www.google.com/recaptcha/admin/create'>https://www.google.com/recaptcha/admin/create</a>");
|
||||
}
|
||||
|
||||
if ($use_ssl) {
|
||||
$server = RECAPTCHA_API_SECURE_SERVER;
|
||||
} else {
|
||||
$server = RECAPTCHA_API_SERVER;
|
||||
return "";
|
||||
}
|
||||
|
||||
$errorpart = "";
|
||||
|
|
@ -114,7 +115,7 @@ function recaptcha_get_html ($pubkey, $error = null, $use_ssl = false)
|
|||
$errorpart = "&error=" . $error;
|
||||
}
|
||||
|
||||
return "<script src='" . $server . ".js'></script><div style='display: inline-block;' class='g-recaptcha' data-sitekey='" . $pubkey . "'></div>";
|
||||
return "<script src='https://www.google.com/recaptcha/api.js' async defer></script><div style='display: inline-block;' class='g-recaptcha' data-sitekey='" . $pubkey . "' data-error-callback='registerRecaptchaWidgetError'></div>";
|
||||
|
||||
}
|
||||
?>
|
||||
|
|
|
|||
75
Panel/modules/register/register_helpers.php
Normal file
75
Panel/modules/register/register_helpers.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
/*
|
||||
*
|
||||
* OGP - Open Game Panel
|
||||
* Copyright (C) 2008 - 2018 The OGP Development Team
|
||||
*
|
||||
* http://www.opengamepanel.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
function register_log_path()
|
||||
{
|
||||
$log_dir = dirname(__FILE__) . '/logs';
|
||||
if (!is_dir($log_dir)) {
|
||||
@mkdir($log_dir, 0775, true);
|
||||
}
|
||||
return $log_dir . '/register.log';
|
||||
}
|
||||
|
||||
function register_log_event($event, $context = array())
|
||||
{
|
||||
$line = date('Y-m-d H:i:s') . ' | ' . $event;
|
||||
if (!empty($context)) {
|
||||
$line .= ' | ' . json_encode($context);
|
||||
}
|
||||
$line .= PHP_EOL;
|
||||
@file_put_contents(register_log_path(), $line, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
function register_get_recaptcha_config($settings)
|
||||
{
|
||||
$sitekey = isset($settings['recaptcha_site_key']) ? trim($settings['recaptcha_site_key']) : '';
|
||||
$secretkey = isset($settings['recaptcha_secret_key']) ? trim($settings['recaptcha_secret_key']) : '';
|
||||
|
||||
if ($sitekey === '' || $secretkey === '') {
|
||||
return array(
|
||||
'enabled' => false,
|
||||
'sitekey' => '',
|
||||
'secretkey' => '',
|
||||
'reason' => 'missing_settings'
|
||||
);
|
||||
}
|
||||
|
||||
// Legacy demo keys are frequently left in place and cause "Invalid site key".
|
||||
if ($sitekey === '6Lc4osYSAAAAAHtYbHvsXIl0h1auXeiqPhagTXAj' && $secretkey === '6Lc4osYSAAAAAHK56NE9ZHLgw3ZuESHhF26bMoNx') {
|
||||
return array(
|
||||
'enabled' => false,
|
||||
'sitekey' => '',
|
||||
'secretkey' => '',
|
||||
'reason' => 'legacy_demo_keys'
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'enabled' => true,
|
||||
'sitekey' => $sitekey,
|
||||
'secretkey' => $secretkey,
|
||||
'reason' => 'configured'
|
||||
);
|
||||
}
|
||||
?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue