@redacto.io/consent-sdk-react-native 5.0.0-beta.1 → 5.0.0-beta.11

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/dist/index.js CHANGED
@@ -43,9 +43,114 @@ var import_react_native_svg3 = __toESM(require("react-native-svg"));
43
43
  // src/RedactoNoticeConsent/api/index.ts
44
44
  var import_jwt_decode = require("jwt-decode");
45
45
 
46
+ // src/shared/sandbox.ts
47
+ var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
48
+
49
+ // src/RedactoNoticeConsent/api/sandbox.ts
50
+ var resolveSandboxAuth = (params) => {
51
+ var _a, _b, _c, _d, _e;
52
+ const token = (_a = params.token) == null ? void 0 : _a.trim();
53
+ if (!token) {
54
+ return null;
55
+ }
56
+ const organisationUuid = (_b = params.organisationUuid) == null ? void 0 : _b.trim();
57
+ const workspaceUuid = (_c = params.workspaceUuid) == null ? void 0 : _c.trim();
58
+ const ucic = (_d = params.sandboxUcic) == null ? void 0 : _d.trim();
59
+ const subject = (_e = params.sandboxSubject) == null ? void 0 : _e.trim();
60
+ if (!organisationUuid || !workspaceUuid) {
61
+ throw new Error(
62
+ "Sandbox mode requires organisationUuid and workspaceUuid props"
63
+ );
64
+ }
65
+ if (!ucic && !subject) {
66
+ throw new Error("Sandbox mode requires a UCIC, email, or mobile");
67
+ }
68
+ return { token, ucic, subject: subject != null ? subject : "", organisationUuid, workspaceUuid };
69
+ };
70
+ var resolveRequestAuth = (accessToken, sandboxParams, decodeTokenSafely2) => {
71
+ const sandbox = resolveSandboxAuth(sandboxParams);
72
+ if (sandbox) {
73
+ return {
74
+ organisationUuid: sandbox.organisationUuid,
75
+ workspaceUuid: sandbox.workspaceUuid,
76
+ sandbox
77
+ };
78
+ }
79
+ const decodedToken = accessToken ? decodeTokenSafely2(accessToken) : null;
80
+ if (!decodedToken) {
81
+ throw new Error("Invalid access token");
82
+ }
83
+ const { organisation_uuid, workspace_uuid } = decodedToken;
84
+ if (!organisation_uuid || !workspace_uuid) {
85
+ throw new Error("Invalid token: missing organization or workspace UUID");
86
+ }
87
+ return {
88
+ organisationUuid: organisation_uuid,
89
+ workspaceUuid: workspace_uuid,
90
+ sandbox: null
91
+ };
92
+ };
93
+ var buildAuthHeaders = (accessToken, sandbox) => {
94
+ if (sandbox) {
95
+ return { [SANDBOX_TOKEN_HEADER]: sandbox.token };
96
+ }
97
+ return { Authorization: `Bearer ${accessToken}` };
98
+ };
99
+ var sandboxBodyIdentity = (sandbox) => {
100
+ if (sandbox.ucic) {
101
+ return { org_user_id: sandbox.ucic };
102
+ }
103
+ return sandbox.subject.includes("@") ? { primary_email: sandbox.subject } : { primary_mobile: sandbox.subject };
104
+ };
105
+ var sandboxQueryIdentity = (sandbox) => sandboxBodyIdentity(sandbox);
106
+
46
107
  // src/constants.ts
47
108
  var DEFAULT_CONSENT_API_BASE_URL = "https://api.redacto.io/consent";
48
109
 
