@redacto.io/consent-sdk-react 10.1.0 → 10.2.0-beta.1

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.
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  SANDBOX_TOKEN_HEADER,
3
- useMediaQuery
4
- } from "./chunk-OGL6OC3A.mjs";
3
+ useMediaQuery,
4
+ withIdempotencyKey
5
+ } from "./chunk-6EET4YOY.mjs";
5
6
 
6
7
  // src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx
7
8
  import { I18nextProvider } from "react-i18next";
@@ -10112,8 +10113,15 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10112
10113
  const queryParams = new URLSearchParams();
10113
10114
  if (language) queryParams.append("language", language);
10114
10115
  const queryString = queryParams.toString();
10115
- const url = privacyCenterUrl(baseRequest, `/form/data${queryString ? `?${queryString}` : ""}`);
10116
- const { useSessionAuth = false, getAuthToken, ...fetchOptions } = options || {};
10116
+ const url = privacyCenterUrl(
10117
+ baseRequest,
10118
+ `/form/data${queryString ? `?${queryString}` : ""}`
10119
+ );
10120
+ const {
10121
+ useSessionAuth = false,
10122
+ getAuthToken,
10123
+ ...fetchOptions
10124
+ } = options || {};
10117
10125
  if (useSessionAuth) {
10118
10126
  return apiFetch(url, {
10119
10127
  ...fetchOptions,
@@ -10134,7 +10142,11 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10134
10142
  */
10135
10143
  async createCaseRequest(baseRequest, payload, authToken, options) {
10136
10144
  const url = privacyCenterUrl(baseRequest, "/case");
10137
- const { useSessionAuth = false, getAuthToken, ...fetchOptions } = options || {};
10145
+ const {
10146
+ useSessionAuth = false,
10147
+ getAuthToken,
10148
+ ...fetchOptions
10149
+ } = options || {};
10138
10150
  const contact = sandboxContact();
10139
10151
  const requestPayload = contact && payload && typeof payload === "object" ? { ...payload, contact } : payload;
10140
10152
  if (useSessionAuth) {
@@ -10188,7 +10200,7 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10188
10200
  const url = `${baseUrl}/public/tokens/token-exchange?token=${encodeURIComponent(token)}`;
10189
10201
  const response = await fetch(url, {
10190
10202
  method: "GET",
10191
- headers: { "Accept": "application/json" }
10203
+ headers: { Accept: "application/json" }
10192
10204
  });
10193
10205
  if (!response.ok) {
10194
10206
  const errorData = await response.json().catch(() => null);
@@ -10228,13 +10240,24 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10228
10240
  */
10229
10241
  async getUserConsents(baseRequest, params, authToken, options) {
10230
10242
  const queryParams = new URLSearchParams();
10231
- if (params.offset !== void 0) queryParams.append("offset", params.offset.toString());
10232
- if (params.limit !== void 0) queryParams.append("limit", params.limit.toString());
10233
- if (params.nominated_offset !== void 0) queryParams.append("nominated_offset", params.nominated_offset.toString());
10234
- if (params.nominated_limit !== void 0) queryParams.append("nominated_limit", params.nominated_limit.toString());
10243
+ if (params.offset !== void 0)
10244
+ queryParams.append("offset", params.offset.toString());
10245
+ if (params.limit !== void 0)
10246
+ queryParams.append("limit", params.limit.toString());
10247
+ if (params.nominated_offset !== void 0)
10248
+ queryParams.append(
10249
+ "nominated_offset",
10250
+ params.nominated_offset.toString()
10251
+ );
10252
+ if (params.nominated_limit !== void 0)
10253
+ queryParams.append(
10254
+ "nominated_limit",
10255
+ params.nominated_limit.toString()
10256
+ );
10235
10257
  if (params.search) queryParams.append("search", params.search);
10236
10258
  if (params.status) queryParams.append("status", params.status);
10237
- if (params.product_uuid) queryParams.append("product_uuid", params.product_uuid);
10259
+ if (params.product_uuid)
10260
+ queryParams.append("product_uuid", params.product_uuid);
10238
10261
  if (params.language) queryParams.append("language", params.language);
10239
10262
  appendSandboxIdentity(queryParams);
10240
10263
  const queryString = queryParams.toString();
@@ -10253,12 +10276,15 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10253
10276
  */
10254
10277
  async getGroupPurposes(baseRequest, productUuid, params, authToken, options) {
10255
10278
  const queryParams = new URLSearchParams();
10256
- if (params.offset !== void 0) queryParams.append("offset", params.offset.toString());
10257
- if (params.limit !== void 0) queryParams.append("limit", params.limit.toString());
10279
+ if (params.offset !== void 0)
10280
+ queryParams.append("offset", params.offset.toString());
10281
+ if (params.limit !== void 0)
10282
+ queryParams.append("limit", params.limit.toString());
10258
10283
  if (params.status) queryParams.append("status", params.status);
10259
10284
  if (params.search) queryParams.append("search", params.search);
10260
10285
  if (params.language) queryParams.append("language", params.language);
10261
- if (params.nominator_uuid) queryParams.append("nominator_uuid", params.nominator_uuid);
10286
+ if (params.nominator_uuid)
10287
+ queryParams.append("nominator_uuid", params.nominator_uuid);
10262
10288
  appendSandboxIdentity(queryParams);
10263
10289
  const queryString = queryParams.toString();
10264
10290
  const suffix = `/user-consents/${productUuid}/purposes${queryString ? `?${queryString}` : ""}`;
@@ -10280,7 +10306,9 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10280
10306
  * `selected: true` to regrant/renew, and `partial: true` so the rest of the
10281
10307
  * notice's purposes are left untouched. The principal is resolved from the
10282
10308
  * JWT, so no `contact`/identifiers are sent in the body, and
10283
- * `consent_event_uuid` is omitted so the ledger mints a fresh event.
10309
+ * `consent_event_uuid` is omitted so the ledger mints a fresh event, and
10310
+ * `product_uuid` pins it to one card -- unscoped, the ledger fans the
10311
+ * answer out over every product the notice covers.
10284
10312
  *
10285
10313
  * Without a ledger, the legacy Python `/manage-consent?status=` endpoint is
10286
10314
  * used with its `{ purpose_uuid, contact, ... }` payload.
@@ -10288,8 +10316,14 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10288
10316
  async manageConsent(baseRequest, purposeId, contact, status, authToken, options, nominatorContact, dataElementUuids, productUuid, noticeUuid, dataElements, language) {
10289
10317
  var _a;
10290
10318
  if (!useLedger()) {
10291
- const url2 = privacyCenterUrl(baseRequest, `/manage-consent?status=${status}`);
10292
- const body2 = { purpose_uuid: purposeId, contact };
10319
+ const url2 = privacyCenterUrl(
10320
+ baseRequest,
10321
+ `/manage-consent?status=${status}`
10322
+ );
10323
+ const body2 = {
10324
+ purpose_uuid: purposeId,
10325
+ contact
10326
+ };
10293
10327
  if (nominatorContact) {
10294
10328
  body2.nominator_contact = nominatorContact;
10295
10329
  }
@@ -10310,7 +10344,9 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10310
10344
  });
10311
10345
  }
10312
10346
  if (!noticeUuid) {
10313
- throw new Error("notice_uuid is required to manage consent via the ledger");
10347
+ throw new Error(
10348
+ "notice_uuid is required to manage consent via the ledger"
10349
+ );
10314
10350
  }
10315
10351
  const purposeSelected = status !== "revoke";
10316
10352
  const elements = (dataElements != null ? dataElements : []).map((de) => {
@@ -10329,6 +10365,12 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10329
10365
  // Sandbox has no JWT, so the ledger resolves the acting test principal
10330
10366
  // from this identity in the body; null (spread no-op) on the live JWT path.
10331
10367
  ...(_a = sandboxBodyIdentity()) != null ? _a : {},
10368
+ // Pins the action to the card the user acted on. Without it the ledger
10369
+ // scopes by the notice and applies the answer to every product the
10370
+ // notice covers, so revoking a purpose held on two products withdrew
10371
+ // both. Stamped on the envelope and the selection, mirroring the Python
10372
+ // relay this path was modelled on.
10373
+ ...productUuid ? { product_uuid: productUuid } : {},
10332
10374
  partial: true,
10333
10375
  declined: false,
10334
10376
  select_all_mandatory: false,
@@ -10336,6 +10378,7 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10336
10378
  purposes: [
10337
10379
  {
10338
10380
  purpose_uuid: purposeId,
10381
+ ...productUuid ? { product_uuid: productUuid } : {},
10339
10382
  selected: purposeSelected,
10340
10383
  data_elements: elements
10341
10384
  }
@@ -10343,11 +10386,19 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10343
10386
  ...language ? { language } : {}
10344
10387
  };
10345
10388
  const url = ledgerUrl(baseRequest, "/submit-consent");
10346
- return privacyCenterApiFetch(url, {
10347
- ...options,
10348
- method: "POST",
10349
- body: JSON.stringify(body),
10350
- authToken: resolveAuthToken(authToken, baseRequest)
10389
+ const serialisedBody = JSON.stringify(body);
10390
+ return withIdempotencyKey(url, serialisedBody, (idempotencyHeaders) => {
10391
+ const headers = new Headers(options == null ? void 0 : options.headers);
10392
+ Object.entries(idempotencyHeaders).forEach(
10393
+ ([name, value]) => headers.set(name, value)
10394
+ );
10395
+ return privacyCenterApiFetch(url, {
10396
+ ...options,
10397
+ method: "POST",
10398
+ body: serialisedBody,
10399
+ headers,
10400
+ authToken: resolveAuthToken(authToken, baseRequest)
10401
+ });
10351
10402
  });
10352
10403
  },
10353
10404
  /**
@@ -10360,7 +10411,10 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10360
10411
  if (language) queryParams.append("language", language);
10361
10412
  appendSandboxIdentity(queryParams);
10362
10413
  const queryString = queryParams.toString();
10363
- const url = privacyCenterUrl(baseRequest, `/activities${queryString ? `?${queryString}` : ""}`);
10414
+ const url = privacyCenterUrl(
10415
+ baseRequest,
10416
+ `/activities${queryString ? `?${queryString}` : ""}`
10417
+ );
10364
10418
  return privacyCenterApiFetch(url, {
10365
10419
  ...options,
10366
10420
  authToken: resolveAuthToken(authToken, baseRequest)
@@ -10398,13 +10452,19 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10398
10452
  */
10399
10453
  async getReceipts(baseRequest, params, authToken, options) {
10400
10454
  const queryParams = new URLSearchParams();
10401
- if (params.skip !== void 0) queryParams.append("skip", params.skip.toString());
10402
- if (params.limit !== void 0) queryParams.append("limit", params.limit.toString());
10403
- if (params.notice_uuid) queryParams.append("notice_uuid", params.notice_uuid);
10404
- if (params.event_type) queryParams.append("event_type", params.event_type);
10455
+ if (params.skip !== void 0)
10456
+ queryParams.append("skip", params.skip.toString());
10457
+ if (params.limit !== void 0)
10458
+ queryParams.append("limit", params.limit.toString());
10459
+ if (params.notice_uuid)
10460
+ queryParams.append("notice_uuid", params.notice_uuid);
10461
+ if (params.event_type)
10462
+ queryParams.append("event_type", params.event_type);
10405
10463
  if (params.status) queryParams.append("status", params.status);
10406
- if (params.created_after) queryParams.append("created_after", params.created_after);
10407
- if (params.created_before) queryParams.append("created_before", params.created_before);
10464
+ if (params.created_after)
10465
+ queryParams.append("created_after", params.created_after);
10466
+ if (params.created_before)
10467
+ queryParams.append("created_before", params.created_before);
10408
10468
  if (params.language) queryParams.append("language", params.language);
10409
10469
  appendSandboxIdentity(queryParams);
10410
10470
  const queryString = queryParams.toString();
@@ -10446,7 +10506,10 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10446
10506
  trimmedToken.startsWith("Bearer ") ? trimmedToken : `Bearer ${trimmedToken}`
10447
10507
  );
10448
10508
  }
10449
- const response = await fetch(url, { method: "GET", headers: requestHeaders });
10509
+ const response = await fetch(url, {
10510
+ method: "GET",
10511
+ headers: requestHeaders
10512
+ });
10450
10513
  if (!response.ok) {
10451
10514
  let errorMessage = `Request failed with status ${response.status}`;
10452
10515
  try {
@@ -10483,7 +10546,11 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10483
10546
  * Get messages for a case (privacy center)
10484
10547
  */
10485
10548
  async getCaseMessages(baseRequest, caseUuid, authToken) {
10486
- const url = caseUrl(baseRequest, caseUuid, `/messages${sandboxIdentitySuffix()}`);
10549
+ const url = caseUrl(
10550
+ baseRequest,
10551
+ caseUuid,
10552
+ `/messages${sandboxIdentitySuffix()}`
10553
+ );
10487
10554
  return privacyCenterApiFetch(url, {
10488
10555
  authToken: resolveAuthToken(authToken, baseRequest)
10489
10556
  });
@@ -10492,7 +10559,11 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10492
10559
  * Send a message on a case (privacy center)
10493
10560
  */
10494
10561
  async sendCaseMessage(baseRequest, caseUuid, body, documentUuids, authToken) {
10495
- const url = caseUrl(baseRequest, caseUuid, `/messages${sandboxIdentitySuffix()}`);
10562
+ const url = caseUrl(
10563
+ baseRequest,
10564
+ caseUuid,
10565
+ `/messages${sandboxIdentitySuffix()}`
10566
+ );
10496
10567
  return privacyCenterApiFetch(url, {
10497
10568
  method: "POST",
10498
10569
  body: JSON.stringify({ body, document_uuids: documentUuids }),
@@ -10503,7 +10574,11 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10503
10574
  * Upload a document on a case (multipart/form-data, privacy center)
10504
10575
  */
10505
10576
  async uploadCaseDocument(baseRequest, caseUuid, file, authToken) {
10506
- const url = caseUrl(baseRequest, caseUuid, `/upload-document${sandboxIdentitySuffix()}`);
10577
+ const url = caseUrl(
10578
+ baseRequest,
10579
+ caseUuid,
10580
+ `/upload-document${sandboxIdentitySuffix()}`
10581
+ );
10507
10582
  const formData = new FormData();
10508
10583
  formData.append("file", file, file.name);
10509
10584
  formData.append("payload", JSON.stringify({ metadata: null }));
@@ -10532,7 +10607,11 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10532
10607
  * Get document info/download URL for a case document (privacy center)
10533
10608
  */
10534
10609
  async getCaseDocument(baseRequest, caseUuid, documentUuid, authToken) {
10535
- const url = caseUrl(baseRequest, caseUuid, `/documents/${documentUuid}${sandboxIdentitySuffix()}`);
10610
+ const url = caseUrl(
10611
+ baseRequest,
10612
+ caseUuid,
10613
+ `/documents/${documentUuid}${sandboxIdentitySuffix()}`
10614
+ );
10536
10615
  return privacyCenterApiFetch(url, {
10537
10616
  authToken: resolveAuthToken(authToken, baseRequest)
10538
10617
  });
@@ -10565,7 +10644,10 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10565
10644
  queryParams.append("language", params.language);
10566
10645
  }
10567
10646
  const queryString = queryParams.toString();
10568
- const url = notificationUrl(baseRequest, queryString ? `?${queryString}` : "");
10647
+ const url = notificationUrl(
10648
+ baseRequest,
10649
+ queryString ? `?${queryString}` : ""
10650
+ );
10569
10651
  return privacyCenterApiFetch(url, {
10570
10652
  authToken: resolveAuthToken(authToken, baseRequest)
10571
10653
  });
@@ -10612,7 +10694,10 @@ function createConsentClient(baseUrl, ledgerBaseUrl) {
10612
10694
  * Acknowledge a notification (sets is_read and is_acknowledged to true)
10613
10695
  */
10614
10696
  async acknowledgeNotification(baseRequest, notificationUuid, authToken) {
10615
- const url = notificationUrl(baseRequest, `/${notificationUuid}/acknowledge`);
10697
+ const url = notificationUrl(
10698
+ baseRequest,
10699
+ `/${notificationUuid}/acknowledge`
10700
+ );
10616
10701
  return privacyCenterApiFetch(url, {
10617
10702
  method: "POST",
10618
10703
  authToken: resolveAuthToken(authToken, baseRequest)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redacto.io/consent-sdk-react",
3
- "version": "10.1.0",
3
+ "version": "10.2.0-beta.1",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",
@@ -1,34 +0,0 @@
1
- // src/RedactoNoticeConsent/useMediaQuery.ts
2
- import { useState, useEffect } from "react";
3
- var useMediaQuery = (query) => {
4
- const getMatches = () => typeof window !== "undefined" ? window.matchMedia(query).matches : false;
5
- const [matches, setMatches] = useState(getMatches);
6
- useEffect(() => {
7
- if (typeof window === "undefined") return;
8
- const media = window.matchMedia(query);
9
- const listener = (e) => {
10
- setMatches(e.matches);
11
- };
12
- if (media.addEventListener) {
13
- media.addEventListener("change", listener);
14
- } else {
15
- media.addListener(listener);
16
- }
17
- return () => {
18
- if (media.removeEventListener) {
19
- media.removeEventListener("change", listener);
20
- } else {
21
- media.removeListener(listener);
22
- }
23
- };
24
- }, [query]);
25
- return matches;
26
- };
27
-
28
- // src/shared/sandbox.ts
29
- var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
30
-
31
- export {
32
- SANDBOX_TOKEN_HEADER,
33
- useMediaQuery
34
- };