0 && !empty($_SESSION["email"]) && $_SESSION["privilege_level"] >= $routerConfig["logged_in_default_permission_level"]; } function isVerified(): bool { global $routerConfig; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["verified_permission_level"]; } function isTrustWorthy(): bool { global $routerConfig; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["trustworthy_permission_level"]; } function isModerator(): bool { global $routerConfig; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["moderator_permission_level"]; } function isUserAdmin(): bool { global $routerConfig; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["user_admin_permission_level"]; } function isAdmin(): bool { global $routerConfig; return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["admin_permission_level"]; } function generateActivationToken(): string { try { return bin2hex(random_bytes(16)); } catch (RandomException) { } } function isEmailAvailable($email): bool { global $mysqli; $stmt = $mysqli->prepare("SELECT COUNT(*) FROM Users WHERE Email = ?"); $stmt->bind_param("s", $email); $stmt->execute(); $count = -1; $stmt->bind_result($count); $stmt->fetch(); $stmt->close(); return $count === 0; } function setDefaultSessionData(): void { global $routerConfig; $_SESSION["ID"] = 0; $_SESSION["first_name"] = ""; $_SESSION["last_name"] = ""; $_SESSION["nickname"] = ""; $_SESSION["email"] = ""; $_SESSION["minecraft_nickname"] = ""; $_SESSION["privilege_level"] = $routerConfig["logged_out_permission_level"]; } function verifyPassword($userID, $password): bool { global $mysqli; $stmt = $mysqli->prepare("SELECT PasswordHash FROM Users WHERE ID = ?"); $stmt->bind_param("i", $userID); $stmt->execute(); $password_hash = ""; $stmt->bind_result($password_hash); $stmt->fetch(); $stmt->close(); return !empty($password_hash) && !empty($password) && password_verify($password, $password_hash); } function UpdateSession(){ global $mysqli; $stmt = $mysqli->prepare("SELECT FirstName, LastName, Nickname, Email, MinecraftNick, PrivilegeLevel, LastLoginAt, LoginCount, ClassID, FavoriteColor FROM Users WHERE ID = ? AND isActivated = 1"); $stmt->bind_param("i", $_SESSION["ID"]); $stmt->execute(); $uid = 0; $first_name = ""; $last_name = ""; $nickname = ""; $password_hash = ""; $email = ""; $minecraft_nickname = ""; $privilege_level = 0; $class_id = 0; $favorite_color = 0; $lastLoginAt = null; $loginCount = 0; $stmt->bind_result($first_name, $last_name, $nickname, $email, $minecraft_nickname, $privilege_level, $lastLoginAt, $loginCount, $class_id, $favorite_color); $stmt->fetch(); $stmt->close(); $_SESSION["first_name"] = $first_name; $_SESSION["last_name"] = $last_name; $_SESSION["nickname"] = $nickname; $_SESSION["email"] = $email; $_SESSION["minecraft_nickname"] = $minecraft_nickname; $_SESSION["privilege_level"] = $privilege_level; $_SESSION["lastLoginAt"] = $lastLoginAt; $_SESSION["loginCount"] = $loginCount; $_SESSION["class_id"] = $class_id; $_SESSION["favorite_color"] = $favorite_color; } function doLogin($email, $password): array { global $mysqli, $routerConfig; $found = false; if (!empty($email) && !empty($password)) { $stmt = $mysqli->prepare("SELECT ID, PasswordHash FROM Users WHERE Email = ? AND isActivated = 1"); $stmt->bind_param("s", $email); $stmt->execute(); $uid = 0; $password_hash = ""; $stmt->bind_result($uid, $password_hash); $stmt->fetch(); $stmt->close(); if (password_verify($password, $password_hash)) { $found = true; $_SESSION["ID"] = $uid; UpdateSession(); // Update LastLoginAt and LoginCount $updateLoginStmt = $mysqli->prepare("UPDATE Users SET LastLoginAt = NOW(), LoginCount = LoginCount + 1 WHERE ID = ?"); $updateLoginStmt->bind_param("i", $uid); $updateLoginStmt->execute(); $updateLoginStmt->close(); } } return $found ? ["Status" => "Success"] : ["Status" => "Fail"]; } function doLogout(): array { if(isLoggedIn()){ setDefaultSessionData(); return ["Status" => "Success"]; } else { return ["Status" => "Fail"]; } } function doRegister($firstname, $lastname, $email, $password, $activation_token): array { global $mysqli, $routerConfig; $status = ["Status" => "Fail"]; if (!empty($activation_token) && !empty($email) && !empty($password) && !empty($firstname) && !empty($lastname) && isEmailAvailable($email)) { $passwordHash = password_hash($password, PASSWORD_DEFAULT); $stmt = $mysqli->prepare("UPDATE Users SET FirstName=?, LastName=?, Email=?, PasswordHash=?, PrivilegeLevel=?, isActivated=1, ActivationToken='', RegisteredAt=NOW() WHERE ActivationToken = ?"); $privilege_level = $routerConfig["logged_in_default_permission_level"]; /** @noinspection SpellCheckingInspection */ $stmt->bind_param("ssssis", $firstname, $lastname, $email, $passwordHash, $privilege_level, $activation_token); $stmt->execute(); if ($stmt->affected_rows > 0) { $status["Status"] = "Success"; } $stmt->close(); } return $status; } function changePassword($oldPassword, $newPassword): array { global $mysqli; $status = ["Status" => "Fail"]; $userID = $_SESSION["ID"]; if(!empty($oldPassword) && !empty($newPassword) && isLoggedIn() && verifyPassword($userID, $oldPassword)){ $passwordHash = password_hash($newPassword, PASSWORD_DEFAULT); $stmt = $mysqli->prepare("UPDATE Users SET PasswordHash = ? WHERE ID = ?"); $stmt->bind_param("si", $passwordHash, $userID); $stmt->execute(); if ($stmt->affected_rows > 0) { $status["Status"] = "Success"; } $stmt->close(); } return $status; } // Function to update user profile function updateUserProfile($firstName, $lastName, $nickname, $minecraft_nickname): array { global $mysqli; $status = ["Status" => "Fail"]; if (isLoggedIn() && !empty($firstName) && !empty($lastName) && !empty($nickname) && !empty($minecraft_nickname)) { $userID = $_SESSION["ID"]; $stmt = $mysqli->prepare("UPDATE Users SET FirstName = ?, LastName = ?, Nickname = ?, MinecraftNick = ? WHERE ID = ?"); /** @noinspection SpellCheckingInspection */ $stmt->bind_param("ssssi", $firstName, $lastName, $nickname, $minecraft_nickname, $userID); $stmt->execute(); if ($stmt->affected_rows > 0) { $status["Status"] = "Success"; } $stmt->close(); } return $status; } // Function to update user email function updateUserEmail($email): array { global $mysqli; $status = ["Status" => "Fail"]; /** @noinspection SpellCheckingInspection */ $validmail = false; if (isLoggedIn() && !empty($email)) { $userID = $_SESSION["ID"]; $stmt_email_check = $mysqli->prepare("SELECT Email FROM Users WHERE ID = ?"); $stmt_email_check->bind_param("i", $userID); $old_email = ""; $stmt_email_check->bind_result($old_email); $stmt_email_check->execute(); $stmt_email_check->fetch(); $stmt_email_check->close(); if ($email != $old_email) { if (isEmailAvailable($email)) { /** @noinspection SpellCheckingInspection */ $validmail = true; } } else { /** @noinspection SpellCheckingInspection */ $validmail = true; } if ($validmail) { $stmt = $mysqli->prepare("UPDATE Users SET Email = ? WHERE ID = ?"); $stmt->bind_param("si", $email, $userID); $stmt->execute(); if ($stmt->affected_rows > 0) { $status["Status"] = "Success"; } $stmt->close(); } } return $status; } function getUserInfo(): array { $output = ["Status" => "Fail"]; if(isLoggedIn()) { global $mysqli; $userID = $_SESSION["ID"]; $stmt = $mysqli->prepare("SELECT FirstName, LastName, Nickname, Email, MinecraftNick FROM Users WHERE ID = ?"); $stmt->bind_param("i", $userID); $stmt->execute(); $firstName = ""; $lastName = ""; $nickname = ""; $email = ""; $minecraft_nickname = ""; $stmt->bind_result($firstName, $lastName, $nickname, $email, $minecraft_nickname); $stmt->fetch(); $stmt->close(); UpdateSession(); $output["Status"] = "Success"; $output["UserInfo"] = [ "ID" => $userID, "FirstName" => $firstName, "LastName" => $lastName, "Nickname" => $nickname, "Email" => $email, "MinecraftNick" => $minecraft_nickname ]; } return $output; } function addActivationCodes($count): array { global $mysqli, $routerConfig; $activationCodes = []; $output = ["Status" => "Fail"]; // Default Status is "Fail" if (is_numeric($count) && $count > 0 && isUserAdmin() && isLoggedIn()) { $stmt = $mysqli->prepare("INSERT INTO Users (ActivationToken, CreatedAt, CreatedBy) VALUES (?, NOW(), ?)"); for ($i = 0; $i < $count; $i++) { $activationCode = generateActivationToken(); $stmt->bind_param("si", $activationCode, $_SESSION["ID"]); $stmt->execute(); if ($stmt->affected_rows > 0) { $activationCodes[] = [ "Code" => $activationCode, "CreatedAt" => date("Y-m-d H:i:s"), "CreatedBy" => $_SESSION["ID"] ]; $output["Status"] = "Success"; $output["ActivationCodes"] = $activationCodes; } } $stmt->close(); } return $output; } function listUsers(): array { global $mysqli, $routerConfig; $output = ["Status" => "Fail"]; // Default Status is "Fail" if (isUserAdmin()) { $users = []; $result = $mysqli->query("SELECT ID, FirstName, LastName, Nickname, Email, MinecraftNick, PrivilegeLevel, CreatedAt, RegisteredAt, LastLoginAt, LoginCount, CreatedBy FROM Users"); // Check if the query executed Successfully if ($result) { while ($row = $result->fetch_assoc()) { $users[] = $row; } $output["Status"] = "Success"; $output["Users"] = $users; } } return $output; } function listActivationCodes(): array { global $mysqli, $routerConfig; $output = ["Status" => "Fail"]; // Default Status is "Fail" if (isUserAdmin()) { $activationCodes = []; // Use placeholders in the query $query = "SELECT ActivationToken, CreatedAt, CreatedBy FROM Users WHERE isActivated = 0"; $stmt = $mysqli->prepare($query); if ($stmt) { // Bind the result variables $activationToken = ""; $createdAt = ""; $createdBy = ""; $stmt->bind_result($activationToken, $createdAt, $createdBy); // Execute the prepared statement $stmt->execute(); // Fetch the results into the bound variables while ($stmt->fetch()) { $activationCodes[] = [ 'ActivationToken' => $activationToken, 'CreatedAt' => $createdAt, 'CreatedBy' => $createdBy ]; } // Check if any results were fetched if (!empty($activationCodes)) { $output["Status"] = "Success"; $output["ActivationCodes"] = $activationCodes; } // Close the statement $stmt->close(); } } return $output; } function deleteUser($userID): array { global $mysqli, $routerConfig; $status = ["Status" => "Fail"]; if (!empty($userID) && isUserAdmin()) { $stmt = $mysqli->prepare("DELETE FROM Users WHERE ID = ?"); $stmt->bind_param("i", $userID); $stmt->execute(); if ($stmt->affected_rows > 0) { $status["Status"] = "Success"; } $stmt->close(); } return $status; } function deleteActivationCode($activationCode): array { global $mysqli, $routerConfig; $status = ["Status" => "Fail"]; if (!empty($activationCode) && isUserAdmin()) { $stmt = $mysqli->prepare("DELETE FROM Users WHERE ActivationToken = ?"); $stmt->bind_param("s", $activationCode); $stmt->execute(); if ($stmt->affected_rows > 0) { $status["Status"] = "Success"; } $stmt->close(); } return $status; }