From eb6a44a369c08016712f8a1e1d0e759923ff48bc 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 44e333259..e39570d04 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 }),