From 8bd291beec652c01b22dc16035a8b95b6921a82c Mon Sep 17 00:00:00 2001 From: qowevisa Date: Fri, 8 Nov 2024 17:13:09 +0200 Subject: [PATCH] Add cookie parsing part of apiFetch and add optional cookies parameter in login function --- src/lib/api.ts | 77 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/src/lib/api.ts b/src/lib/api.ts index 5a8a4c3..bac7291 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,5 +1,61 @@ // src/lib/api.ts +import type { Cookies } from "@sveltejs/kit"; + +// Cookie Helpers {{{ +// +interface CookieOptions { + httpOnly: boolean; + secure: boolean; + sameSite: 'strict' | 'lax' | 'none'; + maxAge: number; + path: string; + domain?: string; +} + +// Helper function to parse set-cookie header +function parseSetCookieHeader(setCookieHeader: string) { + const [cookie, ...attributes] = setCookieHeader.split(';').map(part => part.trim()); + const [name, value] = cookie.split('='); + + const options: CookieOptions = { + httpOnly: false, + secure: process.env.NODE_ENV === 'production', + sameSite: 'strict', + path: '/', + maxAge: 0, + }; + + attributes.forEach(attr => { + const [key, val] = attr.split('='); + + switch (key.toLowerCase()) { + case 'httponly': + options.httpOnly = true; + break; + case 'secure': + options.secure = true; + break; + case 'samesite': + options.sameSite = val?.toLowerCase() as 'strict' | 'lax' | 'none'; + break; + case 'max-age': + options.maxAge = parseInt(val, 10); + break; + case 'path': + options.path = val || '/'; + break; + case 'domain': + options.domain = val; + break; + } + }); + + return { name, value, options }; +} +// }}} +// + // Define the base URL of your API const BASE_API_URL = import.meta.env.VITE_API_BASE_URL_SERVER || 'http://localhost:3111/api'; @@ -18,7 +74,11 @@ interface UserData { } // Generic function for making API requests -export async function apiFetch(endpoint: string, options: RequestInit = {}): Promise { +export async function apiFetch( + endpoint: string, + options: RequestInit = {}, + cookies?: Cookies, +): Promise { const url = `${BASE_API_URL}${endpoint}`; console.log("Fetching ", url) @@ -34,6 +94,17 @@ export async function apiFetch(endpoint: string, options: RequestInit = {}): try { const response = await fetch(url, config); + console.log(response.headers); + if (response.headers) { + const setCookieHeader = response.headers.get("Set-Cookie"); + if (setCookieHeader) { + const parsedCookie = parseSetCookieHeader(setCookieHeader); + if (parsedCookie) { + cookies?.set(parsedCookie.name, parsedCookie.value, parsedCookie.options) + } + } + } + if (!response.ok) { const errorData = await response.json(); // Parse error response as JSON const errorMessage = errorData.message || `Error: ${response.status}`; @@ -48,11 +119,11 @@ export async function apiFetch(endpoint: string, options: RequestInit = {}): } // Login function with type annotation for the response -export async function login(username: string, password: string): Promise { +export async function login(username: string, password: string, cookies?: Cookies): Promise { return apiFetch('/user/login', { method: 'POST', body: JSON.stringify({ username, password }), - }); + }, cookies); } // Get user data function with type annotation for the response