@cookiemunch/sdk 0.5.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/chunk-OSVTQPQG.js +187 -0
- package/dist/chunk-OSVTQPQG.js.map +1 -0
- package/dist/consent.cjs +89 -2
- package/dist/consent.cjs.map +1 -1
- package/dist/consent.d.cts +83 -2
- package/dist/consent.d.ts +83 -2
- package/dist/consent.js +11 -3
- package/dist/index.cjs +415 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1268 -41
- package/dist/index.d.ts +1268 -41
- package/dist/index.js +332 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-G7ORTXTK.js +0 -104
- package/dist/chunk-G7ORTXTK.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -20,15 +20,25 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
CANARY_ISSUER: () => CANARY_ISSUER,
|
|
24
|
+
CONFORMANCE_RULES: () => CONFORMANCE_RULES,
|
|
23
25
|
CONSENT_COOKIE_NAME: () => CONSENT_COOKIE_NAME,
|
|
24
26
|
CookieMunchApiError: () => CookieMunchApiError,
|
|
27
|
+
DEFAULT_JWKS_URL: () => DEFAULT_JWKS_URL,
|
|
25
28
|
SDK_VERSION: () => SDK_VERSION,
|
|
29
|
+
TokenExchangeError: () => TokenExchangeError,
|
|
30
|
+
canaryIdentityFor: () => canaryIdentityFor,
|
|
31
|
+
consentSignaturePayload: () => consentSignaturePayload,
|
|
26
32
|
createCookieMunch: () => createCookieMunch,
|
|
33
|
+
exchangeOperatorToken: () => exchangeOperatorToken,
|
|
27
34
|
getConsent: () => getConsent,
|
|
28
35
|
isAllowed: () => isAllowed,
|
|
29
36
|
mintConsentSyncToken: () => mintConsentSyncToken,
|
|
30
37
|
parseConsentValue: () => parseConsentValue,
|
|
31
38
|
readConsent: () => readConsent,
|
|
39
|
+
runExecutorConformance: () => runExecutorConformance,
|
|
40
|
+
verifyDecisionSignature: () => verifyDecisionSignature,
|
|
41
|
+
verifyToken: () => verifyToken,
|
|
32
42
|
verifyWebhookSignature: () => verifyWebhookSignature
|
|
33
43
|
});
|
|
34
44
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -89,6 +99,7 @@ function normalize(o) {
|
|
|
89
99
|
for (const [k, v] of Object.entries(r.custom)) if (bool(v)) custom[k] = v;
|
|
90
100
|
if (Object.keys(custom).length > 0) out.custom = custom;
|
|
91
101
|
}
|
|
102
|
+
if (typeof r.sig === "string") out.sig = r.sig;
|
|
92
103
|
return out;
|
|
93
104
|
}
|
|
94
105
|
function parseConsentValue(raw) {
|
|
@@ -108,6 +119,12 @@ function parseConsentValue(raw) {
|
|
|
108
119
|
}
|
|
109
120
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
110
121
|
function readConsent(source, opts = {}) {
|
|
122
|
+
const consent = readUnsigned(source, opts);
|
|
123
|
+
if (opts.requireSigned !== true) return consent;
|
|
124
|
+
if (!consent?.sig) return Promise.resolve(null);
|
|
125
|
+
return verifyDecisionSignature(consent, opts).then((ok) => ok ? consent : null);
|
|
126
|
+
}
|
|
127
|
+
function readUnsigned(source, opts) {
|
|
111
128
|
const raw = cookieValue(cookieHeaderOf(source), opts.cookieName ?? CONSENT_COOKIE_NAME);
|
|
112
129
|
const consent = raw ? parseConsentValue(raw) : null;
|
|
113
130
|
if (!consent) return null;
|
|
@@ -128,6 +145,78 @@ function isAllowed(consent, category) {
|
|
|
128
145
|
if (category === "marketing") return consent.marketing === true;
|
|
129
146
|
return consent.custom?.[category] === true;
|
|
130
147
|
}
|
|
148
|
+
var DEFAULT_JWKS_URL = "https://api.cookiemunch.net/v1/partner/jwks.json";
|
|
149
|
+
function consentSignaturePayload(d) {
|
|
150
|
+
const b = (v) => v ? "1" : "0";
|
|
151
|
+
const custom = d.custom ?? {};
|
|
152
|
+
const named = Object.keys(custom).sort().map((k) => `${k}=${b(custom[k])}`).join(",");
|
|
153
|
+
return `cmc1|${d.stamp}|${d.ver}|${d.utc}|${b(d.preferences)}${b(d.statistics)}${b(d.marketing)}|${named}`;
|
|
154
|
+
}
|
|
155
|
+
var jwksCache = /* @__PURE__ */ new Map();
|
|
156
|
+
var JWKS_TTL_MS = 60 * 60 * 1e3;
|
|
157
|
+
async function keySet(opts, kid) {
|
|
158
|
+
if (opts.jwks) return opts.jwks;
|
|
159
|
+
const url = opts.jwksUrl ?? DEFAULT_JWKS_URL;
|
|
160
|
+
const hit = jwksCache.get(url);
|
|
161
|
+
if (hit && Date.now() - hit.at < JWKS_TTL_MS && hit.set.keys.some((k) => k.kid === kid)) return hit.set;
|
|
162
|
+
const f = opts.fetch ?? globalThis.fetch;
|
|
163
|
+
if (!f) throw new Error("no fetch available to load the key set; pass `jwks`");
|
|
164
|
+
const res = await f(url);
|
|
165
|
+
if (!res.ok) throw new Error(`key set ${url} answered ${res.status}`);
|
|
166
|
+
const set = await res.json();
|
|
167
|
+
if (!set || !Array.isArray(set.keys)) throw new Error(`key set ${url} is not a JWKS`);
|
|
168
|
+
jwksCache.set(url, { at: Date.now(), set });
|
|
169
|
+
return set;
|
|
170
|
+
}
|
|
171
|
+
function b64urlBytes(s) {
|
|
172
|
+
const b64 = s.replace(/-/g, "+").replace(/_/g, "/") + "===".slice((s.length + 3) % 4);
|
|
173
|
+
const bin = atob(b64);
|
|
174
|
+
const out = new Uint8Array(bin.length);
|
|
175
|
+
for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
|
|
176
|
+
return out;
|
|
177
|
+
}
|
|
178
|
+
async function edVerify(jwk, data, signature) {
|
|
179
|
+
const subtle = globalThis.crypto?.subtle;
|
|
180
|
+
if (!subtle) throw new Error("WebCrypto is unavailable in this runtime");
|
|
181
|
+
if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) return false;
|
|
182
|
+
const key = await subtle.importKey("jwk", { kty: "OKP", crv: "Ed25519", x: jwk.x }, { name: "Ed25519" }, false, ["verify"]);
|
|
183
|
+
return subtle.verify({ name: "Ed25519" }, key, b64urlBytes(signature), new TextEncoder().encode(data));
|
|
184
|
+
}
|
|
185
|
+
async function verifyDecisionSignature(consent, opts = {}) {
|
|
186
|
+
const dot = consent.sig?.lastIndexOf(".") ?? -1;
|
|
187
|
+
if (!consent.sig || dot <= 0) return false;
|
|
188
|
+
const kid = consent.sig.slice(0, dot);
|
|
189
|
+
try {
|
|
190
|
+
const jwk = (await keySet(opts, kid)).keys.find((k) => k.kid === kid);
|
|
191
|
+
if (!jwk) return false;
|
|
192
|
+
return await edVerify(jwk, consentSignaturePayload(consent), consent.sig.slice(dot + 1));
|
|
193
|
+
} catch {
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async function verifyToken(token, opts = {}) {
|
|
198
|
+
const parts = typeof token === "string" ? token.split(".") : [];
|
|
199
|
+
if (parts.length !== 3) throw new Error("not a JWT");
|
|
200
|
+
const [h, p, s] = parts;
|
|
201
|
+
let header;
|
|
202
|
+
let claims;
|
|
203
|
+
try {
|
|
204
|
+
header = JSON.parse(new TextDecoder().decode(b64urlBytes(h)));
|
|
205
|
+
claims = JSON.parse(new TextDecoder().decode(b64urlBytes(p)));
|
|
206
|
+
} catch {
|
|
207
|
+
throw new Error("malformed token");
|
|
208
|
+
}
|
|
209
|
+
if (header.alg !== "EdDSA" || !header.kid) throw new Error("unexpected token algorithm");
|
|
210
|
+
const jwk = (await keySet(opts, header.kid)).keys.find((k) => k.kid === header.kid);
|
|
211
|
+
if (!jwk || !await edVerify(jwk, `${h}.${p}`, s)) throw new Error("bad signature");
|
|
212
|
+
if (claims.token_use !== "consent") throw new Error("not a consent token");
|
|
213
|
+
const now = (opts.now ?? Date.now()) / 1e3;
|
|
214
|
+
const leeway = opts.leewaySeconds ?? 30;
|
|
215
|
+
if (typeof claims.exp !== "number" || now > claims.exp + leeway) throw new Error("expired");
|
|
216
|
+
if (typeof claims.iat === "number" && claims.iat > now + leeway) throw new Error("issued in the future");
|
|
217
|
+
if (opts.cbid !== void 0 && (claims.cbid !== opts.cbid || claims.aud !== `cookiemunch:${opts.cbid}`)) throw new Error("token is for another site");
|
|
218
|
+
return claims;
|
|
219
|
+
}
|
|
131
220
|
|
|
132
221
|
// src/webhooks.ts
|
|
133
222
|
var import_node_crypto = require("crypto");
|
|
@@ -164,8 +253,219 @@ function mintConsentSyncToken(input) {
|
|
|
164
253
|
return `cms1.${payload}.${sig}`;
|
|
165
254
|
}
|
|
166
255
|
|
|
256
|
+
// src/executor-conformance.ts
|
|
257
|
+
var CANARY_ISSUER = "https://canary.cookiemunch.net";
|
|
258
|
+
var CANARY_EMAIL_RE = /^canary-([0-9a-f]{16})@canary\.cookiemunch\.net$/;
|
|
259
|
+
function canaryIdentityFor(canaryEmail) {
|
|
260
|
+
const m = CANARY_EMAIL_RE.exec(canaryEmail.trim().toLowerCase());
|
|
261
|
+
if (!m) throw new Error("canaryEmail must be the canary address canary-<16 hex>@canary.cookiemunch.net");
|
|
262
|
+
return { iss: CANARY_ISSUER, sub: `canary_${m[1]}`, ext: `canary:${m[1]}` };
|
|
263
|
+
}
|
|
264
|
+
var CONFORMANCE_RULES = [
|
|
265
|
+
{ id: "auth.required", title: "A request without the credential is refused (401 or 403)." },
|
|
266
|
+
{ id: "lookup.email.found", title: "The canary subject is found by its email." },
|
|
267
|
+
{ id: "lookup.identity.found", title: "The canary subject is found by its identity alone (iss + sub), and it is the same subject." },
|
|
268
|
+
{ id: "lookup.unknown.no_match", title: 'An address nobody has answers { subjectId: null, status: "no_match" }.' },
|
|
269
|
+
{ id: "lookup.identity_beats_email", title: "An identity that matches no one is never matched through the email of someone else." },
|
|
270
|
+
{ id: "requests.bad_body.400", title: "A request with an unknown type answers 400 { error, field }." },
|
|
271
|
+
{ id: "requests.alias.canonical_type", title: 'An alias (erasure) is accepted and answered with canonicalType "deletion".' },
|
|
272
|
+
{ id: "requests.execute_after.scheduled", title: 'A deletion with a future executeAfter is "scheduled" with eta equal to executeAfter \u2014 nothing is deleted before it.' },
|
|
273
|
+
{ id: "requests.idempotency.replay", title: "The same Idempotency-Key with the same body returns the same request, not a second one." },
|
|
274
|
+
{ id: "requests.idempotency.mismatch_409", title: "The same Idempotency-Key with a different body answers 409." },
|
|
275
|
+
{ id: "requests.get", title: "GET /privacy/requests/{id} returns the request, still scheduled." },
|
|
276
|
+
{ id: "requests.unknown.404", title: "An unknown request id answers 404." },
|
|
277
|
+
{ id: "requests.cancel.before_execute_after", title: 'A cancel before executeAfter answers status "cancelled".' },
|
|
278
|
+
{ id: "requests.cancel.keeps_data", title: "After a cancel the subject is still there: a lookup finds it." },
|
|
279
|
+
{ id: "version.header", title: "Answers carry X-Version (the highest contract version the executor supports)." }
|
|
280
|
+
];
|
|
281
|
+
function randomTag() {
|
|
282
|
+
const bytes = new Uint8Array(8);
|
|
283
|
+
const c = globalThis.crypto;
|
|
284
|
+
if (c?.getRandomValues) c.getRandomValues(bytes);
|
|
285
|
+
else for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
286
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
287
|
+
}
|
|
288
|
+
function field(json, key) {
|
|
289
|
+
return json && typeof json === "object" ? json[key] : void 0;
|
|
290
|
+
}
|
|
291
|
+
async function runExecutorConformance(o) {
|
|
292
|
+
const doFetch = o.fetch ?? fetch;
|
|
293
|
+
const now = o.now ?? (() => Date.now());
|
|
294
|
+
const base = o.baseUrl.replace(/\/+$/, "") + (o.prefix ?? "/privacy");
|
|
295
|
+
let url;
|
|
296
|
+
try {
|
|
297
|
+
url = new URL(base);
|
|
298
|
+
} catch {
|
|
299
|
+
throw new Error("baseUrl must be an absolute URL");
|
|
300
|
+
}
|
|
301
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && /^(localhost|127\.0\.0\.1|\[::1\])$/.test(url.hostname))) {
|
|
302
|
+
throw new Error("baseUrl must be https (http only for localhost)");
|
|
303
|
+
}
|
|
304
|
+
const identity = canaryIdentityFor(o.canaryEmail);
|
|
305
|
+
const canaryEmail = o.canaryEmail.trim().toLowerCase();
|
|
306
|
+
const auth = o.auth ?? { header: "Authorization", format: "Bearer {secret}" };
|
|
307
|
+
const run = o.runId ?? randomTag();
|
|
308
|
+
const results = /* @__PURE__ */ new Map();
|
|
309
|
+
let version;
|
|
310
|
+
const set = (id, status, detail) => {
|
|
311
|
+
const rule = CONFORMANCE_RULES.find((r) => r.id === id);
|
|
312
|
+
results.set(id, { id, title: rule.title, status, ...detail ? { detail } : {} });
|
|
313
|
+
};
|
|
314
|
+
const pass = (id) => set(id, "pass");
|
|
315
|
+
const fail = (id, detail) => set(id, "fail", detail);
|
|
316
|
+
const skip = (id, detail) => set(id, "skip", detail);
|
|
317
|
+
async function call(method, path, body, extra = {}, withAuth = true) {
|
|
318
|
+
const headers = {
|
|
319
|
+
accept: "application/json",
|
|
320
|
+
"X-Version": "2",
|
|
321
|
+
...withAuth ? { [auth.header]: auth.format.replace("{secret}", o.secret) } : {},
|
|
322
|
+
...body !== void 0 ? { "content-type": "application/json" } : {},
|
|
323
|
+
...extra
|
|
324
|
+
};
|
|
325
|
+
try {
|
|
326
|
+
const res = await doFetch(base + path, { method, headers, ...body !== void 0 ? { body: JSON.stringify(body) } : {} });
|
|
327
|
+
const text = await res.text().catch(() => "");
|
|
328
|
+
let json;
|
|
329
|
+
try {
|
|
330
|
+
json = text ? JSON.parse(text) : void 0;
|
|
331
|
+
} catch {
|
|
332
|
+
json = void 0;
|
|
333
|
+
}
|
|
334
|
+
const v = res.headers.get("x-version");
|
|
335
|
+
if (v && !version) version = v;
|
|
336
|
+
return { status: res.status, json, version: v };
|
|
337
|
+
} catch (err) {
|
|
338
|
+
return { status: 0, json: void 0, version: null, error: err instanceof Error ? err.message : String(err) };
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const said = (a) => a.status === 0 ? `unreachable: ${a.error}` : `HTTP ${a.status} ${JSON.stringify(a.json ?? null).slice(0, 200)}`;
|
|
342
|
+
const key = (rule) => `conformance:${run}:${rule}`;
|
|
343
|
+
const anon = await call("POST", "/lookup", { emails: [canaryEmail] }, {}, false);
|
|
344
|
+
if (anon.status === 0) {
|
|
345
|
+
for (const r of CONFORMANCE_RULES) skip(r.id, said(anon));
|
|
346
|
+
fail("auth.required", said(anon));
|
|
347
|
+
return report();
|
|
348
|
+
}
|
|
349
|
+
if (anon.status === 401 || anon.status === 403) pass("auth.required");
|
|
350
|
+
else fail("auth.required", `without a credential: ${said(anon)}`);
|
|
351
|
+
const byEmail = await call("POST", "/lookup", { emails: [canaryEmail] }, { "Idempotency-Key": key("lookup-email") });
|
|
352
|
+
const subjectId = field(byEmail.json, "subjectId");
|
|
353
|
+
if (byEmail.status === 200 && field(byEmail.json, "status") === "found" && typeof subjectId === "string" && subjectId) pass("lookup.email.found");
|
|
354
|
+
else fail("lookup.email.found", `the canary address: ${said(byEmail)}`);
|
|
355
|
+
const byIdentity = await call("POST", "/lookup", { emails: [], identity, atlas: identity }, { "Idempotency-Key": key("lookup-identity") });
|
|
356
|
+
if (byIdentity.status === 200 && field(byIdentity.json, "status") === "found" && field(byIdentity.json, "subjectId") === subjectId && typeof subjectId === "string") {
|
|
357
|
+
pass("lookup.identity.found");
|
|
358
|
+
} else {
|
|
359
|
+
fail("lookup.identity.found", `the canary identity ${identity.sub}: ${said(byIdentity)}${typeof subjectId === "string" ? ` (by email it was ${subjectId})` : ""}`);
|
|
360
|
+
}
|
|
361
|
+
const nobody = await call("POST", "/lookup", { emails: [`nobody-${run}@canary.cookiemunch.net`] }, { "Idempotency-Key": key("lookup-nobody") });
|
|
362
|
+
if (nobody.status === 200 && field(nobody.json, "status") === "no_match" && field(nobody.json, "subjectId") === null) pass("lookup.unknown.no_match");
|
|
363
|
+
else fail("lookup.unknown.no_match", said(nobody));
|
|
364
|
+
const stranger = { iss: identity.iss, sub: `canary_other_${run}` };
|
|
365
|
+
const crossed = await call("POST", "/lookup", { emails: [canaryEmail], identity: stranger, atlas: stranger }, { "Idempotency-Key": key("lookup-crossed") });
|
|
366
|
+
if (crossed.status === 200 && field(crossed.json, "status") === "no_match") pass("lookup.identity_beats_email");
|
|
367
|
+
else {
|
|
368
|
+
fail(
|
|
369
|
+
"lookup.identity_beats_email",
|
|
370
|
+
`an identity nobody has (${stranger.sub}) with the canary's email: ${said(crossed)} \u2014 the email belongs to a different identity, so this must be no_match`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
const bad = await call("POST", "/requests", { subjectId: subjectId ?? "x", type: "teleport", caseId: `conformance-${run}` }, { "Idempotency-Key": key("bad-body") });
|
|
374
|
+
if (bad.status === 400 && typeof field(bad.json, "error") === "string" && typeof field(bad.json, "field") === "string") pass("requests.bad_body.400");
|
|
375
|
+
else fail("requests.bad_body.400", said(bad));
|
|
376
|
+
if (typeof subjectId !== "string") {
|
|
377
|
+
for (const id of ["requests.alias.canonical_type", "requests.execute_after.scheduled", "requests.idempotency.replay", "requests.idempotency.mismatch_409", "requests.get", "requests.cancel.before_execute_after", "requests.cancel.keeps_data"]) {
|
|
378
|
+
skip(id, "needs the canary subject, which the lookup did not find");
|
|
379
|
+
}
|
|
380
|
+
} else {
|
|
381
|
+
const executeAfter = new Date(Math.ceil((now() + 36e5) / 1e3) * 1e3).toISOString();
|
|
382
|
+
const body = { subjectId, type: "erasure", executeAfter, caseId: `conformance-${run}`, reason: "Cookie Munch conformance check (canary subject)" };
|
|
383
|
+
const opened = await call("POST", "/requests", body, { "Idempotency-Key": key("open") });
|
|
384
|
+
const id = field(opened.json, "id");
|
|
385
|
+
const st = field(opened.json, "status");
|
|
386
|
+
if ((opened.status === 200 || opened.status === 201) && field(opened.json, "canonicalType") === "deletion") pass("requests.alias.canonical_type");
|
|
387
|
+
else fail("requests.alias.canonical_type", `type "erasure": ${said(opened)}`);
|
|
388
|
+
const eta = field(opened.json, "eta");
|
|
389
|
+
if ((opened.status === 200 || opened.status === 201) && st === "scheduled" && typeof eta === "string" && Date.parse(eta) === Date.parse(executeAfter)) {
|
|
390
|
+
pass("requests.execute_after.scheduled");
|
|
391
|
+
} else if (st === "completed" || st === "completed_with_retention" || st === "processing") {
|
|
392
|
+
fail("requests.execute_after.scheduled", `executeAfter is ${executeAfter}, an hour away, and the executor answered "${String(st)}": it acted before executeAfter`);
|
|
393
|
+
} else {
|
|
394
|
+
fail("requests.execute_after.scheduled", `expected status "scheduled" with eta ${executeAfter}: ${said(opened)}`);
|
|
395
|
+
}
|
|
396
|
+
const replay = await call("POST", "/requests", body, { "Idempotency-Key": key("open") });
|
|
397
|
+
if (typeof id === "string" && (replay.status === 200 || replay.status === 201) && field(replay.json, "id") === id) pass("requests.idempotency.replay");
|
|
398
|
+
else fail("requests.idempotency.replay", `a retry with the same key: ${said(replay)}${typeof id === "string" ? ` (first answer id ${id})` : ""}`);
|
|
399
|
+
const mismatch = await call("POST", "/requests", { ...body, reason: "a different body" }, { "Idempotency-Key": key("open") });
|
|
400
|
+
if (mismatch.status === 409) pass("requests.idempotency.mismatch_409");
|
|
401
|
+
else fail("requests.idempotency.mismatch_409", `the same key with a different body: ${said(mismatch)}`);
|
|
402
|
+
if (typeof id !== "string") {
|
|
403
|
+
skip("requests.get", "no request id came back");
|
|
404
|
+
skip("requests.cancel.before_execute_after", "no request id came back");
|
|
405
|
+
skip("requests.cancel.keeps_data", "no request id came back");
|
|
406
|
+
} else {
|
|
407
|
+
const got = await call("GET", `/requests/${encodeURIComponent(id)}`, void 0, { "Idempotency-Key": key("get") });
|
|
408
|
+
if (got.status === 200 && field(got.json, "id") === id && field(got.json, "status") === "scheduled") pass("requests.get");
|
|
409
|
+
else fail("requests.get", said(got));
|
|
410
|
+
const cancelled = await call("POST", `/requests/${encodeURIComponent(id)}/cancel`, {}, { "Idempotency-Key": key("cancel") });
|
|
411
|
+
if (cancelled.status === 200 && field(cancelled.json, "status") === "cancelled") pass("requests.cancel.before_execute_after");
|
|
412
|
+
else fail("requests.cancel.before_execute_after", said(cancelled));
|
|
413
|
+
const after = await call("POST", "/lookup", { emails: [canaryEmail] }, { "Idempotency-Key": key("lookup-after-cancel") });
|
|
414
|
+
if (after.status === 200 && field(after.json, "status") === "found") pass("requests.cancel.keeps_data");
|
|
415
|
+
else fail("requests.cancel.keeps_data", `a lookup after the cancel: ${said(after)} \u2014 a cancel before executeAfter must leave the data intact`);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
const unknown = await call("GET", `/requests/conformance-missing-${run}`, void 0, { "Idempotency-Key": key("unknown") });
|
|
419
|
+
if (unknown.status === 404) pass("requests.unknown.404");
|
|
420
|
+
else fail("requests.unknown.404", said(unknown));
|
|
421
|
+
if (version) pass("version.header");
|
|
422
|
+
else fail("version.header", "no answer carried an X-Version header");
|
|
423
|
+
return report();
|
|
424
|
+
function report() {
|
|
425
|
+
const rules = CONFORMANCE_RULES.map((r) => results.get(r.id) ?? { id: r.id, title: r.title, status: "skip", detail: "not reached" });
|
|
426
|
+
const count = (s) => rules.filter((r) => r.status === s).length;
|
|
427
|
+
return { ok: count("fail") === 0, passed: count("pass"), failed: count("fail"), skipped: count("skip"), rules, ...version ? { version } : {} };
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// src/token-exchange.ts
|
|
432
|
+
var TokenExchangeError = class extends Error {
|
|
433
|
+
constructor(error, status, description) {
|
|
434
|
+
super(description ? `${error}: ${description}` : error);
|
|
435
|
+
this.error = error;
|
|
436
|
+
this.status = status;
|
|
437
|
+
this.name = "TokenExchangeError";
|
|
438
|
+
}
|
|
439
|
+
};
|
|
440
|
+
async function exchangeOperatorToken(input) {
|
|
441
|
+
const base = (input.baseUrl ?? "https://api.cookiemunch.net").replace(/\/+$/, "");
|
|
442
|
+
const form = new URLSearchParams({
|
|
443
|
+
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
444
|
+
subject_token: input.subjectToken,
|
|
445
|
+
subject_token_type: `urn:ietf:params:oauth:token-type:${input.subjectTokenType ?? "access_token"}`,
|
|
446
|
+
scope: input.scope.join(" "),
|
|
447
|
+
resource: input.resource,
|
|
448
|
+
audience: "cookiemunch",
|
|
449
|
+
...input.expiresIn !== void 0 ? { expires_in: String(input.expiresIn) } : {}
|
|
450
|
+
});
|
|
451
|
+
const res = await (input.fetch ?? fetch)(`${base}/v1/oauth/token`, {
|
|
452
|
+
method: "POST",
|
|
453
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
454
|
+
body: form.toString()
|
|
455
|
+
});
|
|
456
|
+
const body = await res.json().catch(() => ({}));
|
|
457
|
+
if (!res.ok) {
|
|
458
|
+
throw new TokenExchangeError(typeof body.error === "string" ? body.error : `http_${res.status}`, res.status, typeof body.error_description === "string" ? body.error_description : void 0);
|
|
459
|
+
}
|
|
460
|
+
return {
|
|
461
|
+
accessToken: String(body.access_token),
|
|
462
|
+
expiresIn: Number(body.expires_in),
|
|
463
|
+
scope: String(body.scope ?? "").split(" ").filter(Boolean)
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
167
467
|
// src/index.ts
|
|
168
|
-
var SDK_VERSION = "0.
|
|
468
|
+
var SDK_VERSION = "0.7.0";
|
|
169
469
|
var CookieMunchApiError = class extends Error {
|
|
170
470
|
constructor(status, message, code, body) {
|
|
171
471
|
super(message);
|
|
@@ -176,6 +476,10 @@ var CookieMunchApiError = class extends Error {
|
|
|
176
476
|
}
|
|
177
477
|
};
|
|
178
478
|
var withBase = (doc, opts) => opts?.baseUpdatedAt !== void 0 ? { ...doc, baseUpdatedAt: opts.baseUpdatedAt } : doc;
|
|
479
|
+
function metaQs(o) {
|
|
480
|
+
const parts = Object.entries(o?.metadata ?? {}).map(([k, v]) => `metadata%5B${encodeURIComponent(k)}%5D=${encodeURIComponent(v)}`);
|
|
481
|
+
return parts.length ? `?${parts.join("&")}` : "";
|
|
482
|
+
}
|
|
179
483
|
function qs(query) {
|
|
180
484
|
if (!query) return "";
|
|
181
485
|
const parts = [];
|
|
@@ -191,9 +495,12 @@ function createCookieMunch(opts) {
|
|
|
191
495
|
const base = `${opts.baseUrl.replace(/\/+$/, "")}/v1`;
|
|
192
496
|
const doFetch = opts.fetch ?? globalThis.fetch;
|
|
193
497
|
if (!doFetch) throw new Error("No fetch available; pass { fetch } in CookieMunchOptions.");
|
|
194
|
-
async function request(method, path, body, raw = false) {
|
|
195
|
-
const headers = { Authorization: `Bearer ${opts.apiKey}`, "User-Agent": opts.userAgent ?? `cookiemunch-js/${SDK_VERSION}
|
|
498
|
+
async function request(method, path, body, raw = false, extraHeaders = {}) {
|
|
499
|
+
const headers = { Authorization: `Bearer ${opts.apiKey}`, "User-Agent": opts.userAgent ?? `cookiemunch-js/${SDK_VERSION}`, ...extraHeaders };
|
|
196
500
|
if (opts.strictUnknownFields && method !== "GET") headers["Prefer"] = "strict-unknown-fields";
|
|
501
|
+
if (opts.apiVersion) headers["CookieMunch-Version"] = opts.apiVersion;
|
|
502
|
+
if (opts.secretRecipient && method !== "GET") headers["X-Secret-Recipient"] = opts.secretRecipient;
|
|
503
|
+
for (const [k, v] of Object.entries(opts.headers ?? {})) headers[k] = v;
|
|
197
504
|
const init = { method, headers };
|
|
198
505
|
if (body !== void 0) {
|
|
199
506
|
headers["Content-Type"] = "application/json";
|
|
@@ -219,22 +526,49 @@ function createCookieMunch(opts) {
|
|
|
219
526
|
return contentType.includes("application/json") ? res.json() : res.text();
|
|
220
527
|
}
|
|
221
528
|
const get = (p) => request("GET", p);
|
|
529
|
+
async function requestBytes(path) {
|
|
530
|
+
const res = await doFetch(`${base}${path}`, { method: "GET", headers: { Authorization: `Bearer ${opts.apiKey}`, "User-Agent": opts.userAgent ?? `cookiemunch-js/${SDK_VERSION}` } });
|
|
531
|
+
if (!res.ok) {
|
|
532
|
+
let message = `request failed with status ${res.status}`;
|
|
533
|
+
let code;
|
|
534
|
+
try {
|
|
535
|
+
const data = await res.json();
|
|
536
|
+
if (typeof data.error === "string") message = data.error;
|
|
537
|
+
if (typeof data.code === "string") code = data.code;
|
|
538
|
+
} catch {
|
|
539
|
+
}
|
|
540
|
+
throw new CookieMunchApiError(res.status, message, code);
|
|
541
|
+
}
|
|
542
|
+
return res.arrayBuffer();
|
|
543
|
+
}
|
|
222
544
|
const enc = encodeURIComponent;
|
|
223
545
|
return {
|
|
224
546
|
me: () => get("/me"),
|
|
225
547
|
languages: () => get("/languages"),
|
|
226
548
|
orgs: {
|
|
227
|
-
list: () => get(
|
|
228
|
-
create: (name, opts2) => request("POST", "/orgs", { name, ...opts2 ?? {} })
|
|
549
|
+
list: (o) => get(`/orgs${metaQs(o)}`),
|
|
550
|
+
create: (name, opts2) => request("POST", "/orgs", { name, ...opts2 ?? {} }),
|
|
551
|
+
deleteSandbox: (id) => request("DELETE", `/orgs/${enc(id)}?hard=1`)
|
|
552
|
+
},
|
|
553
|
+
metadata: {
|
|
554
|
+
get: (type, id) => get(`/metadata/${enc(type)}/${enc(id)}`),
|
|
555
|
+
update: (type, id, metadata, o) => request("PATCH", `/metadata/${enc(type)}/${enc(id)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, { metadata })
|
|
556
|
+
},
|
|
557
|
+
partnerLinks: {
|
|
558
|
+
list: (o) => get(`/partner_links${metaQs(o)}`),
|
|
559
|
+
create: (input) => request("POST", "/partner_links", input),
|
|
560
|
+
revoke: (id) => request("DELETE", `/partner_links/${enc(id)}`)
|
|
229
561
|
},
|
|
562
|
+
provisionEnv: (ref) => get(`/provision/env${qs({ ref })}`),
|
|
230
563
|
sites: {
|
|
231
|
-
list: () => get(
|
|
564
|
+
list: (o) => get(`/sites${metaQs(o)}`),
|
|
232
565
|
create: (input) => request("POST", "/sites", input),
|
|
233
566
|
get: (cbid) => get(`/sites/${enc(cbid)}`),
|
|
234
567
|
update: (cbid, patch, o) => request("PATCH", `/sites/${enc(cbid)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, patch),
|
|
235
568
|
delete: async (cbid) => {
|
|
236
569
|
await request("DELETE", `/sites/${enc(cbid)}`);
|
|
237
570
|
},
|
|
571
|
+
deleteSandbox: (cbid) => request("DELETE", `/sites/${enc(cbid)}?hard=1`),
|
|
238
572
|
listPartners: (cbid) => get(`/sites/${enc(cbid)}/partners`),
|
|
239
573
|
linkPartner: (cbid, input, o) => request("POST", `/sites/${enc(cbid)}/partners${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input),
|
|
240
574
|
unlinkPartner: (cbid, linkId) => request("DELETE", `/sites/${enc(cbid)}/partners/${enc(linkId)}`),
|
|
@@ -283,6 +617,9 @@ function createCookieMunch(opts) {
|
|
|
283
617
|
}),
|
|
284
618
|
cookiePresets: (cbid) => get(`/sites/${enc(cbid)}/cookies/presets`),
|
|
285
619
|
applyCookiePreset: (cbid, vendor, params, o) => request("PUT", `/sites/${enc(cbid)}/cookies/presets/${enc(vendor)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, params ?? {}),
|
|
620
|
+
importCookieManifest: (cbid, input, o) => request("PUT", `/sites/${enc(cbid)}/cookies/presets/custom${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input),
|
|
621
|
+
cookieSuggestions: (cbid) => get(`/sites/${enc(cbid)}/cookies/suggestions`),
|
|
622
|
+
declareCookieSuggestions: (cbid, input, o) => request("POST", `/sites/${enc(cbid)}/cookies/suggestions/declare${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input ?? {}),
|
|
286
623
|
removeCookiePreset: (cbid, vendor, o) => request("DELETE", `/sites/${enc(cbid)}/cookies/presets/${enc(vendor)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`),
|
|
287
624
|
deleteObservedCookie: (async (cbid, name, o) => {
|
|
288
625
|
const out = await request("DELETE", `/sites/${enc(cbid)}/observed-cookies/${enc(name)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`);
|
|
@@ -300,6 +637,8 @@ function createCookieMunch(opts) {
|
|
|
300
637
|
verifyChallenge: (cbid) => get(`/sites/${enc(cbid)}/verify/challenge`),
|
|
301
638
|
createBulk: (sites) => request("POST", "/sites/bulk", { sites }),
|
|
302
639
|
brand: (cbid) => request("POST", `/sites/${enc(cbid)}/brand`, {}),
|
|
640
|
+
getBrand: (cbid) => get(`/sites/${enc(cbid)}/brand`),
|
|
641
|
+
setBrand: (cbid, input, o) => request("PUT", `/sites/${enc(cbid)}/brand${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input),
|
|
303
642
|
getFlow: (cbid) => get(`/sites/${enc(cbid)}/flow`),
|
|
304
643
|
editFlow: (cbid, operations) => request("POST", `/sites/${enc(cbid)}/flow/ops`, { operations }),
|
|
305
644
|
setFlow: (cbid, config) => request("PUT", `/sites/${enc(cbid)}/flow`, config)
|
|
@@ -307,11 +646,13 @@ function createCookieMunch(opts) {
|
|
|
307
646
|
consent: {
|
|
308
647
|
verify: (cbid) => get(`/sites/${enc(cbid)}/consent/verify`),
|
|
309
648
|
stats: (cbid, query) => get(`/sites/${enc(cbid)}/consent/stats${qs(toQuery(query))}`),
|
|
649
|
+
insights: (cbid, query) => get(`/sites/${enc(cbid)}/consent/insights${qs(toQuery(query))}`),
|
|
310
650
|
log: (cbid, query) => get(`/sites/${enc(cbid)}/consent/log${qs(toQuery(query))}`),
|
|
311
651
|
export: (cbid, query) => request("GET", `/sites/${enc(cbid)}/consent/export${qs(toQuery(query))}`, void 0, true),
|
|
312
652
|
receipt: (cbid, stamp) => get(`/sites/${enc(cbid)}/receipt/${enc(stamp)}`),
|
|
313
653
|
eraseSubject: (cbid, stamp) => request("POST", `/sites/${enc(cbid)}/erase-consent`, { stamp }),
|
|
314
654
|
exportSubject: (cbid, stamp) => request("GET", `/sites/${enc(cbid)}/subject-export?stamp=${enc(stamp)}`),
|
|
655
|
+
categoryRegistry: () => get("/categories/registry"),
|
|
315
656
|
ingest: async (input) => {
|
|
316
657
|
const res = await doFetch(`${opts.baseUrl.replace(/\/+$/, "")}/api/v1/consent`, {
|
|
317
658
|
method: "POST",
|
|
@@ -342,7 +683,16 @@ function createCookieMunch(opts) {
|
|
|
342
683
|
delete: async (id) => {
|
|
343
684
|
await request("DELETE", `/dsar/${enc(id)}`);
|
|
344
685
|
},
|
|
345
|
-
markTest: (id) => request("POST", `/dsar/${enc(id)}/mark-test`)
|
|
686
|
+
markTest: (id) => request("POST", `/dsar/${enc(id)}/mark-test`),
|
|
687
|
+
listByTrace: (trace) => get(`/dsar${qs({ trace })}`),
|
|
688
|
+
openCase: (input, o) => request("POST", "/dsar/requests", input, false, {
|
|
689
|
+
...o?.idempotencyKey ? { "Idempotency-Key": o.idempotencyKey } : {},
|
|
690
|
+
...o?.trace ? { "X-ForgeDeck-Trace": o.trace } : {}
|
|
691
|
+
}),
|
|
692
|
+
getCase: (id) => get(`/dsar/requests/${enc(id)}`),
|
|
693
|
+
cancelCase: (id) => request("POST", `/dsar/requests/${enc(id)}/cancel`),
|
|
694
|
+
caseReceipt: (id) => get(`/dsar/requests/${enc(id)}/receipt`),
|
|
695
|
+
caseReceiptPdf: (id) => requestBytes(`/dsar/requests/${enc(id)}/receipt?format=pdf`)
|
|
346
696
|
},
|
|
347
697
|
vendors: {
|
|
348
698
|
list: () => get("/vendors"),
|
|
@@ -445,7 +795,8 @@ function createCookieMunch(opts) {
|
|
|
445
795
|
status: (requestId) => get(`/dsar/${enc(requestId)}/fulfillment`),
|
|
446
796
|
pendingTasks: (limit) => get(`/dsar/agent/tasks${qs({ limit })}`),
|
|
447
797
|
reportTask: (taskId, ok, error) => request("POST", `/dsar/agent/tasks/${enc(taskId)}/result`, { ok, ...error !== void 0 ? { error } : {} }),
|
|
448
|
-
executors: () => get(
|
|
798
|
+
executors: (o) => get(`/dsar/executors${metaQs(o)}`),
|
|
799
|
+
executor: (id) => get(`/dsar/executors/${enc(id)}`),
|
|
449
800
|
connectExecutor: (input) => request("POST", "/dsar/executors", input),
|
|
450
801
|
updateExecutor: (id, patch) => request("PATCH", `/dsar/executors/${enc(id)}`, patch),
|
|
451
802
|
dryRunConnectExecutor: (input) => request("POST", "/dsar/executors?dryRun=1", input),
|
|
@@ -460,7 +811,11 @@ function createCookieMunch(opts) {
|
|
|
460
811
|
},
|
|
461
812
|
taskExport: (requestId, taskId) => get(`/dsar/${enc(requestId)}/tasks/${enc(taskId)}/export`),
|
|
462
813
|
task: (requestId, taskId) => get(`/dsar/${enc(requestId)}/tasks/${enc(taskId)}`),
|
|
463
|
-
testExecutor: (id, input) => request("POST", `/dsar/executors/${enc(id)}/test`, input)
|
|
814
|
+
testExecutor: (id, input) => request("POST", `/dsar/executors/${enc(id)}/test`, input),
|
|
815
|
+
recheckExecutor: (id) => request("POST", `/dsar/executors/${enc(id)}/recheck`),
|
|
816
|
+
executorHealthHistory: (id, opts2 = {}) => get(`/dsar/executors/${enc(id)}/health/history${qs({ limit: opts2.limit })}`),
|
|
817
|
+
executorConformance: (id) => request("POST", `/dsar/executors/${enc(id)}/test`, { conformance: true }),
|
|
818
|
+
rollExecutorCompletionSecret: (id) => request("POST", `/dsar/executors/${enc(id)}/completion-secret/roll`)
|
|
464
819
|
},
|
|
465
820
|
preferences: {
|
|
466
821
|
list: () => get("/preferences"),
|
|
@@ -484,11 +839,32 @@ function createCookieMunch(opts) {
|
|
|
484
839
|
},
|
|
485
840
|
roll: (prefix) => request("POST", `/keys/${enc(prefix)}/roll`),
|
|
486
841
|
update: (prefix, patch) => request("PATCH", `/keys/${enc(prefix)}`, patch),
|
|
487
|
-
report: (o) => get(`/keys/report${qs({ unusedDays: o?.unusedDays, expiringDays: o?.expiringDays })}`)
|
|
842
|
+
report: (o) => get(`/keys/report${qs({ unusedDays: o?.unusedDays, expiringDays: o?.expiringDays })}`),
|
|
843
|
+
listStandard: () => get("/keys?shape=standard"),
|
|
844
|
+
self: () => get("/keys/self"),
|
|
845
|
+
updateSelf: (input) => request("PATCH", "/keys/self", input),
|
|
846
|
+
rollSelf: () => request("POST", "/keys/self/roll"),
|
|
847
|
+
vend: (input) => request("POST", "/keys/vend", input),
|
|
848
|
+
revokeLeaked: (report) => request("POST", "/keys/revoke_leaked", report)
|
|
488
849
|
},
|
|
489
850
|
usage: () => get("/usage"),
|
|
851
|
+
entitlements: () => get("/entitlements"),
|
|
852
|
+
versions: () => get("/versions"),
|
|
853
|
+
sandbox: {
|
|
854
|
+
get: async () => (await get("/sandbox")).sandbox,
|
|
855
|
+
create: (input) => request("POST", "/sandbox", input ?? {}),
|
|
856
|
+
delete: () => request("DELETE", "/sandbox")
|
|
857
|
+
},
|
|
490
858
|
integrationHealth: (cbid) => get(`/integration-health${qs({ cbid })}`),
|
|
491
|
-
|
|
859
|
+
healthWaivers: {
|
|
860
|
+
list: (cbid) => get(`/integration-health/waivers${qs({ cbid })}`),
|
|
861
|
+
set: (input) => request("PUT", "/integration-health/waivers", input),
|
|
862
|
+
remove: async (check, opts2) => {
|
|
863
|
+
await request("DELETE", `/integration-health/waivers${qs({ check, cbid: opts2?.cbid, subject: opts2?.subject })}`);
|
|
864
|
+
}
|
|
865
|
+
},
|
|
866
|
+
embedManifest: (cbid) => get(`/embed${qs({ cbid })}`),
|
|
867
|
+
provision: (input, o) => request("POST", `/provision${qs({ dryRun: o?.dryRun ? "1" : void 0, fromStep: o?.fromStep })}`, input),
|
|
492
868
|
org: {
|
|
493
869
|
get: () => get("/org"),
|
|
494
870
|
update: (patch) => request("PATCH", "/org", patch),
|
|
@@ -518,7 +894,14 @@ function createCookieMunch(opts) {
|
|
|
518
894
|
remove: () => request("DELETE", "/org/rights-identity")
|
|
519
895
|
}
|
|
520
896
|
},
|
|
521
|
-
audit: (limit) => get(`/audit${qs({ limit })}`),
|
|
897
|
+
audit: (limit, opts2) => get(`/audit${qs({ limit, actor: opts2?.actor })}`),
|
|
898
|
+
auditSink: {
|
|
899
|
+
get: () => get("/audit/sink"),
|
|
900
|
+
set: (input) => request("PUT", "/audit/sink", input),
|
|
901
|
+
remove: async () => {
|
|
902
|
+
await request("DELETE", "/audit/sink");
|
|
903
|
+
}
|
|
904
|
+
},
|
|
522
905
|
assets: {
|
|
523
906
|
upload: (input) => request("POST", "/assets", input),
|
|
524
907
|
delete: async (urlOrFileName) => {
|
|
@@ -541,7 +924,7 @@ function createCookieMunch(opts) {
|
|
|
541
924
|
}
|
|
542
925
|
},
|
|
543
926
|
webhooks: {
|
|
544
|
-
list: () => get(
|
|
927
|
+
list: (o) => get(`/webhooks${metaQs(o)}`),
|
|
545
928
|
create: (input) => request("POST", "/webhooks", input),
|
|
546
929
|
update: (id, patch) => request("PATCH", `/webhooks/${enc(id)}`, patch),
|
|
547
930
|
delete: async (id) => {
|
|
@@ -550,7 +933,8 @@ function createCookieMunch(opts) {
|
|
|
550
933
|
rollSecret: (id) => request("POST", `/webhooks/${enc(id)}/roll`),
|
|
551
934
|
test: (id) => request("POST", `/webhooks/${enc(id)}/test`),
|
|
552
935
|
deadLetters: () => get("/webhooks/dead-letters"),
|
|
553
|
-
replayDeadLetter: (id) => request("POST", `/webhooks/dead-letters/${enc(id)}/replay`)
|
|
936
|
+
replayDeadLetter: (id) => request("POST", `/webhooks/dead-letters/${enc(id)}/replay`),
|
|
937
|
+
replay: (id, since, opts2) => request("POST", `/webhooks/${enc(id)}/replay${qs({ since: String(since), limit: opts2?.limit })}`)
|
|
554
938
|
},
|
|
555
939
|
rightsLinks: {
|
|
556
940
|
create: (cbid, input) => request("POST", `/sites/${enc(cbid)}/rights-links`, input)
|
|
@@ -570,6 +954,13 @@ function createCookieMunch(opts) {
|
|
|
570
954
|
set: (cbid, input) => request("PUT", `/sites/${enc(cbid)}/rights-identity`, input),
|
|
571
955
|
remove: (cbid) => request("DELETE", `/sites/${enc(cbid)}/rights-identity`)
|
|
572
956
|
},
|
|
957
|
+
dsarSettings: {
|
|
958
|
+
get: (cbid) => get(`/sites/${enc(cbid)}/dsar-settings`),
|
|
959
|
+
set: (cbid, input) => request("PUT", `/sites/${enc(cbid)}/dsar-settings`, input)
|
|
960
|
+
},
|
|
961
|
+
integrations: {
|
|
962
|
+
subjectCard: (app, person) => get(`/integrations/${enc(app)}/card${qs(person)}`)
|
|
963
|
+
},
|
|
573
964
|
subjects: {
|
|
574
965
|
consent: (subjectId) => get(`/subjects/${enc(subjectId)}/consent`)
|
|
575
966
|
},
|
|
@@ -589,15 +980,25 @@ function createCookieMunch(opts) {
|
|
|
589
980
|
}
|
|
590
981
|
// Annotate the CommonJS export names for ESM import in node:
|
|
591
982
|
0 && (module.exports = {
|
|
983
|
+
CANARY_ISSUER,
|
|
984
|
+
CONFORMANCE_RULES,
|
|
592
985
|
CONSENT_COOKIE_NAME,
|
|
593
986
|
CookieMunchApiError,
|
|
987
|
+
DEFAULT_JWKS_URL,
|
|
594
988
|
SDK_VERSION,
|
|
989
|
+
TokenExchangeError,
|
|
990
|
+
canaryIdentityFor,
|
|
991
|
+
consentSignaturePayload,
|
|
595
992
|
createCookieMunch,
|
|
993
|
+
exchangeOperatorToken,
|
|
596
994
|
getConsent,
|
|
597
995
|
isAllowed,
|
|
598
996
|
mintConsentSyncToken,
|
|
599
997
|
parseConsentValue,
|
|
600
998
|
readConsent,
|
|
999
|
+
runExecutorConformance,
|
|
1000
|
+
verifyDecisionSignature,
|
|
1001
|
+
verifyToken,
|
|
601
1002
|
verifyWebhookSignature
|
|
602
1003
|
});
|
|
603
1004
|
//# sourceMappingURL=index.cjs.map
|