diff --git a/agent/dashboard.php b/agent/dashboard.php index de218b403..51f64253a 100644 --- a/agent/dashboard.php +++ b/agent/dashboard.php @@ -123,6 +123,7 @@ if ($user_config_dashboard_financial_enable == 1) { SELECT client_name, invoice_number, invoice_prefix, payment_amount, payment_date FROM payments JOIN invoices ON payment_invoice_id = invoice_id JOIN clients ON invoice_client_id = client_id + WHERE 1=1 " . clientScopeSql('invoice_client_id') . " ORDER BY payment_id DESC LIMIT 5 "); @@ -607,6 +608,7 @@ if ($user_config_dashboard_technical_enable == 1) { LEFT JOIN contacts ON ticket_contact_id = contact_id WHERE ticket_assigned_to = $session_user_id AND ticket_closed_at IS NULL + " . clientScopeSql('ticket_client_id') . " ORDER BY ticket_number DESC "); ?> diff --git a/agent/post/client.php b/agent/post/client.php index d00a47738..c6f3fbbfd 100644 --- a/agent/post/client.php +++ b/agent/post/client.php @@ -140,6 +140,8 @@ if (isset($_POST['edit_client'])) { $client_id = intval($_POST['client_id']); + enforceClientAccess(); + // Update client mysqli_query($mysqli, "UPDATE clients SET client_name = '$name', client_type = '$type', client_website = '$website', client_referral = '$referral', client_rate = $rate, client_net_terms = $net_terms, client_tax_id_number = '$tax_id_number', client_lead = $lead, client_abbreviation = '$abbreviation', client_notes = '$notes' WHERE client_id = $client_id"); @@ -212,6 +214,8 @@ if (isset($_GET['archive_client'])) { $client_id = intval($_GET['archive_client']); + enforceClientAccess(); + // Archive client mysqli_query($mysqli, "UPDATE clients SET client_archived_at = NOW() WHERE client_id = $client_id"); @@ -242,6 +246,8 @@ if (isset($_GET['restore_client'])) { $client_id = intval($_GET['restore_client']); + enforceClientAccess(); + // Get Client Name $client_name = escapeSql(getFieldById('clients', $client_id, 'client_name')); @@ -263,6 +269,8 @@ if (isset($_GET['delete_client'])) { $client_id = intval($_GET['delete_client']); + enforceClientAccess(); + // Get Client Name $client_name = escapeSql(getFieldById('clients', $client_id, 'client_name')); @@ -761,6 +769,11 @@ if (isset($_POST['bulk_add_client_ticket'])) { // Create ticket for each selected asset if (isset($_POST['client_ids'])) { + // Check every selected client before creating any tickets + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + // Get a Asset Count $client_count = count($_POST['client_ids']); @@ -844,6 +857,11 @@ if (isset($_POST['bulk_edit_client_industry'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = count($_POST['client_ids']); foreach($_POST['client_ids'] as $client_id) { @@ -878,6 +896,11 @@ if (isset($_POST['bulk_edit_client_referral'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = count($_POST['client_ids']); foreach($_POST['client_ids'] as $client_id) { @@ -912,6 +935,11 @@ if (isset($_POST['bulk_edit_client_hourly_rate'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = count($_POST['client_ids']); foreach($_POST['client_ids'] as $client_id) { @@ -946,6 +974,11 @@ if (isset($_POST['bulk_edit_client_net_terms'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = count($_POST['client_ids']); foreach($_POST['client_ids'] as $client_id) { @@ -978,6 +1011,11 @@ if (isset($_POST['bulk_assign_client_tags'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = count($_POST['client_ids']); foreach($_POST['client_ids'] as $client_id) { @@ -1024,6 +1062,11 @@ if (isset($_POST['bulk_send_client_email']) && isset($_POST['client_ids'])) { $client_ids = array_map('intval', $_POST['client_ids']); $count = count($client_ids); + // Check every selected client before queuing anything + foreach ($client_ids as $client_id) { + enforceClientAccess($client_id); + } + // Email metadata $mail_from = escapeSql($_POST['mail_from']); $mail_from_name = escapeSql($_POST['mail_from_name']); @@ -1112,6 +1155,11 @@ if (isset($_POST['bulk_archive_clients'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = 0; foreach ($_POST['client_ids'] as $client_id) { @@ -1148,6 +1196,11 @@ if (isset($_POST['bulk_unarchive_clients'])) { if (isset($_POST['client_ids'])) { + // Check every selected client before changing any of them + foreach ($_POST['client_ids'] as $client_id) { + enforceClientAccess(intval($client_id)); + } + $count = count($_POST['client_ids']); foreach ($_POST['client_ids'] as $client_id) { diff --git a/agent/post/credit.php b/agent/post/credit.php index b2da02849..cfbb6711e 100644 --- a/agent/post/credit.php +++ b/agent/post/credit.php @@ -13,6 +13,9 @@ if (isset($_POST['add_credit'])) { enforceUserPermission('module_sales', 2); $client_id = intval($_POST['client']); + + enforceClientAccess(); + $amount = floatval($_POST['amount']); $type = escapeSql($_POST['type']); $expire = escapeSql($_POST['expire']); diff --git a/agent/post/expense.php b/agent/post/expense.php index d2f5c39a6..43d33b635 100644 --- a/agent/post/expense.php +++ b/agent/post/expense.php @@ -57,12 +57,18 @@ if (isset($_POST['edit_expense'])) { require_once 'expense_model.php'; + $expense_id = intval($_POST['expense_id']); + + // Check the client the expense belongs to now, not just the one submitted + $existing_client_id = intval(getFieldById('expenses', $expense_id, 'expense_client_id')); + if ($existing_client_id) { + enforceClientAccess($existing_client_id); + } + if ($client_id) { enforceClientAccess(); } - $expense_id = intval($_POST['expense_id']); - // Get old receipt $existing_file_name = escapeSql(getFieldById('expenses', $expense_id, 'expense_receipt')); diff --git a/agent/post/recurring_expense.php b/agent/post/recurring_expense.php index b683d3575..3f4032434 100644 --- a/agent/post/recurring_expense.php +++ b/agent/post/recurring_expense.php @@ -63,6 +63,12 @@ if (isset($_POST['edit_recurring_expense'])) { $description = escapeSql($_POST['description']); $reference = escapeSql($_POST['reference']); + // Check the client the recurring expense belongs to now, not just the one submitted + $existing_client_id = intval(getFieldById('recurring_expenses', $recurring_expense_id, 'recurring_expense_client_id')); + if ($existing_client_id) { + enforceClientAccess($existing_client_id); + } + if ($client_id) { enforceClientAccess(); } @@ -97,6 +103,10 @@ if (isset($_GET['delete_recurring_expense'])) { $recurring_expense_description = escapeSql($row['recurring_expense_description']); $client_id = intval($row['recurring_expense_client_id']); + if ($client_id) { + enforceClientAccess(); + } + mysqli_query($mysqli,"DELETE FROM recurring_expenses WHERE recurring_expense_id = $recurring_expense_id"); logAudit("Recurring Expense", "Delete", "$session_name deleted recurring expense $recurring_expense_description", $client_id); diff --git a/agent/post/revenue.php b/agent/post/revenue.php index 39d38aabb..f59114aa8 100644 --- a/agent/post/revenue.php +++ b/agent/post/revenue.php @@ -39,6 +39,12 @@ if (isset($_POST['edit_revenue'])) { enforceUserPermission('module_sales', 2); $revenue_id = intval($_POST['revenue_id']); + + $client_id = intval(getFieldById('revenues', $revenue_id, 'revenue_client_id')); + if ($client_id) { + enforceClientAccess(); + } + $date = escapeSql($_POST['date']); $amount = floatval($_POST['amount']); $account = intval($_POST['account']); @@ -65,6 +71,11 @@ if (isset($_GET['delete_revenue'])) { $revenue_id = intval($_GET['delete_revenue']); + $client_id = intval(getFieldById('revenues', $revenue_id, 'revenue_client_id')); + if ($client_id) { + enforceClientAccess(); + } + // Get Revenue Details $revenue_description = escapeSql(getFieldById('revenues', $revenue_id, 'revenue_description')); diff --git a/agent/post/task.php b/agent/post/task.php index 6c4035655..e68fa3453 100644 --- a/agent/post/task.php +++ b/agent/post/task.php @@ -364,6 +364,9 @@ if (isset($_GET['approve_ticket_task'])) { exit; } + $client_id = intval(getFieldById('tickets', $ticket_id, 'ticket_client_id')); + enforceClientAccess(); + // Validate approver (deny) if ($required_user > 0 && $required_user !== $session_user_id) { flashAlert("You cannot approve that task", 'error'); @@ -399,6 +402,11 @@ if (isset($_GET['delete_ticket_task_approver'])) { $approval_id = intval($_GET['delete_ticket_task_approver']); + $sql = mysqli_query($mysqli, "SELECT ticket_client_id FROM task_approvals LEFT JOIN tasks ON task_id = approval_task_id LEFT JOIN tickets ON ticket_id = task_ticket_id WHERE approval_id = $approval_id"); + $row = mysqli_fetch_assoc($sql); + $client_id = intval($row['ticket_client_id'] ?? 0); + enforceClientAccess(); + mysqli_query($mysqli, "DELETE FROM task_approvals WHERE approval_id = $approval_id"); logAudit("Task", "Delete", "$session_name deleted task approval request ($approval_id)", 0, 0); diff --git a/agent/post/trip.php b/agent/post/trip.php index 9e0cbc87b..35a669b2f 100644 --- a/agent/post/trip.php +++ b/agent/post/trip.php @@ -40,6 +40,12 @@ if (isset($_POST['edit_trip'])) { $trip_id = intval($_POST['trip_id']); + // Check the client the trip belongs to now, not just the one submitted + $existing_client_id = intval(getFieldById('trips', $trip_id, 'trip_client_id')); + if ($existing_client_id) { + enforceClientAccess($existing_client_id); + } + $client_id = intval($_POST['client_id']); if ($client_id) { diff --git a/agent/reports/client_ticket_time_detail.php b/agent/reports/client_ticket_time_detail.php index 8cbbc777b..7585e26f7 100644 --- a/agent/reports/client_ticket_time_detail.php +++ b/agent/reports/client_ticket_time_detail.php @@ -76,6 +76,7 @@ $billing_increment_minutes = (int) round($billing_increment_seconds / 60); // Ticket-level billable flag (same as your original report) $billable_sql = $billable_only ? " AND t.ticket_billable = 1 " : ""; +$client_scope_sql = clientScopeSql('c.client_id'); /** * Query returns ONLY replies that have time_worked and are within date range. @@ -108,6 +109,7 @@ $stmt = $mysqli->prepare(" WHERE c.client_archived_at IS NULL $billable_sql + $client_scope_sql ORDER BY c.client_name ASC, t.ticket_number ASC, diff --git a/agent/reports/income_by_client.php b/agent/reports/income_by_client.php index bad40193a..5d5c8a27f 100644 --- a/agent/reports/income_by_client.php +++ b/agent/reports/income_by_client.php @@ -48,9 +48,10 @@ $sql_payment_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(payment_date) A $sql_clients = "SELECT c.client_id, c.client_name, SUM(p.payment_amount) AS amount_paid FROM clients AS c JOIN invoices AS i ON c.client_id = i.invoice_client_id - JOIN payments AS p ON i.invoice_id = p.payment_invoice_id"; + JOIN payments AS p ON i.invoice_id = p.payment_invoice_id + WHERE 1=1" . clientScopeSql('c.client_id'); if ($year != 'all') { - $sql_clients .= " WHERE YEAR(p.payment_date) = $year"; + $sql_clients .= " AND YEAR(p.payment_date) = $year"; } $sql_clients .= " GROUP BY c.client_id HAVING amount_paid > 599 diff --git a/agent/reports/outstanding_balances.php b/agent/reports/outstanding_balances.php index 0a55a77a5..6af09b0e9 100644 --- a/agent/reports/outstanding_balances.php +++ b/agent/reports/outstanding_balances.php @@ -38,6 +38,7 @@ enforceUserPermission('module_financial'); GROUP BY payment_invoice_id) as payments ON invoices.invoice_id = payments.payment_invoice_id + WHERE 1=1 " . clientScopeSql('clients.client_id') . " GROUP BY clients.client_id, clients.client_name diff --git a/agent/reports/recurring_by_client.php b/agent/reports/recurring_by_client.php index e7204f233..3a5f76b44 100644 --- a/agent/reports/recurring_by_client.php +++ b/agent/reports/recurring_by_client.php @@ -11,6 +11,7 @@ $sql = mysqli_query($mysqli, " FROM clients LEFT JOIN recurring_invoices ON client_id = recurring_invoice_client_id WHERE recurring_invoice_status = 1 + " . clientScopeSql('clients.client_id') . " GROUP BY clients.client_id HAVING recurring_monthly_total > 0 ORDER BY recurring_monthly_total DESC diff --git a/agent/reports/sla_by_client.php b/agent/reports/sla_by_client.php index 4ea519d99..1b00305cf 100644 --- a/agent/reports/sla_by_client.php +++ b/agent/reports/sla_by_client.php @@ -25,7 +25,7 @@ if ($month) { $sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC"); -$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC"); +$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL " . clientScopeSql('client_id') . " ORDER BY client_name ASC"); // Clock time spent on resolved tickets, gathered for every client at once diff --git a/agent/reports/ticket_by_client.php b/agent/reports/ticket_by_client.php index dd7985872..03661e840 100644 --- a/agent/reports/ticket_by_client.php +++ b/agent/reports/ticket_by_client.php @@ -18,7 +18,7 @@ if (isset($_GET['month'])) { $sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC"); -$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL ORDER BY client_name ASC"); +$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE client_archived_at IS NULL " . clientScopeSql('client_id') . " ORDER BY client_name ASC"); ?> diff --git a/agent/reports/tickets_unbilled.php b/agent/reports/tickets_unbilled.php index 0f1b9ba18..840ec0edd 100644 --- a/agent/reports/tickets_unbilled.php +++ b/agent/reports/tickets_unbilled.php @@ -12,7 +12,7 @@ if (isset($_GET['year'])) { $sql_ticket_years = mysqli_query($mysqli, "SELECT DISTINCT YEAR(ticket_created_at) AS ticket_year FROM tickets ORDER BY ticket_year DESC"); -$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients ORDER BY client_name ASC"); +$sql_clients = mysqli_query($mysqli, "SELECT client_id, client_name FROM clients WHERE 1=1 " . clientScopeSql('client_id') . " ORDER BY client_name ASC"); $rows = 0;