From e7d6d2f1ec90f044c97aef74f8575b357bc557fb Mon Sep 17 00:00:00 2001 From: rcourtman Date: Tue, 23 Dec 2025 12:19:39 +0000 Subject: [PATCH] Polish: Standardize API calls to use apiClient --- frontend-modern/src/components/DemoBanner.tsx | 3 ++- .../Settings/ChangePasswordModal.tsx | 26 ++++-------------- .../src/components/Settings/NodeModal.tsx | 2 +- .../Settings/QuickSecuritySetup.tsx | 27 ++----------------- 4 files changed, 10 insertions(+), 48 deletions(-) diff --git a/frontend-modern/src/components/DemoBanner.tsx b/frontend-modern/src/components/DemoBanner.tsx index 85a72add8..a2714f170 100644 --- a/frontend-modern/src/components/DemoBanner.tsx +++ b/frontend-modern/src/components/DemoBanner.tsx @@ -1,4 +1,5 @@ import { createSignal, onMount, Show } from 'solid-js'; +import { apiFetch } from '@/utils/apiClient'; export function DemoBanner() { const [isDemoMode, setIsDemoMode] = createSignal(false); @@ -7,7 +8,7 @@ export function DemoBanner() { onMount(async () => { // Check if we're in demo mode by trying a test request try { - const response = await fetch('/api/health'); + const response = await apiFetch('/api/health'); const demoHeader = response.headers.get('X-Demo-Mode'); if (demoHeader === 'true') { setIsDemoMode(true); diff --git a/frontend-modern/src/components/Settings/ChangePasswordModal.tsx b/frontend-modern/src/components/Settings/ChangePasswordModal.tsx index 620ebf77a..e0cb40baf 100644 --- a/frontend-modern/src/components/Settings/ChangePasswordModal.tsx +++ b/frontend-modern/src/components/Settings/ChangePasswordModal.tsx @@ -1,5 +1,6 @@ import { Component, createSignal, Show } from 'solid-js'; import { Portal } from 'solid-js/web'; +import { apiFetch } from '@/utils/apiClient'; import { notificationStore } from '@/stores/notifications'; import { SectionHeader } from '@/components/shared/SectionHeader'; import { formField, labelClass, controlClass, formHelpText } from '@/components/shared/Form'; @@ -39,32 +40,15 @@ export const ChangePasswordModal: Component = (props) setLoading(true); try { - // Get CSRF token from cookie - const csrfToken = document.cookie - .split('; ') - .find((row) => row.startsWith('pulse_csrf=')) - ?.split('=')[1]; - - // Get the actual username from sessionStorage or use 'admin' as fallback - const authUser = sessionStorage.getItem('pulse_auth_user') || 'admin'; - const headers: Record = { - 'Content-Type': 'application/json', - Authorization: `Basic ${btoa(`${authUser}:${currentPassword()}`)}`, - }; - - // Add CSRF token if available - if (csrfToken) { - headers['X-CSRF-Token'] = csrfToken; - } - - const response = await fetch('/api/security/change-password', { + const response = await apiFetch('/api/security/change-password', { method: 'POST', - headers, + headers: { + Authorization: `Basic ${btoa(`${authUser}:${currentPassword()}`)}`, + }, body: JSON.stringify({ currentPassword: currentPassword(), newPassword: newPassword(), }), - credentials: 'include', }); if (!response.ok) { diff --git a/frontend-modern/src/components/Settings/NodeModal.tsx b/frontend-modern/src/components/Settings/NodeModal.tsx index 25e7448f9..e45cbab04 100644 --- a/frontend-modern/src/components/Settings/NodeModal.tsx +++ b/frontend-modern/src/components/Settings/NodeModal.tsx @@ -1578,7 +1578,7 @@ export const NodeModal: Component = (props) => { const scriptUrl = `/api/setup-script?type=pbs&host=${encodedHost}&pulse_url=${pulseUrl}`; // Fetch the script using the current session - const response = await fetch(scriptUrl); + const response = await apiFetch(scriptUrl); if (!response.ok) { throw new Error('Failed to fetch setup script'); } diff --git a/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx b/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx index a5cd67d0a..d21ccd5fe 100644 --- a/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx +++ b/frontend-modern/src/components/Settings/QuickSecuritySetup.tsx @@ -1,7 +1,7 @@ import { Component, createSignal, Show } from 'solid-js'; import { showSuccess, showError } from '@/utils/toast'; import { copyToClipboard } from '@/utils/clipboard'; -import { clearAuth as clearApiClientAuth } from '@/utils/apiClient'; +import { clearAuth as clearApiClientAuth, apiFetchJSON } from '@/utils/apiClient'; import { SectionHeader } from '@/components/shared/SectionHeader'; import { formField, labelClass, controlClass, formHelpText } from '@/components/shared/Form'; @@ -82,38 +82,15 @@ export const QuickSecuritySetup: Component = (props) => apiToken: generateToken(), }; - // Get CSRF token from cookie for authenticated requests (rotation mode) - const csrfToken = document.cookie - .split('; ') - .find((row) => row.startsWith('pulse_csrf=')) - ?.split('=')[1]; - - const headers: Record = { - 'Content-Type': 'application/json', - }; - if (csrfToken) { - headers['X-CSRF-Token'] = csrfToken; - } - // Call API to enable security - const response = await fetch('/api/security/quick-setup', { + const result = await apiFetchJSON<{ skipped?: boolean; message?: string }>('/api/security/quick-setup', { method: 'POST', - headers, body: JSON.stringify({ ...newCredentials, force: isRotation, }), - credentials: 'include', // Include cookies for CSRF }); - if (!response.ok) { - const error = await response.text(); - throw new Error(error || 'Failed to setup security'); - } - - // Parse response to check if setup was skipped - const result = await response.json(); - if (result.skipped) { // Security was already configured, don't show credentials showError(