diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-20 17:02:16 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-20 17:02:16 -1000 |
| commit | 6cdfc55e5712075fef24a559138c054ef58e1ac1 (patch) | |
| tree | ba2a78bb10c4664c4b370107116f19c0250a7f2c /web/static/js/app.js | |
| parent | 5b6defbc8c3082013a86b727b4c75370ba3385c7 (diff) | |
Fix CSRF token missing from refresh fetch requests
Manual JavaScript fetch() calls weren't including the CSRF token,
causing 403 Forbidden on /api/refresh. Extract token from
hx-headers body attribute and include in all POST requests.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'web/static/js/app.js')
| -rw-r--r-- | web/static/js/app.js | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/web/static/js/app.js b/web/static/js/app.js index 0f1f087..4d26e66 100644 --- a/web/static/js/app.js +++ b/web/static/js/app.js @@ -3,6 +3,21 @@ // Constants const AUTO_REFRESH_INTERVAL = 5 * 60 * 1000; // 5 minutes in milliseconds +// Get CSRF token from body hx-headers attribute +function getCSRFToken() { + const body = document.body; + const headers = body.getAttribute('hx-headers'); + if (headers) { + try { + const parsed = JSON.parse(headers); + return parsed['X-CSRF-Token'] || ''; + } catch (e) { + console.error('Failed to parse CSRF token:', e); + } + } + return ''; +} + // Track current active tab (read from URL for state persistence) const urlParams = new URLSearchParams(window.location.search); let currentTab = urlParams.get('tab') || 'tasks'; @@ -94,7 +109,10 @@ async function refreshData() { try { // Force API refresh (updates cache) const refreshResponse = await fetch('/api/refresh', { - method: 'POST' + method: 'POST', + headers: { + 'X-CSRF-Token': getCSRFToken() + } }); if (!refreshResponse.ok) throw new Error('Refresh failed'); @@ -148,7 +166,10 @@ async function autoRefresh() { try { // Force API refresh (updates cache) const refreshResponse = await fetch('/api/refresh', { - method: 'POST' + method: 'POST', + headers: { + 'X-CSRF-Token': getCSRFToken() + } }); if (!refreshResponse.ok) throw new Error('Refresh failed'); |
