Initial commit
This commit is contained in:
60
packages/core-consent/src/migration.ts
Normal file
60
packages/core-consent/src/migration.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import type { ConsentCategory, ConsentGrantMeta } from "./consent-types";
|
||||
import type { IConsent } from "./consent.interface";
|
||||
|
||||
/** Cookie name written by the anonymous consent banner. */
|
||||
export const CONSENT_COOKIE_NAME = "cc_consent";
|
||||
|
||||
/**
|
||||
* Parses a raw Cookie header string and returns the consent categories the
|
||||
* anonymous visitor granted via the banner cookie. Returns null when the
|
||||
* consent cookie is absent or empty.
|
||||
*
|
||||
* Expected cookie value format: comma-separated category names,
|
||||
* e.g. "necessary,analytics,marketing".
|
||||
*/
|
||||
export function extractAnonymousConsent(
|
||||
cookieHeader: string,
|
||||
): ConsentCategory[] | null {
|
||||
const cookies = parseCookieHeader(cookieHeader);
|
||||
const raw = cookies.get(CONSENT_COOKIE_NAME);
|
||||
if (!raw) return null;
|
||||
const categories = raw
|
||||
.split(",")
|
||||
.map((c) => c.trim())
|
||||
.filter(Boolean) as ConsentCategory[];
|
||||
return categories.length > 0 ? categories : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates anonymous consent categories into an authenticated user's consent
|
||||
* record. Calls IConsent.grant for each category with method "signup-migration"
|
||||
* so the migration is traceable in the audit log. No-op when cookieState is
|
||||
* null (visitor had no consent cookie).
|
||||
*/
|
||||
export async function migrateAnonymousConsent(opts: {
|
||||
consent: IConsent;
|
||||
cookieState: ConsentCategory[] | null;
|
||||
bannerVersion?: string;
|
||||
policyVersion?: string;
|
||||
}): Promise<void> {
|
||||
const { consent, cookieState, bannerVersion, policyVersion } = opts;
|
||||
if (!cookieState) return;
|
||||
const meta: ConsentGrantMeta = { method: "signup-migration" };
|
||||
if (bannerVersion !== undefined) meta.bannerVersion = bannerVersion;
|
||||
if (policyVersion !== undefined) meta.policyVersion = policyVersion;
|
||||
for (const category of cookieState) {
|
||||
await consent.grant(category, meta);
|
||||
}
|
||||
}
|
||||
|
||||
function parseCookieHeader(cookieHeader: string): Map<string, string> {
|
||||
const map = new Map<string, string>();
|
||||
for (const part of cookieHeader.split(";")) {
|
||||
const eqIdx = part.indexOf("=");
|
||||
if (eqIdx === -1) continue;
|
||||
const name = part.slice(0, eqIdx).trim();
|
||||
const value = part.slice(eqIdx + 1).trim();
|
||||
if (name) map.set(name, value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
Reference in New Issue
Block a user