fix: oprava kritických bezpečnostních chyb a bugů z code review

- SEC-1: nahrazen exec('fsutil') za PHP-native is_link()+realpath() v NasFileManager - eliminace command injection
- SEC-2: přidáno ověření aktuálního hesla při změně hesla (profile.php + DashProfile.jsx)
- BUG-1: attendance punch obalen do transakce s SELECT FOR UPDATE - prevence race condition při dvojkliku
- BUG-2: eliminován N+1 SQL dotaz pro VAT v invoice listu - výpočet přesunut do subquery
- BUG-5/6: delete a update attendance záznamů obaleny do transakcí - prevence nekonzistentního stavu
- BUG-7: opravena duplikace nabídky - přidáno chybějící pole unit v offer items

ESLint: 0 errors | PHPCS: 0 errors | Build: OK

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-17 13:46:20 +01:00
parent 913344b8c4
commit 5550358b15
45 changed files with 373 additions and 301 deletions

View File

@@ -213,6 +213,8 @@ function handleGetList(PDO $pdo): void
c.name as customer_name,
(SELECT COALESCE(SUM(ii.quantity * ii.unit_price), 0)
FROM invoice_items ii WHERE ii.invoice_id = i.id) as subtotal,
(SELECT COALESCE(SUM(ii.quantity * ii.unit_price * ii.vat_rate / 100), 0)
FROM invoice_items ii WHERE ii.invoice_id = i.id) as vat_amount,
o.order_number
{$from} {$where}
ORDER BY {$p['sort']} {$p['order']}",
@@ -222,20 +224,11 @@ function handleGetList(PDO $pdo): void
$invoices = $result['items'];
// Dopocitat celkovou castku s DPH
foreach ($invoices as &$inv) {
$subtotal = (float) $inv['subtotal'];
if ($inv['apply_vat']) {
$vatStmt = $pdo->prepare('
SELECT COALESCE(SUM(quantity * unit_price * vat_rate / 100), 0)
FROM invoice_items WHERE invoice_id = ?
');
$vatStmt->execute([$inv['id']]);
$vatAmount = (float) $vatStmt->fetchColumn();
$inv['total'] = $subtotal + $vatAmount;
} else {
$inv['total'] = $subtotal;
}
$inv['total'] = $inv['apply_vat']
? $subtotal + (float) $inv['vat_amount']
: $subtotal;
}
unset($inv);