From 4fdd5ae76910fc40fd7213470d998ba3c27fa41d Mon Sep 17 00:00:00 2001 From: johnnyq Date: Tue, 4 Mar 2025 00:13:21 -0500 Subject: [PATCH 1/8] Fix Bug adding software license if no vendor is selected --- post/user/software.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/post/user/software.php b/post/user/software.php index 1d5f8290d..58177a8ee 100644 --- a/post/user/software.php +++ b/post/user/software.php @@ -66,7 +66,7 @@ $expire = "'" . $expire . "'"; } $notes = sanitizeInput($_POST['notes']); - $vendor = sanitizeInput($_POST['vendor'] ?? 0); + $vendor = intval($_POST['vendor'] ?? 0); mysqli_query($mysqli,"INSERT INTO software SET software_name = '$name', software_version = '$version', software_description = '$description', software_type = '$type', software_key = '$key', software_license_type = '$license_type', software_seats = $seats, software_purchase_reference = '$purchase_reference', software_purchase = $purchase, software_expire = $expire, software_notes = '$notes', software_vendor_id = $vendor, software_client_id = $client_id"); @@ -127,7 +127,7 @@ $expire = "'" . $expire . "'"; } $notes = sanitizeInput($_POST['notes']); - $vendor = sanitizeInput($_POST['vendor'] ?? 0); + $vendor = intval($_POST['vendor'] ?? 0); mysqli_query($mysqli,"UPDATE software SET software_name = '$name', software_version = '$version', software_description = '$description', software_type = '$type', software_key = '$key', software_license_type = '$license_type', software_seats = $seats, software_purchase_reference = '$purchase_reference', software_purchase = $purchase, software_expire = $expire, software_notes = '$notes', software_vendor_id = $vendor WHERE software_id = $software_id"); From ad9e4b4fb40e7525540e4c04d94f38601dcc1b6f Mon Sep 17 00:00:00 2001 From: johnnyq Date: Tue, 4 Mar 2025 13:45:21 -0500 Subject: [PATCH 2/8] Added new php function to retrieve and escape a single record from a specified table using an id getFieldById(table, id, field_to_retrieve, escape_method) escape method defaults to SQL but html and json and int can be specified --- functions.php | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/functions.php b/functions.php index 903fe9480..4e013c37f 100644 --- a/functions.php +++ b/functions.php @@ -1413,4 +1413,91 @@ function logAuth($status, $details) { // Helper function for missing data fallback function getFallback($data) { return !empty($data) ? $data : 'N/A'; +} + +/** + * Retrieves a specified field's value from a table based on the record's id. + * It validates the table and field names, automatically determines the primary key (or uses the first column as fallback), + * and returns the field value with an appropriate escaping method. + * + * @param string $table The name of the table. + * @param int $id The record's id. + * @param string $field The field (column) to retrieve. + * @param string $escape_method The escape method: 'sql' (default, auto-detects int), 'html', 'json', or 'int'. + * + * @return mixed The escaped field value, or null if not found or invalid input. + */ +function getFieldById($table, $id, $field, $escape_method = 'sql') { + global $mysqli; // Use the global MySQLi connection + + // Validate table and field names to allow only letters, numbers, and underscores + if (!preg_match('/^[a-zA-Z0-9_]+$/', $table) || !preg_match('/^[a-zA-Z0-9_]+$/', $field)) { + return null; // Invalid table or field name + } + + // Sanitize id as an integer + $id = (int)$id; + + // Get the list of columns and their details from the table + $columns_result = mysqli_query($mysqli, "SHOW COLUMNS FROM `$table`"); + if (!$columns_result || mysqli_num_rows($columns_result) == 0) { + return null; // Table not found or has no columns + } + + // Build an associative array with column details + $columns = []; + while ($row = mysqli_fetch_assoc($columns_result)) { + $columns[$row['Field']] = [ + 'type' => $row['Type'], + 'key' => $row['Key'] + ]; + } + + // Find the primary key field if available + $id_field = null; + foreach ($columns as $col => $details) { + if ($details['key'] === 'PRI') { + $id_field = $col; + break; + } + } + // Fallback: if no primary key is found, use the first column + if (!$id_field) { + reset($columns); + $id_field = key($columns); + } + + // Ensure the requested field exists; if not, default to the id field + if (!array_key_exists($field, $columns)) { + $field = $id_field; + } + + // Build and execute the query to fetch the specified field value + $query = "SELECT `$field` FROM `$table` WHERE `$id_field` = $id"; + $sql = mysqli_query($mysqli, $query); + + if ($sql && mysqli_num_rows($sql) > 0) { + $row = mysqli_fetch_assoc($sql); + $value = $row[$field]; + + // Apply the desired escaping method or auto-detect integer type if using SQL escaping + switch ($escape_method) { + case 'html': + return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); // Escape for HTML + case 'json': + return json_encode($value); // Escape for JSON + case 'int': + return (int)$value; // Explicitly cast value to integer + case 'sql': + default: + // Auto-detect if the field type is integer + if (stripos($columns[$field]['type'], 'int') !== false) { + return (int)$value; + } else { + return sanitizeInput($value); // Escape for SQL using a custom function + } + } + } + + return null; // Return null if no record was found } \ No newline at end of file From 52a62fc23ca309558e0d8fa0e0caf6a7f8896857 Mon Sep 17 00:00:00 2001 From: johnnyq Date: Fri, 7 Mar 2025 14:47:47 -0500 Subject: [PATCH 3/8] Fix Client URL in recurring Invoices --- recurring_invoices.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/recurring_invoices.php b/recurring_invoices.php index a7f796569..e4e8ecf32 100644 --- a/recurring_invoices.php +++ b/recurring_invoices.php @@ -70,8 +70,8 @@ From 757a62c35b2cb8f130856a51a97159915cd74326 Mon Sep 17 00:00:00 2001 From: johnnyq Date: Fri, 7 Mar 2025 16:44:38 -0500 Subject: [PATCH 4/8] Fix Ticket Count under contact listing --- ajax/ajax_asset_details.php | 2 +- ajax/ajax_contact_details.php | 2 +- contacts.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ajax/ajax_asset_details.php b/ajax/ajax_asset_details.php index 21ff47a2f..b72660e08 100644 --- a/ajax/ajax_asset_details.php +++ b/ajax/ajax_asset_details.php @@ -848,7 +848,7 @@ function updateAssetNotes(asset_id) {