/** * CookieService - Service de gestion des cookies côté client * SECURITY: Pour les cookies httpOnly, le backend les gère directement * Ce service gère uniquement les cookies non-httpOnly si nécessaire */ /** * Définit un cookie * Note: Pour les cookies httpOnly, le backend doit les setter via Set-Cookie header * @param name - Nom du cookie * @param value - Valeur du cookie * @param days - Nombre de jours avant expiration * @param options - Options supplémentaires (path, domain, secure, sameSite) */ export function setCookie( name: string, value: string, days?: number, options?: { path?: string; domain?: string; secure?: boolean; sameSite?: 'Strict' | 'Lax' | 'None'; }, ): void { let cookieString = `${name}=${encodeURIComponent(value)}`; if (days !== undefined) { const date = new Date(); date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); cookieString += `; expires=${date.toUTCString()}`; } if (options?.path) { cookieString += `; path=${options.path}`; } if (options?.domain) { cookieString += `; domain=${options.domain}`; } if (options?.secure || import.meta.env.PROD) { cookieString += '; secure'; } if (options?.sameSite) { cookieString += `; sameSite=${options.sameSite}`; } document.cookie = cookieString; } /** * Récupère un cookie par son nom * Note: Les cookies httpOnly ne sont pas accessibles via JavaScript * @param name - Nom du cookie * @returns Valeur du cookie ou null si non trouvé */ export function getCookie(name: string): string | null { const nameEQ = `${name}=`; const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { let cookie = cookies[i]; if (cookie == null) continue; while (cookie.charAt(0) === ' ') { cookie = cookie.substring(1, cookie.length); } if (cookie.indexOf(nameEQ) === 0) { return decodeURIComponent(cookie.substring(nameEQ.length, cookie.length)); } } return null; } /** * Supprime un cookie * @param name - Nom du cookie * @param options - Options (path, domain) */ export function deleteCookie( name: string, options?: { path?: string; domain?: string }, ): void { let cookieString = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC`; if (options?.path) { cookieString += `; path=${options.path}`; } if (options?.domain) { cookieString += `; domain=${options.domain}`; } document.cookie = cookieString; } /** * Vérifie si les cookies sont supportés * @returns true si les cookies sont supportés */ export function areCookiesSupported(): boolean { try { document.cookie = 'test=1'; const supported = document.cookie.indexOf('test=') !== -1; document.cookie = 'test=; expires=Thu, 01 Jan 1970 00:00:00 UTC'; return supported; } catch { return false; } }