fix(#351): CSRF-403 bei KI-Chat und Wiki-Save behoben — /auth/me liefert csrf_token, streamChat nutzt gemeinsamen Client-Token statt totem sessionStorage-Key; Regressionstests pytest+vitest

This commit is contained in:
Agent Zero
2026-08-27 11:03:24 +02:00
parent 9510b3a7c9
commit ebf4b0363c
6 changed files with 93 additions and 3 deletions
@@ -0,0 +1,56 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { getCsrfToken, setCsrfToken } from '@/api/client';
import { streamChat } from '@/api/ai';
describe('streamChat CSRF header', () => {
const originalFetch = globalThis.fetch;
beforeEach(() => {
setCsrfToken('test-csrf-token');
globalThis.fetch = vi.fn().mockResolvedValue(
new Response(
'data: {"type":"done"}\n\ndata: [DONE]\n\n',
{
status: 200,
headers: { 'Content-Type': 'text/event-stream' },
},
),
) as unknown as typeof fetch;
});
afterEach(() => {
setCsrfToken(null);
globalThis.fetch = originalFetch;
vi.restoreAllMocks();
});
it('sends the shared client CSRF token as X-CSRF-Token header', async () => {
expect(getCsrfToken()).toBe('test-csrf-token');
const gen = streamChat('conv-1', 'Hallo');
for await (const _ of gen) {
// consume stream until [DONE]
}
const fetchMock = globalThis.fetch as ReturnType<typeof vi.fn>;
expect(fetchMock).toHaveBeenCalledTimes(1);
const [, init] = fetchMock.mock.calls[0] as [string, RequestInit];
const headers = init.headers as Record<string, string>;
// Regression: token previously came from a never-written sessionStorage key → 403
expect(headers['X-CSRF-Token']).toBe('test-csrf-token');
});
it('targets the conversation stream endpoint with JSON body', async () => {
const gen = streamChat('conv-42', 'Frage', 'agent-9');
for await (const _ of gen) {
// consume stream until [DONE]
}
const fetchMock = globalThis.fetch as ReturnType<typeof vi.fn>;
const [url, init] = fetchMock.mock.calls[0] as [string, RequestInit];
expect(url).toBe('/api/v1/ai/conversations/conv-42/stream');
expect(init.method).toBe('POST');
expect(init.credentials).toBe('include');
expect(JSON.parse(init.body as string)).toEqual({ content: 'Frage', agent_id: 'agent-9' });
});
});