Add password reset feature and server management pages
Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com>
This commit is contained in:
parent
0a573145d3
commit
5f93c6728e
14 changed files with 1580 additions and 5 deletions
286
_website/forgot_password.php
Normal file
286
_website/forgot_password.php
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
<?php
|
||||
// Start a separate session for the website
|
||||
session_name("gameservers_website");
|
||||
session_start();
|
||||
|
||||
// Include database configuration
|
||||
require_once(__DIR__ . '/includes/config.inc.php');
|
||||
|
||||
// Create database connection
|
||||
$db = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
|
||||
if (!$db) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Logger function
|
||||
function logger($logtext){
|
||||
file_put_contents(__DIR__ . "/logfile.txt", $logtext . PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$error = '';
|
||||
|
||||
// Process password reset request
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['request_reset'])) {
|
||||
$identifier = trim($_POST['identifier'] ?? '');
|
||||
|
||||
if (empty($identifier)) {
|
||||
$error = 'Please enter your username or email address.';
|
||||
} else {
|
||||
// Sanitize input
|
||||
$identifier = mysqli_real_escape_string($db, $identifier);
|
||||
|
||||
// Check if it's an email or username
|
||||
$query = "SELECT user_id, users_login, users_email FROM ogp_users
|
||||
WHERE users_login = '$identifier' OR users_email = '$identifier' LIMIT 1";
|
||||
$result = mysqli_query($db, $query);
|
||||
|
||||
if ($result && mysqli_num_rows($result) === 1) {
|
||||
$user = mysqli_fetch_assoc($result);
|
||||
|
||||
// Generate reset token
|
||||
$token = bin2hex(random_bytes(32));
|
||||
$expires = date('Y-m-d H:i:s', strtotime('+1 hour'));
|
||||
|
||||
// Check if password_reset_tokens table exists
|
||||
$table_check = mysqli_query($db, "SHOW TABLES LIKE 'ogp_password_reset_tokens'");
|
||||
if (!$table_check || mysqli_num_rows($table_check) === 0) {
|
||||
// Create table if it doesn't exist
|
||||
$create_table = "CREATE TABLE IF NOT EXISTS ogp_password_reset_tokens (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
token VARCHAR(64) NOT NULL,
|
||||
expires DATETIME NOT NULL,
|
||||
used TINYINT(1) DEFAULT 0,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_token (token),
|
||||
INDEX idx_user_id (user_id)
|
||||
)";
|
||||
mysqli_query($db, $create_table);
|
||||
}
|
||||
|
||||
// Delete any existing tokens for this user
|
||||
$stmt = $db->prepare("DELETE FROM ogp_password_reset_tokens WHERE user_id = ?");
|
||||
$stmt->bind_param('i', $user['user_id']);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
// Insert new token
|
||||
$stmt = $db->prepare("INSERT INTO ogp_password_reset_tokens (user_id, token, expires) VALUES (?, ?, ?)");
|
||||
$stmt->bind_param('iss', $user['user_id'], $token, $expires);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
// Build reset link
|
||||
$reset_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
|
||||
. "://{$_SERVER['HTTP_HOST']}"
|
||||
. dirname($_SERVER['SCRIPT_NAME'])
|
||||
. "/reset_password.php?token=" . urlencode($token);
|
||||
|
||||
// Send email (for now, just show the link - actual email sending requires mail configuration)
|
||||
$email_body = "Hello {$user['users_login']},\n\n"
|
||||
. "You requested a password reset. Click the link below to reset your password:\n\n"
|
||||
. "{$reset_link}\n\n"
|
||||
. "This link will expire in 1 hour.\n\n"
|
||||
. "If you did not request this reset, please ignore this email.";
|
||||
|
||||
// Attempt to send email
|
||||
$headers = "From: noreply@" . $_SERVER['HTTP_HOST'] . "\r\n"
|
||||
. "Reply-To: noreply@" . $_SERVER['HTTP_HOST'] . "\r\n"
|
||||
. "X-Mailer: PHP/" . phpversion();
|
||||
|
||||
$email_sent = @mail($user['users_email'], "Password Reset Request", $email_body, $headers);
|
||||
|
||||
logger("Password reset requested for user: {$user['users_login']} (email sent: " . ($email_sent ? 'yes' : 'no') . ")");
|
||||
|
||||
if ($email_sent) {
|
||||
$message = "Password reset instructions have been sent to your email address.";
|
||||
} else {
|
||||
// If email fails, show the link directly (development mode)
|
||||
$message = "Password reset link generated. In production, this would be emailed to you.<br><br>"
|
||||
. "For testing, use this link: <a href='$reset_link'>Reset Password</a>";
|
||||
}
|
||||
} else {
|
||||
// For security, don't reveal if user exists or not
|
||||
$message = "If an account exists with that username or email, password reset instructions have been sent.";
|
||||
logger("Password reset requested for unknown identifier: $identifier");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close database connection
|
||||
mysqli_close($db);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Forgot Password - GameServers.World</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
min-height: calc(100vh - 140px);
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
.reset-container {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.reset-header {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.reset-header h1 {
|
||||
font-size: 1.8rem;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.reset-header p {
|
||||
color: #666;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-group input {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border: 2px solid #e1e8ed;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.form-group input:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.btn-submit:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.btn-submit:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background-color: #fee;
|
||||
border: 1px solid #fcc;
|
||||
color: #c33;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: #efe;
|
||||
border: 1px solid #cfc;
|
||||
color: #3c3;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php include(__DIR__ . '/includes/top.php'); ?>
|
||||
<?php include(__DIR__ . '/includes/menu.php'); ?>
|
||||
<div class="content">
|
||||
<div class="reset-container">
|
||||
<div class="reset-header">
|
||||
<h1>Forgot Password</h1>
|
||||
<p>Enter your username or email to reset your password</p>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-error"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($message)): ?>
|
||||
<div class="alert alert-success"><?php echo $message; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="POST" action="forgot_password.php">
|
||||
<div class="form-group">
|
||||
<label for="identifier">Username or Email</label>
|
||||
<input type="text" id="identifier" name="identifier" required autofocus>
|
||||
</div>
|
||||
|
||||
<button type="submit" name="request_reset" class="btn-submit">Request Password Reset</button>
|
||||
</form>
|
||||
|
||||
<div class="footer-links">
|
||||
<a href="login.php">Back to Login</a> |
|
||||
<a href="index.php">Home</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<?php include(__DIR__ . '/includes/footer.php'); ?>
|
||||
</html>
|
||||
|
|
@ -3,6 +3,6 @@
|
|||
?>
|
||||
<footer class="gsw-footer">
|
||||
<div class="container-wide">
|
||||
<a href="privacy.php">Privacy</a> | <a href="tos.php">TOS</a> | <a href="https://worlddomination.dev" target="_blank" rel="noopener">Worlddomination.dev</a>
|
||||
<a href="privacy.php">Privacy</a> | <a href="tos.php">TOS</a> | <a href="server_status.php">Server Status</a> | <a href="https://worlddomination.dev" target="_blank" rel="noopener">Worlddomination.dev</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
|
|
|||
|
|
@ -51,6 +51,9 @@ if ($is_logged_in) {
|
|||
<nav class="gsw-header-nav">
|
||||
<a href="index.php" class="gsw-nav-link">Home</a>
|
||||
<a href="serverlist.php" class="gsw-nav-link">Game Servers</a>
|
||||
<?php if ($is_logged_in): ?>
|
||||
<a href="my_servers.php" class="gsw-nav-link">My Servers</a>
|
||||
<?php endif; ?>
|
||||
<li>
|
||||
<a href="cart.php">Cart
|
||||
<?php
|
||||
|
|
|
|||
|
|
@ -338,7 +338,8 @@ mysqli_close($db);
|
|||
<button type="submit" name="login" class="btn-login">Sign In</button>
|
||||
</form>
|
||||
<div class="center mt-12">
|
||||
<a href="register.php">Register</a>
|
||||
<a href="register.php">Register</a> |
|
||||
<a href="forgot_password.php">Forgot Password?</a>
|
||||
</div>
|
||||
|
||||
<div class="divider">or</div>
|
||||
|
|
|
|||
138
_website/my_servers.php
Normal file
138
_website/my_servers.php
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>My Servers - GameServers.World</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
// Require login for this page
|
||||
require_once(__DIR__ . '/includes/login_required.php');
|
||||
|
||||
// Include database configuration
|
||||
require_once(__DIR__ . '/includes/config.inc.php');
|
||||
|
||||
// Create database connection
|
||||
$db = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
|
||||
if (!$db) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Include top bar and menu
|
||||
include(__DIR__ . '/includes/top.php');
|
||||
include(__DIR__ . '/includes/menu.php');
|
||||
|
||||
// Get user ID from session
|
||||
$user_id = intval($_SESSION['website_user_id']);
|
||||
|
||||
// Fetch user's active servers
|
||||
// We'll look for homes assigned to this user
|
||||
// The relationship is: ogp_billing_orders -> user_id and contains home_id references
|
||||
// We need to join with ogp_home to get server details
|
||||
|
||||
$query = "SELECT
|
||||
h.home_id,
|
||||
h.home_name,
|
||||
h.enabled,
|
||||
rs.remote_server_name,
|
||||
gc.game_name,
|
||||
o.order_id,
|
||||
o.status,
|
||||
o.created_at,
|
||||
o.invoice_duration,
|
||||
DATE_ADD(o.created_at, INTERVAL
|
||||
CASE
|
||||
WHEN o.invoice_duration = 'month' THEN 30
|
||||
WHEN o.invoice_duration = 'year' THEN 365
|
||||
ELSE 30
|
||||
END DAY
|
||||
) as expiration_date,
|
||||
bs.service_name,
|
||||
bs.price_monthly
|
||||
FROM ogp_home h
|
||||
LEFT JOIN ogp_remote_servers rs ON h.remote_server_id = rs.remote_server_id
|
||||
LEFT JOIN ogp_game_configs gc ON h.home_cfg_id = gc.home_cfg_id
|
||||
LEFT JOIN ogp_billing_orders o ON h.user_id = o.user_id
|
||||
LEFT JOIN ogp_billing_services bs ON o.service_id = bs.service_id
|
||||
WHERE h.user_id = $user_id
|
||||
ORDER BY h.home_id DESC";
|
||||
|
||||
$result = mysqli_query($db, $query);
|
||||
|
||||
?>
|
||||
|
||||
<div class="site-panel">
|
||||
<div class="site-panel-title">My Game Servers</div>
|
||||
|
||||
<?php if ($result && mysqli_num_rows($result) > 0): ?>
|
||||
<table class="cart-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Server Name</th>
|
||||
<th>Game</th>
|
||||
<th>Location</th>
|
||||
<th>Status</th>
|
||||
<th>Expiration Date</th>
|
||||
<th>Monthly Price</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($server = mysqli_fetch_assoc($result)): ?>
|
||||
<?php
|
||||
$is_active = $server['enabled'] == 1;
|
||||
$is_expired = strtotime($server['expiration_date']) < time();
|
||||
$status_class = $is_active ? 'text-success' : 'text-danger';
|
||||
$status_text = $is_active ? 'Active' : 'Inactive';
|
||||
|
||||
if ($is_expired) {
|
||||
$status_text = 'Expired';
|
||||
$status_class = 'text-danger';
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($server['home_name'] ?? 'Unknown'); ?></td>
|
||||
<td><?php echo htmlspecialchars($server['game_name'] ?? $server['service_name'] ?? 'Unknown'); ?></td>
|
||||
<td><?php echo htmlspecialchars($server['remote_server_name'] ?? 'Unknown'); ?></td>
|
||||
<td class="<?php echo $status_class; ?>"><?php echo $status_text; ?></td>
|
||||
<td><?php echo $server['expiration_date'] ? date('M d, Y', strtotime($server['expiration_date'])) : 'N/A'; ?></td>
|
||||
<td><?php echo $server['price_monthly'] ? '$' . number_format($server['price_monthly'], 2) : 'N/A'; ?></td>
|
||||
<td>
|
||||
<?php if ($server['order_id']): ?>
|
||||
<a href="renew_server.php?order_id=<?php echo urlencode($server['order_id']); ?>" class="btn-primary" style="padding:8px 16px;text-decoration:none;display:inline-block;border-radius:6px;">Renew</a>
|
||||
<?php else: ?>
|
||||
<span class="muted">N/A</span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="panel" style="text-align:center;padding:40px;">
|
||||
<p style="font-size:1.2rem;margin-bottom:20px;">You don't have any game servers yet.</p>
|
||||
<a href="serverlist.php" class="btn-primary" style="padding:12px 24px;text-decoration:none;display:inline-block;border-radius:8px;">Browse Game Servers</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// Close database connection
|
||||
mysqli_close($db);
|
||||
?>
|
||||
|
||||
<style>
|
||||
.text-success {
|
||||
color: #10b981;
|
||||
font-weight: 600;
|
||||
}
|
||||
.text-danger {
|
||||
color: #ef4444;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
</body>
|
||||
<?php include(__DIR__ . '/includes/footer.php'); ?>
|
||||
</html>
|
||||
|
|
@ -99,7 +99,7 @@ THIS IS WHAT WE DISPLAY ON THE SHOP PAGE AT THE TOP
|
|||
|
||||
|
||||
|
||||
<img src="<?php echo $row['img_url'] ;?>" width="460" height="225" >
|
||||
<img src="../<?php echo $row['img_url'];?>" width="460" height="225" >
|
||||
<br>
|
||||
<?php echo $row['service_name'];?>
|
||||
<br>
|
||||
|
|
@ -136,7 +136,7 @@ if ($row['price_monthly'] == 0.0) {
|
|||
?>
|
||||
<div class="float-left decorative-bottom">
|
||||
|
||||
<img src="<?php echo $row['img_url'];?>" width=230 height=112 border=0 ">
|
||||
<img src="../<?php echo $row['img_url'];?>" width=230 height=112 border=0 ">
|
||||
<center><b> <?php echo $row['service_name'];?></b></center>
|
||||
<?php
|
||||
|
||||
|
|
|
|||
129
_website/renew_server.php
Normal file
129
_website/renew_server.php
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Renew Server - GameServers.World</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
// Require login for this page
|
||||
require_once(__DIR__ . '/includes/login_required.php');
|
||||
|
||||
// Include database configuration
|
||||
require_once(__DIR__ . '/includes/config.inc.php');
|
||||
|
||||
// Create database connection
|
||||
$db = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
|
||||
if (!$db) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Include top bar and menu
|
||||
include(__DIR__ . '/includes/top.php');
|
||||
include(__DIR__ . '/includes/menu.php');
|
||||
|
||||
// Get order ID from URL
|
||||
$order_id = isset($_GET['order_id']) ? intval($_GET['order_id']) : 0;
|
||||
$user_id = intval($_SESSION['website_user_id']);
|
||||
|
||||
if ($order_id === 0) {
|
||||
echo '<div class="site-panel"><p class="text-danger">Invalid order ID.</p></div>';
|
||||
include(__DIR__ . '/includes/footer.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch order details
|
||||
$query = "SELECT o.*, bs.service_name, bs.price_monthly, bs.price_year
|
||||
FROM ogp_billing_orders o
|
||||
LEFT JOIN ogp_billing_services bs ON o.service_id = bs.service_id
|
||||
WHERE o.order_id = $order_id AND o.user_id = $user_id
|
||||
LIMIT 1";
|
||||
$result = mysqli_query($db, $query);
|
||||
|
||||
if (!$result || mysqli_num_rows($result) === 0) {
|
||||
echo '<div class="site-panel"><p class="text-danger">Order not found or you do not have permission to renew this server.</p></div>';
|
||||
mysqli_close($db);
|
||||
include(__DIR__ . '/includes/footer.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$order = mysqli_fetch_assoc($result);
|
||||
|
||||
// Process renewal
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['confirm_renewal'])) {
|
||||
$duration = isset($_POST['duration']) ? $_POST['duration'] : 'month';
|
||||
$price = ($duration === 'year') ? $order['price_year'] : $order['price_monthly'];
|
||||
|
||||
// Create a new order for renewal
|
||||
// In a real system, this would redirect to payment gateway
|
||||
// For now, we'll just show a message
|
||||
|
||||
$message = "Renewal initiated for " . htmlspecialchars($order['service_name']) . ". ";
|
||||
$message .= "Duration: " . ($duration === 'year' ? '1 year' : '1 month') . ". ";
|
||||
$message .= "Total: $" . number_format($price, 2) . ". ";
|
||||
$message .= "In a production system, you would be redirected to payment processing.";
|
||||
|
||||
echo '<div class="site-panel"><div class="alert alert-success">' . $message . '</div></div>';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="site-panel">
|
||||
<div class="site-panel-title">Renew Server</div>
|
||||
|
||||
<div class="panel" style="max-width:600px;margin:20px auto;">
|
||||
<h3 style="margin-bottom:20px;"><?php echo htmlspecialchars($order['service_name']); ?></h3>
|
||||
|
||||
<form method="POST" action="">
|
||||
<div class="form-group" style="margin-bottom:20px;">
|
||||
<label style="display:block;margin-bottom:10px;">
|
||||
<input type="radio" name="duration" value="month" checked>
|
||||
1 Month - $<?php echo number_format($order['price_monthly'], 2); ?>
|
||||
</label>
|
||||
<?php if ($order['price_year'] > 0): ?>
|
||||
<label style="display:block;">
|
||||
<input type="radio" name="duration" value="year">
|
||||
1 Year - $<?php echo number_format($order['price_year'], 2); ?>
|
||||
</label>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<button type="submit" name="confirm_renewal" class="btn-primary" style="padding:12px 24px;border-radius:8px;">
|
||||
Proceed to Payment
|
||||
</button>
|
||||
|
||||
<a href="my_servers.php" style="margin-left:20px;color:#667eea;">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// Close database connection
|
||||
mysqli_close($db);
|
||||
?>
|
||||
|
||||
<style>
|
||||
.alert-success {
|
||||
background-color: #d1fae5;
|
||||
border: 1px solid #6ee7b7;
|
||||
color: #065f46;
|
||||
padding: 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.form-group label {
|
||||
cursor: pointer;
|
||||
padding: 12px;
|
||||
border: 2px solid #e1e8ed;
|
||||
border-radius: 8px;
|
||||
background: rgba(255,255,255,0.05);
|
||||
}
|
||||
.form-group label:hover {
|
||||
background: rgba(255,255,255,0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
</body>
|
||||
<?php include(__DIR__ . '/includes/footer.php'); ?>
|
||||
</html>
|
||||
296
_website/reset_password.php
Normal file
296
_website/reset_password.php
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
<?php
|
||||
// Start a separate session for the website
|
||||
session_name("gameservers_website");
|
||||
session_start();
|
||||
|
||||
// Include database configuration
|
||||
require_once(__DIR__ . '/includes/config.inc.php');
|
||||
|
||||
// Create database connection
|
||||
$db = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
|
||||
if (!$db) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Logger function
|
||||
function logger($logtext){
|
||||
file_put_contents(__DIR__ . "/logfile.txt", $logtext . PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$error = '';
|
||||
$token_valid = false;
|
||||
$user_id = null;
|
||||
|
||||
// Get token from URL
|
||||
$token = isset($_GET['token']) ? trim($_GET['token']) : '';
|
||||
|
||||
if (empty($token)) {
|
||||
$error = 'Invalid or missing reset token.';
|
||||
} else {
|
||||
// Sanitize token
|
||||
$token = mysqli_real_escape_string($db, $token);
|
||||
|
||||
// Verify token
|
||||
$query = "SELECT user_id, expires, used FROM ogp_password_reset_tokens
|
||||
WHERE token = '$token' LIMIT 1";
|
||||
$result = mysqli_query($db, $query);
|
||||
|
||||
if ($result && mysqli_num_rows($result) === 1) {
|
||||
$token_data = mysqli_fetch_assoc($result);
|
||||
|
||||
// Check if token is expired or used
|
||||
if ($token_data['used'] == 1) {
|
||||
$error = 'This password reset link has already been used.';
|
||||
} elseif (strtotime($token_data['expires']) < time()) {
|
||||
$error = 'This password reset link has expired. Please request a new one.';
|
||||
} else {
|
||||
$token_valid = true;
|
||||
$user_id = $token_data['user_id'];
|
||||
}
|
||||
} else {
|
||||
$error = 'Invalid password reset token.';
|
||||
}
|
||||
}
|
||||
|
||||
// Process password reset
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['reset_password']) && $token_valid) {
|
||||
$new_password = $_POST['new_password'] ?? '';
|
||||
$confirm_password = $_POST['confirm_password'] ?? '';
|
||||
|
||||
if (empty($new_password) || empty($confirm_password)) {
|
||||
$error = 'Please enter and confirm your new password.';
|
||||
} elseif ($new_password !== $confirm_password) {
|
||||
$error = 'Passwords do not match.';
|
||||
} elseif (strlen($new_password) < 8) {
|
||||
$error = 'Password must be at least 8 characters long.';
|
||||
} else {
|
||||
// Hash the password (MD5 for panel compatibility, with modern hash shadow if column exists)
|
||||
$md5_password = md5($new_password);
|
||||
|
||||
// Check if shadow column exists
|
||||
$has_shadow = false;
|
||||
$res_cols = mysqli_query($db, "SHOW COLUMNS FROM ogp_users LIKE 'users_pass_hash'");
|
||||
if ($res_cols && mysqli_num_rows($res_cols) > 0) {
|
||||
$has_shadow = true;
|
||||
}
|
||||
|
||||
// Update password
|
||||
if ($has_shadow) {
|
||||
$modern_hash = password_hash($new_password, PASSWORD_DEFAULT);
|
||||
$stmt = $db->prepare("UPDATE ogp_users SET users_passwd = ?, users_pass_hash = ? WHERE user_id = ?");
|
||||
$stmt->bind_param('ssi', $md5_password, $modern_hash, $user_id);
|
||||
} else {
|
||||
$stmt = $db->prepare("UPDATE ogp_users SET users_passwd = ? WHERE user_id = ?");
|
||||
$stmt->bind_param('si', $md5_password, $user_id);
|
||||
}
|
||||
|
||||
if ($stmt->execute()) {
|
||||
// Mark token as used
|
||||
$stmt2 = $db->prepare("UPDATE ogp_password_reset_tokens SET used = 1 WHERE token = ?");
|
||||
$stmt2->bind_param('s', $token);
|
||||
$stmt2->execute();
|
||||
$stmt2->close();
|
||||
|
||||
logger("Password reset completed for user_id: $user_id");
|
||||
|
||||
$message = 'Password has been reset successfully. You can now login with your new password.';
|
||||
$token_valid = false; // Prevent form from showing again
|
||||
} else {
|
||||
$error = 'Failed to reset password. Please try again.';
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
|
||||
// Close database connection
|
||||
mysqli_close($db);
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Reset Password - GameServers.World</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
min-height: calc(100vh - 140px);
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
.reset-container {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
padding: 40px;
|
||||
}
|
||||
|
||||
.reset-header {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.reset-header h1 {
|
||||
font-size: 1.8rem;
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.reset-header p {
|
||||
color: #666;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.form-group input {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border: 2px solid #e1e8ed;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
transition: border-color 0.3s;
|
||||
}
|
||||
|
||||
.form-group input:focus {
|
||||
outline: none;
|
||||
border-color: #667eea;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.btn-submit:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
|
||||
}
|
||||
|
||||
.btn-submit:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background-color: #fee;
|
||||
border: 1px solid #fcc;
|
||||
color: #c33;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background-color: #efe;
|
||||
border: 1px solid #cfc;
|
||||
color: #3c3;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.password-requirements {
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php include(__DIR__ . '/includes/top.php'); ?>
|
||||
<?php include(__DIR__ . '/includes/menu.php'); ?>
|
||||
<div class="content">
|
||||
<div class="reset-container">
|
||||
<div class="reset-header">
|
||||
<h1>Reset Password</h1>
|
||||
<p>Enter your new password</p>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($error)): ?>
|
||||
<div class="alert alert-error"><?php echo htmlspecialchars($error); ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($message)): ?>
|
||||
<div class="alert alert-success"><?php echo $message; ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($token_valid): ?>
|
||||
<form method="POST" action="reset_password.php?token=<?php echo urlencode($token); ?>">
|
||||
<div class="form-group">
|
||||
<label for="new_password">New Password</label>
|
||||
<input type="password" id="new_password" name="new_password" required autofocus>
|
||||
<div class="password-requirements">Must be at least 8 characters long</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="confirm_password">Confirm Password</label>
|
||||
<input type="password" id="confirm_password" name="confirm_password" required>
|
||||
</div>
|
||||
|
||||
<button type="submit" name="reset_password" class="btn-submit">Reset Password</button>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="footer-links">
|
||||
<a href="login.php">Back to Login</a> |
|
||||
<a href="index.php">Home</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<?php include(__DIR__ . '/includes/footer.php'); ?>
|
||||
</html>
|
||||
204
_website/server_status.php
Normal file
204
_website/server_status.php
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Server Status - GameServers.World</title>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
// Include database configuration
|
||||
require_once(__DIR__ . '/includes/config.inc.php');
|
||||
|
||||
// Create database connection
|
||||
$db = mysqli_connect($db_host, $db_user, $db_pass, $db_name);
|
||||
if (!$db) {
|
||||
die("Connection failed: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Include top bar and menu
|
||||
include(__DIR__ . '/includes/top.php');
|
||||
include(__DIR__ . '/includes/menu.php');
|
||||
|
||||
// Check if server status table exists, if not create it
|
||||
$table_check = mysqli_query($db, "SHOW TABLES LIKE 'ogp_server_status'");
|
||||
if (!$table_check || mysqli_num_rows($table_check) === 0) {
|
||||
// Create table for server status updates
|
||||
$create_table = "CREATE TABLE IF NOT EXISTS ogp_server_status (
|
||||
status_id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
remote_server_id INT NOT NULL,
|
||||
server_name VARCHAR(255) NOT NULL,
|
||||
ip_address VARCHAR(45),
|
||||
status ENUM('online', 'offline', 'maintenance') DEFAULT 'offline',
|
||||
cpu_usage DECIMAL(5,2),
|
||||
memory_usage DECIMAL(5,2),
|
||||
disk_usage DECIMAL(5,2),
|
||||
uptime VARCHAR(50),
|
||||
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
notes TEXT,
|
||||
INDEX idx_remote_server (remote_server_id),
|
||||
UNIQUE KEY unique_server (remote_server_id)
|
||||
)";
|
||||
mysqli_query($db, $create_table);
|
||||
}
|
||||
|
||||
// Fetch all remote servers and their status
|
||||
$query = "SELECT
|
||||
rs.remote_server_id,
|
||||
rs.remote_server_name,
|
||||
rs.agent_ip,
|
||||
rs.enabled,
|
||||
ss.status,
|
||||
ss.cpu_usage,
|
||||
ss.memory_usage,
|
||||
ss.disk_usage,
|
||||
ss.uptime,
|
||||
ss.last_updated,
|
||||
ss.notes
|
||||
FROM ogp_remote_servers rs
|
||||
LEFT JOIN ogp_server_status ss ON rs.remote_server_id = ss.remote_server_id
|
||||
ORDER BY rs.remote_server_name";
|
||||
|
||||
$result = mysqli_query($db, $query);
|
||||
|
||||
?>
|
||||
|
||||
<div class="site-panel">
|
||||
<div class="site-panel-title">Server Status</div>
|
||||
|
||||
<div style="margin-bottom:20px;text-align:center;">
|
||||
<p style="color:rgba(255,255,255,0.7);">Real-time status of our game server infrastructure</p>
|
||||
</div>
|
||||
|
||||
<?php if ($result && mysqli_num_rows($result) > 0): ?>
|
||||
<table class="cart-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Server Name</th>
|
||||
<th>Location/IP</th>
|
||||
<th>Status</th>
|
||||
<th>CPU Usage</th>
|
||||
<th>Memory Usage</th>
|
||||
<th>Disk Usage</th>
|
||||
<th>Uptime</th>
|
||||
<th>Last Updated</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($server = mysqli_fetch_assoc($result)): ?>
|
||||
<?php
|
||||
// Determine status
|
||||
$status = $server['status'] ?? 'unknown';
|
||||
if ($server['enabled'] == 0) {
|
||||
$status = 'maintenance';
|
||||
}
|
||||
|
||||
// Status styling
|
||||
$status_class = '';
|
||||
$status_display = ucfirst($status);
|
||||
switch ($status) {
|
||||
case 'online':
|
||||
$status_class = 'status-online';
|
||||
break;
|
||||
case 'offline':
|
||||
$status_class = 'status-offline';
|
||||
break;
|
||||
case 'maintenance':
|
||||
$status_class = 'status-maintenance';
|
||||
break;
|
||||
default:
|
||||
$status_class = 'status-unknown';
|
||||
$status_display = 'Unknown';
|
||||
}
|
||||
|
||||
// Format last updated
|
||||
$last_updated = 'Never';
|
||||
if ($server['last_updated']) {
|
||||
$timestamp = strtotime($server['last_updated']);
|
||||
$diff = time() - $timestamp;
|
||||
if ($diff < 60) {
|
||||
$last_updated = 'Just now';
|
||||
} elseif ($diff < 3600) {
|
||||
$last_updated = floor($diff / 60) . ' min ago';
|
||||
} elseif ($diff < 86400) {
|
||||
$last_updated = floor($diff / 3600) . ' hours ago';
|
||||
} else {
|
||||
$last_updated = date('M d, Y', $timestamp);
|
||||
}
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td><strong><?php echo htmlspecialchars($server['remote_server_name']); ?></strong></td>
|
||||
<td><?php echo htmlspecialchars($server['agent_ip'] ?? 'N/A'); ?></td>
|
||||
<td>
|
||||
<span class="status-badge <?php echo $status_class; ?>">
|
||||
<?php echo $status_display; ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo $server['cpu_usage'] ? number_format($server['cpu_usage'], 1) . '%' : 'N/A'; ?></td>
|
||||
<td><?php echo $server['memory_usage'] ? number_format($server['memory_usage'], 1) . '%' : 'N/A'; ?></td>
|
||||
<td><?php echo $server['disk_usage'] ? number_format($server['disk_usage'], 1) . '%' : 'N/A'; ?></td>
|
||||
<td><?php echo htmlspecialchars($server['uptime'] ?? 'N/A'); ?></td>
|
||||
<td><?php echo $last_updated; ?></td>
|
||||
</tr>
|
||||
<?php if (!empty($server['notes'])): ?>
|
||||
<tr>
|
||||
<td colspan="8" style="padding-left:40px;font-size:0.9rem;color:rgba(255,255,255,0.7);">
|
||||
<em><?php echo htmlspecialchars($server['notes']); ?></em>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php else: ?>
|
||||
<div class="panel" style="text-align:center;padding:40px;">
|
||||
<p style="font-size:1.2rem;">No server status information available.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="margin-top:30px;text-align:center;color:rgba(255,255,255,0.6);font-size:0.9rem;">
|
||||
<p>Server status is updated automatically every 5 minutes.</p>
|
||||
<p style="margin-top:10px;">If you experience any issues, please contact support.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
// Close database connection
|
||||
mysqli_close($db);
|
||||
?>
|
||||
|
||||
<style>
|
||||
.status-badge {
|
||||
display: inline-block;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.status-online {
|
||||
background-color: #10b981;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
background-color: #ef4444;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-maintenance {
|
||||
background-color: #f59e0b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-unknown {
|
||||
background-color: #6b7280;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
</body>
|
||||
<?php include(__DIR__ . '/includes/footer.php'); ?>
|
||||
</html>
|
||||
|
|
@ -59,7 +59,7 @@ include(__DIR__ . '/includes/menu.php');
|
|||
?>
|
||||
<br>
|
||||
|
||||
<a href="order.php?service_id=<?php echo urlencode($row['service_id']); ?>" class="gsw-btn">Order Server</a>
|
||||
<a href="order.php?service_id=<?php echo urlencode($row['service_id']); ?>" class="gsw-btn" style="display:inline-block;padding:12px 24px;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:white;text-decoration:none;border-radius:8px;font-weight:600;transition:transform 0.2s;">Order Now</a>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<!-- Single service detail view -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue