Security: remove test/debug/install files from production

This commit is contained in:
2026-05-22 13:05:18 +00:00
parent 2e587941c2
commit 894392065c
9 changed files with 0 additions and 613 deletions
-117
View File
@@ -1,117 +0,0 @@
# ══════════════════════════════════════════════════════════
# TomTomGames Security Configuration
# ══════════════════════════════════════════════════════════
Options -Indexes -Includes
ServerSignature Off
# ── Block all sensitive file types ───────────────────────
<FilesMatch "\.(sql|env|log|sh|md|git|bak|backup|old|orig|tmp|swp|cfg|ini|conf|yaml|yml|json.bak)$">
Order allow,deny
Deny from all
</FilesMatch>
# ── Block direct access to sensitive PHP files ───────────
<FilesMatch "^(phpcheck|test|test_mail|test_login|sgtest|install|config|db|auth|mailer|square|smtp)\.php$">
Order allow,deny
Deny from all
</FilesMatch>
# ── Block access to includes and vendor folders ──────────
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^includes/ - [F,L]
RewriteRule ^vendor/ - [F,L]
RewriteRule ^mail_queue/ - [F,L]
RewriteRule ^\.git/ - [F,L]
</IfModule>
# ── Block common attack vectors ──────────────────────────
<IfModule mod_rewrite.c>
RewriteEngine On
# Block SQL injection attempts in query strings
RewriteCond %{QUERY_STRING} (union|select|insert|drop|delete|update|cast|exec|declare|char|convert|truncate).*= [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} \.\./\.\. [NC,OR]
RewriteCond %{QUERY_STRING} (javascript|vbscript|expression|applet|meta|xml|blink|link|iframe|input|embed|script|object|marquee) [NC]
RewriteRule .* - [F,L]
# Block base64 encoded attacks
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR]
RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [NC]
RewriteRule .* - [F,L]
# Block common exploit scanners and bad bots
RewriteCond %{HTTP_USER_AGENT} (nikto|sqlmap|havij|nessus|masscan|zgrab|python-requests/2\.6|libwww-perl|wget|curl\/7\.[0-4]) [NC]
RewriteRule .* - [F,L]
</IfModule>
# ── Block access to WordPress paths (scanners look for these) ──
<IfModule mod_rewrite.c>
RewriteRule ^wp-admin - [F,L]
RewriteRule ^wp-login - [F,L]
RewriteRule ^xmlrpc - [F,L]
RewriteRule ^\.env - [F,L]
RewriteRule ^composer\. - [F,L]
</IfModule>
# ── Security Headers ──────────────────────────────────────
<IfModule mod_headers.c>
# Prevent MIME type sniffing
Header always set X-Content-Type-Options "nosniff"
# Prevent clickjacking
Header always set X-Frame-Options "DENY"
# XSS protection
Header always set X-XSS-Protection "1; mode=block"
# Referrer policy
Header always set Referrer-Policy "strict-origin-when-cross-origin"
# Permissions policy — disable dangerous browser features
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=(), usb=(), magnetometer=(), gyroscope=()"
# Content Security Policy — restrict where resources can load from
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://web.squarecdn.com https://sandbox.web.squarecdn.com https://js.squareup.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https: wss:; frame-src 'none'"
# Strict Transport Security — force HTTPS for 1 year
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# Remove server info headers
Header unset Server
Header unset X-Powered-By
</IfModule>
# ── Canonical HTTPS + non-www redirect ───────────────────
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
</IfModule>
# ── Block PHP execution in uploads folder (if it exists) ─
<IfModule mod_rewrite.c>
RewriteRule ^uploads/.*\.php$ - [F,L]
</IfModule>
# ── Gzip compression ──────────────────────────────────────
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json image/svg+xml
</IfModule>
# ── Browser caching ───────────────────────────────────────
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 1 hour"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/webp "access plus 1 month"
ExpiresByType application/json "access plus 1 day"
</IfModule>
-28
View File
@@ -1,28 +0,0 @@
<?php
// Fix broadcast_list in admin.php on server - delete after running
$f = '/home/tomtomgames.com/public_html/api/admin.php';
$c = file_get_contents($f);
$idx = strpos($c, "case 'broadcast_list':");
$end = strpos($c, " break;", $idx) + 14;
$new = "case 'broadcast_list':\n try {\n \$sql = \"SELECT b.id, b.subject, b.message, b.target, b.sent_at, u.username AS sender_name, (SELECT COUNT(*) FROM broadcast_reads WHERE broadcast_id=b.id) AS read_count, (SELECT COUNT(*) FROM broadcast_replies WHERE broadcast_id=b.id) AS reply_count, (SELECT COUNT(*) FROM users WHERE status='active' AND is_admin=0) AS total_players FROM broadcasts b JOIN users u ON b.admin_id=u.id ORDER BY b.sent_at DESC LIMIT 100\";\n \$stmt = db()->query(\$sql);\n echo json_encode(['success'=>true,'broadcasts'=>\$stmt->fetchAll()]);\n } catch(Exception \$e) {\n echo json_encode(['success'=>false,'error'=>\$e->getMessage()]);\n }\n break;";
$c = substr($c, 0, $idx) . $new . substr($c, $end);
file_put_contents($f, $c);
// Verify it works
require_once '/home/tomtomgames.com/includes/config.php';
require_once '/home/tomtomgames.com/includes/db.php';
try {
$stmt = db()->query("SELECT COUNT(*) FROM broadcasts");
echo "OK - broadcasts in DB: " . $stmt->fetchColumn() . "\n";
$stmt2 = db()->query("SELECT b.id, b.subject, b.sent_at, u.username AS sender_name FROM broadcasts b JOIN users u ON b.admin_id=u.id ORDER BY b.sent_at DESC LIMIT 5");
$rows = $stmt2->fetchAll();
echo "Query works - rows: " . count($rows) . "\n";
foreach($rows as $r) echo " #{$r['id']}: {$r['subject']} by {$r['sender_name']}\n";
} catch(Exception $e) {
echo "ERROR: " . $e->getMessage() . "\n";
}
echo "DONE - delete this file\n";
-206
View File
@@ -1,206 +0,0 @@
<?php
$key = $_GET['key'] ?? '';
if ($key !== 'TomGames2024Admin') die('<h2 style="font-family:sans-serif;color:red">Access denied. Add ?key=TomGames2024Admin to URL.</h2>');
require_once __DIR__ . '/../includes/config.php';
$log = [];
function ok($msg) { global $log; $log[] = ['t'=>'ok', 'm'=>$msg]; }
function err($msg) { global $log; $log[] = ['t'=>'err', 'm'=>$msg]; }
function warn($msg) { global $log; $log[] = ['t'=>'warn','m'=>$msg]; }
function info($msg) { global $log; $log[] = ['t'=>'info','m'=>$msg]; }
try {
$pdo = new PDO("mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=utf8mb4", DB_USER, DB_PASS,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
ok('Connected to <strong>'.DB_NAME.'</strong> as <strong>'.DB_USER.'</strong>');
} catch (Exception $e) {
die('<pre style="color:red">CONNECTION FAILED: '.htmlspecialchars($e->getMessage()).'</pre>');
}
// Helper: check if column exists
function colExists(PDO $pdo, string $table, string $col): bool {
$r = $pdo->query("SHOW COLUMNS FROM `$table` LIKE '$col'")->fetch();
return (bool)$r;
}
// ── CREATE TABLES ───────────────────────────────────────────
$tables = [
'users' => "CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
alias VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE,
email_verified TINYINT(1) DEFAULT 0,
tokens DECIMAL(10,2) DEFAULT 0,
is_admin TINYINT(1) DEFAULT 0,
status ENUM('active','suspended') DEFAULT 'active',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_login DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
'pending_registrations' => "CREATE TABLE IF NOT EXISTS pending_registrations (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
alias VARCHAR(100) NOT NULL,
email VARCHAR(150) NOT NULL,
token VARCHAR(64) UNIQUE NOT NULL,
expires_at DATETIME NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
'token_purchases' => "CREATE TABLE IF NOT EXISTS token_purchases (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
tokens INT NOT NULL,
amount_cents INT NOT NULL,
payment_method VARCHAR(20) DEFAULT 'card',
square_payment_id VARCHAR(255),
platform_id VARCHAR(50),
game_alias VARCHAR(100),
player_name VARCHAR(100),
billing_name VARCHAR(160),
billing_address VARCHAR(200),
billing_city VARCHAR(80),
billing_state VARCHAR(2),
billing_zip VARCHAR(10),
billing_email VARCHAR(150),
is_custom TINYINT(1) DEFAULT 0,
failure_reason TEXT,
card_brand VARCHAR(30),
card_last4 VARCHAR(4),
receipt_url VARCHAR(512),
status ENUM('pending','completed','failed') DEFAULT 'pending',
admin_note TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
'cashout_requests' => "CREATE TABLE IF NOT EXISTS cashout_requests (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
platform_id VARCHAR(50) NOT NULL,
alias VARCHAR(100) NOT NULL,
tokens DECIMAL(10,2) NOT NULL,
status ENUM('pending','approved','rejected') DEFAULT 'pending',
admin_note TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
resolved_at DATETIME,
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
'saved_billing' => "CREATE TABLE IF NOT EXISTS saved_billing (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT UNIQUE NOT NULL,
first_name VARCHAR(80),
last_name VARCHAR(80),
email VARCHAR(150),
address VARCHAR(200),
city VARCHAR(80),
state VARCHAR(2),
zip VARCHAR(10),
card_brand VARCHAR(30),
card_last4 VARCHAR(4),
card_exp_month VARCHAR(2),
card_exp_year VARCHAR(4),
sq_card_id VARCHAR(255),
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
'chat_messages' => "CREATE TABLE IF NOT EXISTS chat_messages (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
sender ENUM('user','admin') NOT NULL,
message TEXT NOT NULL,
is_read TINYINT(1) DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4",
];
foreach ($tables as $name => $sql) {
try { $pdo->exec($sql); ok("Table <strong>$name</strong> ✓"); }
catch (Exception $e) { err("Table <strong>$name</strong>: ".htmlspecialchars($e->getMessage())); }
}
// ── ADD MISSING COLUMNS (compatible with MySQL 5.6/5.7/8) ──
// Check existence first, then ALTER — works on all MySQL versions
$addCols = [
// [table, column, definition, after]
['token_purchases', 'billing_name', "VARCHAR(160)", 'player_name'],
['token_purchases', 'billing_address', "VARCHAR(200)", 'billing_name'],
['token_purchases', 'billing_city', "VARCHAR(80)", 'billing_address'],
['token_purchases', 'billing_state', "VARCHAR(2)", 'billing_city'],
['token_purchases', 'billing_zip', "VARCHAR(10)", 'billing_state'],
['token_purchases', 'billing_email', "VARCHAR(150)", 'billing_zip'],
['token_purchases', 'is_custom', "TINYINT(1) DEFAULT 0", 'billing_email'],
['token_purchases', 'failure_reason', "TEXT", 'is_custom'],
['token_purchases', 'card_brand', "VARCHAR(30)", 'failure_reason'],
['token_purchases', 'card_last4', "VARCHAR(4)", 'card_brand'],
['token_purchases', 'receipt_url', "VARCHAR(512)", 'card_last4'],
['token_purchases', 'admin_note', "TEXT", 'status'],
['users', 'email_verified', "TINYINT(1) DEFAULT 0", 'email'],
];
foreach ($addCols as [$tbl, $col, $def, $after]) {
if (colExists($pdo, $tbl, $col)) {
ok("Column <strong>$tbl.$col</strong> already exists ✓");
} else {
try {
$pdo->exec("ALTER TABLE `$tbl` ADD COLUMN `$col` $def AFTER `$after`");
ok("Column <strong>$tbl.$col</strong> added ✓");
} catch (Exception $e) {
err("Column <strong>$tbl.$col</strong>: ".htmlspecialchars($e->getMessage()));
}
}
}
// ── FIX ADMIN email_verified ────────────────────────────────
try {
$n = $pdo->exec("UPDATE users SET email_verified=1 WHERE is_admin=1");
ok("Admin accounts email_verified set to 1 ($n updated)");
} catch (Exception $e) { warn("Admin fix: ".htmlspecialchars($e->getMessage())); }
// ── SUMMARY ─────────────────────────────────────────────────
$tables_now = $pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
info("All tables: <strong>".implode(', ', $tables_now)."</strong>");
try {
$total = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
$admins = $pdo->query("SELECT COUNT(*) FROM users WHERE is_admin=1")->fetchColumn();
info("Users: <strong>$total total</strong>, $admins admin(s)");
} catch (Exception $e) {}
?>
<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>TomTomGames DB Install</title>
<style>
body{font-family:'Segoe UI',sans-serif;background:#0a0a12;color:#e8e8f0;max-width:680px;margin:40px auto;padding:20px}
h1{font-size:20px;margin-bottom:4px;background:linear-gradient(135deg,#f0c040,#00e5ff);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.sub{color:#8888aa;font-size:13px;margin-bottom:24px}
.row{padding:9px 14px;border-radius:7px;margin-bottom:5px;font-size:13px;display:flex;align-items:flex-start;gap:10px}
.ok {background:rgba(0,230,118,.08);border:1px solid rgba(0,230,118,.2)}
.err {background:rgba(255,68,68,.1);border:1px solid rgba(255,68,68,.3);color:#ff9999}
.warn{background:rgba(255,214,10,.07);border:1px solid rgba(255,214,10,.2);color:#ffd60a}
.info{background:rgba(0,229,255,.06);border:1px solid rgba(0,229,255,.15);color:#aaddff}
.ic{flex-shrink:0;font-weight:700}
.next{background:rgba(240,192,64,.07);border:1px solid rgba(240,192,64,.2);border-radius:10px;padding:16px;margin-top:24px}
.next h2{color:#f0c040;font-size:14px;margin-bottom:8px}
.next ol{padding-left:16px;line-height:2;color:#ccccdd;font-size:13px}
.del{background:rgba(255,68,68,.07);border:1px solid rgba(255,68,68,.2);border-radius:7px;padding:10px 14px;margin-top:14px;font-size:12px;color:#ff9999}
</style></head><body>
<h1>🎮 TomTomGames — DB Install / Repair</h1>
<div class="sub">Database: <strong><?= DB_NAME ?></strong></div>
<?php foreach ($log as $e): $ic = $e['t']==='ok'?'✓':($e['t']==='err'?'✗':($e['t']==='warn'?'⚠':'')); ?>
<div class="row <?= $e['t'] ?>"><span class="ic"><?= $ic ?></span><span><?= $e['m'] ?></span></div>
<?php endforeach; ?>
<div class="next"><h2>Next Steps</h2><ol>
<li>All green ✓? Your database is fully set up</li>
<li>Visit <strong>/create_admin.php</strong> to create admin account (if needed)</li>
<li>Visit <strong>https://tomtomgames.com</strong> — app should load normally</li>
<li><strong>Delete install.php</strong> from your server now</li>
</ol></div>
<div class="del">⚠ Delete <code>install.php</code> after use — it exposes DB structure.</div>
</body></html>
-25
View File
@@ -1,25 +0,0 @@
<?php
// Admin only diagnostic - delete after use
$files = [
'../../includes/db.php',
'../../includes/auth.php',
'../api/admin.php',
];
foreach ($files as $f) {
$full = __DIR__ . '/' . $f;
$out = shell_exec("php -l " . escapeshellarg($full) . " 2>&1");
echo $f . ": " . trim($out) . "\n";
}
// Also test DB connection directly
try {
require_once __DIR__ . '/../../includes/config.php';
require_once __DIR__ . '/../../includes/db.php';
$v = db()->query("SELECT COUNT(*) FROM users")->fetchColumn();
echo "\nDB OK — users: $v\n";
$v2 = db()->query("SELECT version FROM app_version ORDER BY id DESC LIMIT 1")->fetchColumn();
echo "App version: $v2\n";
} catch (Throwable $e) {
echo "\nDB ERROR: " . $e->getMessage() . "\n";
echo "File: " . $e->getFile() . " line " . $e->getLine() . "\n";
}
-26
View File
@@ -1,26 +0,0 @@
<?php
require_once __DIR__ . '/../includes/config.php';
require_once __DIR__ . '/../includes/db.php';
header('Content-Type: application/json');
// Test what the referrals API would return for each user
$users = db()->query("SELECT id, username, referral_code FROM users")->fetchAll();
$out = [];
foreach ($users as $u) {
$out[] = [
'id' => $u['id'],
'username' => $u['username'],
'referral_code' => $u['referral_code'],
'referral_url' => 'https://tomtomgames.com/?ref=' . $u['referral_code'],
];
}
// Also check tiers
$tiers = db()->query("SELECT id, name, min_referrals, tokens_per_ref, bonus_tokens, is_active FROM referral_tiers ORDER BY sort_order")->fetchAll();
echo json_encode([
'users' => $out,
'tiers' => $tiers,
'tier_count' => count($tiers),
], JSON_PRETTY_PRINT);
-96
View File
@@ -1,96 +0,0 @@
<?php
require_once '/home/tomtomgames.com/includes/config.php';
require_once '/home/tomtomgames.com/includes/db.php';
// 1. referral_tiers
db()->exec("CREATE TABLE IF NOT EXISTS referral_tiers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
min_referrals INT NOT NULL DEFAULT 1,
tokens_per_ref DECIMAL(10,2) NOT NULL DEFAULT 10,
bonus_tokens DECIMAL(10,2) NOT NULL DEFAULT 0,
description VARCHAR(300),
is_active TINYINT(1) DEFAULT 1,
sort_order INT DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
echo "referral_tiers table OK\n";
// 2. Seed tiers
$count = (int)db()->query("SELECT COUNT(*) FROM referral_tiers")->fetchColumn();
if ($count == 0) {
$seeds = [
['Bronze Referrer', 1, 5, 0, 'Earn 5 tokens for each verified referral', 1, 0],
['Silver Referrer', 5, 8, 25, 'Earn 8 tokens per referral + 25 bonus at 5 referrals', 1, 1],
['Gold Referrer', 10, 10, 100, 'Earn 10 tokens per referral + 100 bonus at 10 referrals', 1, 2],
['Elite Referrer', 25, 15, 250, 'Earn 15 tokens per referral + 250 bonus at 25 referrals', 1, 3],
];
$st = db()->prepare("INSERT INTO referral_tiers (name,min_referrals,tokens_per_ref,bonus_tokens,description,is_active,sort_order) VALUES (?,?,?,?,?,?,?)");
foreach ($seeds as $s) $st->execute($s);
echo "4 tiers seeded\n";
} else {
echo "Tiers already exist: $count\n";
}
// 3. referrals table
db()->exec("CREATE TABLE IF NOT EXISTS referrals (
id INT AUTO_INCREMENT PRIMARY KEY,
referrer_id INT NOT NULL,
referred_id INT NOT NULL UNIQUE,
tier_id INT,
status ENUM('pending','verified','denied','deleted') DEFAULT 'pending',
tokens_awarded DECIMAL(10,2) DEFAULT 0,
admin_id INT,
admin_note VARCHAR(300),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
resolved_at DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
echo "referrals table OK\n";
// 4. referral_social_shares
db()->exec("CREATE TABLE IF NOT EXISTS referral_social_shares (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
platform VARCHAR(50) NOT NULL,
bonus_tokens DECIMAL(10,2) DEFAULT 5,
status ENUM('pending','approved','denied') DEFAULT 'pending',
admin_id INT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
resolved_at DATETIME
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
echo "referral_social_shares table OK\n";
// 5. Add referral_code to users
$cols = array_column(db()->query("SHOW COLUMNS FROM users")->fetchAll(), 'Field');
if (!in_array('referral_code', $cols)) {
db()->exec("ALTER TABLE users ADD COLUMN referral_code VARCHAR(20) UNIQUE");
echo "referral_code column added\n";
}
// 6. Add referred_by to users
if (!in_array('referred_by', $cols)) {
db()->exec("ALTER TABLE users ADD COLUMN referred_by INT DEFAULT NULL");
echo "referred_by column added\n";
}
// 7. Add referred_by to pending_registrations
$pcols = array_column(db()->query("SHOW COLUMNS FROM pending_registrations")->fetchAll(), 'Field');
if (!in_array('referred_by', $pcols)) {
db()->exec("ALTER TABLE pending_registrations ADD COLUMN referred_by INT DEFAULT NULL");
echo "pending_registrations.referred_by added\n";
}
// 8. Generate codes for users missing one
$users = db()->query("SELECT id FROM users WHERE referral_code IS NULL OR referral_code = ''")->fetchAll();
$upd = db()->prepare("UPDATE users SET referral_code=? WHERE id=?");
foreach ($users as $u) {
$code = strtoupper(substr(md5($u['id'].uniqid()), 0, 8));
$upd->execute([$code, $u['id']]);
}
echo count($users) . " users given referral codes\n";
// 9. Show sample
$sample = db()->query("SELECT username, referral_code FROM users LIMIT 5")->fetchAll();
foreach ($sample as $r) echo " " . $r['username'] . ": " . $r['referral_code'] . "\n";
echo "\nDONE\n";
-6
View File
@@ -1,6 +0,0 @@
<?php
echo json_encode([
'php' => PHP_VERSION,
'time' => date('Y-m-d H:i:s'),
'status' => 'ok'
]);
-18
View File
@@ -1,18 +0,0 @@
<?php
// POST test - simulates exactly what the app does
ob_start();
try { require_once __DIR__ . '/../includes/auth.php'; } catch(Throwable $e) { ob_end_clean(); die(json_encode(['boot_error'=>$e->getMessage()])); }
ob_end_clean();
header('Content-Type: application/json');
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$data = json_decode(file_get_contents('php://input'), true);
$result = loginUser($data['username'] ?? '', $data['password'] ?? '');
if ($result['success']) unset($result['user']['password']);
echo json_encode($result);
exit;
}
// GET - show users
$users = db()->query("SELECT id,username,alias,is_admin,email_verified,status FROM users")->fetchAll();
echo json_encode(['users'=>$users,'session_id'=>session_id()]);
-91
View File
@@ -1,91 +0,0 @@
<?php
// Standalone email test - no auth required for diagnosis
// DELETE THIS FILE after confirming email works
$result = [];
$result['php_version'] = PHP_VERSION;
$result['mail_function_exists'] = function_exists('mail');
$result['server_software'] = $_SERVER['SERVER_SOFTWARE'] ?? 'unknown';
$result['hostname'] = gethostname();
// Check sendmail path
$sendmail = ini_get('sendmail_path');
$result['sendmail_path'] = $sendmail ?: 'not set';
// Check if we can detect SMTP settings
$result['smtp_host'] = ini_get('SMTP') ?: 'not set';
$result['smtp_port'] = ini_get('smtp_port') ?: 'not set';
$to = $_POST['to'] ?? '';
$sent = false;
$sendError = '';
if ($to && filter_var($to, FILTER_VALIDATE_EMAIL) && isset($_POST['send'])) {
$subject = 'TomTomGames Email Test';
$message = "This is a test email from TomTomGames.\n\nIf you received this, PHP mail() is working correctly on this server.";
$headers = "From: noreply@tomtomgames.com\r\n";
$headers .= "Reply-To: support@tomtomgames.com\r\n";
$headers .= "X-Mailer: PHP/" . PHP_VERSION;
// Capture any mail errors
set_error_handler(function($errno, $errstr) use (&$sendError) {
$sendError = $errstr;
});
$sent = mail($to, $subject, $message, $headers, '-fnoreply@tomtomgames.com');
restore_error_handler();
$result['mail_return'] = $sent;
$result['mail_error'] = $sendError ?: 'none';
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Email Test</title>
<style>
body{font-family:monospace;background:#0a0a12;color:#e8e8f0;padding:24px;max-width:600px;margin:0 auto}
h2{color:#f0c040}
.box{background:#1a1a2e;border:1px solid #333;border-radius:8px;padding:16px;margin:12px 0}
.ok{color:#00e676}.err{color:#ff4444}.warn{color:#f0c040}
input{background:#111;border:1px solid #444;color:#fff;padding:8px 12px;width:280px;border-radius:6px;font-size:14px}
button{background:#f0c040;color:#000;border:none;padding:10px 20px;border-radius:6px;font-weight:700;cursor:pointer;margin-left:8px}
label{display:block;margin-bottom:6px;color:#aaa;font-size:13px}
</style>
</head>
<body>
<h2>TomTomGames — Email Diagnostics</h2>
<div class="box">
<b>Server Info:</b><br>
PHP: <span class="ok"><?= $result['php_version'] ?></span><br>
Server: <?= htmlspecialchars($result['server_software']) ?><br>
Hostname: <?= htmlspecialchars($result['hostname']) ?><br>
mail() function: <span class="<?= $result['mail_function_exists'] ? 'ok' : 'err' ?>"><?= $result['mail_function_exists'] ? 'EXISTS' : 'MISSING' ?></span><br>
sendmail_path: <span class="warn"><?= htmlspecialchars($result['sendmail_path']) ?></span><br>
SMTP: <span class="warn"><?= htmlspecialchars($result['smtp_host']) ?>:<?= htmlspecialchars($result['smtp_port']) ?></span>
</div>
<?php if ($to): ?>
<div class="box">
<b>Send Result:</b><br>
To: <?= htmlspecialchars($to) ?><br>
mail() returned: <span class="<?= $sent ? 'ok' : 'err' ?>"><?= $sent ? 'TRUE (queued for delivery)' : 'FALSE (failed)' ?></span><br>
Error: <span class="warn"><?= htmlspecialchars($result['mail_error']) ?></span><br>
<?php if ($sent): ?>
<br><span class="ok">Check your inbox (and spam folder). If nothing arrives in 5 minutes, the server is not sending outbound mail.</span>
<?php else: ?>
<br><span class="err">mail() returned false — server cannot send email. You need to configure SMTP (PHPMailer) or enable sendmail.</span>
<?php endif; ?>
</div>
<?php endif; ?>
<div class="box">
<form method="POST">
<label>Send test email to:</label>
<input type="email" name="to" value="<?= htmlspecialchars($to) ?>" placeholder="your@email.com" required>
<button type="submit" name="send" value="1">Send Test</button>
</form>
</div>
<p style="color:#555;font-size:11px">Delete test_mail.php after diagnosis is complete.</p>
</body>
</html>