From e83d46844303b89086593e38b711c218c56bbd7f Mon Sep 17 00:00:00 2001 From: Andreas Date: Fri, 8 Dec 2023 06:42:48 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Commented=20some=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/controllers/UserController.php | 71 ++++++++---- src/app/controllers/UtilController.php | 64 ++++++++--- src/app/models/AdminModel.php | 148 ++++++++++++++----------- src/app/models/UsersModel.php | 26 +++-- 4 files changed, 200 insertions(+), 109 deletions(-) diff --git a/src/app/controllers/UserController.php b/src/app/controllers/UserController.php index 0256ef0..49cebd5 100644 --- a/src/app/controllers/UserController.php +++ b/src/app/controllers/UserController.php @@ -569,10 +569,14 @@ public function isDiscordLinked() public function discord_link($code) { + // Get the user ID from the session $uid = Session::Get("uid"); + + // Check if the Discord authorization code is provided if (!empty($code)) { $discord_code = $code; - + + // Set up the payload for the token request to Discord $payload = [ 'code' => $discord_code, 'client_id' => Util::securevar(client_id), @@ -581,69 +585,90 @@ public function discord_link($code) 'redirect_uri' => Util::securevar(SITE_URL . SUB_DIR . '/user/profile.php'), 'scope' => 'identify', ]; - + + // Convert the payload to a URL-encoded string $payload_string = http_build_query($payload); + + $discord_token_url = "https://discordapp.com/api/v9/oauth2/token"; - + + $ch = curl_init(); + + // Set cURL options for token request curl_setopt($ch, CURLOPT_URL, $discord_token_url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $payload_string); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - + + $result = curl_exec($ch); - + + if ($result === false) { Util::display("Error: " . Util::securevar(curl_error($ch))); curl_close($ch); exit(); } - + + $result = json_decode($result, true); - + + if (!isset($result["access_token"])) { Util::display("Error: Failed to get access token from Discord."); exit(); } - + + if (!isset($result["refresh_token"])) { Util::display("Error: Failed to get refresh token from Discord."); exit(); } - + + // Securely store access and refresh tokens $access_token = Util::securevar($result["access_token"]); $refresh_token = Util::securevar($result["refresh_token"]); - + + // Discord user info URL $discord_users_url = "https://discordapp.com/api/users/@me"; + + // Set cURL options for user info request $header = [ "Authorization: Bearer $access_token", "Content-Type: application/x-www-form-urlencoded", ]; - curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_URL, $discord_users_url); curl_setopt($ch, CURLOPT_POST, false); - + + $result = curl_exec($ch); - + + if ($result === false) { Util::display("Error: " . Util::securevar(curl_error($ch))); curl_close($ch); exit(); } - + + $result = json_decode($result, true); - + + if (!isset($result["id"])) { Util::display("Error: Failed to get user ID from Discord."); exit(); } - + + // Securely store user ID and avatar $id = Util::securevar($result["id"]); $avatar = Util::securevar($result["avatar"]); - + + // Set the path for saving the user's avatar $path = Util::securevar(IMG_DIR . $uid); - + + // Delete existing avatar files if (@getimagesize($path . ".png")) { unlink($path . ".png"); } elseif (@getimagesize($path . ".jpg")) { @@ -651,18 +676,26 @@ public function discord_link($code) } elseif (@getimagesize($path . ".gif")) { unlink($path . ".gif"); } - + + // Download and save the user's avatar from Discord $url = "https://cdn.discordapp.com/avatars/$id/$avatar.png"; $img = $path . ".png"; file_put_contents($img, file_get_contents($url)); + + // Set appropriate permissions on directories and files chmod(IMG_DIR, 0775); chmod($img, 0775); + + // Set the access token, refresh token, and Discord ID in the session $this->set_access_token($access_token); $this->set_refresh_token($refresh_token); $this->set_dcid($id, $uid); + + // Redirect to the user's profile page header("location: profile.php"); } } + public function downloadAvatarWithAccessToken($userId, $uid) diff --git a/src/app/controllers/UtilController.php b/src/app/controllers/UtilController.php index 0a90278..c6a949c 100644 --- a/src/app/controllers/UtilController.php +++ b/src/app/controllers/UtilController.php @@ -50,6 +50,17 @@ public static function display($string) echo $string; } + + /** + * Sanitizes and secures a variable or an array of variables. + * + * This function applies HTML escaping, removes extra whitespace, and + * protects against potential cross-site scripting (XSS) attacks. + * + * @param mixed $var The variable or array to be secured. + * @return mixed The secured variable or array. + */ + public static function securevar($var) { if (empty($var)) { @@ -174,6 +185,12 @@ public static function muteCheck() return $res; } + /** + * Calculate the number of days since the user's join date, + * based on the stored 'createdAt' value in the session. + * + * @return int The number of days since the user joined. + */ public static function getjoin() { $joindate = Session::get("createdAt"); @@ -181,18 +198,47 @@ public static function getjoin() $date = new DateTime($joindate); $interval = $now->diff($date); + // Return the number of days as an integer return (int) $interval->format("%a"); } + + /** + * Calculate the number of days since a specified join date. + * + * @param string $joindate The join date in "Y-m-d H:i:s" format. + * + * @return int The number of days since the specified join date. + */ public static function getjoinprofile($joindate) { $now = new DateTime(); $date = DateTime::createFromFormat("Y-m-d H:i:s", $joindate); $interval = $now->diff($date); + // Return the number of days as an integer return (int) $interval->format("%a"); } + + public static function daysago($dateString) + { + if (!$dateString) { + return 'Not available'; + } + $date = strtotime($dateString); + $now = time(); + $diff = $now - $date; + $days = floor($diff / (60 * 60 * 24)); + if ($days == 0) { + return 'Today'; + } elseif ($days == 1) { + return 'Yesterday'; + } else { + return $days . ' days ago'; + } + } + public static function getavatar($uid) { $path = IMG_DIR . $uid; @@ -234,22 +280,4 @@ public static function getextention($uid) return false; } } - - public static function daysago($dateString) - { - if (!$dateString) { - return 'Not available'; - } - $date = strtotime($dateString); - $now = time(); - $diff = $now - $date; - $days = floor($diff / (60 * 60 * 24)); - if ($days == 0) { - return 'Today'; - } elseif ($days == 1) { - return 'Yesterday'; - } else { - return $days . ' days ago'; - } - } } diff --git a/src/app/models/AdminModel.php b/src/app/models/AdminModel.php index c7245a5..c6eaa2d 100644 --- a/src/app/models/AdminModel.php +++ b/src/app/models/AdminModel.php @@ -27,15 +27,15 @@ protected function UserArray() protected function bannedArray() { + // Retrieve a list of banned users if the user is an admin or support user if ($this->checkadmin() or $this->checksupp()) { - $query = 'SELECT * FROM `users` where banned = 1 ORDER BY uid ASC'; - + $query = 'SELECT * FROM `users` WHERE banned = 1 ORDER BY uid ASC'; $this->prepare($query); $this->statement->execute(); - return $this->statement->fetchAll(); } } + protected function updatenews($news) { @@ -77,8 +77,11 @@ protected function bannreason($reason, $uid) protected function subgift($name, $sub, $time) { + // Check if the user calling the function is an admin if ($this->checkadmin()) { + // If the subscription duration is less than or equal to 0 if ($sub <= 0) { + // Handle different time cases if ($time === 'LT') { $time = '24000'; } @@ -86,66 +89,69 @@ protected function subgift($name, $sub, $time) $time = '3'; } if ($time === '-') { - return false; + return false; // If time is '-', return false } - + + // Calculate the expiration date of the subscription $date = new DateTime(); // Get current date $days = 'P' . $time . 'D'; $date->add(new DateInterval($days)); // Adds custom days $subTime = $date->format('Y-m-d'); // Format Year-Month-Day - - $this->prepare( - 'UPDATE `users` SET `sub` = ? WHERE `username` = ?' - ); + + // Update the user's subscription in the database + $this->prepare('UPDATE `users` SET `sub` = ? WHERE `username` = ?'); $this->statement->execute([$subTime, $name]); - + + // Log the sub gift action $user = new UserController(); $username = Session::get('username'); $user->loguser($name, "$username gifted you a $time day/s sub"); } else { + // If the subscription duration is greater than 0 if ($time === '-') { - $this->prepare( - 'UPDATE `users` SET `sub` = NULL WHERE `username` = ?' - ); + // Remove the user's subscription + $this->prepare('UPDATE `users` SET `sub` = NULL WHERE `username` = ?'); $this->statement->execute([$name]); - + + // Log the removal of the subscription $username = Session::get('username'); $user = new UserController(); - $user->log($username, "Removed $name`s sub", admin_logs); + $user->log($username, "Removed $name`s sub", 'admin_logs'); $this->admin_log(Session::get("username"), "Removed $name`s sub"); $user->loguser($name, "$username removed your sub"); } else { + // Handle different time cases if ($time === 'LT') { $time = '24000'; } if ($time === 'T') { $time = '3'; } - - $this->prepare( - 'SELECT `sub` FROM `users` WHERE `username` = ?' - ); + + // Retrieve the current subscription expiration date from the database + $this->prepare('SELECT `sub` FROM `users` WHERE `username` = ?'); $this->statement->execute([$name]); $date = $this->statement->fetch(); $date1 = date_create($date->sub); $days = 'P' . $time . 'D'; $date1->add(new DateInterval($days)); $subTime = $date1->format('Y-m-d'); // Format Year-Month-Day - - $this->prepare( - 'UPDATE `users` SET `sub` = ? WHERE `username` = ?' - ); + + // Update the user's subscription in the database + $this->prepare('UPDATE `users` SET `sub` = ? WHERE `username` = ?'); $this->statement->execute([$subTime, $name]); - + + // Log the sub gift action $user = new UserController(); $username = Session::get('username'); - $user->log($username, "Gifted a $time day/s sub. \n to: $name", admin_logs); + $user->log($username, "Gifted a $time day/s sub. \n to: $name", 'admin_logs'); $user->loguser($name, "$username gifted you a $time day/s sub", false); $this->admin_log(Session::get("username"), "Gifted a $time day/s sub. \n to: $name"); } } } } + protected function checksubbyun($name) { @@ -586,25 +592,29 @@ protected function SystemVersion($ver) // protected function Systemfreeze() { + // Check if the user calling the function is an admin if ($this->checkadmin()) { + // Fetch the 'frozen' status from the 'system' table $this->prepare('SELECT `frozen` FROM `system`'); $this->statement->execute(); $result = $this->statement->fetch(); - + + // If the system is not frozen if ((int) $result->frozen === 0) { + // Update the 'frozen' status in the 'system' table to 1 $this->prepare('UPDATE `system` SET `frozen` = 1'); $this->statement->execute(); - - $this->prepare( - 'UPDATE `system` SET `freezingtime` = UNIX_TIMESTAMP()' - ); + + // Update the 'freezingtime' in the 'system' table to the current UNIX timestamp + $this->prepare('UPDATE `system` SET `freezingtime` = UNIX_TIMESTAMP()'); $this->statement->execute(); - + + // Fetch all users from the 'users' table $this->prepare('SELECT * FROM `users`'); $this->statement->execute(); - $userarray = $this->statement->fetchAll(); - + + // Iterate through each user foreach ($userarray as $row) { $date = new DateTime(); // Get current date $currentDate = $date->format('Y-m-d'); // Format Year-Month-Day @@ -612,81 +622,89 @@ protected function Systemfreeze() $date2 = date_create($row->sub); // Convert String to date format $diff = date_diff($date1, $date2); $sub = intval($diff->format('%R%a')); - + + // If the user has an active subscription if ($sub >= 1) { - $this->prepare( - 'UPDATE `users` SET `frozen` = 1 where `username` = ? ' - ); + // Update the 'frozen' status for the user to 1 + $this->prepare('UPDATE `users` SET `frozen` = 1 WHERE `username` = ?'); $this->statement->execute([$row->username]); } } + + // Log the freezing action $username = Session::get('username'); $user = new UserController(); - $user->log($username, "Freezed all subs", system_logs); + $user->log($username, "Freezed all subs", 'system_logs'); $user->loguser($row->username, "Sub freezed by $username"); $this->admin_log($username, "Freezed all subs"); - } else { + // If the system is already frozen $this->prepare('SELECT * FROM `users`'); $this->statement->execute(); - $userarray = $this->statement->fetchAll(); - + + // Iterate through each user foreach ($userarray as $row) { + // If the user is frozen if ($row->frozen != 0) { - $this->prepare( - 'UPDATE `users` SET `frozen` = 0 where `username` = ? ' - ); + // Update the 'frozen' status for the user to 0 + $this->prepare('UPDATE `users` SET `frozen` = 0 WHERE `username` = ?'); $this->statement->execute([$row->username]); - + + // Fetch 'freezingtime' from the 'system' table $this->prepare('SELECT * FROM `system`'); $this->statement->execute(); $result = $this->statement->fetch(); $freezingtime = $result->freezingtime; $freezingtime = gmdate('Y-m-d', $freezingtime); - + + // Get the current date $timenow = gmdate('Y-m-d', time()); - - $date1 = date_create($freezingtime); // Convert String to date format - $date2 = date_create($timenow); // Convert String to date format + + // Calculate the difference in days between 'freezingtime' and the current date + $date1 = date_create($freezingtime); + $date2 = date_create($timenow); $diff = date_diff($date1, $date2); $diff = intval($diff->format('%R%a')); - $days = 'P' . $diff . 'D'; - - - $this->prepare( - 'SELECT `sub` FROM `users` WHERE `username` = ?' - ); + + // Fetch the current subscription expiration date for the user + $this->prepare('SELECT `sub` FROM `users` WHERE `username` = ?'); $this->statement->execute([$row->username]); - $currentsub = $this->statement->fetch(); + $currentsub = $this->statement->fetch(); $currentsub = date_create($currentsub->sub); - + + // Add the calculated days to the current subscription expiration date $currentsub->add(new DateInterval($days)); $subTime = $currentsub->format('Y-m-d'); // Format Year-Month-Day - - $this->prepare( - 'UPDATE `users` SET `sub` = ? WHERE `username` = ?' - ); + + // Update the user's subscription in the 'users' table + $this->prepare('UPDATE `users` SET `sub` = ? WHERE `username` = ?'); $this->statement->execute([$subTime, $row->username]); + + // Log the unfreezing action $user = new UserController(); $user->loguser($row->username, "Sub unfreezed by " . Session::get('username'), false); } } - + + // Reset 'frozen' status in the 'system' table to 0 $this->prepare('UPDATE `system` SET `frozen` = 0'); $this->statement->execute(); - + + // Reset 'freezingtime' in the 'system' table to 0 $this->prepare('UPDATE `system` SET `freezingtime` = 0'); $this->statement->execute(); - + + // Log the unfreezing action $username = Session::get('username'); $user = new UserController(); - $user->log($username, "Unfreezed all subs", system_logs); + $user->log($username, "Unfreezed all subs", 'system_logs'); $this->admin_log($username, "Unfreezed all subs"); } } } + // protected function Systeminvite() diff --git a/src/app/models/UsersModel.php b/src/app/models/UsersModel.php index ea6ce3b..bd654b0 100644 --- a/src/app/models/UsersModel.php +++ b/src/app/models/UsersModel.php @@ -201,32 +201,43 @@ protected function login($username, $password) protected function logintoken($token) { + // Check if the provided token exists in the 'login' table $this->prepare("SELECT * FROM `login` WHERE `remembertoken` = ?"); $this->statement->execute([$token]); - + if ($this->statement->rowCount() > 0) { $row = $this->statement->fetch(); $username = $row->username; - + if ($row) { + // Set a cookie named 'login_cookie' with the provided token, valid for 1 year setcookie("login_cookie", $token, time() + 31556926, '/'); - + + // Fetch user information from the 'users' table using the username $this->prepare('SELECT * FROM `users` WHERE `username` = ?'); $this->statement->execute([$username]); $newrow = $this->statement->fetch(); - + + // If user information is found if ($newrow) { + // Get user's Info $ip = $this->getip(); $browser = $this->get_user_Browser(); $os = $this->get_user_os(); - + + // Get the current date and time in the 'Europe/Vienna' timezone date_default_timezone_set("Europe/Vienna"); $time = date("F d S, G:i"); + + // Update the 'login' table with the new timestamp, IP, browser, and OS $this->prepare("UPDATE `login` SET `time` = ?, `ip` = ?, `browser` = ?, `os` = ? WHERE `remembertoken` = ?"); $this->statement->execute([$time, $ip, $browser, $os, $token]); + + // Log the user's login via cookie $this->loguser($username, "Logged in via cookie"); - return $newrow; // Return username if authentication succeeds. - + + // Return user information if authentication succeeds + return $newrow; } else { return false; } @@ -237,6 +248,7 @@ protected function logintoken($token) return false; } } + protected function addrememberToken($token, $username) {