Security: defense-in-depth company isolation for all operations
Critical fixes: - company_logo_upload: validate user has access to target company - All delete functions (db.php): accept optional company_id parameter for defense-in-depth filtering (customers, devices, ipam, guides, leads, tickets, archives, mailboxes, rules, templates, todos) - All API delete calls now pass company_id to db layer - ticket_bulk_delete: per-ticket company_id filtering - todo_comment/time/subtask operations: verify todo belongs to company - dbGetMailbox: optional company_id scoping, used in smtp_test - requireCompanyOrParam: no longer mutates session permanently - Fix _dbFetch typo in zammad_attachment (was runtime error) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
68
db.php
68
db.php
@@ -1171,8 +1171,9 @@ function dbSaveCustomer(string $companyId, array $customer): void {
|
||||
}
|
||||
}
|
||||
|
||||
function dbDeleteCustomer(string $customerId): void {
|
||||
_dbExecute("DELETE FROM customers WHERE id = ?", [$customerId]);
|
||||
function dbDeleteCustomer(string $customerId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM customers WHERE id = ? AND company_id = ?", [$customerId, $companyId]);
|
||||
else _dbExecute("DELETE FROM customers WHERE id = ?", [$customerId]);
|
||||
}
|
||||
|
||||
// ==================== SIJAINNIT (SITES) — POISTETTU, KÄYTETÄÄN LAITETILOJA ====================
|
||||
@@ -1224,8 +1225,9 @@ function dbSaveDevice(string $companyId, array $device): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteDevice(string $deviceId): void {
|
||||
_dbExecute("DELETE FROM devices WHERE id = ?", [$deviceId]);
|
||||
function dbDeleteDevice(string $deviceId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM devices WHERE id = ? AND company_id = ?", [$deviceId, $companyId]);
|
||||
else _dbExecute("DELETE FROM devices WHERE id = ?", [$deviceId]);
|
||||
}
|
||||
|
||||
// ==================== IPAM ====================
|
||||
@@ -1270,8 +1272,9 @@ function dbSaveIpam(string $companyId, array $entry): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteIpam(string $id): void {
|
||||
_dbExecute("DELETE FROM ipam WHERE id = ?", [$id]);
|
||||
function dbDeleteIpam(string $id, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM ipam WHERE id = ? AND company_id = ?", [$id, $companyId]);
|
||||
else _dbExecute("DELETE FROM ipam WHERE id = ?", [$id]);
|
||||
}
|
||||
|
||||
// ==================== OHJEET (GUIDES) ====================
|
||||
@@ -1288,8 +1291,9 @@ function dbSaveGuideCategory(string $companyId, array $cat): void {
|
||||
", [$cat['id'], $companyId, $cat['nimi'] ?? '', $cat['sort_order'] ?? 0]);
|
||||
}
|
||||
|
||||
function dbDeleteGuideCategory(string $catId): void {
|
||||
_dbExecute("DELETE FROM guide_categories WHERE id = ?", [$catId]);
|
||||
function dbDeleteGuideCategory(string $catId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM guide_categories WHERE id = ? AND company_id = ?", [$catId, $companyId]);
|
||||
else _dbExecute("DELETE FROM guide_categories WHERE id = ?", [$catId]);
|
||||
}
|
||||
|
||||
function dbLoadGuides(string $companyId): array {
|
||||
@@ -1334,8 +1338,9 @@ function dbSaveGuide(string $companyId, array $g): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteGuide(string $guideId): void {
|
||||
_dbExecute("DELETE FROM guides WHERE id = ?", [$guideId]);
|
||||
function dbDeleteGuide(string $guideId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM guides WHERE id = ? AND company_id = ?", [$guideId, $companyId]);
|
||||
else _dbExecute("DELETE FROM guides WHERE id = ?", [$guideId]);
|
||||
}
|
||||
|
||||
// ==================== LIIDIT ====================
|
||||
@@ -1376,8 +1381,9 @@ function dbSaveLead(string $companyId, array $lead): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteLead(string $leadId): void {
|
||||
_dbExecute("DELETE FROM leads WHERE id = ?", [$leadId]);
|
||||
function dbDeleteLead(string $leadId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM leads WHERE id = ? AND company_id = ?", [$leadId, $companyId]);
|
||||
else _dbExecute("DELETE FROM leads WHERE id = ?", [$leadId]);
|
||||
}
|
||||
|
||||
// ==================== TIKETIT ====================
|
||||
@@ -1508,8 +1514,9 @@ function dbSaveTicket(string $companyId, array $ticket): void {
|
||||
}
|
||||
}
|
||||
|
||||
function dbDeleteTicket(string $ticketId): void {
|
||||
_dbExecute("DELETE FROM tickets WHERE id = ?", [$ticketId]);
|
||||
function dbDeleteTicket(string $ticketId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM tickets WHERE id = ? AND company_id = ?", [$ticketId, $companyId]);
|
||||
else _dbExecute("DELETE FROM tickets WHERE id = ?", [$ticketId]);
|
||||
}
|
||||
|
||||
function dbFindTicketByMessageId(string $companyId, string $messageId): ?array {
|
||||
@@ -1550,8 +1557,9 @@ function dbRestoreArchive(string $archiveId): ?array {
|
||||
return json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
function dbDeleteArchive(string $archiveId): void {
|
||||
_dbExecute("DELETE FROM archives WHERE id = ?", [$archiveId]);
|
||||
function dbDeleteArchive(string $archiveId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM archives WHERE id = ? AND company_id = ?", [$archiveId, $companyId]);
|
||||
else _dbExecute("DELETE FROM archives WHERE id = ?", [$archiveId]);
|
||||
}
|
||||
|
||||
// ==================== CHANGELOG ====================
|
||||
@@ -1624,12 +1632,17 @@ function dbSaveMailbox(string $companyId, array $mailbox): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteMailbox(string $mailboxId): void {
|
||||
_dbExecute("DELETE FROM mailboxes WHERE id = ?", [$mailboxId]);
|
||||
function dbDeleteMailbox(string $mailboxId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM mailboxes WHERE id = ? AND company_id = ?", [$mailboxId, $companyId]);
|
||||
else _dbExecute("DELETE FROM mailboxes WHERE id = ?", [$mailboxId]);
|
||||
}
|
||||
|
||||
function dbGetMailbox(string $mailboxId): ?array {
|
||||
$b = _dbFetchOne("SELECT * FROM mailboxes WHERE id = ?", [$mailboxId]);
|
||||
function dbGetMailbox(string $mailboxId, string $companyId = ''): ?array {
|
||||
if ($companyId) {
|
||||
$b = _dbFetchOne("SELECT * FROM mailboxes WHERE id = ? AND company_id = ?", [$mailboxId, $companyId]);
|
||||
} else {
|
||||
$b = _dbFetchOne("SELECT * FROM mailboxes WHERE id = ?", [$mailboxId]);
|
||||
}
|
||||
if ($b) {
|
||||
$b['aktiivinen'] = (bool)$b['aktiivinen'];
|
||||
$b['imap_port'] = (int)$b['imap_port'];
|
||||
@@ -1679,8 +1692,9 @@ function dbSaveTicketRule(string $companyId, array $rule): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteTicketRule(string $ruleId): void {
|
||||
_dbExecute("DELETE FROM ticket_rules WHERE id = ?", [$ruleId]);
|
||||
function dbDeleteTicketRule(string $ruleId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM ticket_rules WHERE id = ? AND company_id = ?", [$ruleId, $companyId]);
|
||||
else _dbExecute("DELETE FROM ticket_rules WHERE id = ?", [$ruleId]);
|
||||
}
|
||||
|
||||
// ==================== TIKETTITYYPIT ====================
|
||||
@@ -1801,8 +1815,9 @@ function dbSaveTemplate(string $companyId, array $tpl): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteTemplate(string $templateId): void {
|
||||
_dbExecute("DELETE FROM reply_templates WHERE id = ?", [$templateId]);
|
||||
function dbDeleteTemplate(string $templateId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM reply_templates WHERE id = ? AND company_id = ?", [$templateId, $companyId]);
|
||||
else _dbExecute("DELETE FROM reply_templates WHERE id = ?", [$templateId]);
|
||||
}
|
||||
|
||||
// ==================== PRIORITY EMAILS (ASIAKKUUDET) ====================
|
||||
@@ -1888,8 +1903,9 @@ function dbSaveTodo(string $companyId, array $todo): void {
|
||||
]);
|
||||
}
|
||||
|
||||
function dbDeleteTodo(string $todoId): void {
|
||||
_dbExecute("DELETE FROM todos WHERE id = ?", [$todoId]);
|
||||
function dbDeleteTodo(string $todoId, string $companyId = ''): void {
|
||||
if ($companyId) _dbExecute("DELETE FROM todos WHERE id = ? AND company_id = ?", [$todoId, $companyId]);
|
||||
else _dbExecute("DELETE FROM todos WHERE id = ?", [$todoId]);
|
||||
}
|
||||
|
||||
function dbAddTodoComment(string $todoId, array $comment): void {
|
||||
|
||||
Reference in New Issue
Block a user