Implement security hardening across frontend, backend, and infrastructure
- nginx: add X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, and Referrer-Policy headers on all responses; rate limit /api/auth/login to 5 req/min per IP (burst 3) to prevent brute force - frontend: add escHtml() utility to api.js; use it on all notes fields across dashboard, log, history, flock, and budget pages to prevent XSS - log.js: fix broken loadRecent() call referencing removed #recent-body element; replaced with loadHistory() from history.js - schemas.py: raise minimum password length from 6 to 10 characters - admin.py: add audit logging for password reset, disable, delete, and impersonate actions; fix impersonate to use named admin param for logging - main.py: add startup env validation — exits with clear error if any required env var is missing; configure structured logging to stdout - docker-compose.yml: add log rotation (10 MB / 3 files) to all services Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,26 +1,3 @@
|
||||
async function loadRecent() {
|
||||
const tbody = document.getElementById('recent-body');
|
||||
try {
|
||||
const eggs = await API.get('/api/eggs');
|
||||
const recent = eggs.slice(0, 7);
|
||||
|
||||
if (recent.length === 0) {
|
||||
tbody.innerHTML = '<tr class="empty-row"><td colspan="3">No entries yet.</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
tbody.innerHTML = recent.map(e => `
|
||||
<tr>
|
||||
<td>${fmtDate(e.date)}</td>
|
||||
<td>${e.eggs}</td>
|
||||
<td class="notes">${e.notes || ''}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
} catch (err) {
|
||||
tbody.innerHTML = '<tr class="empty-row"><td colspan="3">Could not load recent entries.</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const form = document.getElementById('log-form');
|
||||
const msg = document.getElementById('msg');
|
||||
@@ -42,11 +19,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
showMessage(msg, 'Entry saved!');
|
||||
form.reset();
|
||||
setToday(document.getElementById('date'));
|
||||
loadRecent();
|
||||
loadHistory();
|
||||
} catch (err) {
|
||||
showMessage(msg, `Error: ${err.message}`, 'error');
|
||||
}
|
||||
});
|
||||
|
||||
loadRecent();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user