PT

@core / consent

1.1.0 ▾
verificadoMIT
GitHub

Consentimento de cookies LGPD/RGPD: banner com recusar igual a aceitar, categorias, registro de prova e Consent Mode v2

Código9 arquivosContexto~743 tokensanálise aprovada

A árvore exata que será injetada, após o .genpmignore. Fixada em

src/lib/consent/adapters/http.tssomente leitura · 37d6a8f
// POST /api/consent {analytics, marketing, preferences, action?} → guarda y fija la cookie. GET → estado actual.
// Solo JSON y del mismo origen (anti-CSRF): un formulario `text/plain` de otro sitio no puede "aceptar todo".
import { z } from 'zod';
import { ChoicesInput, getConsent, recordConsent } from '../index.ts';

const Body = ChoicesInput.extend({ action: z.enum(['banner', 'preferences', 'withdraw']).default('banner') });

/** Rechaza peticiones de otro sitio: `Sec-Fetch-Site: cross-site` u `Origin` con otro host (o `null`). */
function crossSite(req: Request): boolean {
  if (req.headers.get('sec-fetch-site') === 'cross-site') return true;
  const origin = req.headers.get('origin');
  if (!origin) return false;
  try {
    return new URL(origin).host !== new URL(req.url).host;
  } catch {
    return true;
  }
}

export async function handleConsent(req: Request, opts: { cookiesByCategory?: Partial<Record<'analytics' | 'marketing' | 'preferences', string[]>> } = {}): Promise<Response> {
  if (req.method === 'GET') return Response.json(getConsent(req.headers.get('cookie')), { headers: { 'cache-control': 'private, no-store' } });
  if (req.method !== 'POST') return Response.json({ error: 'method_not_allowed' }, { status: 405 });
  if (crossSite(req)) return Response.json({ error: 'forbidden' }, { status: 403 });
  if (!(req.headers.get('content-type') ?? '').toLowerCase().startsWith('application/json')) return Response.json({ error: 'unsupported_media_type' }, { status: 415 });
  const body = Body.safeParse(await req.json().catch(() => null));
  if (!body.success) return Response.json({ error: 'invalid' }, { status: 400 });
  const { action, ...choices } = body.data;
  const { state, setCookies } = await recordConsent({ choices, action, cookieHeader: req.headers.get('cookie') }, { cookiesByCategory: opts.cookiesByCategory, secure: new URL(req.url).protocol === 'https:' });
  const headers = new Headers({ 'cache-control': 'no-store', 'content-type': 'application/json' });
  for (const c of setCookies) headers.append('set-cookie', c);
  return new Response(JSON.stringify(state), { headers });
}

Denunciar @core/consent

Entre com o GitHub para denunciar um pacote.