diff --git a/apps/web/src/components/ai/openclaw-state-machine.tsx b/apps/web/src/components/ai/openclaw-state-machine.tsx index 7b918918..29122333 100644 --- a/apps/web/src/components/ai/openclaw-state-machine.tsx +++ b/apps/web/src/components/ai/openclaw-state-machine.tsx @@ -19,6 +19,7 @@ import { useState, useEffect, useCallback, useRef } from 'react' import { useTranslations } from 'next-intl' import { cn } from '@/lib/utils' +import { useCSRF } from '@/hooks/useCSRF' import { OpenClawPanel, type OpenClawStatus } from './openclaw-panel' import type { ThinkingStream as _ThinkingStream, DEFAULT_THINKING_MESSAGES as _DEFAULT_THINKING_MESSAGES } from './thinking-stream' import { ApprovalCard, type ApprovalRequest } from '@/components/approval/approval-card' @@ -94,6 +95,7 @@ export function OpenClawStateMachine({ className, }: OpenClawStateMachineProps) { const t = useTranslations() + const { csrfToken } = useCSRF() // State const [machineState, setMachineState] = useState('idle') @@ -199,9 +201,13 @@ export function OpenClawStateMachine({ signerCounter.current++ try { + const headers: Record = { 'Content-Type': 'application/json' } + if (csrfToken) headers['X-CSRF-Token'] = csrfToken + const response = await fetch(`${apiBaseUrl}/api/v1/approvals/${approvalId}/sign`, { method: 'POST', - headers: { 'Content-Type': 'application/json' }, + headers, + credentials: 'include', body: JSON.stringify({ signer_id: signer.id, signer_name: signer.name, @@ -223,7 +229,7 @@ export function OpenClawStateMachine({ setError(err instanceof Error ? err.message : 'Sign failed') return -1 } - }, [fetchPendingApprovals]) + }, [fetchPendingApprovals, csrfToken]) // ========================================================================== // API: Reject Request