summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-20 17:02:16 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-20 17:02:16 -1000
commit6cdfc55e5712075fef24a559138c054ef58e1ac1 (patch)
treeba2a78bb10c4664c4b370107116f19c0250a7f2c
parent5b6defbc8c3082013a86b727b4c75370ba3385c7 (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>
-rw-r--r--web/static/js/app.js25
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');