aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/utils.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/utils.ts')
-rw-r--r--frontend/src/utils.ts31
1 files changed, 31 insertions, 0 deletions
diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts
new file mode 100644
index 0000000..129ebbb
--- /dev/null
+++ b/frontend/src/utils.ts
@@ -0,0 +1,31 @@
+export function getCookie(name: string): string | undefined {
+ const value = `; ${document.cookie}`;
+ const parts = value.split(`; ${name}=`);
+ if (parts.length === 2) return parts.pop()?.split(';').shift();
+}
+
+/**
+ * A wrapper around fetch that automatically includes the CSRF token
+ * for state-changing requests (POST, PUT, DELETE).
+ */
+export async function apiFetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
+ const method = init?.method?.toUpperCase() || 'GET';
+ const isStateChanging = ['POST', 'PUT', 'DELETE'].includes(method);
+
+ const headers = new Headers(init?.headers || {});
+
+ if (isStateChanging) {
+ const token = getCookie('csrf_token');
+ if (token) {
+ headers.set('X-CSRF-Token', token);
+ }
+ }
+
+ // Ensure requests are treated as coming from our own origin if needed,
+ // but for a same-origin API, standard fetch defaults are usually fine.
+
+ return fetch(input, {
+ ...init,
+ headers,
+ });
+}