security: fix all Medium findings from FLAWS_REPORT audit
- Auth: TOTP replay protection with counter tracking, constant-time backup code comparison, atomic lockout increment, per-token logout - Invoices/PDFs: net-based VAT calculation, dangerous URL scheme stripping in cleanQuillHtml, orders-pdf error handling - Orders: reject item changes on status transition, cascading delete cleanup, take:1 with orderBy - Projects: atomic rename collision handling, MIME/extension validation, empty customer name rejection - Attendance: Czech public holiday awareness in frontend fund calculation, leave_hours 0 handling, invalid date NaN guard, bounded per-month queries in workfund - Users/Admin: profile audit logging + password validation, session revocation guard, session ID validation, dashboard DB aggregation, soft-deleted record protection in scope templates - Frontend: FormField label linkage, Pagination ARIA, error handling in OrderConfirmationModal, 401 propagation, GPS emoji hidden from screen readers, table sort state fix, geolocation race/abort cleanup, Leaflet popup DOM safety, Vehicles toggleActive minimal body, CompanySettings ref mutation fix, OfferDetail unlock abort, AttendanceBalances combined fetches - Utils: env validation, Puppeteer concurrency mutex, invoice alert cron cleanup on shutdown, body limit alignment, TOTP error logging, trustProxy from env, symlink rejection, rate cache Map usage Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -10,13 +10,13 @@ interface CnbRate {
|
||||
amount: number;
|
||||
}
|
||||
|
||||
const rateCache: Record<string, Record<string, number>> = {};
|
||||
const rateCache = new Map<string, Record<string, number>>();
|
||||
|
||||
async function fetchRatesForDate(
|
||||
date?: string,
|
||||
): Promise<Record<string, number>> {
|
||||
const key = date || "today";
|
||||
if (rateCache[key]) return rateCache[key];
|
||||
if (rateCache.has(key)) return rateCache.get(key)!;
|
||||
|
||||
try {
|
||||
let url = "https://api.cnb.cz/cnbapi/exrates/daily?lang=EN";
|
||||
@@ -32,11 +32,11 @@ async function fetchRatesForDate(
|
||||
rates[r.currencyCode] = r.rate / r.amount;
|
||||
}
|
||||
|
||||
rateCache[key] = rates;
|
||||
rateCache.set(key, rates);
|
||||
return rates;
|
||||
} catch (err) {
|
||||
console.error("Failed to fetch CNB exchange rates:", err);
|
||||
if (rateCache["today"]) return rateCache["today"];
|
||||
if (rateCache.has("today")) return rateCache.get("today")!;
|
||||
throw new Error("Nepodařilo se získat aktuální kurzy z ČNB");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user