From ab51d40de364f43e4ee1d01d2838c92b5fea33b2 Mon Sep 17 00:00:00 2001 From: Julien Date: Sat, 23 Nov 2024 22:29:39 +0100 Subject: [PATCH] feat: automatically add csrf token in request headers Fix #21 --- .changeset/healthy-coats-teach.md | 7 +++++++ packages/client/src/client.ts | 22 +++++++++++++++++++++- packages/client/tests/client.spec.ts | 25 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 .changeset/healthy-coats-teach.md diff --git a/.changeset/healthy-coats-teach.md b/.changeset/healthy-coats-teach.md new file mode 100644 index 0000000..10223a4 --- /dev/null +++ b/.changeset/healthy-coats-teach.md @@ -0,0 +1,7 @@ +--- +'@tuyau/client': minor +--- + +Now the client will automatically add the CSRF token in the headers of each request when present in the cookies, exactly like Axios does. + +Related #21 diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts index 1393d6c..6d35fb9 100644 --- a/packages/client/src/client.ts +++ b/packages/client/src/client.ts @@ -67,6 +67,18 @@ function createProxy(options: { }) } +/** + * Automatically append the csrf token to the request headers + */ +function appendCsrfToken(request: Request) { + const xCsrfToken = globalThis.document?.cookie + .split('; ') + .find((row) => row.startsWith('XSRF-TOKEN=')) + .split('=')[1] + + request.headers.set('X-XSRF-TOKEN', decodeURIComponent(xCsrfToken)) +} + /** * Create a new Tuyau client */ @@ -76,7 +88,15 @@ export function createTuyau( ? TuyauClient : TuyauRpcClient { const baseUrl = options.baseUrl - const client = ky.create({ prefixUrl: baseUrl, throwHttpErrors: false, ...options }) + const client = ky.create({ + prefixUrl: baseUrl, + throwHttpErrors: false, + ...options, + hooks: { + ...options.hooks, + beforeRequest: [...(options.hooks?.beforeRequest || []), appendCsrfToken], + }, + }) return createProxy({ client, baseUrl, config: options }) } diff --git a/packages/client/tests/client.spec.ts b/packages/client/tests/client.spec.ts index 5d4ced6..85ab14d 100644 --- a/packages/client/tests/client.spec.ts +++ b/packages/client/tests/client.spec.ts @@ -578,4 +578,29 @@ test.group('Client | Runtime', () => { }, }) }) + + test('automatically pickup cookie x-csrf-token', async () => { + // @ts-ignore osef + globalThis.document ||= {} + globalThis.document.cookie = 'XSRF-TOKEN=123' + + const tuyau = createTuyau<{ + routes: [] + definition: { + users: { + $get: { + request: any + response: { 200: Simplify> } + } + } + } + }>({ baseUrl: 'http://localhost:3333' }) + + nock('http://localhost:3333') + .get('/users') + .reply(200, { token: '123' }) + .matchHeader('X-XSRF-TOKEN', '123') + + await tuyau.users.$get() + }) })