2024-01-16 19:24:40 +01:00
< ? php
2024-01-31 22:05:23 +01:00
use Random\RandomException ;
function isLoggedIn () : bool
{
global $routerConfig ;
2024-02-03 16:08:26 +01:00
return $_SESSION [ " ID " ] > 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 ;
2024-01-16 19:24:40 +01:00
}
2024-02-01 09:38:16 +01:00
function setDefaultSessionData () : void
{
2024-02-01 10:50:07 +01:00
global $routerConfig ;
2024-02-01 09:38:16 +01:00
$_SESSION [ " ID " ] = 0 ;
$_SESSION [ " first_name " ] = " " ;
$_SESSION [ " last_name " ] = " " ;
$_SESSION [ " nickname " ] = " " ;
$_SESSION [ " email " ] = " " ;
2024-02-03 16:08:26 +01:00
$_SESSION [ " minecraft_nickname " ] = " " ;
$_SESSION [ " privilege_level " ] = $routerConfig [ " logged_out_permission_level " ];
2024-02-01 09:38:16 +01:00
}
2024-01-31 22:05:23 +01:00
function verifyPassword ( $userID , $password ) : bool
{
2024-01-16 19:24:40 +01:00
global $mysqli ;
2024-01-31 22:05:23 +01:00
$stmt = $mysqli -> prepare ( " SELECT PasswordHash FROM Users WHERE ID = ? " );
$stmt -> bind_param ( " i " , $userID );
$stmt -> execute ();
2024-02-03 16:08:26 +01:00
$password_hash = " " ;
$stmt -> bind_result ( $password_hash );
2024-01-31 22:05:23 +01:00
$stmt -> fetch ();
$stmt -> close ();
2024-02-03 17:10:54 +01:00
return ! empty ( $password_hash ) && ! empty ( $password ) && password_verify ( $password , $password_hash );
2024-01-31 22:05:23 +01:00
}
2024-02-04 08:57:35 +01:00
function UpdateSession (){
global $mysqli ;
$stmt = $mysqli -> prepare ( " SELECT FirstName, LastName, Nickname, Email, MinecraftNick, PrivilegeLevel, LastLoginAt, LoginCount 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 ;
$lastLoginAt = null ;
$loginCount = 0 ;
$stmt -> bind_result ( $uid , $first_name , $last_name , $nickname , $email , $password_hash , $minecraft_nickname , $privilege_level , $lastLoginAt , $loginCount );
$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 ;
}
2024-01-31 22:05:23 +01:00
function doLogin ( $email , $password ) : array
{
global $mysqli , $routerConfig ;
2024-01-18 11:53:39 +01:00
$found = false ;
2024-01-31 23:07:12 +01:00
if ( ! empty ( $email ) && ! empty ( $password )) {
2024-02-04 08:57:35 +01:00
$stmt = $mysqli -> prepare ( " SELECT ID, PasswordHash FROM Users WHERE Email = ? AND isActivated = 1 " );
2024-01-16 19:24:40 +01:00
$stmt -> bind_param ( " s " , $email );
$stmt -> execute ();
2024-01-18 11:49:38 +01:00
2024-02-03 16:08:26 +01:00
$uid = 0 ;
2024-02-04 08:57:35 +01:00
2024-02-03 16:08:26 +01:00
$password_hash = " " ;
2024-02-04 08:57:35 +01:00
$stmt -> bind_result ( $uid , $password_hash );
2024-02-03 17:15:21 +01:00
$stmt -> fetch ();
2024-02-03 17:16:23 +01:00
$stmt -> close ();
2024-01-16 20:43:57 +01:00
2024-02-03 17:15:21 +01:00
if ( password_verify ( $password , $password_hash )) {
$found = true ;
2024-02-04 08:57:35 +01:00
$_SESSION [ " ID " ] = $uid ;
UpdateSession ();
2024-02-03 17:15:21 +01:00
// 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 ();
2024-01-16 19:24:40 +01:00
}
}
2024-02-03 16:08:26 +01:00
return $found ? [ " Status " => " Success " ] : [ " Status " => " Fail " ];
2024-01-16 19:24:40 +01:00
}
2024-01-31 22:05:23 +01:00
function doLogout () : array
{
2024-01-16 19:24:40 +01:00
if ( isLoggedIn ()){
2024-02-03 16:08:26 +01:00
setDefaultSessionData ();
return [ " Status " => " Success " ];
2024-01-18 11:49:38 +01:00
} else {
2024-02-03 16:08:26 +01:00
return [ " Status " => " Fail " ];
2024-01-16 19:24:40 +01:00
}
}
2024-02-03 16:08:26 +01:00
function doRegister ( $firstname , $lastname , $email , $password , $activation_token ) : array
2024-01-31 22:05:23 +01:00
{
2024-01-31 23:07:12 +01:00
global $mysqli , $routerConfig ;
2024-02-03 16:08:26 +01:00
$status = [ " Status " => " Fail " ];
2024-02-03 18:09:48 +01:00
2024-02-03 16:08:26 +01:00
if ( ! empty ( $activation_token ) && ! empty ( $email ) && ! empty ( $password ) && ! empty ( $firstname ) && ! empty ( $lastname ) && isEmailAvailable ( $email )) {
2024-01-18 11:49:38 +01:00
$passwordHash = password_hash ( $password , PASSWORD_DEFAULT );
2024-02-03 18:09:48 +01:00
2024-02-03 18:18:51 +01:00
$stmt = $mysqli -> prepare ( " UPDATE Users SET FirstName=?, LastName=?, Email=?, PasswordHash=?, PrivilegeLevel=?, isActivated=1, ActivationToken='', RegisteredAt=NOW() WHERE ActivationToken = ? " );
2024-02-03 16:08:26 +01:00
$privilege_level = $routerConfig [ " logged_in_default_permission_level " ];
2024-02-03 18:09:48 +01:00
2024-02-03 16:18:48 +01:00
/** @noinspection SpellCheckingInspection */
2024-02-03 18:09:48 +01:00
$stmt -> bind_param ( " ssssiss " , $firstname , $lastname , $email , $passwordHash , $privilege_level , $activation_token , $activation_token );
2024-01-18 11:49:38 +01:00
$stmt -> execute ();
2024-02-03 18:09:48 +01:00
2024-01-18 11:49:38 +01:00
if ( $stmt -> affected_rows > 0 ) {
2024-02-03 16:08:26 +01:00
$status [ " Status " ] = " Success " ;
2024-01-16 19:24:40 +01:00
}
2024-02-03 18:09:48 +01:00
2024-01-18 11:49:38 +01:00
$stmt -> close ();
2024-01-16 19:24:40 +01:00
}
2024-02-03 18:09:48 +01:00
2024-01-18 11:49:38 +01:00
return $status ;
2024-01-16 19:24:40 +01:00
}
2024-02-03 18:09:48 +01:00
2024-02-03 16:08:26 +01:00
function changePassword ( $oldPassword , $newPassword ) : array
2024-01-31 22:05:23 +01:00
{
2024-02-03 16:08:26 +01:00
global $mysqli ;
$status = [ " Status " => " Fail " ];
$userID = $_SESSION [ " ID " ];
if ( ! empty ( $oldPassword ) && ! empty ( $newPassword ) && isLoggedIn () && verifyPassword ( $userID , $oldPassword )){
2024-01-31 22:05:23 +01:00
$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 ) {
2024-02-03 16:08:26 +01:00
$status [ " Status " ] = " Success " ;
2024-01-31 22:05:23 +01:00
}
$stmt -> close ();
}
return $status ;
}
2024-02-03 16:08:26 +01:00
// Function to update user profile
function updateUserProfile ( $firstName , $lastName , $nickname , $minecraft_nickname ) : array
2024-01-31 22:05:23 +01:00
{
global $mysqli ;
2024-02-03 16:08:26 +01:00
$status = [ " Status " => " Fail " ];
if ( isLoggedIn () && ! empty ( $firstName ) && ! empty ( $lastName ) && ! empty ( $nickname ) && ! empty ( $minecraft_nickname )) {
$userID = $_SESSION [ " ID " ];
2024-01-31 22:05:23 +01:00
$stmt = $mysqli -> prepare ( " UPDATE Users SET FirstName = ?, LastName = ?, Nickname = ?, MinecraftNick = ? WHERE ID = ? " );
2024-02-03 16:18:48 +01:00
/** @noinspection SpellCheckingInspection */
2024-02-03 16:08:26 +01:00
$stmt -> bind_param ( " ssssi " , $firstName , $lastName , $nickname , $minecraft_nickname , $userID );
2024-01-31 22:05:23 +01:00
$stmt -> execute ();
2024-02-03 16:08:26 +01:00
2024-01-31 22:05:23 +01:00
if ( $stmt -> affected_rows > 0 ) {
2024-02-03 16:08:26 +01:00
$status [ " Status " ] = " Success " ;
2024-01-31 22:05:23 +01:00
}
2024-02-03 16:08:26 +01:00
2024-01-31 22:05:23 +01:00
$stmt -> close ();
}
2024-02-03 16:08:26 +01:00
2024-01-31 22:05:23 +01:00
return $status ;
}
2024-02-03 16:08:26 +01:00
// Function to update user email
function updateUserEmail ( $email ) : array
2024-01-31 22:05:23 +01:00
{
global $mysqli ;
2024-02-03 16:08:26 +01:00
$status = [ " Status " => " Fail " ];
2024-02-03 16:18:48 +01:00
/** @noinspection SpellCheckingInspection */
2024-02-03 16:08:26 +01:00
$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 )) {
2024-02-03 16:18:48 +01:00
/** @noinspection SpellCheckingInspection */
2024-02-03 16:08:26 +01:00
$validmail = true ;
}
} else {
2024-02-03 16:18:48 +01:00
/** @noinspection SpellCheckingInspection */
2024-02-03 16:08:26 +01:00
$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 = ? " );
2024-01-31 22:05:23 +01:00
$stmt -> bind_param ( " i " , $userID );
$stmt -> execute ();
2024-02-03 16:08:26 +01:00
2024-01-31 22:05:23 +01:00
$firstName = " " ;
$lastName = " " ;
$nickname = " " ;
$email = " " ;
2024-02-03 16:08:26 +01:00
$minecraft_nickname = " " ;
2024-01-31 22:05:23 +01:00
2024-02-03 16:08:26 +01:00
$stmt -> bind_result ( $firstName , $lastName , $nickname , $email , $minecraft_nickname );
2024-01-31 22:05:23 +01:00
$stmt -> fetch ();
$stmt -> close ();
2024-02-04 08:57:35 +01:00
UpdateSession ();
2024-02-03 17:30:51 +01:00
$output [ " Status " ] = " Success " ;
2024-01-31 22:05:23 +01:00
2024-02-03 17:30:51 +01:00
$output [ " UserInfo " ] = [
2024-02-03 16:08:26 +01:00
" ID " => $userID ,
2024-01-31 22:05:23 +01:00
" FirstName " => $firstName ,
" LastName " => $lastName ,
" Nickname " => $nickname ,
" Email " => $email ,
2024-02-03 16:08:26 +01:00
" MinecraftNick " => $minecraft_nickname
2024-01-31 22:05:23 +01:00
];
2024-02-03 16:08:26 +01:00
}
return $output ;
2024-01-31 22:05:23 +01:00
}
2024-01-31 23:07:12 +01:00
function addActivationCodes ( $count ) : array
2024-01-31 22:05:23 +01:00
{
2024-01-31 23:07:12 +01:00
global $mysqli , $routerConfig ;
2024-01-31 22:05:23 +01:00
$activationCodes = [];
2024-01-31 23:07:12 +01:00
2024-02-03 17:30:51 +01:00
$output = [ " Status " => " Fail " ]; // Default Status is "Fail"
2024-02-03 23:01:20 +01:00
if ( is_numeric ( $count ) && $count > 0 && isUserAdmin () && isLoggedIn ()) {
2024-02-03 17:57:41 +01:00
$stmt = $mysqli -> prepare ( " INSERT INTO Users (ActivationToken, CreatedAt, CreatedBy) VALUES (?, NOW(), ?) " );
2024-01-31 23:07:12 +01:00
2024-01-31 22:05:23 +01:00
for ( $i = 0 ; $i < $count ; $i ++ ) {
$activationCode = generateActivationToken ();
2024-02-03 17:55:54 +01:00
$stmt -> bind_param ( " si " , $activationCode , $_SESSION [ " ID " ]);
2024-01-31 22:05:23 +01:00
$stmt -> execute ();
2024-01-31 23:07:12 +01:00
2024-01-31 22:05:23 +01:00
if ( $stmt -> affected_rows > 0 ) {
2024-01-31 23:07:12 +01:00
$activationCodes [] = [
" Code " => $activationCode ,
" CreatedAt " => date ( " Y-m-d H:i:s " ),
" CreatedBy " => $_SESSION [ " ID " ]
];
2024-02-03 17:30:51 +01:00
$output [ " Status " ] = " Success " ;
$output [ " ActivationCodes " ] = $activationCodes ;
2024-01-31 22:05:23 +01:00
}
}
2024-01-31 23:07:12 +01:00
2024-01-31 22:05:23 +01:00
$stmt -> close ();
}
2024-01-31 23:07:12 +01:00
2024-02-03 17:30:51 +01:00
return $output ;
2024-01-31 22:05:23 +01:00
}
function listUsers () : array
{
2024-01-31 23:07:12 +01:00
global $mysqli , $routerConfig ;
2024-02-03 17:30:51 +01:00
$output = [ " Status " => " Fail " ]; // Default Status is "Fail"
2024-01-31 23:07:12 +01:00
2024-02-03 16:08:26 +01:00
if ( isUserAdmin ()) {
2024-01-31 23:07:12 +01:00
$users = [];
$result = $mysqli -> query ( " SELECT ID, FirstName, LastName, Nickname, Email, MinecraftNick, PrivilegeLevel, CreatedAt, RegisteredAt, LastLoginAt, LoginCount, CreatedBy FROM Users " );
2024-02-03 16:08:26 +01:00
// Check if the query executed Successfully
2024-01-31 23:07:12 +01:00
if ( $result ) {
while ( $row = $result -> fetch_assoc ()) {
$users [] = $row ;
}
2024-02-03 17:30:51 +01:00
$output [ " Status " ] = " Success " ;
$output [ " Users " ] = $users ;
2024-01-31 23:07:12 +01:00
}
2024-01-31 22:05:23 +01:00
}
2024-01-31 23:07:12 +01:00
2024-02-03 17:30:51 +01:00
return $output ;
2024-01-31 22:05:23 +01:00
}
function listActivationCodes () : array
{
2024-01-31 23:07:12 +01:00
global $mysqli , $routerConfig ;
2024-02-03 17:30:51 +01:00
$output = [ " Status " => " Fail " ]; // Default Status is "Fail"
2024-01-31 23:07:12 +01:00
2024-02-03 16:08:26 +01:00
if ( isUserAdmin ()) {
2024-01-31 23:07:12 +01:00
$activationCodes = [];
2024-02-03 17:55:54 +01:00
// 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
];
2024-01-31 23:07:12 +01:00
}
2024-02-03 17:55:54 +01:00
// Check if any results were fetched
if ( ! empty ( $activationCodes )) {
$output [ " Status " ] = " Success " ;
$output [ " ActivationCodes " ] = $activationCodes ;
}
// Close the statement
$stmt -> close ();
2024-01-31 23:07:12 +01:00
}
2024-01-31 22:05:23 +01:00
}
2024-02-03 17:30:51 +01:00
return $output ;
2024-01-31 22:05:23 +01:00
}
2024-01-31 23:07:12 +01:00
2024-02-03 17:55:54 +01:00
2024-01-31 23:07:12 +01:00
function deleteUser ( $userID ) : array
{
global $mysqli , $routerConfig ;
2024-02-03 16:08:26 +01:00
$status = [ " Status " => " Fail " ];
if ( ! empty ( $userID ) && isUserAdmin ()) {
2024-01-31 23:07:12 +01:00
$stmt = $mysqli -> prepare ( " DELETE FROM Users WHERE ID = ? " );
$stmt -> bind_param ( " i " , $userID );
$stmt -> execute ();
if ( $stmt -> affected_rows > 0 ) {
2024-02-03 16:08:26 +01:00
$status [ " Status " ] = " Success " ;
2024-01-31 23:07:12 +01:00
}
$stmt -> close ();
}
return $status ;
}
function deleteActivationCode ( $activationCode ) : array
{
global $mysqli , $routerConfig ;
2024-02-03 16:08:26 +01:00
$status = [ " Status " => " Fail " ];
if ( ! empty ( $activationCode ) && isUserAdmin ()) {
2024-01-31 23:07:12 +01:00
$stmt = $mysqli -> prepare ( " DELETE FROM Users WHERE ActivationToken = ? " );
$stmt -> bind_param ( " s " , $activationCode );
$stmt -> execute ();
if ( $stmt -> affected_rows > 0 ) {
2024-02-03 16:08:26 +01:00
$status [ " Status " ] = " Success " ;
2024-01-31 23:07:12 +01:00
}
$stmt -> close ();
}
return $status ;
}