From 43d7f86d90f2462228c7469b7b03712c20e0880a Mon Sep 17 00:00:00 2001 From: o-psi Date: Mon, 18 Dec 2023 17:34:11 +0000 Subject: [PATCH 1/9] Readable Password Ajax --- ajax.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ajax.php b/ajax.php index 991883f9..da6fee02 100644 --- a/ajax.php +++ b/ajax.php @@ -479,3 +479,7 @@ if (isset($_GET['get_totp_token_via_id'])) { mysqli_query($mysqli,"INSERT INTO logs SET log_type = 'Login', log_action = 'View TOTP', log_description = '$session_name viewed login TOTP code for $name', log_ip = '$session_ip', log_user_agent = '$session_user_agent', log_client_id = $client_id, log_user_id = $session_user_id, log_entity_id = $login_id"); } } + +if (isset($_GET['get_readable_pass'])) { + echo GenerateReadablePassword(4); +} From e0c8b0c30d20fa948d90c97843a11175cb9d4588 Mon Sep 17 00:00:00 2001 From: o-psi Date: Mon, 18 Dec 2023 17:34:22 +0000 Subject: [PATCH 2/9] Readable Password Function --- functions.php | 60 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/functions.php b/functions.php index b471d80b..36586536 100644 --- a/functions.php +++ b/functions.php @@ -15,8 +15,7 @@ use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; // Function to generate both crypto & URL safe random strings -function randomString($length = 16) -{ +function randomString($length = 16) { // Generate some cryptographically safe random bytes // Generate a little more than requested as we'll lose some later converting $random_bytes = random_bytes($length + 5); @@ -33,8 +32,7 @@ function randomString($length = 16) } // Older keygen function - only used for TOTP currently -function key32gen() -{ +function key32gen() { $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $chars .= "234567"; while (1) { @@ -256,8 +254,7 @@ function setupFirstUserSpecificKey($user_password, $site_encryption_master_key) * New Users: Requires the admin setting up their account have a Specific/Session key configured * Password Changes: Will use the current info in the session. */ -function encryptUserSpecificKey($user_password) -{ +function encryptUserSpecificKey($user_password) { $iv = randomString(); $salt = randomString(); @@ -871,4 +868,55 @@ function calculateAccountBalance($mysqli, $account_id) { } return $balance; +} + +function generateReadablePassword($security_level) { + // Arrays of words + $adjectives = ['Smart', 'Swift', 'Secure', 'Stable', 'Digital', 'Virtual', 'Active', 'Dynamic', 'Innovative', 'Efficient', 'Portable', 'Wireless', 'Rapid', 'Intuitive', 'Automated', 'Robust', 'Reliable', 'Sleek', 'Modern', 'Happy', 'Funny', 'Quick', 'Bright', 'Clever', 'Gentle', 'Brave', 'Calm', 'Eager', 'Fierce', 'Kind', 'Lucky', 'Proud', 'Silly', 'Witty', 'Bold', 'Curious', 'Elated', 'Gracious', 'Honest', 'Jolly', 'Merry', 'Noble', 'Optimistic', 'Playful', 'Quirky', 'Rustic', 'Steady', 'Tranquil', 'Upbeat']; + $nouns = ['Computer', 'Laptop', 'Tablet', 'Server', 'Router', 'Software', 'Hardware', 'Pixel', 'Byte', 'App', 'Network', 'Cloud', 'Firewall', 'Email', 'Database', 'Folder', 'Document', 'Interface', 'Program', 'Gadget', 'Dinosaur', 'Tiger', 'Elephant', 'Kangaroo', 'Monkey', 'Unicorn', 'Dragon', 'Puppy', 'Kitten', 'Parrot', 'Lion', 'Bear', 'Fox', 'Wolf', 'Rabbit', 'Deer', 'Owl', 'Hedgehog', 'Turtle', 'Frog', 'Butterfly', 'Panda', 'Giraffe', 'Zebra', 'Peacock', 'Koala', 'Raccoon', 'Squirrel', 'Hippo', 'Rhino', 'Book', "Monitor"]; + $verbs = ['Connects', 'Runs', 'Processes', 'Secures', 'Encrypts', 'Saves', 'Updates', 'Boots', 'Scans', 'Compiles', 'Executes', 'Restores', 'Installs', 'Configures', 'Downloads', 'Streams', 'BacksUp', 'Syncs', 'Browses', 'Navigates', 'Runs', 'Jumps', 'Flies', 'Swims', 'Dances', 'Sings', 'Hops', 'Skips', 'Races', 'Climbs', 'Crawls', 'Glides', 'Twirls', 'Swings', 'Sprints', 'Gallops', 'Trots', 'Wanders', 'Strolls', 'Marches']; + $adverbs = ['Quickly', 'Slowly', 'Gracefully', 'Wildly', 'Loudly', 'Silently', 'Cheerfully', 'Eagerly', 'Gently', 'Happily', 'Jovially', 'Kindly', 'Lazily', 'Merrily', 'Neatly', 'Politely', 'Quietly', 'Rapidly', 'Smoothly', 'Tightly', 'Swiftly', 'Securely', 'Efficiently', 'Rapidly', 'Smoothly', 'Reliably', 'Safely', 'Wirelessly', 'Instantly', 'Silently', 'Automatically', 'Seamlessly', 'Digitally', 'Virtually', 'Continuously', 'Regularly', 'Intelligently', 'Logically']; + + // Randomly select words from arrays + $adj = $adjectives[array_rand($adjectives)]; + $noun = $nouns[array_rand($nouns)]; + $verb = $verbs[array_rand($verbs)]; + $adv = $adverbs[array_rand($adverbs)]; + + + + // Combine to create a base password + if ($security_level > 2 ) { + $password = "The" . $adj . $noun . $adv . $verb; + } else { + $password = $adj . $noun . $verb; + } + + // Mapping of letters to special characters and numbers + $mappings = [ + 'A' => '@', 'a' => '@', + 'E' => '3', 'e' => '3', + 'I' => '!', 'i' => '!', + 'O' => '0', 'o' => '0', + 'S' => '$', 's' => '$' + ]; + + // Replace characters based on mappings + if ($security_level > 4) { + $password = strtr($password, $mappings); + } else { + // Randomly replace characters based on mappings + for ($i = 0; $i < strlen($password); $i++) { + if (array_key_exists($password[$i], $mappings) && rand(0, 1)) { + $password[$i] = $mappings[$password[$i]]; + } + } + } + + if ($security_level > 3) { + // Add a random number at the end + $password .= rand(0, 99); + } + + return $password; } \ No newline at end of file From f0567c1fb7ec25d641dcb5401af88cd74ed2c45b Mon Sep 17 00:00:00 2001 From: o-psi Date: Mon, 18 Dec 2023 17:34:39 +0000 Subject: [PATCH 3/9] add password generation functionality --- client_contact_add_modal.php | 60 ++++++++++++----------- client_contact_details.php | 24 ++++++++++ client_contact_edit_modal.php | 90 +++++++++++++++++++++-------------- 3 files changed, 110 insertions(+), 64 deletions(-) diff --git a/client_contact_add_modal.php b/client_contact_add_modal.php index b7c8cf7c..b3762c2b 100644 --- a/client_contact_add_modal.php +++ b/client_contact_add_modal.php @@ -124,7 +124,7 @@ while ($row = mysqli_fetch_array($sql)) { $location_id = intval($row['location_id']); $location_name = nullable_htmlentities($row['location_name']); - ?> + ?> @@ -137,7 +137,7 @@
- +
@@ -145,7 +145,7 @@
- +
@@ -153,7 +153,7 @@
- +
@@ -183,36 +183,40 @@
- -
-
- -
-
- + +
+
+ +
+
+ +
+
-
-
- - diff --git a/client_contact_details.php b/client_contact_details.php index 45b79986..17687d6a 100644 --- a/client_contact_details.php +++ b/client_contact_details.php @@ -574,6 +574,30 @@ if (isset($_GET['contact_id'])) { diff --git a/client_logins.php b/client_logins.php index dc1ddf21..a7030acc 100644 --- a/client_logins.php +++ b/client_logins.php @@ -50,7 +50,9 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
- +
@@ -67,107 +69,110 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
- "> - - - - - - - - - + "> + + + + + + + + + - "; - } - $login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); - if (empty($login_username)) { - $login_username_display = "-"; - } else { - $login_username_display = "$login_username"; - } - $login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); - $login_otp_secret = nullable_htmlentities($row['login_otp_secret']); - $login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; - if (empty($login_otp_secret)) { - $otp_display = "-"; - } else { - $otp_display = " Hover.."; - } - $login_note = nullable_htmlentities($row['login_note']); - $login_important = intval($row['login_important']); - $login_contact_id = intval($row['login_contact_id']); - $login_vendor_id = intval($row['login_vendor_id']); - $login_asset_id = intval($row['login_asset_id']); - $login_software_id = intval($row['login_software_id']); + while ($row = mysqli_fetch_array($sql)) { + $login_id = intval($row['login_id']); + $login_name = nullable_htmlentities($row['login_name']); + $login_description = nullable_htmlentities($row['login_description']); + if (empty($login_description)) { + $login_description_display = "-"; + } else { + $login_description_display = $login_description; + } + $login_uri = nullable_htmlentities($row['login_uri']); + if (empty($login_uri)) { + $login_uri_display = "-"; + } else { + $login_uri_display = "$login_uri"; + } + $login_username = nullable_htmlentities(decryptLoginEntry($row['login_username'])); + if (empty($login_username)) { + $login_username_display = "-"; + } else { + $login_username_display = "$login_username"; + } + $login_password = nullable_htmlentities(decryptLoginEntry($row['login_password'])); + $login_otp_secret = nullable_htmlentities($row['login_otp_secret']); + $login_id_with_secret = '"' . $row['login_id'] . '","' . $row['login_otp_secret'] . '"'; + if (empty($login_otp_secret)) { + $otp_display = "-"; + } else { + $otp_display = " Hover.."; + } + $login_note = nullable_htmlentities($row['login_note']); + $login_important = intval($row['login_important']); + $login_contact_id = intval($row['login_contact_id']); + $login_vendor_id = intval($row['login_vendor_id']); + $login_asset_id = intval($row['login_asset_id']); + $login_software_id = intval($row['login_software_id']); ?> - "> - - - - - - - "> + + + + + + + - + + + ?>
NameDescriptionUsernamePasswordOTPURIAction
NameDescriptionUsernamePasswordOTPURIAction
- - - - - - - -
+ + + + + + + + - -
+ ?>
@@ -176,8 +181,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); function showOTP(id, secret) { //Send a GET request to ajax.php as ajax.php?get_totp_token=true&totp_secret=SECRET jQuery.get( - "ajax.php", - {get_totp_token: 'true', totp_secret: secret}, + "ajax.php", { + get_totp_token: 'true', + totp_secret: secret + }, function(data) { //If we get a response from post.php, parse it as JSON const token = JSON.parse(data); @@ -191,8 +198,10 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); function showOTPViaLoginID(login_id) { // Send a GET request to ajax.php as ajax.php?get_totp_token_via_id=true&login_id=ID jQuery.get( - "ajax.php", - {get_totp_token_via_id: 'true', login_id: login_id}, + "ajax.php", { + get_totp_token_via_id: 'true', + login_id: login_id + }, function(data) { //If we get a response from post.php, parse it as JSON const token = JSON.parse(data); @@ -204,7 +213,24 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); } function generatePassword() { - document.getElementById("password").value = "" + document.getElementById("password").value = "" + } + + function generatePassword() { + var url = '/ajax.php?get_readable_pass=true'; + + // Make an AJAX request to the server + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + + xhr.onreadystatechange = function() { + if (xhr.readyState == 4 && xhr.status == 200) { + var password = xhr.responseText; + + document.getElementById("password").value = password; + } + }; + xhr.send(); } @@ -219,4 +245,3 @@ require_once "client_login_import_modal.php"; require_once "client_login_export_modal.php"; require_once "footer.php"; - From dd7131cae198031eb8d894a54fa7682f6f328d07 Mon Sep 17 00:00:00 2001 From: o-psi Date: Fri, 22 Dec 2023 15:14:56 +0000 Subject: [PATCH 5/9] Fix ticket_assigned_to filter in SQL query --- tickets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tickets.php b/tickets.php index e369638e..71fa73a6 100644 --- a/tickets.php +++ b/tickets.php @@ -58,7 +58,7 @@ $sql = mysqli_query( LEFT JOIN assets ON ticket_asset_id = asset_id LEFT JOIN locations ON ticket_location_id = location_id LEFT JOIN vendors ON ticket_vendor_id = vendor_id - WHERE ticket_assigned_to LIKE '%$ticket_assigned_filter%' + WHERE ticket_assigned_to LIKE '$ticket_assigned_filter' AND $ticket_status_snippet AND DATE(ticket_created_at) BETWEEN '$dtf' AND '$dtt' AND (CONCAT(ticket_prefix,ticket_number) LIKE '%$q%' OR client_name LIKE '%$q%' OR ticket_subject LIKE '%$q%' OR ticket_status LIKE '%$q%' OR ticket_priority LIKE '%$q%' OR user_name LIKE '%$q%' OR contact_name LIKE '%$q%' OR asset_name LIKE '%$q%' OR vendor_name LIKE '%$q%' OR ticket_vendor_ticket_number LIKE '%q%') From 61a0086514fc68ac334fe22ecec11e651109e568 Mon Sep 17 00:00:00 2001 From: o-psi Date: Fri, 22 Dec 2023 17:06:48 +0000 Subject: [PATCH 6/9] Fix ticket assignment filter bug --- tickets.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tickets.php b/tickets.php index 71fa73a6..2f74722f 100644 --- a/tickets.php +++ b/tickets.php @@ -1,5 +1,6 @@ Date: Fri, 22 Dec 2023 17:16:26 +0000 Subject: [PATCH 7/9] Add ticket status color for "Client-Replied" --- tickets.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tickets.php b/tickets.php index b4a27bc8..82fde80d 100644 --- a/tickets.php +++ b/tickets.php @@ -314,6 +314,8 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); $ticket_status_color = "success"; } elseif ($ticket_status == "Closed") { $ticket_status_color = "dark"; + } elseif ($ticket_status == "Client-Replied") { + $ticket_status_color = "warning"; } else{ $ticket_status_color = "secondary"; } From 77145432ee6b553fe85034ff3bb95d285051a777 Mon Sep 17 00:00:00 2001 From: o-psi Date: Fri, 22 Dec 2023 17:19:00 +0000 Subject: [PATCH 8/9] Added autoclose to dark --- tickets.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tickets.php b/tickets.php index 82fde80d..d0291ac1 100644 --- a/tickets.php +++ b/tickets.php @@ -314,6 +314,8 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']); $ticket_status_color = "success"; } elseif ($ticket_status == "Closed") { $ticket_status_color = "dark"; + } elseif ($ticket_status == "Auto Close") { + $ticket_status_color = "dark"; } elseif ($ticket_status == "Client-Replied") { $ticket_status_color = "warning"; } else{ From 5dda94a1ec88ded1116adcdfd1cb05c2af1e67ce Mon Sep 17 00:00:00 2001 From: o-psi Date: Fri, 22 Dec 2023 17:45:39 +0000 Subject: [PATCH 9/9] Fix typo in accounting module condition --- tickets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tickets.php b/tickets.php index 8c70b8dd..507f4ca6 100644 --- a/tickets.php +++ b/tickets.php @@ -367,7 +367,7 @@ $user_active_assigned_tickets = intval($row['total_tickets_assigned']);
-