SPB Git

spb/phi-conseil

Public
2.4 KB · 68 lines typescript
1/**2 * Consentement aux témoins (cookies) — Loi 25 (Québec) / RGPD :3 * refus par défaut pour tout ce qui n'est pas strictement nécessaire,4 * choix granulaire, révocable à tout moment, conservé 180 jours.5 *6 * Le site ne pose aujourd'hui AUCUN témoin non nécessaire : ce module est la7 * porte d'entrée obligatoire pour tout futur outil d'analyse ou de marketing8 * (`hasConsent("analytics")` avant de charger un script).9 */1011export const CONSENT_COOKIE = "phi_consent";12export const CONSENT_VERSION = 1;13export const CONSENT_MAX_AGE_S = 180 * 24 * 60 * 60;14export const CONSENT_EVENT = "phi-consent-change";15export const CONSENT_OPEN_EVENT = "phi-consent-open";1617export const OPTIONAL_CATEGORIES = ["analytics", "marketing"] as const;18export type OptionalCategory = (typeof OPTIONAL_CATEGORIES)[number];19export type Category = "necessary" | OptionalCategory;2021export type Consent = {22  version: number;23  date: string; // ISO24  necessary: true;25  analytics: boolean;26  marketing: boolean;27};2829export function allRejected(): Consent {30  return { version: CONSENT_VERSION, date: new Date().toISOString(), necessary: true, analytics: false, marketing: false };31}3233export function allAccepted(): Consent {34  return { version: CONSENT_VERSION, date: new Date().toISOString(), necessary: true, analytics: true, marketing: true };35}3637export function parseConsent(raw: string | null | undefined): Consent | null {38  if (!raw) return null;39  try {40    const v = JSON.parse(decodeURIComponent(raw)) as Partial<Consent>;41    if (v.version !== CONSENT_VERSION) return null; // nouvelle version = redemander42    if (typeof v.analytics !== "boolean" || typeof v.marketing !== "boolean") return null;43    return {44      version: CONSENT_VERSION,45      date: typeof v.date === "string" ? v.date : new Date(0).toISOString(),46      necessary: true,47      analytics: v.analytics,48      marketing: v.marketing,49    };50  } catch {51    return null;52  }53}5455export function serializeConsent(c: Consent): string {56  return encodeURIComponent(JSON.stringify(c));57}5859export function readConsentCookie(cookieHeader: string): Consent | null {60  const m = cookieHeader.match(new RegExp(`(?:^|;\\s*)${CONSENT_COOKIE}=([^;]*)`));61  return parseConsent(m?.[1]);62}6364export function hasConsent(consent: Consent | null, category: Category): boolean {65  if (category === "necessary") return true;66  return consent?.[category] === true;67}68
Files · main
Menu

Theme