@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.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CONSENT_COOKIE_NAME,
|
|
3
|
+
DEFAULT_JWKS_URL,
|
|
4
|
+
consentSignaturePayload,
|
|
3
5
|
getConsent,
|
|
4
6
|
isAllowed,
|
|
5
7
|
parseConsentValue,
|
|
6
|
-
readConsent
|
|
7
|
-
|
|
8
|
+
readConsent,
|
|
9
|
+
verifyDecisionSignature,
|
|
10
|
+
verifyToken
|
|
11
|
+
} from "./chunk-OSVTQPQG.js";
|
|
8
12
|
|
|
9
13
|
// src/webhooks.ts
|
|
10
14
|
import { createHmac, timingSafeEqual } from "crypto";
|
|
@@ -41,8 +45,219 @@ function mintConsentSyncToken(input) {
|
|
|
41
45
|
return `cms1.${payload}.${sig}`;
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
// src/executor-conformance.ts
|
|
49
|
+
var CANARY_ISSUER = "https://canary.cookiemunch.net";
|
|
50
|
+
var CANARY_EMAIL_RE = /^canary-([0-9a-f]{16})@canary\.cookiemunch\.net$/;
|
|
51
|
+
function canaryIdentityFor(canaryEmail) {
|
|
52
|
+
const m = CANARY_EMAIL_RE.exec(canaryEmail.trim().toLowerCase());
|
|
53
|
+
if (!m) throw new Error("canaryEmail must be the canary address canary-<16 hex>@canary.cookiemunch.net");
|
|
54
|
+
return { iss: CANARY_ISSUER, sub: `canary_${m[1]}`, ext: `canary:${m[1]}` };
|
|
55
|
+
}
|
|
56
|
+
var CONFORMANCE_RULES = [
|
|
57
|
+
{ id: "auth.required", title: "A request without the credential is refused (401 or 403)." },
|
|
58
|
+
{ id: "lookup.email.found", title: "The canary subject is found by its email." },
|
|
59
|
+
{ id: "lookup.identity.found", title: "The canary subject is found by its identity alone (iss + sub), and it is the same subject." },
|
|
60
|
+
{ id: "lookup.unknown.no_match", title: 'An address nobody has answers { subjectId: null, status: "no_match" }.' },
|
|
61
|
+
{ id: "lookup.identity_beats_email", title: "An identity that matches no one is never matched through the email of someone else." },
|
|
62
|
+
{ id: "requests.bad_body.400", title: "A request with an unknown type answers 400 { error, field }." },
|
|
63
|
+
{ id: "requests.alias.canonical_type", title: 'An alias (erasure) is accepted and answered with canonicalType "deletion".' },
|
|
64
|
+
{ 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.' },
|
|
65
|
+
{ id: "requests.idempotency.replay", title: "The same Idempotency-Key with the same body returns the same request, not a second one." },
|
|
66
|
+
{ id: "requests.idempotency.mismatch_409", title: "The same Idempotency-Key with a different body answers 409." },
|
|
67
|
+
{ id: "requests.get", title: "GET /privacy/requests/{id} returns the request, still scheduled." },
|
|
68
|
+
{ id: "requests.unknown.404", title: "An unknown request id answers 404." },
|
|
69
|
+
{ id: "requests.cancel.before_execute_after", title: 'A cancel before executeAfter answers status "cancelled".' },
|
|
70
|
+
{ id: "requests.cancel.keeps_data", title: "After a cancel the subject is still there: a lookup finds it." },
|
|
71
|
+
{ id: "version.header", title: "Answers carry X-Version (the highest contract version the executor supports)." }
|
|
72
|
+
];
|
|
73
|
+
function randomTag() {
|
|
74
|
+
const bytes = new Uint8Array(8);
|
|
75
|
+
const c = globalThis.crypto;
|
|
76
|
+
if (c?.getRandomValues) c.getRandomValues(bytes);
|
|
77
|
+
else for (let i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
|
|
78
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
79
|
+
}
|
|
80
|
+
function field(json, key) {
|
|
81
|
+
return json && typeof json === "object" ? json[key] : void 0;
|
|
82
|
+
}
|
|
83
|
+
async function runExecutorConformance(o) {
|
|
84
|
+
const doFetch = o.fetch ?? fetch;
|
|
85
|
+
const now = o.now ?? (() => Date.now());
|
|
86
|
+
const base = o.baseUrl.replace(/\/+$/, "") + (o.prefix ?? "/privacy");
|
|
87
|
+
let url;
|
|
88
|
+
try {
|
|
89
|
+
url = new URL(base);
|
|
90
|
+
} catch {
|
|
91
|
+
throw new Error("baseUrl must be an absolute URL");
|
|
92
|
+
}
|
|
93
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && /^(localhost|127\.0\.0\.1|\[::1\])$/.test(url.hostname))) {
|
|
94
|
+
throw new Error("baseUrl must be https (http only for localhost)");
|
|
95
|
+
}
|
|
96
|
+
const identity = canaryIdentityFor(o.canaryEmail);
|
|
97
|
+
const canaryEmail = o.canaryEmail.trim().toLowerCase();
|
|
98
|
+
const auth = o.auth ?? { header: "Authorization", format: "Bearer {secret}" };
|
|
99
|
+
const run = o.runId ?? randomTag();
|
|
100
|
+
const results = /* @__PURE__ */ new Map();
|
|
101
|
+
let version;
|
|
102
|
+
const set = (id, status, detail) => {
|
|
103
|
+
const rule = CONFORMANCE_RULES.find((r) => r.id === id);
|
|
104
|
+
results.set(id, { id, title: rule.title, status, ...detail ? { detail } : {} });
|
|
105
|
+
};
|
|
106
|
+
const pass = (id) => set(id, "pass");
|
|
107
|
+
const fail = (id, detail) => set(id, "fail", detail);
|
|
108
|
+
const skip = (id, detail) => set(id, "skip", detail);
|
|
109
|
+
async function call(method, path, body, extra = {}, withAuth = true) {
|
|
110
|
+
const headers = {
|
|
111
|
+
accept: "application/json",
|
|
112
|
+
"X-Version": "2",
|
|
113
|
+
...withAuth ? { [auth.header]: auth.format.replace("{secret}", o.secret) } : {},
|
|
114
|
+
...body !== void 0 ? { "content-type": "application/json" } : {},
|
|
115
|
+
...extra
|
|
116
|
+
};
|
|
117
|
+
try {
|
|
118
|
+
const res = await doFetch(base + path, { method, headers, ...body !== void 0 ? { body: JSON.stringify(body) } : {} });
|
|
119
|
+
const text = await res.text().catch(() => "");
|
|
120
|
+
let json;
|
|
121
|
+
try {
|
|
122
|
+
json = text ? JSON.parse(text) : void 0;
|
|
123
|
+
} catch {
|
|
124
|
+
json = void 0;
|
|
125
|
+
}
|
|
126
|
+
const v = res.headers.get("x-version");
|
|
127
|
+
if (v && !version) version = v;
|
|
128
|
+
return { status: res.status, json, version: v };
|
|
129
|
+
} catch (err) {
|
|
130
|
+
return { status: 0, json: void 0, version: null, error: err instanceof Error ? err.message : String(err) };
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const said = (a) => a.status === 0 ? `unreachable: ${a.error}` : `HTTP ${a.status} ${JSON.stringify(a.json ?? null).slice(0, 200)}`;
|
|
134
|
+
const key = (rule) => `conformance:${run}:${rule}`;
|
|
135
|
+
const anon = await call("POST", "/lookup", { emails: [canaryEmail] }, {}, false);
|
|
136
|
+
if (anon.status === 0) {
|
|
137
|
+
for (const r of CONFORMANCE_RULES) skip(r.id, said(anon));
|
|
138
|
+
fail("auth.required", said(anon));
|
|
139
|
+
return report();
|
|
140
|
+
}
|
|
141
|
+
if (anon.status === 401 || anon.status === 403) pass("auth.required");
|
|
142
|
+
else fail("auth.required", `without a credential: ${said(anon)}`);
|
|
143
|
+
const byEmail = await call("POST", "/lookup", { emails: [canaryEmail] }, { "Idempotency-Key": key("lookup-email") });
|
|
144
|
+
const subjectId = field(byEmail.json, "subjectId");
|
|
145
|
+
if (byEmail.status === 200 && field(byEmail.json, "status") === "found" && typeof subjectId === "string" && subjectId) pass("lookup.email.found");
|
|
146
|
+
else fail("lookup.email.found", `the canary address: ${said(byEmail)}`);
|
|
147
|
+
const byIdentity = await call("POST", "/lookup", { emails: [], identity, atlas: identity }, { "Idempotency-Key": key("lookup-identity") });
|
|
148
|
+
if (byIdentity.status === 200 && field(byIdentity.json, "status") === "found" && field(byIdentity.json, "subjectId") === subjectId && typeof subjectId === "string") {
|
|
149
|
+
pass("lookup.identity.found");
|
|
150
|
+
} else {
|
|
151
|
+
fail("lookup.identity.found", `the canary identity ${identity.sub}: ${said(byIdentity)}${typeof subjectId === "string" ? ` (by email it was ${subjectId})` : ""}`);
|
|
152
|
+
}
|
|
153
|
+
const nobody = await call("POST", "/lookup", { emails: [`nobody-${run}@canary.cookiemunch.net`] }, { "Idempotency-Key": key("lookup-nobody") });
|
|
154
|
+
if (nobody.status === 200 && field(nobody.json, "status") === "no_match" && field(nobody.json, "subjectId") === null) pass("lookup.unknown.no_match");
|
|
155
|
+
else fail("lookup.unknown.no_match", said(nobody));
|
|
156
|
+
const stranger = { iss: identity.iss, sub: `canary_other_${run}` };
|
|
157
|
+
const crossed = await call("POST", "/lookup", { emails: [canaryEmail], identity: stranger, atlas: stranger }, { "Idempotency-Key": key("lookup-crossed") });
|
|
158
|
+
if (crossed.status === 200 && field(crossed.json, "status") === "no_match") pass("lookup.identity_beats_email");
|
|
159
|
+
else {
|
|
160
|
+
fail(
|
|
161
|
+
"lookup.identity_beats_email",
|
|
162
|
+
`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`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
const bad = await call("POST", "/requests", { subjectId: subjectId ?? "x", type: "teleport", caseId: `conformance-${run}` }, { "Idempotency-Key": key("bad-body") });
|
|
166
|
+
if (bad.status === 400 && typeof field(bad.json, "error") === "string" && typeof field(bad.json, "field") === "string") pass("requests.bad_body.400");
|
|
167
|
+
else fail("requests.bad_body.400", said(bad));
|
|
168
|
+
if (typeof subjectId !== "string") {
|
|
169
|
+
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"]) {
|
|
170
|
+
skip(id, "needs the canary subject, which the lookup did not find");
|
|
171
|
+
}
|
|
172
|
+
} else {
|
|
173
|
+
const executeAfter = new Date(Math.ceil((now() + 36e5) / 1e3) * 1e3).toISOString();
|
|
174
|
+
const body = { subjectId, type: "erasure", executeAfter, caseId: `conformance-${run}`, reason: "Cookie Munch conformance check (canary subject)" };
|
|
175
|
+
const opened = await call("POST", "/requests", body, { "Idempotency-Key": key("open") });
|
|
176
|
+
const id = field(opened.json, "id");
|
|
177
|
+
const st = field(opened.json, "status");
|
|
178
|
+
if ((opened.status === 200 || opened.status === 201) && field(opened.json, "canonicalType") === "deletion") pass("requests.alias.canonical_type");
|
|
179
|
+
else fail("requests.alias.canonical_type", `type "erasure": ${said(opened)}`);
|
|
180
|
+
const eta = field(opened.json, "eta");
|
|
181
|
+
if ((opened.status === 200 || opened.status === 201) && st === "scheduled" && typeof eta === "string" && Date.parse(eta) === Date.parse(executeAfter)) {
|
|
182
|
+
pass("requests.execute_after.scheduled");
|
|
183
|
+
} else if (st === "completed" || st === "completed_with_retention" || st === "processing") {
|
|
184
|
+
fail("requests.execute_after.scheduled", `executeAfter is ${executeAfter}, an hour away, and the executor answered "${String(st)}": it acted before executeAfter`);
|
|
185
|
+
} else {
|
|
186
|
+
fail("requests.execute_after.scheduled", `expected status "scheduled" with eta ${executeAfter}: ${said(opened)}`);
|
|
187
|
+
}
|
|
188
|
+
const replay = await call("POST", "/requests", body, { "Idempotency-Key": key("open") });
|
|
189
|
+
if (typeof id === "string" && (replay.status === 200 || replay.status === 201) && field(replay.json, "id") === id) pass("requests.idempotency.replay");
|
|
190
|
+
else fail("requests.idempotency.replay", `a retry with the same key: ${said(replay)}${typeof id === "string" ? ` (first answer id ${id})` : ""}`);
|
|
191
|
+
const mismatch = await call("POST", "/requests", { ...body, reason: "a different body" }, { "Idempotency-Key": key("open") });
|
|
192
|
+
if (mismatch.status === 409) pass("requests.idempotency.mismatch_409");
|
|
193
|
+
else fail("requests.idempotency.mismatch_409", `the same key with a different body: ${said(mismatch)}`);
|
|
194
|
+
if (typeof id !== "string") {
|
|
195
|
+
skip("requests.get", "no request id came back");
|
|
196
|
+
skip("requests.cancel.before_execute_after", "no request id came back");
|
|
197
|
+
skip("requests.cancel.keeps_data", "no request id came back");
|
|
198
|
+
} else {
|
|
199
|
+
const got = await call("GET", `/requests/${encodeURIComponent(id)}`, void 0, { "Idempotency-Key": key("get") });
|
|
200
|
+
if (got.status === 200 && field(got.json, "id") === id && field(got.json, "status") === "scheduled") pass("requests.get");
|
|
201
|
+
else fail("requests.get", said(got));
|
|
202
|
+
const cancelled = await call("POST", `/requests/${encodeURIComponent(id)}/cancel`, {}, { "Idempotency-Key": key("cancel") });
|
|
203
|
+
if (cancelled.status === 200 && field(cancelled.json, "status") === "cancelled") pass("requests.cancel.before_execute_after");
|
|
204
|
+
else fail("requests.cancel.before_execute_after", said(cancelled));
|
|
205
|
+
const after = await call("POST", "/lookup", { emails: [canaryEmail] }, { "Idempotency-Key": key("lookup-after-cancel") });
|
|
206
|
+
if (after.status === 200 && field(after.json, "status") === "found") pass("requests.cancel.keeps_data");
|
|
207
|
+
else fail("requests.cancel.keeps_data", `a lookup after the cancel: ${said(after)} \u2014 a cancel before executeAfter must leave the data intact`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const unknown = await call("GET", `/requests/conformance-missing-${run}`, void 0, { "Idempotency-Key": key("unknown") });
|
|
211
|
+
if (unknown.status === 404) pass("requests.unknown.404");
|
|
212
|
+
else fail("requests.unknown.404", said(unknown));
|
|
213
|
+
if (version) pass("version.header");
|
|
214
|
+
else fail("version.header", "no answer carried an X-Version header");
|
|
215
|
+
return report();
|
|
216
|
+
function report() {
|
|
217
|
+
const rules = CONFORMANCE_RULES.map((r) => results.get(r.id) ?? { id: r.id, title: r.title, status: "skip", detail: "not reached" });
|
|
218
|
+
const count = (s) => rules.filter((r) => r.status === s).length;
|
|
219
|
+
return { ok: count("fail") === 0, passed: count("pass"), failed: count("fail"), skipped: count("skip"), rules, ...version ? { version } : {} };
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// src/token-exchange.ts
|
|
224
|
+
var TokenExchangeError = class extends Error {
|
|
225
|
+
constructor(error, status, description) {
|
|
226
|
+
super(description ? `${error}: ${description}` : error);
|
|
227
|
+
this.error = error;
|
|
228
|
+
this.status = status;
|
|
229
|
+
this.name = "TokenExchangeError";
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
async function exchangeOperatorToken(input) {
|
|
233
|
+
const base = (input.baseUrl ?? "https://api.cookiemunch.net").replace(/\/+$/, "");
|
|
234
|
+
const form = new URLSearchParams({
|
|
235
|
+
grant_type: "urn:ietf:params:oauth:grant-type:token-exchange",
|
|
236
|
+
subject_token: input.subjectToken,
|
|
237
|
+
subject_token_type: `urn:ietf:params:oauth:token-type:${input.subjectTokenType ?? "access_token"}`,
|
|
238
|
+
scope: input.scope.join(" "),
|
|
239
|
+
resource: input.resource,
|
|
240
|
+
audience: "cookiemunch",
|
|
241
|
+
...input.expiresIn !== void 0 ? { expires_in: String(input.expiresIn) } : {}
|
|
242
|
+
});
|
|
243
|
+
const res = await (input.fetch ?? fetch)(`${base}/v1/oauth/token`, {
|
|
244
|
+
method: "POST",
|
|
245
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
246
|
+
body: form.toString()
|
|
247
|
+
});
|
|
248
|
+
const body = await res.json().catch(() => ({}));
|
|
249
|
+
if (!res.ok) {
|
|
250
|
+
throw new TokenExchangeError(typeof body.error === "string" ? body.error : `http_${res.status}`, res.status, typeof body.error_description === "string" ? body.error_description : void 0);
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
accessToken: String(body.access_token),
|
|
254
|
+
expiresIn: Number(body.expires_in),
|
|
255
|
+
scope: String(body.scope ?? "").split(" ").filter(Boolean)
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
44
259
|
// src/index.ts
|
|
45
|
-
var SDK_VERSION = "0.
|
|
260
|
+
var SDK_VERSION = "0.7.0";
|
|
46
261
|
var CookieMunchApiError = class extends Error {
|
|
47
262
|
constructor(status, message, code, body) {
|
|
48
263
|
super(message);
|
|
@@ -53,6 +268,10 @@ var CookieMunchApiError = class extends Error {
|
|
|
53
268
|
}
|
|
54
269
|
};
|
|
55
270
|
var withBase = (doc, opts) => opts?.baseUpdatedAt !== void 0 ? { ...doc, baseUpdatedAt: opts.baseUpdatedAt } : doc;
|
|
271
|
+
function metaQs(o) {
|
|
272
|
+
const parts = Object.entries(o?.metadata ?? {}).map(([k, v]) => `metadata%5B${encodeURIComponent(k)}%5D=${encodeURIComponent(v)}`);
|
|
273
|
+
return parts.length ? `?${parts.join("&")}` : "";
|
|
274
|
+
}
|
|
56
275
|
function qs(query) {
|
|
57
276
|
if (!query) return "";
|
|
58
277
|
const parts = [];
|
|
@@ -68,9 +287,12 @@ function createCookieMunch(opts) {
|
|
|
68
287
|
const base = `${opts.baseUrl.replace(/\/+$/, "")}/v1`;
|
|
69
288
|
const doFetch = opts.fetch ?? globalThis.fetch;
|
|
70
289
|
if (!doFetch) throw new Error("No fetch available; pass { fetch } in CookieMunchOptions.");
|
|
71
|
-
async function request(method, path, body, raw = false) {
|
|
72
|
-
const headers = { Authorization: `Bearer ${opts.apiKey}`, "User-Agent": opts.userAgent ?? `cookiemunch-js/${SDK_VERSION}
|
|
290
|
+
async function request(method, path, body, raw = false, extraHeaders = {}) {
|
|
291
|
+
const headers = { Authorization: `Bearer ${opts.apiKey}`, "User-Agent": opts.userAgent ?? `cookiemunch-js/${SDK_VERSION}`, ...extraHeaders };
|
|
73
292
|
if (opts.strictUnknownFields && method !== "GET") headers["Prefer"] = "strict-unknown-fields";
|
|
293
|
+
if (opts.apiVersion) headers["CookieMunch-Version"] = opts.apiVersion;
|
|
294
|
+
if (opts.secretRecipient && method !== "GET") headers["X-Secret-Recipient"] = opts.secretRecipient;
|
|
295
|
+
for (const [k, v] of Object.entries(opts.headers ?? {})) headers[k] = v;
|
|
74
296
|
const init = { method, headers };
|
|
75
297
|
if (body !== void 0) {
|
|
76
298
|
headers["Content-Type"] = "application/json";
|
|
@@ -96,22 +318,49 @@ function createCookieMunch(opts) {
|
|
|
96
318
|
return contentType.includes("application/json") ? res.json() : res.text();
|
|
97
319
|
}
|
|
98
320
|
const get = (p) => request("GET", p);
|
|
321
|
+
async function requestBytes(path) {
|
|
322
|
+
const res = await doFetch(`${base}${path}`, { method: "GET", headers: { Authorization: `Bearer ${opts.apiKey}`, "User-Agent": opts.userAgent ?? `cookiemunch-js/${SDK_VERSION}` } });
|
|
323
|
+
if (!res.ok) {
|
|
324
|
+
let message = `request failed with status ${res.status}`;
|
|
325
|
+
let code;
|
|
326
|
+
try {
|
|
327
|
+
const data = await res.json();
|
|
328
|
+
if (typeof data.error === "string") message = data.error;
|
|
329
|
+
if (typeof data.code === "string") code = data.code;
|
|
330
|
+
} catch {
|
|
331
|
+
}
|
|
332
|
+
throw new CookieMunchApiError(res.status, message, code);
|
|
333
|
+
}
|
|
334
|
+
return res.arrayBuffer();
|
|
335
|
+
}
|
|
99
336
|
const enc = encodeURIComponent;
|
|
100
337
|
return {
|
|
101
338
|
me: () => get("/me"),
|
|
102
339
|
languages: () => get("/languages"),
|
|
103
340
|
orgs: {
|
|
104
|
-
list: () => get(
|
|
105
|
-
create: (name, opts2) => request("POST", "/orgs", { name, ...opts2 ?? {} })
|
|
341
|
+
list: (o) => get(`/orgs${metaQs(o)}`),
|
|
342
|
+
create: (name, opts2) => request("POST", "/orgs", { name, ...opts2 ?? {} }),
|
|
343
|
+
deleteSandbox: (id) => request("DELETE", `/orgs/${enc(id)}?hard=1`)
|
|
344
|
+
},
|
|
345
|
+
metadata: {
|
|
346
|
+
get: (type, id) => get(`/metadata/${enc(type)}/${enc(id)}`),
|
|
347
|
+
update: (type, id, metadata, o) => request("PATCH", `/metadata/${enc(type)}/${enc(id)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, { metadata })
|
|
106
348
|
},
|
|
349
|
+
partnerLinks: {
|
|
350
|
+
list: (o) => get(`/partner_links${metaQs(o)}`),
|
|
351
|
+
create: (input) => request("POST", "/partner_links", input),
|
|
352
|
+
revoke: (id) => request("DELETE", `/partner_links/${enc(id)}`)
|
|
353
|
+
},
|
|
354
|
+
provisionEnv: (ref) => get(`/provision/env${qs({ ref })}`),
|
|
107
355
|
sites: {
|
|
108
|
-
list: () => get(
|
|
356
|
+
list: (o) => get(`/sites${metaQs(o)}`),
|
|
109
357
|
create: (input) => request("POST", "/sites", input),
|
|
110
358
|
get: (cbid) => get(`/sites/${enc(cbid)}`),
|
|
111
359
|
update: (cbid, patch, o) => request("PATCH", `/sites/${enc(cbid)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, patch),
|
|
112
360
|
delete: async (cbid) => {
|
|
113
361
|
await request("DELETE", `/sites/${enc(cbid)}`);
|
|
114
362
|
},
|
|
363
|
+
deleteSandbox: (cbid) => request("DELETE", `/sites/${enc(cbid)}?hard=1`),
|
|
115
364
|
listPartners: (cbid) => get(`/sites/${enc(cbid)}/partners`),
|
|
116
365
|
linkPartner: (cbid, input, o) => request("POST", `/sites/${enc(cbid)}/partners${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input),
|
|
117
366
|
unlinkPartner: (cbid, linkId) => request("DELETE", `/sites/${enc(cbid)}/partners/${enc(linkId)}`),
|
|
@@ -160,6 +409,9 @@ function createCookieMunch(opts) {
|
|
|
160
409
|
}),
|
|
161
410
|
cookiePresets: (cbid) => get(`/sites/${enc(cbid)}/cookies/presets`),
|
|
162
411
|
applyCookiePreset: (cbid, vendor, params, o) => request("PUT", `/sites/${enc(cbid)}/cookies/presets/${enc(vendor)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, params ?? {}),
|
|
412
|
+
importCookieManifest: (cbid, input, o) => request("PUT", `/sites/${enc(cbid)}/cookies/presets/custom${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input),
|
|
413
|
+
cookieSuggestions: (cbid) => get(`/sites/${enc(cbid)}/cookies/suggestions`),
|
|
414
|
+
declareCookieSuggestions: (cbid, input, o) => request("POST", `/sites/${enc(cbid)}/cookies/suggestions/declare${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input ?? {}),
|
|
163
415
|
removeCookiePreset: (cbid, vendor, o) => request("DELETE", `/sites/${enc(cbid)}/cookies/presets/${enc(vendor)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`),
|
|
164
416
|
deleteObservedCookie: (async (cbid, name, o) => {
|
|
165
417
|
const out = await request("DELETE", `/sites/${enc(cbid)}/observed-cookies/${enc(name)}${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`);
|
|
@@ -177,6 +429,8 @@ function createCookieMunch(opts) {
|
|
|
177
429
|
verifyChallenge: (cbid) => get(`/sites/${enc(cbid)}/verify/challenge`),
|
|
178
430
|
createBulk: (sites) => request("POST", "/sites/bulk", { sites }),
|
|
179
431
|
brand: (cbid) => request("POST", `/sites/${enc(cbid)}/brand`, {}),
|
|
432
|
+
getBrand: (cbid) => get(`/sites/${enc(cbid)}/brand`),
|
|
433
|
+
setBrand: (cbid, input, o) => request("PUT", `/sites/${enc(cbid)}/brand${qs({ dryRun: o?.dryRun ? "1" : void 0 })}`, input),
|
|
180
434
|
getFlow: (cbid) => get(`/sites/${enc(cbid)}/flow`),
|
|
181
435
|
editFlow: (cbid, operations) => request("POST", `/sites/${enc(cbid)}/flow/ops`, { operations }),
|
|
182
436
|
setFlow: (cbid, config) => request("PUT", `/sites/${enc(cbid)}/flow`, config)
|
|
@@ -184,11 +438,13 @@ function createCookieMunch(opts) {
|
|
|
184
438
|
consent: {
|
|
185
439
|
verify: (cbid) => get(`/sites/${enc(cbid)}/consent/verify`),
|
|
186
440
|
stats: (cbid, query) => get(`/sites/${enc(cbid)}/consent/stats${qs(toQuery(query))}`),
|
|
441
|
+
insights: (cbid, query) => get(`/sites/${enc(cbid)}/consent/insights${qs(toQuery(query))}`),
|
|
187
442
|
log: (cbid, query) => get(`/sites/${enc(cbid)}/consent/log${qs(toQuery(query))}`),
|
|
188
443
|
export: (cbid, query) => request("GET", `/sites/${enc(cbid)}/consent/export${qs(toQuery(query))}`, void 0, true),
|
|
189
444
|
receipt: (cbid, stamp) => get(`/sites/${enc(cbid)}/receipt/${enc(stamp)}`),
|
|
190
445
|
eraseSubject: (cbid, stamp) => request("POST", `/sites/${enc(cbid)}/erase-consent`, { stamp }),
|
|
191
446
|
exportSubject: (cbid, stamp) => request("GET", `/sites/${enc(cbid)}/subject-export?stamp=${enc(stamp)}`),
|
|
447
|
+
categoryRegistry: () => get("/categories/registry"),
|
|
192
448
|
ingest: async (input) => {
|
|
193
449
|
const res = await doFetch(`${opts.baseUrl.replace(/\/+$/, "")}/api/v1/consent`, {
|
|
194
450
|
method: "POST",
|
|
@@ -219,7 +475,16 @@ function createCookieMunch(opts) {
|
|
|
219
475
|
delete: async (id) => {
|
|
220
476
|
await request("DELETE", `/dsar/${enc(id)}`);
|
|
221
477
|
},
|
|
222
|
-
markTest: (id) => request("POST", `/dsar/${enc(id)}/mark-test`)
|
|
478
|
+
markTest: (id) => request("POST", `/dsar/${enc(id)}/mark-test`),
|
|
479
|
+
listByTrace: (trace) => get(`/dsar${qs({ trace })}`),
|
|
480
|
+
openCase: (input, o) => request("POST", "/dsar/requests", input, false, {
|
|
481
|
+
...o?.idempotencyKey ? { "Idempotency-Key": o.idempotencyKey } : {},
|
|
482
|
+
...o?.trace ? { "X-ForgeDeck-Trace": o.trace } : {}
|
|
483
|
+
}),
|
|
484
|
+
getCase: (id) => get(`/dsar/requests/${enc(id)}`),
|
|
485
|
+
cancelCase: (id) => request("POST", `/dsar/requests/${enc(id)}/cancel`),
|
|
486
|
+
caseReceipt: (id) => get(`/dsar/requests/${enc(id)}/receipt`),
|
|
487
|
+
caseReceiptPdf: (id) => requestBytes(`/dsar/requests/${enc(id)}/receipt?format=pdf`)
|
|
223
488
|
},
|
|
224
489
|
vendors: {
|
|
225
490
|
list: () => get("/vendors"),
|
|
@@ -322,7 +587,8 @@ function createCookieMunch(opts) {
|
|
|
322
587
|
status: (requestId) => get(`/dsar/${enc(requestId)}/fulfillment`),
|
|
323
588
|
pendingTasks: (limit) => get(`/dsar/agent/tasks${qs({ limit })}`),
|
|
324
589
|
reportTask: (taskId, ok, error) => request("POST", `/dsar/agent/tasks/${enc(taskId)}/result`, { ok, ...error !== void 0 ? { error } : {} }),
|
|
325
|
-
executors: () => get(
|
|
590
|
+
executors: (o) => get(`/dsar/executors${metaQs(o)}`),
|
|
591
|
+
executor: (id) => get(`/dsar/executors/${enc(id)}`),
|
|
326
592
|
connectExecutor: (input) => request("POST", "/dsar/executors", input),
|
|
327
593
|
updateExecutor: (id, patch) => request("PATCH", `/dsar/executors/${enc(id)}`, patch),
|
|
328
594
|
dryRunConnectExecutor: (input) => request("POST", "/dsar/executors?dryRun=1", input),
|
|
@@ -337,7 +603,11 @@ function createCookieMunch(opts) {
|
|
|
337
603
|
},
|
|
338
604
|
taskExport: (requestId, taskId) => get(`/dsar/${enc(requestId)}/tasks/${enc(taskId)}/export`),
|
|
339
605
|
task: (requestId, taskId) => get(`/dsar/${enc(requestId)}/tasks/${enc(taskId)}`),
|
|
340
|
-
testExecutor: (id, input) => request("POST", `/dsar/executors/${enc(id)}/test`, input)
|
|
606
|
+
testExecutor: (id, input) => request("POST", `/dsar/executors/${enc(id)}/test`, input),
|
|
607
|
+
recheckExecutor: (id) => request("POST", `/dsar/executors/${enc(id)}/recheck`),
|
|
608
|
+
executorHealthHistory: (id, opts2 = {}) => get(`/dsar/executors/${enc(id)}/health/history${qs({ limit: opts2.limit })}`),
|
|
609
|
+
executorConformance: (id) => request("POST", `/dsar/executors/${enc(id)}/test`, { conformance: true }),
|
|
610
|
+
rollExecutorCompletionSecret: (id) => request("POST", `/dsar/executors/${enc(id)}/completion-secret/roll`)
|
|
341
611
|
},
|
|
342
612
|
preferences: {
|
|
343
613
|
list: () => get("/preferences"),
|
|
@@ -361,11 +631,32 @@ function createCookieMunch(opts) {
|
|
|
361
631
|
},
|
|
362
632
|
roll: (prefix) => request("POST", `/keys/${enc(prefix)}/roll`),
|
|
363
633
|
update: (prefix, patch) => request("PATCH", `/keys/${enc(prefix)}`, patch),
|
|
364
|
-
report: (o) => get(`/keys/report${qs({ unusedDays: o?.unusedDays, expiringDays: o?.expiringDays })}`)
|
|
634
|
+
report: (o) => get(`/keys/report${qs({ unusedDays: o?.unusedDays, expiringDays: o?.expiringDays })}`),
|
|
635
|
+
listStandard: () => get("/keys?shape=standard"),
|
|
636
|
+
self: () => get("/keys/self"),
|
|
637
|
+
updateSelf: (input) => request("PATCH", "/keys/self", input),
|
|
638
|
+
rollSelf: () => request("POST", "/keys/self/roll"),
|
|
639
|
+
vend: (input) => request("POST", "/keys/vend", input),
|
|
640
|
+
revokeLeaked: (report) => request("POST", "/keys/revoke_leaked", report)
|
|
365
641
|
},
|
|
366
642
|
usage: () => get("/usage"),
|
|
643
|
+
entitlements: () => get("/entitlements"),
|
|
644
|
+
versions: () => get("/versions"),
|
|
645
|
+
sandbox: {
|
|
646
|
+
get: async () => (await get("/sandbox")).sandbox,
|
|
647
|
+
create: (input) => request("POST", "/sandbox", input ?? {}),
|
|
648
|
+
delete: () => request("DELETE", "/sandbox")
|
|
649
|
+
},
|
|
367
650
|
integrationHealth: (cbid) => get(`/integration-health${qs({ cbid })}`),
|
|
368
|
-
|
|
651
|
+
healthWaivers: {
|
|
652
|
+
list: (cbid) => get(`/integration-health/waivers${qs({ cbid })}`),
|
|
653
|
+
set: (input) => request("PUT", "/integration-health/waivers", input),
|
|
654
|
+
remove: async (check, opts2) => {
|
|
655
|
+
await request("DELETE", `/integration-health/waivers${qs({ check, cbid: opts2?.cbid, subject: opts2?.subject })}`);
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
embedManifest: (cbid) => get(`/embed${qs({ cbid })}`),
|
|
659
|
+
provision: (input, o) => request("POST", `/provision${qs({ dryRun: o?.dryRun ? "1" : void 0, fromStep: o?.fromStep })}`, input),
|
|
369
660
|
org: {
|
|
370
661
|
get: () => get("/org"),
|
|
371
662
|
update: (patch) => request("PATCH", "/org", patch),
|
|
@@ -395,7 +686,14 @@ function createCookieMunch(opts) {
|
|
|
395
686
|
remove: () => request("DELETE", "/org/rights-identity")
|
|
396
687
|
}
|
|
397
688
|
},
|
|
398
|
-
audit: (limit) => get(`/audit${qs({ limit })}`),
|
|
689
|
+
audit: (limit, opts2) => get(`/audit${qs({ limit, actor: opts2?.actor })}`),
|
|
690
|
+
auditSink: {
|
|
691
|
+
get: () => get("/audit/sink"),
|
|
692
|
+
set: (input) => request("PUT", "/audit/sink", input),
|
|
693
|
+
remove: async () => {
|
|
694
|
+
await request("DELETE", "/audit/sink");
|
|
695
|
+
}
|
|
696
|
+
},
|
|
399
697
|
assets: {
|
|
400
698
|
upload: (input) => request("POST", "/assets", input),
|
|
401
699
|
delete: async (urlOrFileName) => {
|
|
@@ -418,7 +716,7 @@ function createCookieMunch(opts) {
|
|
|
418
716
|
}
|
|
419
717
|
},
|
|
420
718
|
webhooks: {
|
|
421
|
-
list: () => get(
|
|
719
|
+
list: (o) => get(`/webhooks${metaQs(o)}`),
|
|
422
720
|
create: (input) => request("POST", "/webhooks", input),
|
|
423
721
|
update: (id, patch) => request("PATCH", `/webhooks/${enc(id)}`, patch),
|
|
424
722
|
delete: async (id) => {
|
|
@@ -427,7 +725,8 @@ function createCookieMunch(opts) {
|
|
|
427
725
|
rollSecret: (id) => request("POST", `/webhooks/${enc(id)}/roll`),
|
|
428
726
|
test: (id) => request("POST", `/webhooks/${enc(id)}/test`),
|
|
429
727
|
deadLetters: () => get("/webhooks/dead-letters"),
|
|
430
|
-
replayDeadLetter: (id) => request("POST", `/webhooks/dead-letters/${enc(id)}/replay`)
|
|
728
|
+
replayDeadLetter: (id) => request("POST", `/webhooks/dead-letters/${enc(id)}/replay`),
|
|
729
|
+
replay: (id, since, opts2) => request("POST", `/webhooks/${enc(id)}/replay${qs({ since: String(since), limit: opts2?.limit })}`)
|
|
431
730
|
},
|
|
432
731
|
rightsLinks: {
|
|
433
732
|
create: (cbid, input) => request("POST", `/sites/${enc(cbid)}/rights-links`, input)
|
|
@@ -447,6 +746,13 @@ function createCookieMunch(opts) {
|
|
|
447
746
|
set: (cbid, input) => request("PUT", `/sites/${enc(cbid)}/rights-identity`, input),
|
|
448
747
|
remove: (cbid) => request("DELETE", `/sites/${enc(cbid)}/rights-identity`)
|
|
449
748
|
},
|
|
749
|
+
dsarSettings: {
|
|
750
|
+
get: (cbid) => get(`/sites/${enc(cbid)}/dsar-settings`),
|
|
751
|
+
set: (cbid, input) => request("PUT", `/sites/${enc(cbid)}/dsar-settings`, input)
|
|
752
|
+
},
|
|
753
|
+
integrations: {
|
|
754
|
+
subjectCard: (app, person) => get(`/integrations/${enc(app)}/card${qs(person)}`)
|
|
755
|
+
},
|
|
450
756
|
subjects: {
|
|
451
757
|
consent: (subjectId) => get(`/subjects/${enc(subjectId)}/consent`)
|
|
452
758
|
},
|
|
@@ -465,15 +771,25 @@ function createCookieMunch(opts) {
|
|
|
465
771
|
};
|
|
466
772
|
}
|
|
467
773
|
export {
|
|
774
|
+
CANARY_ISSUER,
|
|
775
|
+
CONFORMANCE_RULES,
|
|
468
776
|
CONSENT_COOKIE_NAME,
|
|
469
777
|
CookieMunchApiError,
|
|
778
|
+
DEFAULT_JWKS_URL,
|
|
470
779
|
SDK_VERSION,
|
|
780
|
+
TokenExchangeError,
|
|
781
|
+
canaryIdentityFor,
|
|
782
|
+
consentSignaturePayload,
|
|
471
783
|
createCookieMunch,
|
|
784
|
+
exchangeOperatorToken,
|
|
472
785
|
getConsent,
|
|
473
786
|
isAllowed,
|
|
474
787
|
mintConsentSyncToken,
|
|
475
788
|
parseConsentValue,
|
|
476
789
|
readConsent,
|
|
790
|
+
runExecutorConformance,
|
|
791
|
+
verifyDecisionSignature,
|
|
792
|
+
verifyToken,
|
|
477
793
|
verifyWebhookSignature
|
|
478
794
|
};
|
|
479
795
|
//# sourceMappingURL=index.js.map
|