110
+ // src/shared/languages.ts
111
+ var languageOptions = [
112
+ { value: "en", label: "English" },
113
+ { value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
114
+ { value: "te", label: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (Telugu)" },
115
+ { value: "mr", label: "\u092E\u0930\u093E\u0920\u0940 (Marathi)" },
116
+ { value: "ta", label: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (Tamil)" },
117
+ { value: "ur", label: "\u0627\u0631\u062F\u0648 (Urdu)" },
118
+ { value: "gu", label: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)" },
119
+ { value: "kn", label: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 (Kannada)" },
120
+ { value: "ml", label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (Malayalam)" },
121
+ { value: "pa", label: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40 (Punjabi)" },
122
+ { value: "or", label: "\u0B13\u0B21\u0B3C\u0B3F\u0B06 (Odia)" },
123
+ { value: "as", label: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)" },
124
+ { value: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)" },
125
+ { value: "mai", label: "\u092E\u0948\u0925\u093F\u0932\u0940 (Maithili)" },
126
+ { value: "ne", label: "\u0928\u0947\u092A\u093E\u0932\u0940 (Nepali)" },
127
+ { value: "sd", label: "\u0633\u0646\u068C\u064A (Sindhi)" },
128
+ { value: "doi", label: "\u0921\u094B\u0917\u0930\u0940 (Dogri)" },
129
+ { value: "mni-Mtei", label: "\uABC3\uABE9\uABC7\uABE9\uABC2\uABE3\uABDF (Manipuri)" },
130
+ { value: "gom", label: "\u0915\u094B\u0902\u0915\u0923\u0940 (Goan Konkani)" },
131
+ { value: "sa", label: "\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E\u094D (Sanskrit)" },
132
+ { value: "brx", label: "\u092C\u0921\u093C\u094B (Bodo)" },
133
+ { value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
134
+ { value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
135
+ ];
136
+ var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
137
+ var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
138
+ var englishName = (label) => {
139
+ var _a, _b;
140
+ return (_b = (_a = label.match(/\(([^)]+)\)\s*$/)) == null ? void 0 : _a[1]) != null ? _b : label;
141
+ };
142
+ var codeByName = new Map(
143
+ languageOptions.map((o) => [englishName(o.label).toLowerCase(), o.value])
144
+ );
145
+ function toLanguageCode(lang) {
146
+ var _a, _b, _c;
147
+ if (!lang) return void 0;
148
+ const trimmed = lang.trim();
149
+ if (!trimmed) return void 0;
150
+ const lower = trimmed.toLowerCase();
151
+ return (_c = (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByName.get(lower)) != null ? _b : codeByLower.get(lower)) != null ? _c : trimmed;
152
+ }
153
+
49
154
  // src/RedactoNoticeConsent/api/index.ts
50
155
  var apiCache = /* @__PURE__ */ new Map();
51
156
  var CACHE_TTL = 5 * 60 * 1e3;
@@ -81,21 +186,19 @@ var fetchConsentContent = async ({
81
186
  specific_uuid,
82
187
  validate_against = "all",
83
188
  include_fully_consented_data = false,
84
- signal
189
+ signal,
190
+ ...sandboxParams
85
191
  }) => {
86
- if (!noticeId || !accessToken || !validate_against) {
87
- throw new Error("noticeId and accessToken are required");
192
+ if (!noticeId || !validate_against) {
193
+ throw new Error("noticeId is required");
88
194
  }
89
- const decodedToken = decodeTokenSafely(accessToken);
90
- if (!decodedToken) {
91
- throw new Error("Invalid access token");
92
- }
93
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
94
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
95
- throw new Error("Invalid token: missing organization or workspace UUID");
195
+ if (!accessToken && !sandboxParams.token) {
196
+ throw new Error("accessToken or token is required");
96
197
  }
198
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
97
199
  const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
98
- const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
200
+ const cacheIdentity = sandbox ? `sandbox:${sandbox.organisationUuid}:${sandbox.workspaceUuid}:${sandbox.ucic || sandbox.subject}` : accessToken;
201
+ const cacheKey = `${cacheIdentity}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
99
202
  if (validate_against === "all" && !specific_uuid) {
100
203
  const cachedData = getCachedData(cacheKey);
101
204
  if (cachedData) {
@@ -112,10 +215,15 @@ var fetchConsentContent = async ({
112
215
  if (include_fully_consented_data) {
113
216
  url.searchParams.append("include_fully_consented_data", "true");
114
217
  }
218
+ if (sandbox) {
219
+ for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {
220
+ url.searchParams.append(key, value);
221
+ }
222
+ }
115
223
  const response = await fetch(url.toString(), {
116
224
  method: "GET",
117
225
  headers: {
118
- Authorization: `Bearer ${accessToken}`,
226
+ ...buildAuthHeaders(accessToken, sandbox),
119
227
  "Accept-Language": language,
120
228
  "Content-Type": "application/json"
121
229
  },
@@ -154,20 +262,18 @@ var submitConsentEvent = async ({
154
262
  meta_data,
155
263
  guardianVerificationReference,
156
264
  selfDeclaredAdult,
157
- signal
265
+ language,
266
+ signal,
267
+ ...sandboxParams
158
268
  }) => {
159
- if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
160
- throw new Error("noticeUuid, accessToken, and purposes array are required");
161
- }
162
- const decodedToken = decodeTokenSafely(accessToken);
163
- if (!decodedToken) {
164
- throw new Error("Invalid access token");
269
+ if (!noticeUuid || !Array.isArray(purposes)) {
270
+ throw new Error("noticeUuid and purposes array are required");
165
271
  }
166
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
167
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
168
- throw new Error("Invalid token: missing organization or workspace UUID");
272
+ if (!accessToken && !sandboxParams.token) {
273
+ throw new Error("accessToken or token is required");
169
274
  }
170
- const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
275
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
276
+ const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
171
277
  const validatedPurposes = purposes.map((purpose) => {
172
278
  if (!purpose.uuid) {
173
279
  throw new Error("Invalid purpose data: missing uuid");
@@ -190,17 +296,19 @@ var submitConsentEvent = async ({
190
296
  declined: Boolean(declined),
191
297
  meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0,
192
298
  guardian_verification_reference: guardianVerificationReference,
193
- self_declared_adult: selfDeclaredAdult
299
+ self_declared_adult: selfDeclaredAdult,
300
+ language: toLanguageCode(language)
194
301
  };
302
+ const requestBody = sandbox ? { ...payload, ...sandboxBodyIdentity(sandbox) } : payload;
195
303
  const response = await fetch(
196
304
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
197
305
  {
198
306
  method: "POST",
199
307
  headers: {
200
- Authorization: `Bearer ${accessToken}`,
308
+ ...buildAuthHeaders(accessToken, sandbox),
201
309
  "Content-Type": "application/json"
202
310
  },
203
- body: JSON.stringify(payload),
311
+ body: JSON.stringify(requestBody),
204
312
  signal
205
313
  }
206
314
  );
@@ -226,28 +334,30 @@ var submitConsentEvent = async ({
226
334
  var fetchTTSAudioUrls = async ({
227
335
  accessToken,
228
336
  baseUrl,
337
+ ledgerBaseUrl,
229
338
  noticeUuid,
230
339
  language,
231
- signal
340
+ signal,
341
+ ...sandboxParams
232
342
  }) => {
233
- if (!accessToken || !noticeUuid || !language) {
234
- throw new Error("accessToken, noticeUuid, and language are required");
343
+ if (!accessToken && !sandboxParams.token || !noticeUuid || !language) {
344
+ throw new Error("accessToken (or token), noticeUuid, and language are required");
235
345
  }
236
- const decodedToken = decodeTokenSafely(accessToken);
237
- if (!decodedToken) {
238
- throw new Error("Invalid access token");
239
- }
240
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
241
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
242
- throw new Error("Invalid token: missing organization or workspace UUID");
243
- }
244
- const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
346
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
347
+ const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
245
348
  const normalizedLanguage = language === "en" || language === "EN" ? "English" : language;
246
- const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${encodeURIComponent(normalizedLanguage)}`;
247
- const response = await fetch(url, {
349
+ const url = new URL(
350
+ `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${encodeURIComponent(normalizedLanguage)}`
351
+ );
352
+ if (sandbox) {
353
+ for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {
354
+ url.searchParams.append(key, value);
355
+ }
356
+ }
357
+ const response = await fetch(url.toString(), {
248
358
  method: "GET",
249
359
  headers: {
250
- Authorization: `Bearer ${accessToken}`,
360
+ ...buildAuthHeaders(accessToken, sandbox),
251
361
  Accept: "application/json",
252
362
  "Content-Type": "application/json"
253
363
  },
@@ -416,122 +526,6 @@ var verifyGuardianStatus = async ({
416
526
  };
417
527
  };
418
528
 
419
- // src/shared/notice-consent-status.ts
420
- var import_jwt_decode2 = require("jwt-decode");
421
- var decodeNoticeConsentToken = (token) => {
422
- try {
423
- return (0, import_jwt_decode2.jwtDecode)(token);
424
- } catch {
425
- return null;
426
- }
427
- };
428
- var fetchNoticeConsentStatusForScope = async ({
429
- accessToken,
430
- ledgerBaseUrl,
431
- organisationUuid,
432
- workspaceUuid,
433
- noticeUuid,
434
- signal
435
- }) => {
436
- if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {
437
- return null;
438
- }
439
- try {
440
- const response = await fetch(
441
- `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,
442
- {
443
- method: "POST",
444
- headers: {
445
- Authorization: `Bearer ${accessToken}`,
446
- "Content-Type": "application/json"
447
- },
448
- body: "{}",
449
- signal
450
- }
451
- );
452
- if (!response.ok) {
453
- return null;
454
- }
455
- const data = await response.json();
456
- const body = data && typeof data === "object" && "detail" in data && data.detail ? data.detail : data;
457
- if (!body || !Array.isArray(body.purposes)) {
458
- return null;
459
- }
460
- return body;
461
- } catch {
462
- return null;
463
- }
464
- };
465
- var fetchNoticeConsentStatus = async ({
466
- accessToken,
467
- ledgerBaseUrl,
468
- noticeUuid,
469
- signal
470
- }) => {
471
- if (!accessToken || !ledgerBaseUrl || !noticeUuid) {
472
- return null;
473
- }
474
- const decodedToken = decodeNoticeConsentToken(accessToken);
475
- if (!decodedToken) {
476
- return null;
477
- }
478
- const {
479
- organisation_uuid: ORGANISATION_UUID,
480
- workspace_uuid: WORKSPACE_UUID
481
- } = decodedToken;
482
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
483
- return null;
484
- }
485
- return fetchNoticeConsentStatusForScope({
486
- accessToken,
487
- ledgerBaseUrl,
488
- organisationUuid: ORGANISATION_UUID,
489
- workspaceUuid: WORKSPACE_UUID,
490
- noticeUuid,
491
- signal
492
- });
493
- };
494
- var isNoticeFullyConsented = (status) => status.consented && status.all_mandatory_active;
495
- var buildLedgerConsentOverlay = (status, configPurposes) => {
496
- var _a, _b;
497
- const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));
498
- const hasHistory = status.purposes.some(
499
- (p) => (p.status || "INACTIVE") !== "INACTIVE"
500
- );
501
- if (!hasHistory) {
502
- return null;
503
- }
504
- const purpose_selections = {};
505
- for (const cp of configPurposes) {
506
- const lp = byUuid.get(cp.uuid);
507
- const purposeStatus = (lp == null ? void 0 : lp.status) || "INACTIVE";
508
- const selectedByUuid = new Map(
509
- ((lp == null ? void 0 : lp.data_elements) || []).map((de) => [de.uuid, de.selected])
510
- );
511
- const data_elements = {};
512
- for (const de of cp.data_elements) {
513
- data_elements[de.uuid] = {
514
- selected: (_a = selectedByUuid.get(de.uuid)) != null ? _a : false,
515
- enabled: de.enabled,
516
- required: de.required
517
- };
518
- }
519
- purpose_selections[cp.uuid] = {
520
- selected: (_b = lp == null ? void 0 : lp.selected) != null ? _b : false,
521
- status: purposeStatus,
522
- needs_reconsent: purposeStatus !== "ACTIVE",
523
- data_elements
524
- };
525
- }
526
- const reconsent_required = configPurposes.some(
527
- (cp) => {
528
- var _a2;
529
- return (((_a2 = purpose_selections[cp.uuid]) == null ? void 0 : _a2.status) || "INACTIVE") !== "ACTIVE";
530
- }
531
- );
532
- return { reconsent_required, purpose_selections };
533
- };
534
-
535
529
  // src/RedactoNoticeConsent/components/Checkbox.tsx
536
530
  var import_react_native = require("react-native");
537
531
  var import_react_native_svg = __toESM(require("react-native-svg"));
@@ -1754,6 +1748,12 @@ var RedactoNoticeConsent = ({
1754
1748
  noticeId,
1755
1749
  accessToken,
1756
1750
  refreshToken: _refreshToken,
1751
+ token,
1752
+ email,
1753
+ mobile,
1754
+ ucic,
1755
+ organisationUuid,
1756
+ workspaceUuid,
1757
1757
  baseUrl,
1758
1758
  ledgerBaseUrl,
1759
1759
  settings,
@@ -1769,6 +1769,16 @@ var RedactoNoticeConsent = ({
1769
1769
  }) => {
1770
1770
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u;
1771
1771
  const { isMobile } = useResponsive();
1772
+ const sandboxParams = (0, import_react2.useMemo)(
1773
+ () => ({
1774
+ token,
1775
+ sandboxUcic: ucic,
1776
+ sandboxSubject: email || mobile,
1777
+ organisationUuid,
1778
+ workspaceUuid
1779
+ }),
1780
+ [token, ucic, email, mobile, organisationUuid, workspaceUuid]
1781
+ );
1772
1782
  const [content, setContent] = (0, import_react2.useState)(null);
1773
1783
  const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
1774
1784
  const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
@@ -1815,7 +1825,6 @@ var RedactoNoticeConsent = ({
1815
1825
  const abortControllerRef = (0, import_react2.useRef)(null);
1816
1826
  const hasBootstrappedLanguageRef = (0, import_react2.useRef)(false);
1817
1827
  const fetchContent = (0, import_react2.useCallback)(async () => {
1818
- var _a2, _b2;
1819
1828
  if (abortControllerRef.current) {
1820
1829
  abortControllerRef.current.abort();
1821
1830
  }
@@ -1823,34 +1832,21 @@ var RedactoNoticeConsent = ({
1823
1832
  setIsLoading(true);
1824
1833
  setErrorMessage(null);
1825
1834
  try {
1835
+ const noticeBaseUrl = ledgerBaseUrl && !applicationId && !token ? ledgerBaseUrl : baseUrl;
1826
1836
  const data = await fetchConsentContent({
1827
1837
  noticeId,
1828
1838
  accessToken,
1829
- baseUrl,
1839
+ baseUrl: noticeBaseUrl,
1830
1840
  language: "English",
1831
1841
  validate_against: validateAgainst,
1832
1842
  include_fully_consented_data: includeFullyConsentedData,
1833
1843
  specific_uuid: applicationId,
1834
- signal: abortControllerRef.current.signal
1844
+ signal: abortControllerRef.current.signal,
1845
+ ...sandboxParams
1835
1846
  });
1836
1847
  const activeConfig2 = data.detail.active_config;
1837
- let purposeSelections = data.detail.purpose_selections;
1838
- let reconsentRequired = data.detail.reconsent_required || false;
1839
- if (ledgerBaseUrl && !applicationId) {
1840
- const ledgerStatus = await fetchNoticeConsentStatus({
1841
- accessToken,
1842
- ledgerBaseUrl,
1843
- noticeUuid: noticeId,
1844
- signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal
1845
- });
1846
- if (ledgerStatus) {
1847
- const overlay = buildLedgerConsentOverlay(ledgerStatus, activeConfig2.purposes);
1848
- reconsentRequired = (_b2 = overlay == null ? void 0 : overlay.reconsent_required) != null ? _b2 : false;
1849
- purposeSelections = overlay == null ? void 0 : overlay.purpose_selections;
1850
- data.detail.purpose_selections = purposeSelections;
1851
- data.detail.reconsent_required = reconsentRequired;
1852
- }
1853
- }
1848
+ const purposeSelections = data.detail.purpose_selections;
1849
+ const reconsentRequired = data.detail.reconsent_required || false;
1854
1850
  const noticeIsMinor = data.detail.is_minor || false;
1855
1851
  setIsMinor(noticeIsMinor);
1856
1852
  const initialCollapsed = {};
@@ -1863,9 +1859,9 @@ var RedactoNoticeConsent = ({
1863
1859
  const purposeSelected = sel ? sel.selected : false;
1864
1860
  initialPurposeState[purpose.uuid] = purposeSelected;
1865
1861
  purpose.data_elements.forEach((el) => {
1866
- var _a3, _b3, _c2;
1862
+ var _a2, _b2, _c2;
1867
1863
  const combinedId = `${purpose.uuid}-${el.uuid}`;
1868
- const elementSel = (_c2 = (_b3 = (_a3 = sel == null ? void 0 : sel.data_elements) == null ? void 0 : _a3[el.uuid]) == null ? void 0 : _b3.selected) != null ? _c2 : false;
1864
+ const elementSel = (_c2 = (_b2 = (_a2 = sel == null ? void 0 : sel.data_elements) == null ? void 0 : _a2[el.uuid]) == null ? void 0 : _b2.selected) != null ? _c2 : false;
1869
1865
  initialDataElementState[combinedId] = elementSel;
1870
1866
  initialDataElementSelectionsMap[combinedId] = elementSel;
1871
1867
  });
@@ -1913,7 +1909,7 @@ var RedactoNoticeConsent = ({
1913
1909
  } finally {
1914
1910
  setIsLoading(false);
1915
1911
  }
1916
- }, [noticeId, accessToken, baseUrl, ledgerBaseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
1912
+ }, [noticeId, accessToken, sandboxParams, token, baseUrl, ledgerBaseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
1917
1913
  (0, import_react2.useEffect)(() => {
1918
1914
  hasBootstrappedLanguageRef.current = false;
1919
1915
  }, [noticeId, accessToken]);
@@ -1934,8 +1930,10 @@ var RedactoNoticeConsent = ({
1934
1930
  const data = await fetchTTSAudioUrls({
1935
1931
  accessToken,
1936
1932
  baseUrl,
1933
+ ledgerBaseUrl,
1937
1934
  noticeUuid: content.detail.active_config.notice_uuid,
1938
- language: selectedLanguage
1935
+ language: selectedLanguage,
1936
+ ...sandboxParams
1939
1937
  });
1940
1938
  const urls = {
1941
1939
  notice_text: data.detail.notice_text_audio_url,
@@ -1989,7 +1987,7 @@ var RedactoNoticeConsent = ({
1989
1987
  setTtsAudioUrls({});
1990
1988
  setIsTTSAvailable(false);
1991
1989
  }
1992
- }, [content, accessToken, baseUrl, selectedLanguage]);
1990
+ }, [content, accessToken, sandboxParams, baseUrl, ledgerBaseUrl, selectedLanguage]);
1993
1991
  const clearPlaybackWatchers = (0, import_react2.useCallback)(() => {
1994
1992
  if (playbackSubscriptionRef.current) {
1995
1993
  playbackSubscriptionRef.current.remove();
@@ -2329,7 +2327,9 @@ var RedactoNoticeConsent = ({
2329
2327
  declined: false,
2330
2328
  meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
2331
2329
  guardianVerificationReference: verificationReferenceRef.current || void 0,
2332
- selfDeclaredAdult: selfDeclaredAdult || void 0
2330
+ selfDeclaredAdult: selfDeclaredAdult || void 0,
2331
+ language: selectedLanguage,
2332
+ ...sandboxParams
2333
2333
  });
2334
2334
  await stopAudio();
2335
2335
  clearApiCache();
@@ -2344,7 +2344,7 @@ var RedactoNoticeConsent = ({
2344
2344
  } finally {
2345
2345
  setIsSubmitting(false);
2346
2346
  }
2347
- }, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
2347
+ }, [content, accessToken, sandboxParams, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, selectedLanguage, selfDeclaredAdult, stopAudio, onAccept, onError]);
2348
2348
  const handleDecline = (0, import_react2.useCallback)(() => {
2349
2349
  stopAudio();
2350
2350
  stopPolling();
@@ -2946,14 +2946,16 @@ var fetchConsentContent2 = async ({
2946
2946
  org_uuid,
2947
2947
  workspace_uuid,
2948
2948
  notice_uuid,
2949
+ accessToken,
2949
2950
  baseUrl,
2950
2951
  language = "en",
2951
2952
  specific_uuid,
2952
2953
  signal
2953
2954
  }) => {
2954
2955
  const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
2956
+ const noticesUrl = `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices`;
2955
2957
  const url = new URL(
2956
- `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices/get-notice/${notice_uuid}`
2958
+ accessToken ? `${noticesUrl}/${notice_uuid}` : `${noticesUrl}/get-notice/${notice_uuid}`
2957
2959
  );
2958
2960
  if (specific_uuid) {
2959
2961
  url.searchParams.append("specific_uuid", specific_uuid);
@@ -2962,7 +2964,8 @@ var fetchConsentContent2 = async ({
2962
2964
  method: "GET",
2963
2965
  headers: {
2964
2966
  "Content-Type": "application/json",
2965
- "Accept-Language": language
2967
+ "Accept-Language": language,
2968
+ ...accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
2966
2969
  },
2967
2970
  signal
2968
2971
  });
@@ -2996,7 +2999,8 @@ var submitConsentEvent2 = async ({
2996
2999
  noticeUuid,
2997
3000
  purposes,
2998
3001
  declined,
2999
- meta_data
3002
+ meta_data,
3003
+ language
3000
3004
  }) => {
3001
3005
  var _a, _b;
3002
3006
  const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
@@ -3019,7 +3023,8 @@ var submitConsentEvent2 = async ({
3019
3023
  select_all_mandatory: false,
3020
3024
  source: "MOBILE",
3021
3025
  declined,
3022
- meta_data
3026
+ meta_data,
3027
+ language: toLanguageCode(language)
3023
3028
  };
3024
3029
  const response = await fetch(
3025
3030
  `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
@@ -3058,6 +3063,46 @@ var submitConsentEvent2 = async ({
3058
3063
  }
3059
3064
  };
3060
3065
 
3066
+ // src/shared/notice-consent-status.ts
3067
+ var fetchNoticeConsentStatusForScope = async ({
3068
+ accessToken,
3069
+ ledgerBaseUrl,
3070
+ organisationUuid,
3071
+ workspaceUuid,
3072
+ noticeUuid,
3073
+ signal
3074
+ }) => {
3075
+ if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {
3076
+ return null;
3077
+ }
3078
+ try {
3079
+ const response = await fetch(
3080
+ `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,
3081
+ {
3082
+ method: "POST",
3083
+ headers: {
3084
+ Authorization: `Bearer ${accessToken}`,
3085
+ "Content-Type": "application/json"
3086
+ },
3087
+ body: "{}",
3088
+ signal
3089
+ }
3090
+ );
3091
+ if (!response.ok) {
3092
+ return null;
3093
+ }
3094
+ const data = await response.json();
3095
+ const body = data && typeof data === "object" && "detail" in data && data.detail ? data.detail : data;
3096
+ if (!body || !Array.isArray(body.purposes)) {
3097
+ return null;
3098
+ }
3099
+ return body;
3100
+ } catch {
3101
+ return null;
3102
+ }
3103
+ };
3104
+ var isNoticeFullyConsented = (status) => status.consented && status.all_mandatory_active;
3105
+
3061
3106
  // src/RedactoNoticeConsentInline/styles.ts
3062
3107
  var import_react_native6 = require("react-native");
3063
3108
  var styles3 = import_react_native6.StyleSheet.create({
@@ -3401,11 +3446,13 @@ var RedactoConsentInlineComponent = ({
3401
3446
  const fetchNotice = (0, import_react3.useCallback)(async (signal) => {
3402
3447
  setIsLoading(true);
3403
3448
  setFetchError(null);
3449
+ setHasAlreadyConsented(false);
3404
3450
  try {
3405
3451
  const consentContentData = await fetchConsentContent2({
3406
3452
  org_uuid,
3407
3453
  workspace_uuid,
3408
3454
  notice_uuid,
3455
+ accessToken,
3409
3456
  baseUrl,
3410
3457
  language,
3411
3458
  specific_uuid: applicationId,
@@ -3455,7 +3502,7 @@ var RedactoConsentInlineComponent = ({
3455
3502
  setIsLoading(false);
3456
3503
  }
3457
3504
  }
3458
- }, [org_uuid, workspace_uuid, notice_uuid, baseUrl, language, applicationId, onError]);
3505
+ }, [org_uuid, workspace_uuid, notice_uuid, accessToken, baseUrl, language, applicationId, onError]);
3459
3506
  (0, import_react3.useEffect)(() => {
3460
3507
  const controller = new AbortController();
3461
3508
  void fetchNotice(controller.signal);
@@ -3567,7 +3614,8 @@ var RedactoConsentInlineComponent = ({
3567
3614
  };
3568
3615
  }),
3569
3616
  declined: false,
3570
- meta_data: applicationId ? { specific_uuid: applicationId } : void 0
3617
+ meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
3618
+ language: selectedLanguage
3571
3619
  });
3572
3620
  onAccept == null ? void 0 : onAccept();
3573
3621
  hasSubmittedRef.current = false;
@@ -3590,6 +3638,7 @@ var RedactoConsentInlineComponent = ({
3590
3638
  selectedDataElements,
3591
3639
  selectedPurposes,
3592
3640
  applicationId,
3641
+ selectedLanguage,
3593
3642
  onAccept
3594
3643
  ]
3595
3644
  );