v1.0.4 - Clean start

This commit is contained in:
2026-05-15 16:46:08 -05:00
parent 28d2f8102d
commit 500a0219b8
17 changed files with 846 additions and 934 deletions
+59 -3
View File
@@ -310,14 +310,16 @@ switch ($action) {
$stmt->execute([$uid]);
$current = $stmt->fetchColumn();
$new_val = $current ? 0 : 1;
// If granting admin, also set email_verified=1
if ($new_val) {
db()->prepare("UPDATE users SET is_admin=1, email_verified=1 WHERE id=?")->execute([$uid]);
} else {
db()->prepare("UPDATE users SET is_admin=0 WHERE id=?")->execute([$uid]);
}
logActivity($new_val?'admin_granted':'admin_revoked', $uid, (int)$_SESSION['user_id'], 'user', $uid, 'Admin status changed to '.($new_val?'admin':'player'));
echo json_encode(['success'=>true, 'is_admin'=>$new_val]);
// Force the affected user to re-login by invalidating their sessions
// Store a flag in DB that forces re-auth on next request
db()->prepare("UPDATE users SET last_login=last_login WHERE id=?")->execute([$uid]);
logActivity($new_val?'admin_granted':'admin_revoked', $uid, (int)$_SESSION['user_id'], 'user', $uid, 'Admin status changed to '.($new_val?'admin':'player'), '', 'admin', '', '', 'warning');
echo json_encode(['success'=>true, 'is_admin'=>$new_val, 'needs_relogin'=>true, 'message'=>$new_val ? 'Admin access granted. User must log out and back in.' : 'Admin access removed. User must log out and back in.']);
break;
// ─── TOGGLE SUSPEND ───────────────────────────────────────
@@ -439,6 +441,24 @@ switch ($action) {
echo json_encode(['success'=>true,'broadcasts'=>$rows]);
break;
case 'broadcast_list':
try {
$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";
$stmt = db()->query($sql);
echo json_encode(['success'=>true,'broadcasts'=>$stmt->fetchAll()]);
} catch(Exception $e) {
echo json_encode(['success'=>false,'error'=>$e->getMessage()]);
}
break;
case 'broadcast_send':
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; }
$d = json_decode(file_get_contents('php://input'), true);
@@ -468,6 +488,42 @@ switch ($action) {
echo json_encode(['success'=>true]);
break;
case 'broadcast_edit':
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$id = (int)($d['id'] ?? 0);
$subject = substr(trim($d['subject'] ?? ''), 0, 200);
$message = trim($d['message'] ?? '');
$target = in_array($d['target']??'', ['all','verified','unverified','admins']) ? $d['target'] : 'all';
if (!$id || !$subject || !$message) { echo json_encode(['success'=>false,'error'=>'Missing fields']); exit; }
db()->prepare("UPDATE broadcasts SET subject=?, message=?, target=? WHERE id=?")->execute([$subject, $message, $target, $id]);
logAdminAction('BROADCAST_EDITED', $adminId, 'broadcast', $id, 'Edited broadcast #'.$id, '', '', 'info');
echo json_encode(['success'=>true]);
break;
case 'broadcast_resend':
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { echo json_encode(['success'=>false]); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$id = (int)($d['id'] ?? 0);
if (!$id) { echo json_encode(['success'=>false,'error'=>'Missing ID']); exit; }
$bc = db()->prepare("SELECT * FROM broadcasts WHERE id=?");
$bc->execute([$id]);
$orig = $bc->fetch();
if (!$orig) { echo json_encode(['success'=>false,'error'=>'Broadcast not found']); exit; }
// Count recipients
$target = $orig['target'];
$countSql = "SELECT COUNT(*) FROM users WHERE status='active' AND is_admin=0";
if ($target === 'verified') $countSql .= " AND email_verified=1";
if ($target === 'unverified') $countSql .= " AND email_verified=0";
$recipientCount = (int)db()->query($countSql)->fetchColumn();
// Delete old reads so everyone sees it again
db()->prepare("DELETE FROM broadcast_reads WHERE broadcast_id=?")->execute([$id]);
// Update sent_at to now
db()->prepare("UPDATE broadcasts SET sent_at=NOW() WHERE id=?")->execute([$id]);
logAdminAction('BROADCAST_RESENT', $adminId, 'broadcast', $id, 'Resent broadcast #'.$id.' to '.$recipientCount.' players', '', '', 'info');
echo json_encode(['success'=>true,'recipient_count'=>$recipientCount]);
break;
case 'broadcast_reads':
$bid = (int)($_GET['broadcast_id']??0);
$rows = db()->prepare("SELECT br.read_at, u.username, u.alias FROM broadcast_reads br JOIN users u ON br.user_id=u.id WHERE br.broadcast_id=? ORDER BY br.read_at ASC");
+4 -1
View File
@@ -1,5 +1,5 @@
<?php
ob_start(); // Buffer any accidental output (PHP errors, notices, etc.)
ob_start();
try {
require_once __DIR__ . '/../../includes/auth.php';
} catch (Throwable $e) {
@@ -28,5 +28,8 @@ if (!$user) {
exit;
}
// Sync session is_admin with DB value — catches admin elevation/demotion
$_SESSION['is_admin'] = (int)$user['is_admin'];
unset($user['password']);
echo json_encode(['success' => true, 'user' => $user]);
+9 -2
View File
@@ -20,6 +20,13 @@ if ($method === 'GET') {
$user->execute([$userId]);
$u = $user->fetch();
// Auto-generate code if missing
if (empty($u['referral_code'])) {
$code = strtoupper(substr(md5($userId.uniqid()),0,8));
db()->prepare("UPDATE users SET referral_code=? WHERE id=?")->execute([$code, $userId]);
$u['referral_code'] = $code;
}
// Count verified referrals
$countStmt = db()->prepare("SELECT COUNT(*) FROM referrals WHERE referrer_id=? AND status='verified'");
$countStmt->execute([$userId]);
@@ -175,7 +182,7 @@ if ($action === 'resolve_referral') {
db()->prepare("UPDATE referrals SET status='verified', tier_id=?, tokens_awarded=?, admin_id=?, admin_note=?, resolved_at=NOW() WHERE id=?")
->execute([$tier['id'] ?? null, $totalAward, (int)$_SESSION['user_id'], $note, $id]);
db()->prepare("UPDATE users SET tokens=tokens+? WHERE id=?")->execute([$totalAward, $ref['referrer_id']]);
logAdminAction('REFERRAL_VERIFIED', (int)\$_SESSION['user_id'], 'referral', \$id, 'Verified referral #'.\$id.' — awarded '.\$totalAward.' tokens to user #'.\$ref['referrer_id'], 'pending', 'verified', 'info');
logAdminAction('REFERRAL_VERIFIED', (int)$_SESSION['user_id'], 'referral', $id, 'Verified referral #'.$id.' — awarded '.$totalAward.' tokens to user #'.$ref['referrer_id'], 'pending', 'verified', 'info');
db()->commit();
echo json_encode(['success'=>true,'tokens_awarded'=>$totalAward,'bonus'=>$bonusTokens,'tier'=>$tier['name']??'']);
} catch(Exception $e) {
@@ -199,7 +206,7 @@ if ($action === 'resolve_share') {
db()->prepare("UPDATE referral_social_shares SET status=?,admin_id=?,resolved_at=NOW() WHERE id=?")->execute([$status,(int)$_SESSION['user_id'],$id]);
if ($status === 'approved') {
db()->prepare("UPDATE users SET tokens=tokens+? WHERE id=?")->execute([$share['bonus_tokens'],$share['user_id']]);
logAdminAction('SOCIAL_SHARE_APPROVED', (int)\$_SESSION['user_id'], 'referral_share', \$id, 'Approved social share #'.\$id.' — awarded '.\$share['bonus_tokens'].' bonus tokens to user #'.\$share['user_id'], '', 'approved', 'info');
logAdminAction('SOCIAL_SHARE_APPROVED', (int)$_SESSION['user_id'], 'referral_share', $id, 'Approved social share #'.$id.' — awarded '.$share['bonus_tokens'].' bonus tokens to user #'.$share['user_id'], '', 'approved', 'info');
}
echo json_encode(['success'=>true]);
exit;