@redacto.io/consent-sdk-react-native 4.0.1-beta.0 → 5.0.0-beta.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.
@@ -9868,7 +9868,15 @@ function arrayBufferToBase64(buffer) {
9868
9868
  }
9869
9869
  return result;
9870
9870
  }
9871
- function createConsentClient(baseUrl) {
9871
+ function createConsentClient(baseUrl, ledgerBaseUrl) {
9872
+ const useLedger = Boolean(ledgerBaseUrl);
9873
+ const ledgerBase = (ledgerBaseUrl != null ? ledgerBaseUrl : "").replace(/\/$/, "");
9874
+ function ledgerUrl(baseRequest, path) {
9875
+ if (!useLedger) {
9876
+ throw new Error("ledgerUrl called without a configured ledgerBaseUrl");
9877
+ }
9878
+ return `${ledgerBase}/public/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}${path}`;
9879
+ }
9872
9880
  async function privacyCenterApiFetch(url, options) {
9873
9881
  const { authToken, getAuthToken, headers = {}, ...fetchOptions } = options;
9874
9882
  const requestHeaders = new Headers();
@@ -10070,7 +10078,8 @@ function createConsentClient(baseUrl) {
10070
10078
  if (params.product_uuid) queryParams.append("product_uuid", params.product_uuid);
10071
10079
  if (params.language) queryParams.append("language", params.language);
10072
10080
  const queryString = queryParams.toString();
10073
- const url = `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/user-consents${queryString ? `?${queryString}` : ""}`;
10081
+ const consentsSuffix = `/user-consents${queryString ? `?${queryString}` : ""}`;
10082
+ const url = useLedger ? ledgerUrl(baseRequest, consentsSuffix) : `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center${consentsSuffix}`;
10074
10083
  return privacyCenterApiFetch(url, {
10075
10084
  ...options,
10076
10085
  method: "GET",
@@ -10090,7 +10099,8 @@ function createConsentClient(baseUrl) {
10090
10099
  if (params.language) queryParams.append("language", params.language);
10091
10100
  if (params.nominator_uuid) queryParams.append("nominator_uuid", params.nominator_uuid);
10092
10101
  const queryString = queryParams.toString();
10093
- const url = `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/user-consents/${productUuid}/purposes${queryString ? `?${queryString}` : ""}`;
10102
+ const purposesSuffix = `/user-consents/${productUuid}/purposes${queryString ? `?${queryString}` : ""}`;
10103
+ const url = useLedger ? ledgerUrl(baseRequest, purposesSuffix) : `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center${purposesSuffix}`;
10094
10104
  return privacyCenterApiFetch(url, {
10095
10105
  ...options,
10096
10106
  method: "GET",
@@ -10098,17 +10108,66 @@ function createConsentClient(baseUrl) {
10098
10108
  });
10099
10109
  },
10100
10110
  /**
10101
- * Manage consent (privacy center) - revoke, regrant, or renew
10111
+ * Manage consent (privacy center) - revoke, regrant, or renew.
10112
+ *
10113
+ * The Go ledger has no manage-consent route, so with a ledger configured
10114
+ * this is expressed as a `partial` submit-consent on the ledger — mirroring
10115
+ * the Python dual-write relay: the affected purpose is re-submitted with
10116
+ * `selected: false` to revoke or `selected: true` to regrant/renew, and
10117
+ * `partial: true` so the rest of the notice's purposes are left untouched.
10118
+ * The principal is resolved from the JWT, so no `contact`/identifiers are
10119
+ * sent in the body.
10120
+ *
10121
+ * Without a ledger, the legacy Python `/manage-consent?status=` endpoint is
10122
+ * used with its `{ purpose_uuid, contact, ... }` payload.
10102
10123
  */
10103
- async manageConsent(baseRequest, purposeId, contact, status, authToken, options, nominatorContact, dataElementUuids) {
10104
- const url = `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/manage-consent?status=${status}`;
10105
- const body = { purpose_uuid: purposeId, contact };
10106
- if (nominatorContact) {
10107
- body.nominator_contact = nominatorContact;
10124
+ async manageConsent(baseRequest, purposeId, contact, status, authToken, options, nominatorContact, dataElementUuids, noticeUuid, dataElements) {
10125
+ if (!useLedger) {
10126
+ const url2 = `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/manage-consent?status=${status}`;
10127
+ const body2 = { purpose_uuid: purposeId, contact };
10128
+ if (nominatorContact) {
10129
+ body2.nominator_contact = nominatorContact;
10130
+ }
10131
+ if (Array.isArray(dataElementUuids) && dataElementUuids.length > 0) {
10132
+ body2.data_element_uuids = dataElementUuids;
10133
+ }
10134
+ return privacyCenterApiFetch(url2, {
10135
+ ...options,
10136
+ method: "POST",
10137
+ body: JSON.stringify(body2),
10138
+ authToken: authToken || baseRequest.authToken
10139
+ });
10108
10140
  }
10109
- if (Array.isArray(dataElementUuids) && dataElementUuids.length > 0) {
10110
- body.data_element_uuids = dataElementUuids;
10141
+ if (!noticeUuid) {
10142
+ throw new Error("notice_uuid is required to manage consent via the ledger");
10111
10143
  }
10144
+ const purposeSelected = status !== "revoke";
10145
+ const elements = (dataElements != null ? dataElements : []).map((de) => {
10146
+ let selected;
10147
+ if (status === "revoke") {
10148
+ selected = false;
10149
+ } else if (status === "regrant") {
10150
+ selected = Array.isArray(dataElementUuids) ? dataElementUuids.includes(de.uuid) : de.selected;
10151
+ } else {
10152
+ selected = de.selected;
10153
+ }
10154
+ return { uuid: de.uuid, selected };
10155
+ });
10156
+ const body = {
10157
+ notice_uuid: noticeUuid,
10158
+ partial: true,
10159
+ declined: false,
10160
+ select_all_mandatory: false,
10161
+ self_declared_adult: false,
10162
+ purposes: [
10163
+ {
10164
+ purpose_uuid: purposeId,
10165
+ selected: purposeSelected,
10166
+ data_elements: elements
10167
+ }
10168
+ ]
10169
+ };
10170
+ const url = ledgerUrl(baseRequest, "/submit-consent");
10112
10171
  return privacyCenterApiFetch(url, {
10113
10172
  ...options,
10114
10173
  method: "POST",
@@ -10145,7 +10204,8 @@ function createConsentClient(baseUrl) {
10145
10204
  if (params.notice_uuid) queryParams.append("notice_uuid", params.notice_uuid);
10146
10205
  if (params.language) queryParams.append("language", params.language);
10147
10206
  const queryString = queryParams.toString();
10148
- const url = `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/receipts${queryString ? `?${queryString}` : ""}`;
10207
+ const receiptsSuffix = `/receipts${queryString ? `?${queryString}` : ""}`;
10208
+ const url = useLedger ? ledgerUrl(baseRequest, receiptsSuffix) : `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center${receiptsSuffix}`;
10149
10209
  return privacyCenterApiFetch(url, {
10150
10210
  ...options,
10151
10211
  method: "GET",
@@ -10159,7 +10219,7 @@ function createConsentClient(baseUrl) {
10159
10219
  * the RN UI writes to a temp file to open/share. 404 => not found.
10160
10220
  */
10161
10221
  async getReceiptPdf(baseRequest, receiptUuid, authToken) {
10162
- const url = `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/receipts/${receiptUuid}/pdf`;
10222
+ const url = useLedger ? ledgerUrl(baseRequest, `/receipts/${receiptUuid}/download`) : `${baseUrl}/organisations/${baseRequest.organisationUuid}/workspaces/${baseRequest.workspaceUuid}/dsar/privacy-center/receipts/${receiptUuid}/pdf`;
10163
10223
  const token = authToken || baseRequest.authToken;
10164
10224
  const requestHeaders = new Headers();
10165
10225
  requestHeaders.set("Accept", "application/pdf");
@@ -10318,11 +10378,16 @@ function createConsentClient(baseUrl) {
10318
10378
  // src/RedactoPrivacyCenter/context/BaseUrlContext.tsx
10319
10379
  import { jsx as jsx3 } from "react/jsx-runtime";
10320
10380
  var BaseUrlContext = createContext(null);
10321
- function BaseUrlProvider({ children, baseUrl }) {
10381
+ function BaseUrlProvider({
10382
+ children,
10383
+ baseUrl,
10384
+ ledgerBaseUrl
10385
+ }) {
10322
10386
  const value = useMemo(() => ({
10323
10387
  baseUrl,
10324
- consentClient: createConsentClient(baseUrl)
10325
- }), [baseUrl]);
10388
+ ledgerBaseUrl,
10389
+ consentClient: createConsentClient(baseUrl, ledgerBaseUrl)
10390
+ }), [baseUrl, ledgerBaseUrl]);
10326
10391
  return /* @__PURE__ */ jsx3(BaseUrlContext.Provider, { value, children });
10327
10392
  }
10328
10393
  function useBaseUrl() {
@@ -10521,7 +10586,6 @@ async function fetchUserConsentsServer(params) {
10521
10586
  }
10522
10587
  }
10523
10588
  async function manageConsentServer(params) {
10524
- var _a3;
10525
10589
  try {
10526
10590
  if (!params.consentClient) {
10527
10591
  throw new Error("Consent client is required");
@@ -10539,9 +10603,14 @@ async function manageConsentServer(params) {
10539
10603
  params.authToken,
10540
10604
  void 0,
10541
10605
  params.nominatorContact,
10542
- params.dataElementUuids
10606
+ params.dataElementUuids,
10607
+ params.noticeUuid,
10608
+ params.dataElements
10543
10609
  );
10544
- return (_a3 = result == null ? void 0 : result.success) != null ? _a3 : null;
10610
+ if (result && typeof result === "object" && "success" in result) {
10611
+ return Boolean(result.success);
10612
+ }
10613
+ return true;
10545
10614
  } catch (error) {
10546
10615
  if (isAuthError(error)) {
10547
10616
  throw error;
@@ -11025,7 +11094,9 @@ var manageConsent = async ({
11025
11094
  authContext,
11026
11095
  consentClient,
11027
11096
  nominatorContact,
11028
- dataElementUuids
11097
+ dataElementUuids,
11098
+ noticeUuid,
11099
+ dataElements
11029
11100
  }) => {
11030
11101
  try {
11031
11102
  const accessToken = await ensureValidToken(organizationId, workspaceId, void 0, authContext, consentClient);
@@ -11041,7 +11112,9 @@ var manageConsent = async ({
11041
11112
  authToken: accessToken,
11042
11113
  consentClient,
11043
11114
  nominatorContact,
11044
- dataElementUuids
11115
+ dataElementUuids,
11116
+ noticeUuid,
11117
+ dataElements
11045
11118
  });
11046
11119
  return result;
11047
11120
  } catch (error) {
@@ -11060,7 +11133,9 @@ var manageConsent = async ({
11060
11133
  authToken: newAccessToken || void 0,
11061
11134
  consentClient,
11062
11135
  nominatorContact,
11063
- dataElementUuids
11136
+ dataElementUuids,
11137
+ noticeUuid,
11138
+ dataElements
11064
11139
  });
11065
11140
  }
11066
11141
  console.error(`Error ${action} consent:`, error);
@@ -15008,6 +15083,7 @@ function ConsentManager() {
15008
15083
  }, [fetchData]);
15009
15084
  const handleManageConsent = useCallback6(
15010
15085
  async (purposeId, action, nominatorContact, dataElementUuids) => {
15086
+ var _a3, _b;
15011
15087
  if (!organizationId || !workspaceId || !email) return;
15012
15088
  setIsManageLoading(true);
15013
15089
  try {
@@ -15020,7 +15096,14 @@ function ConsentManager() {
15020
15096
  authContext,
15021
15097
  consentClient,
15022
15098
  nominatorContact,
15023
- dataElementUuids
15099
+ dataElementUuids,
15100
+ // Ledger mode: the partial submit-consent needs the notice and the
15101
+ // purpose's data elements; both ride on the selected (ledger-served) row.
15102
+ noticeUuid: (_a3 = selectedRecord == null ? void 0 : selectedRecord.notice_uuid) != null ? _a3 : void 0,
15103
+ dataElements: (_b = selectedRecord == null ? void 0 : selectedRecord.data_elements) == null ? void 0 : _b.map((de) => ({
15104
+ uuid: de.uuid,
15105
+ selected: de.selected
15106
+ }))
15024
15107
  });
15025
15108
  setIsModalOpen(false);
15026
15109
  setSelectedRecord(null);
@@ -15032,7 +15115,7 @@ function ConsentManager() {
15032
15115
  setIsManageLoading(false);
15033
15116
  }
15034
15117
  },
15035
- [organizationId, workspaceId, email, authContext, consentClient, fetchData, t]
15118
+ [organizationId, workspaceId, email, authContext, consentClient, selectedRecord, fetchData, t]
15036
15119
  );
15037
15120
  const handleExport = useCallback6(async () => {
15038
15121
  if (!consentData.length) return;
@@ -20448,6 +20531,7 @@ function PrivacyCenterContent({ onBack }) {
20448
20531
  }
20449
20532
  function RedactoPrivacyCenter({
20450
20533
  baseUrl,
20534
+ ledgerBaseUrl,
20451
20535
  slug,
20452
20536
  // `theme` is accepted for backwards compatibility but no longer used — the
20453
20537
  // Privacy Center themes itself from per-org branding.
@@ -20459,7 +20543,7 @@ function RedactoPrivacyCenter({
20459
20543
  initialCaseUuid,
20460
20544
  onBack
20461
20545
  }) {
20462
- return /* @__PURE__ */ jsx64(SafeAreaBoundary, { children: /* @__PURE__ */ jsx64(KeyboardProviderCompat, { children: /* @__PURE__ */ jsx64(QueryClientProvider, { client: privacyCenterQueryClient, children: /* @__PURE__ */ jsx64(I18nextProvider, { i18n: i18n_default, children: /* @__PURE__ */ jsx64(ThemeProvider, { slug, baseUrl, children: /* @__PURE__ */ jsx64(BaseUrlProvider, { baseUrl, children: /* @__PURE__ */ jsx64(
20546
+ return /* @__PURE__ */ jsx64(SafeAreaBoundary, { children: /* @__PURE__ */ jsx64(KeyboardProviderCompat, { children: /* @__PURE__ */ jsx64(QueryClientProvider, { client: privacyCenterQueryClient, children: /* @__PURE__ */ jsx64(I18nextProvider, { i18n: i18n_default, children: /* @__PURE__ */ jsx64(ThemeProvider, { slug, baseUrl, children: /* @__PURE__ */ jsx64(BaseUrlProvider, { baseUrl, ledgerBaseUrl, children: /* @__PURE__ */ jsx64(
20463
20547
  AuthProvider,
20464
20548
  {
20465
20549
  accessToken,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redacto.io/consent-sdk-react-native",
3
- "version": "4.0.1-beta.0",
3
+ "version": "5.0.0-beta.0",
4
4
  "description": "React Native SDK for integrating Redacto consent notices and privacy center in mobile apps.",
5
5
  "keywords": [
6
6
  "consent",
@@ -101,12 +101,14 @@
101
101
  "react-native": "0.76.9",
102
102
  "react-native-svg": "^15.0.0",
103
103
  "tsup": "^8.4.0",
104
- "typescript": "5.8.2"
104
+ "typescript": "5.8.2",
105
+ "vitest": "^4.1.8"
105
106
  },
106
107
  "scripts": {
107
108
  "build": "tsup",
108
109
  "dev": "tsup --watch",
109
110
  "check:locales": "node scripts/check-locales.js",
110
- "release": "pnpm run build"
111
+ "release": "pnpm run build",
112
+ "test": "vitest"
111
113
  }
112
114
  }