From 7815b45483949f32a6ad5fb3c6dc2003e8b0035f Mon Sep 17 00:00:00 2001 From: rcourtman Date: Wed, 12 Nov 2025 00:00:55 +0000 Subject: [PATCH] Fix CSRF token validation failure in Settings diagnostics endpoints (related to #600) The "Check Proxy Nodes" button in Settings > Diagnostics was returning 403 Forbidden due to missing CSRF token. The frontend was using native fetch() instead of apiFetch() which automatically includes CSRF tokens for POST requests. Fixed three endpoints in Settings.tsx: - /api/diagnostics (GET) - for consistency - /api/diagnostics/temperature-proxy/register-nodes (POST) - reported issue - /api/diagnostics/docker/prepare-token (POST) - same bug Note: Export/import config endpoints intentionally continue using native fetch() because they need custom 401/403 handling to show the API token modal instead of redirecting to login. --- frontend-modern/src/components/Settings/Settings.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend-modern/src/components/Settings/Settings.tsx b/frontend-modern/src/components/Settings/Settings.tsx index 44e3332..e39570d 100644 --- a/frontend-modern/src/components/Settings/Settings.tsx +++ b/frontend-modern/src/components/Settings/Settings.tsx @@ -17,6 +17,7 @@ import { copyToClipboard } from '@/utils/clipboard'; import { getPulsePort, getPulseWebSocketUrl } from '@/utils/url'; import { logger } from '@/utils/logger'; import { + apiFetch, clearApiToken as clearApiClientToken, getApiToken as getApiClientToken, setApiToken as setApiClientToken, @@ -794,7 +795,7 @@ const Settings: Component = (props) => { const runDiagnostics = async () => { setRunningDiagnostics(true); try { - const response = await fetch('/api/diagnostics'); + const response = await apiFetch('/api/diagnostics'); const diag = await response.json(); setDiagnosticsData(diag); } catch (err) { @@ -809,7 +810,7 @@ const Settings: Component = (props) => { if (proxyActionLoading()) return; setProxyActionLoading('register-nodes'); try { - const response = await fetch('/api/diagnostics/temperature-proxy/register-nodes', { + const response = await apiFetch('/api/diagnostics/temperature-proxy/register-nodes', { method: 'POST', }); const data = await response.json().catch(() => null); @@ -843,7 +844,7 @@ const Settings: Component = (props) => { if (dockerActionLoading()) return; setDockerActionLoading(hostId); try { - const response = await fetch('/api/diagnostics/docker/prepare-token', { + const response = await apiFetch('/api/diagnostics/docker/prepare-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ hostId }),