fix: codebase audit fixes — indexes, daily_rate, anomaly key, CSRF, chat pruning, shopping_name
## v1.7.6 - DB: fix shopping_name Pi→Piadina, Grana→Formaggio, Prosciutto cotto→Affettato, Panna acida→Panna - DB: composite indexes idx_transactions_type_date + idx_transactions_pid_type_undone (+ migration) - PHP: daily_rate uses first_in→last_activity window (not first_in→now) - PHP: anomaly dismiss key uses product_id+direction (stable, not product_id+round(expected)) - PHP: smart shopping — products exhausted within 14 days bypass token/family suppression - PHP: chat pruning — DELETE messages beyond 200 after each chatSave() - PHP: getStats() — 5 queries → 1 consolidated query with subselects - PHP: bringCleanupObsolete — 300ms delay between bulk removals - PHP: CSRF guard — POST write actions require X-EverShelf-Request:1 or Content-Type:application/json - JS: api() — sends X-EverShelf-Request:1 on all POST requests - JS: _opLog — prunes entries older than 30 days in addition to 200-entry cap
This commit is contained in:
+8
-5
@@ -2502,7 +2502,7 @@ async function api(action, params = {}, method = 'GET', body = null, extraHeader
|
||||
}
|
||||
const opts = { method, cache: 'no-store' };
|
||||
if (body) {
|
||||
opts.headers = { 'Content-Type': 'application/json', ...extraHeaders };
|
||||
opts.headers = { 'Content-Type': 'application/json', 'X-EverShelf-Request': '1', ...extraHeaders };
|
||||
opts.body = JSON.stringify(body);
|
||||
} else if (Object.keys(extraHeaders).length > 0) {
|
||||
opts.headers = { ...extraHeaders };
|
||||
@@ -9264,10 +9264,13 @@ async function cleanupObsoleteBringItems() {
|
||||
function logOperation(action, details) {
|
||||
try {
|
||||
const log = JSON.parse(localStorage.getItem('_opLog') || '[]');
|
||||
log.push({ ts: new Date().toISOString(), action, details });
|
||||
// Keep last 200 entries
|
||||
if (log.length > 200) log.splice(0, log.length - 200);
|
||||
localStorage.setItem('_opLog', JSON.stringify(log));
|
||||
const now = Date.now();
|
||||
log.push({ ts: new Date(now).toISOString(), action, details });
|
||||
// Prune: keep only last 200 entries AND entries newer than 30 days
|
||||
const cutoff = now - 30 * 24 * 60 * 60 * 1000;
|
||||
const pruned = log.filter(e => new Date(e.ts).getTime() >= cutoff);
|
||||
const final = pruned.length > 200 ? pruned.slice(pruned.length - 200) : pruned;
|
||||
localStorage.setItem('_opLog', JSON.stringify(final));
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user