@redacto.io/consent-sdk-react 10.0.0-beta.0 → 10.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.
Files changed (89) hide show
  1. package/.turbo/turbo-build.log +22 -25
  2. package/CHANGELOG.md +123 -0
  3. package/README.md +78 -0
  4. package/dist/{chunk-6A665OPR.mjs → chunk-OGL6OC3A.mjs} +4 -0
  5. package/dist/index.d.mts +43 -8
  6. package/dist/index.d.ts +43 -8
  7. package/dist/index.js +345 -237
  8. package/dist/index.mjs +344 -238
  9. package/dist/privacy-center.d.mts +113 -37
  10. package/dist/privacy-center.d.ts +113 -37
  11. package/dist/privacy-center.js +2317 -1910
  12. package/dist/privacy-center.mjs +2245 -1835
  13. package/package.json +1 -1
  14. package/src/RedactoNoticeAssisted/RedactoNoticeAssisted.test.tsx +87 -0
  15. package/src/RedactoNoticeAssisted/RedactoNoticeAssisted.tsx +27 -0
  16. package/src/RedactoNoticeAssisted/api/index.ts +7 -1
  17. package/src/RedactoNoticeAssisted/api/types.ts +2 -0
  18. package/src/RedactoNoticeAssisted/i18n.ts +0 -55
  19. package/src/RedactoNoticeAssisted/types.ts +2 -0
  20. package/src/RedactoNoticeConsent/RedactoNoticeConsent.test.tsx +42 -8
  21. package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +75 -33
  22. package/src/RedactoNoticeConsent/api/index.ts +90 -177
  23. package/src/RedactoNoticeConsent/api/sandbox.ts +150 -0
  24. package/src/RedactoNoticeConsent/api/types.ts +60 -44
  25. package/src/RedactoNoticeConsent/language-codes.ts +0 -2
  26. package/src/RedactoNoticeConsent/types.ts +29 -3
  27. package/src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx +86 -5
  28. package/src/RedactoNoticeConsentInline/api/index.ts +14 -5
  29. package/src/RedactoNoticeConsentInline/api/notice-read-routing.test.ts +72 -0
  30. package/src/RedactoNoticeConsentInline/api/types.ts +4 -1
  31. package/src/RedactoNoticeConsentInline/types.ts +1 -1
  32. package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +8 -5
  33. package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +38 -3
  34. package/src/RedactoPrivacyCenter/api/actions.ts +13 -5
  35. package/src/RedactoPrivacyCenter/api/client.ts +216 -39
  36. package/src/RedactoPrivacyCenter/api/fetcher.ts +24 -9
  37. package/src/RedactoPrivacyCenter/components/AppShell/AppShell.tsx +28 -0
  38. package/src/RedactoPrivacyCenter/components/AppShell/UserMenu.tsx +107 -76
  39. package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +2 -1
  40. package/src/RedactoPrivacyCenter/components/Form.tsx +53 -24
  41. package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +1 -1
  42. package/src/RedactoPrivacyCenter/components/SelectUser.tsx +95 -0
  43. package/src/RedactoPrivacyCenter/components/SelectUserGate.tsx +195 -0
  44. package/src/RedactoPrivacyCenter/components/constant.ts +11 -0
  45. package/src/RedactoPrivacyCenter/components/groupHelpers.ts +42 -6
  46. package/src/RedactoPrivacyCenter/context/AuthContext.tsx +131 -39
  47. package/src/RedactoPrivacyCenter/context/BaseUrlContext.tsx +1 -1
  48. package/src/RedactoPrivacyCenter/context/ProfileSwitchContext.tsx +15 -0
  49. package/src/RedactoPrivacyCenter/context/types.ts +39 -1
  50. package/src/RedactoPrivacyCenter/lib/api.ts +3 -0
  51. package/src/RedactoPrivacyCenter/lib/constants.ts +12 -6
  52. package/src/RedactoPrivacyCenter/lib/locales.ts +0 -3
  53. package/src/RedactoPrivacyCenter/lib/sandbox.ts +104 -0
  54. package/src/RedactoPrivacyCenter/lib/types.ts +78 -2
  55. package/src/RedactoPrivacyCenter/lib/utils.ts +15 -0
  56. package/src/RedactoPrivacyCenter/locales/as/translation.json +7 -1
  57. package/src/RedactoPrivacyCenter/locales/bn/translation.json +7 -1
  58. package/src/RedactoPrivacyCenter/locales/brx/translation.json +7 -1
  59. package/src/RedactoPrivacyCenter/locales/doi/translation.json +7 -1
  60. package/src/RedactoPrivacyCenter/locales/en/translation.json +8 -1
  61. package/src/RedactoPrivacyCenter/locales/gom/translation.json +7 -1
  62. package/src/RedactoPrivacyCenter/locales/gu/translation.json +7 -1
  63. package/src/RedactoPrivacyCenter/locales/hi/translation.json +7 -1
  64. package/src/RedactoPrivacyCenter/locales/kn/translation.json +7 -1
  65. package/src/RedactoPrivacyCenter/locales/ks/translation.json +7 -1
  66. package/src/RedactoPrivacyCenter/locales/mai/translation.json +7 -1
  67. package/src/RedactoPrivacyCenter/locales/ml/translation.json +7 -1
  68. package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +7 -1
  69. package/src/RedactoPrivacyCenter/locales/mr/translation.json +7 -1
  70. package/src/RedactoPrivacyCenter/locales/ne/translation.json +7 -1
  71. package/src/RedactoPrivacyCenter/locales/or/translation.json +7 -1
  72. package/src/RedactoPrivacyCenter/locales/pa/translation.json +7 -1
  73. package/src/RedactoPrivacyCenter/locales/sa/translation.json +7 -1
  74. package/src/RedactoPrivacyCenter/locales/sat/translation.json +7 -1
  75. package/src/RedactoPrivacyCenter/locales/sd/translation.json +7 -1
  76. package/src/RedactoPrivacyCenter/locales/ta/translation.json +7 -1
  77. package/src/RedactoPrivacyCenter/locales/te/translation.json +7 -1
  78. package/src/RedactoPrivacyCenter/locales/ur/translation.json +7 -1
  79. package/src/RedactoPrivacyCenter/styles/injectStyles.ts +112 -2
  80. package/src/RedactoPrivacyCenter/styles/pcStyles.ts +17 -0
  81. package/src/RedactoPrivacyCenter/ui/PCAvatar.test.tsx +83 -0
  82. package/src/RedactoPrivacyCenter/ui/PCAvatar.tsx +33 -9
  83. package/src/shared/notice-consent-status.ts +190 -0
  84. package/src/shared/sandbox.ts +6 -0
  85. package/tests/Form.test.tsx +190 -7
  86. package/tests/RevokeWarningMessage.test.tsx +151 -0
  87. package/tests/consentClient.test.ts +217 -0
  88. package/tests/manageConsentServer.test.ts +38 -0
  89. package/src/RedactoPrivacyCenter/locales/bho/translation.json +0 -334
package/dist/index.mjs CHANGED
@@ -1,12 +1,13 @@
1
1
  import {
2
+ SANDBOX_TOKEN_HEADER,
2
3
  useMediaQuery
3
- } from "./chunk-6A665OPR.mjs";
4
+ } from "./chunk-OGL6OC3A.mjs";
4
5
 
5
6
  // src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
6
7
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
8
 
8
9
  // src/RedactoNoticeConsent/api/index.ts
9
- import { jwtDecode } from "jwt-decode";
10
+ import { jwtDecode as jwtDecode2 } from "jwt-decode";
10
11
 
11
12
  // src/shared/api-errors.ts
12
13
  var ApiError = class extends Error {
@@ -66,6 +67,141 @@ async function parseApiError(response, fallbackMessage) {
66
67
  });
67
68
  }
68
69
 
70
+ // src/RedactoNoticeConsent/api/sandbox.ts
71
+ var resolveSandboxAuth = (params) => {
72
+ var _a, _b, _c, _d, _e;
73
+ const token = (_a = params.token) == null ? void 0 : _a.trim();
74
+ if (!token) {
75
+ return null;
76
+ }
77
+ const organisationUuid = (_b = params.organisationUuid) == null ? void 0 : _b.trim();
78
+ const workspaceUuid = (_c = params.workspaceUuid) == null ? void 0 : _c.trim();
79
+ const ucic = (_d = params.sandboxUcic) == null ? void 0 : _d.trim();
80
+ const subject = (_e = params.sandboxSubject) == null ? void 0 : _e.trim();
81
+ if (!organisationUuid || !workspaceUuid) {
82
+ throw new Error(
83
+ "Sandbox mode requires organisationUuid and workspaceUuid props"
84
+ );
85
+ }
86
+ if (!ucic && !subject) {
87
+ throw new Error("Sandbox mode requires a UCIC, email, or mobile");
88
+ }
89
+ return { token, ucic, subject: subject != null ? subject : "", organisationUuid, workspaceUuid };
90
+ };
91
+ var resolveRequestAuth = (accessToken, sandboxParams, decodeTokenSafely2) => {
92
+ const sandbox = resolveSandboxAuth(sandboxParams);
93
+ if (sandbox) {
94
+ return {
95
+ organisationUuid: sandbox.organisationUuid,
96
+ workspaceUuid: sandbox.workspaceUuid,
97
+ sandbox
98
+ };
99
+ }
100
+ const decodedToken = accessToken ? decodeTokenSafely2(accessToken) : null;
101
+ if (!decodedToken) {
102
+ throw new Error("Invalid access token");
103
+ }
104
+ const { organisation_uuid, workspace_uuid } = decodedToken;
105
+ if (!organisation_uuid || !workspace_uuid) {
106
+ throw new Error("Invalid token: missing organization or workspace UUID");
107
+ }
108
+ return {
109
+ organisationUuid: organisation_uuid,
110
+ workspaceUuid: workspace_uuid,
111
+ sandbox: null
112
+ };
113
+ };
114
+ var buildAuthHeaders = (accessToken, sandbox) => {
115
+ if (sandbox) {
116
+ return { [SANDBOX_TOKEN_HEADER]: sandbox.token };
117
+ }
118
+ return { Authorization: `Bearer ${accessToken}` };
119
+ };
120
+ var sandboxBodyIdentity = (sandbox) => {
121
+ if (sandbox.ucic) {
122
+ return { org_user_id: sandbox.ucic };
123
+ }
124
+ return sandbox.subject.includes("@") ? { primary_email: sandbox.subject } : { primary_mobile: sandbox.subject };
125
+ };
126
+ var sandboxQueryIdentity = (sandbox) => sandboxBodyIdentity(sandbox);
127
+
128
+ // src/shared/notice-consent-status.ts
129
+ import { jwtDecode } from "jwt-decode";
130
+ var decodeNoticeConsentToken = (token) => {
131
+ try {
132
+ return jwtDecode(token);
133
+ } catch {
134
+ return null;
135
+ }
136
+ };
137
+ var fetchNoticeConsentStatusForScope = async ({
138
+ accessToken,
139
+ ledgerBaseUrl,
140
+ organisationUuid,
141
+ workspaceUuid,
142
+ noticeUuid,
143
+ signal
144
+ }) => {
145
+ if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {
146
+ return null;
147
+ }
148
+ try {
149
+ const response = await fetch(
150
+ `${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,
151
+ {
152
+ method: "POST",
153
+ headers: {
154
+ Authorization: `Bearer ${accessToken}`,
155
+ "Content-Type": "application/json"
156
+ },
157
+ body: "{}",
158
+ signal
159
+ }
160
+ );
161
+ if (!response.ok) {
162
+ return null;
163
+ }
164
+ const data = await response.json();
165
+ const body = data && typeof data === "object" && "detail" in data && data.detail ? data.detail : data;
166
+ if (!body || !Array.isArray(body.purposes)) {
167
+ return null;
168
+ }
169
+ return body;
170
+ } catch {
171
+ return null;
172
+ }
173
+ };
174
+ var fetchNoticeConsentStatus = async ({
175
+ accessToken,
176
+ ledgerBaseUrl,
177
+ noticeUuid,
178
+ signal
179
+ }) => {
180
+ if (!accessToken || !ledgerBaseUrl || !noticeUuid) {
181
+ return null;
182
+ }
183
+ const decodedToken = decodeNoticeConsentToken(accessToken);
184
+ if (!decodedToken) {
185
+ return null;
186
+ }
187
+ const {
188
+ organisation_uuid: ORGANISATION_UUID,
189
+ workspace_uuid: WORKSPACE_UUID
190
+ } = decodedToken;
191
+ if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
192
+ return null;
193
+ }
194
+ return fetchNoticeConsentStatusForScope({
195
+ accessToken,
196
+ ledgerBaseUrl,
197
+ organisationUuid: ORGANISATION_UUID,
198
+ workspaceUuid: WORKSPACE_UUID,
199
+ noticeUuid,
200
+ signal
201
+ });
202
+ };
203
+ var isNoticeFullyConsented = (status) => status.consented && status.all_mandatory_active;
204
+
69
205
  // src/RedactoNoticeConsent/api/index.ts
70
206
  var BASE_URL = "https://api.redacto.io/consent";
71
207
  var apiCache = /* @__PURE__ */ new Map();
@@ -85,7 +221,7 @@ function setCachedData(key, data, ttl = CACHE_TTL) {
85
221
  }
86
222
  function decodeTokenSafely(token) {
87
223
  try {
88
- return jwtDecode(token);
224
+ return jwtDecode2(token);
89
225
  } catch (error) {
90
226
  console.warn("Failed to decode JWT token:", error);
91
227
  return null;
@@ -102,21 +238,19 @@ var fetchConsentContent = async ({
102
238
  specific_uuid,
103
239
  validate_against = "all",
104
240
  include_fully_consented_data = false,
105
- signal
241
+ signal,
242
+ ...sandboxParams
106
243
  }) => {
107
- if (!noticeId || !accessToken || !validate_against) {
108
- throw new Error("noticeId and accessToken are required");
109
- }
110
- const decodedToken = decodeTokenSafely(accessToken);
111
- if (!decodedToken) {
112
- throw new Error("Invalid access token");
244
+ if (!noticeId || !validate_against) {
245
+ throw new Error("noticeId is required");
113
246
  }
114
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
115
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
116
- throw new Error("Invalid token: missing organization or workspace UUID");
247
+ if (!accessToken && !sandboxParams.token) {
248
+ throw new Error("accessToken or token is required");
117
249
  }
250
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
118
251
  const apiBaseUrl = baseUrl || BASE_URL;
119
- const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
252
+ const cacheIdentity = sandbox ? `sandbox:${sandbox.organisationUuid}:${sandbox.workspaceUuid}:${sandbox.ucic || sandbox.subject}` : accessToken;
253
+ const cacheKey = `${cacheIdentity}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
120
254
  if (validate_against === "all" && !specific_uuid) {
121
255
  const cachedData = getCachedData(cacheKey);
122
256
  if (cachedData) {
@@ -133,10 +267,15 @@ var fetchConsentContent = async ({
133
267
  if (include_fully_consented_data) {
134
268
  url.searchParams.append("include_fully_consented_data", "true");
135
269
  }
270
+ if (sandbox) {
271
+ for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {
272
+ url.searchParams.append(key, value);
273
+ }
274
+ }
136
275
  const response = await fetch(url.toString(), {
137
276
  method: "GET",
138
277
  headers: {
139
- Authorization: `Bearer ${accessToken}`,
278
+ ...buildAuthHeaders(accessToken, sandbox),
140
279
  "Accept-Language": language
141
280
  },
142
281
  signal
@@ -155,6 +294,7 @@ var fetchConsentContent = async ({
155
294
  };
156
295
  var submitConsentEvent = async ({
157
296
  accessToken,
297
+ baseUrl,
158
298
  ledgerBaseUrl,
159
299
  noticeUuid,
160
300
  purposes,
@@ -163,23 +303,17 @@ var submitConsentEvent = async ({
163
303
  meta_data,
164
304
  guardianVerificationReference,
165
305
  selfDeclaredAdult,
166
- signal
306
+ signal,
307
+ ...sandboxParams
167
308
  }) => {
168
- if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
169
- throw new Error("noticeUuid, accessToken, and purposes array are required");
309
+ if (!noticeUuid || !Array.isArray(purposes)) {
310
+ throw new Error("noticeUuid and purposes array are required");
170
311
  }
171
- const decodedToken = decodeTokenSafely(accessToken);
172
- if (!decodedToken) {
173
- throw new Error("Invalid access token");
312
+ if (!accessToken && !sandboxParams.token) {
313
+ throw new Error("accessToken or token is required");
174
314
  }
175
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
176
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
177
- throw new Error("Invalid token: missing organization or workspace UUID");
178
- }
179
- if (!ledgerBaseUrl) {
180
- throw new Error("ledgerBaseUrl is required to submit consent");
181
- }
182
- const apiBaseUrl = ledgerBaseUrl;
315
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
316
+ const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;
183
317
  const validatedPurposes = purposes.map((purpose) => {
184
318
  if (!purpose.uuid) {
185
319
  throw new Error(`Invalid purpose data: missing uuid`);
@@ -205,15 +339,16 @@ var submitConsentEvent = async ({
205
339
  guardian_verification_reference: guardianVerificationReference,
206
340
  self_declared_adult: selfDeclaredAdult
207
341
  };
342
+ const requestBody = sandbox ? { ...payload, ...sandboxBodyIdentity(sandbox) } : payload;
208
343
  const response = await fetch(
209
344
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
210
345
  {
211
346
  method: "POST",
212
347
  headers: {
213
- Authorization: `Bearer ${accessToken}`,
348
+ ...buildAuthHeaders(accessToken, sandbox),
214
349
  "Content-Type": "application/json"
215
350
  },
216
- body: JSON.stringify(payload),
351
+ body: JSON.stringify(requestBody),
217
352
  signal
218
353
  }
219
354
  );
@@ -225,112 +360,32 @@ var submitConsentEvent = async ({
225
360
  }
226
361
  apiCache.clear();
227
362
  };
228
- var fetchNoticeConsentStatus = async ({
229
- accessToken,
230
- ledgerBaseUrl,
231
- noticeUuid,
232
- signal
233
- }) => {
234
- if (!accessToken || !ledgerBaseUrl || !noticeUuid) {
235
- return null;
236
- }
237
- const decodedToken = decodeTokenSafely(accessToken);
238
- if (!decodedToken) {
239
- return null;
240
- }
241
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
242
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
243
- return null;
244
- }
245
- try {
246
- const response = await fetch(
247
- `${ledgerBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/check-consent`,
248
- {
249
- method: "POST",
250
- headers: {
251
- Authorization: `Bearer ${accessToken}`,
252
- "Content-Type": "application/json"
253
- },
254
- body: "{}",
255
- signal
256
- }
257
- );
258
- if (!response.ok) {
259
- return null;
260
- }
261
- const data = await response.json();
262
- const body = data && typeof data === "object" && "detail" in data && data.detail ? data.detail : data;
263
- if (!body || !Array.isArray(body.purposes)) {
264
- return null;
265
- }
266
- return body;
267
- } catch {
268
- return null;
269
- }
270
- };
271
- var buildLedgerConsentOverlay = (status, configPurposes) => {
272
- var _a, _b;
273
- const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));
274
- const hasHistory = status.purposes.some(
275
- (p) => (p.status || "INACTIVE") !== "INACTIVE"
276
- );
277
- if (!hasHistory) {
278
- return null;
279
- }
280
- const purpose_selections = {};
281
- for (const cp of configPurposes) {
282
- const lp = byUuid.get(cp.uuid);
283
- const purposeStatus = (lp == null ? void 0 : lp.status) || "INACTIVE";
284
- const selectedByUuid = new Map(
285
- ((lp == null ? void 0 : lp.data_elements) || []).map((de) => [de.uuid, de.selected])
286
- );
287
- const data_elements = {};
288
- for (const de of cp.data_elements) {
289
- data_elements[de.uuid] = {
290
- selected: (_a = selectedByUuid.get(de.uuid)) != null ? _a : false,
291
- enabled: de.enabled,
292
- required: de.required
293
- };
294
- }
295
- purpose_selections[cp.uuid] = {
296
- selected: (_b = lp == null ? void 0 : lp.selected) != null ? _b : false,
297
- status: purposeStatus,
298
- needs_reconsent: purposeStatus !== "ACTIVE",
299
- data_elements
300
- };
301
- }
302
- const reconsent_required = configPurposes.some(
303
- (cp) => {
304
- var _a2;
305
- return (((_a2 = purpose_selections[cp.uuid]) == null ? void 0 : _a2.status) || "INACTIVE") !== "ACTIVE";
306
- }
307
- );
308
- return { reconsent_required, purpose_selections };
309
- };
310
363
  var fetchTTSAudioUrls = async ({
311
364
  accessToken,
312
365
  baseUrl,
366
+ ledgerBaseUrl,
313
367
  noticeUuid,
314
368
  language,
315
- signal
369
+ signal,
370
+ ...sandboxParams
316
371
  }) => {
317
- if (!accessToken || !noticeUuid || !language) {
318
- throw new Error("accessToken, noticeUuid, and language are required");
319
- }
320
- const decodedToken = decodeTokenSafely(accessToken);
321
- if (!decodedToken) {
322
- throw new Error("Invalid access token");
372
+ if (!accessToken && !sandboxParams.token || !noticeUuid || !language) {
373
+ throw new Error("accessToken (or token), noticeUuid, and language are required");
323
374
  }
324
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
325
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
326
- throw new Error("Invalid token: missing organization or workspace UUID");
375
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
376
+ const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;
377
+ const url = new URL(
378
+ `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`
379
+ );
380
+ if (sandbox) {
381
+ for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {
382
+ url.searchParams.append(key, value);
383
+ }
327
384
  }
328
- const apiBaseUrl = baseUrl || BASE_URL;
329
- const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
330
- const response = await fetch(url, {
385
+ const response = await fetch(url.toString(), {
331
386
  method: "GET",
332
387
  headers: {
333
- Authorization: `Bearer ${accessToken}`,
388
+ ...buildAuthHeaders(accessToken, sandbox),
334
389
  Accept: "application/json"
335
390
  },
336
391
  signal
@@ -372,7 +427,10 @@ var initiateGuardianVerification = async ({
372
427
  if (!decodedToken) {
373
428
  throw new Error("Invalid access token");
374
429
  }
375
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
430
+ const {
431
+ organisation_uuid: ORGANISATION_UUID,
432
+ workspace_uuid: WORKSPACE_UUID
433
+ } = decodedToken;
376
434
  if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
377
435
  throw new Error("Invalid token: missing organization or workspace UUID");
378
436
  }
@@ -446,7 +504,10 @@ var verifyGuardianStatus = async ({
446
504
  if (!decodedToken) {
447
505
  throw new Error("Invalid access token");
448
506
  }
449
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
507
+ const {
508
+ organisation_uuid: ORGANISATION_UUID,
509
+ workspace_uuid: WORKSPACE_UUID
510
+ } = decodedToken;
450
511
  if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
451
512
  throw new Error("Invalid token: missing organization or workspace UUID");
452
513
  }
@@ -459,9 +520,7 @@ var verifyGuardianStatus = async ({
459
520
  Authorization: `Bearer ${accessToken}`,
460
521
  "Content-Type": "application/json"
461
522
  },
462
- body: JSON.stringify({
463
- session_token: sessionToken
464
- }),
523
+ body: JSON.stringify({ session_token: sessionToken }),
465
524
  signal
466
525
  }
467
526
  );
@@ -504,7 +563,6 @@ var LANGUAGE_NATIVE_LABELS = {
504
563
  English: "English",
505
564
  Assamese: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)",
506
565
  Bengali: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)",
507
- Bhojpuri: "\u092D\u094B\u091C\u092A\u0941\u0930\u0940 (Bhojpuri)",
508
566
  Bodo: "\u092C\u0921\u093C\u094B (Bodo)",
509
567
  Dogri: "\u0921\u094B\u0917\u0930\u0940 (Dogri)",
510
568
  Gujarati: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)",
@@ -534,7 +592,6 @@ var LANGUAGE_NAME_TO_BCP47 = {
534
592
  English: "en",
535
593
  Assamese: "as",
536
594
  Bengali: "bn",
537
- Bhojpuri: "bho",
538
595
  Bodo: "brx",
539
596
  Dogri: "doi",
540
597
  Gujarati: "gu",
@@ -2325,6 +2382,12 @@ var RedactoNoticeConsent = ({
2325
2382
  noticeId,
2326
2383
  accessToken,
2327
2384
  refreshToken,
2385
+ token,
2386
+ email,
2387
+ mobile,
2388
+ ucic,
2389
+ organisationUuid,
2390
+ workspaceUuid,
2328
2391
  baseUrl,
2329
2392
  ledgerBaseUrl,
2330
2393
  language = "en",
@@ -2343,15 +2406,43 @@ var RedactoNoticeConsent = ({
2343
2406
  reviewModeButtonText = "Continue"
2344
2407
  }) => {
2345
2408
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2409
+ const sandboxParams = useMemo(
2410
+ () => ({
2411
+ token,
2412
+ sandboxUcic: ucic,
2413
+ sandboxSubject: email || mobile,
2414
+ organisationUuid,
2415
+ workspaceUuid
2416
+ }),
2417
+ [token, ucic, email, mobile, organisationUuid, workspaceUuid]
2418
+ );
2346
2419
  const propValidationError = useMemo(() => {
2347
2420
  if (!(noticeId == null ? void 0 : noticeId.trim())) {
2348
2421
  return "RedactoNoticeConsent: 'noticeId' prop is required and cannot be empty";
2349
2422
  }
2423
+ if (token == null ? void 0 : token.trim()) {
2424
+ if (!(organisationUuid == null ? void 0 : organisationUuid.trim()) || !(workspaceUuid == null ? void 0 : workspaceUuid.trim())) {
2425
+ return "RedactoNoticeConsent: sandbox mode requires 'organisationUuid' and 'workspaceUuid'";
2426
+ }
2427
+ if (!(email == null ? void 0 : email.trim()) && !(mobile == null ? void 0 : mobile.trim()) && !(ucic == null ? void 0 : ucic.trim())) {
2428
+ return "RedactoNoticeConsent: sandbox mode requires 'email', 'mobile', or 'ucic'";
2429
+ }
2430
+ return null;
2431
+ }
2350
2432
  if (!(accessToken == null ? void 0 : accessToken.trim())) {
2351
2433
  return "RedactoNoticeConsent: 'accessToken' prop is required and cannot be empty";
2352
2434
  }
2353
2435
  return null;
2354
- }, [noticeId, accessToken]);
2436
+ }, [
2437
+ noticeId,
2438
+ accessToken,
2439
+ token,
2440
+ organisationUuid,
2441
+ workspaceUuid,
2442
+ email,
2443
+ mobile,
2444
+ ucic
2445
+ ]);
2355
2446
  if (propValidationError) {
2356
2447
  return /* @__PURE__ */ jsxs(
2357
2448
  "div",
@@ -2681,7 +2772,7 @@ var RedactoNoticeConsent = ({
2681
2772
  return content.dpo_info[key] || defaultText;
2682
2773
  };
2683
2774
  const fetchNotice = async () => {
2684
- var _a2, _b2, _c2;
2775
+ var _a2;
2685
2776
  if (isRequestInProgressRef.current) {
2686
2777
  return;
2687
2778
  }
@@ -2695,16 +2786,18 @@ var RedactoNoticeConsent = ({
2695
2786
  setShowAgeVerification(false);
2696
2787
  setShowGuardianForm(false);
2697
2788
  try {
2789
+ const noticeBaseUrl = ledgerBaseUrl && !applicationId && !token ? ledgerBaseUrl : baseUrl;
2698
2790
  const consentContentData = await fetchConsentContent({
2699
2791
  noticeId,
2700
2792
  accessToken,
2701
2793
  refreshToken,
2702
- baseUrl,
2794
+ baseUrl: noticeBaseUrl,
2703
2795
  language,
2704
2796
  specific_uuid: applicationId,
2705
2797
  validate_against: validateAgainst,
2706
2798
  include_fully_consented_data: includeFullyConsentedData,
2707
- signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal
2799
+ signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal,
2800
+ ...sandboxParams
2708
2801
  });
2709
2802
  const activeConfig = consentContentData.detail.active_config;
2710
2803
  setContent(activeConfig);
@@ -2722,24 +2815,8 @@ var RedactoNoticeConsent = ({
2722
2815
  {}
2723
2816
  );
2724
2817
  setCollapsedPurposes(initialCollapsedState);
2725
- let isReconsentRequired = consentContentData.detail.reconsent_required;
2726
- let purposeSelections = consentContentData.detail.purpose_selections;
2727
- if (ledgerBaseUrl && !applicationId) {
2728
- const ledgerStatus = await fetchNoticeConsentStatus({
2729
- accessToken,
2730
- ledgerBaseUrl,
2731
- noticeUuid: noticeId,
2732
- signal: (_b2 = abortControllerRef.current) == null ? void 0 : _b2.signal
2733
- });
2734
- if (ledgerStatus) {
2735
- const overlay = buildLedgerConsentOverlay(
2736
- ledgerStatus,
2737
- activeConfig.purposes
2738
- );
2739
- isReconsentRequired = (_c2 = overlay == null ? void 0 : overlay.reconsent_required) != null ? _c2 : false;
2740
- purposeSelections = overlay == null ? void 0 : overlay.purpose_selections;
2741
- }
2742
- }
2818
+ const isReconsentRequired = consentContentData.detail.reconsent_required;
2819
+ const purposeSelections = consentContentData.detail.purpose_selections;
2743
2820
  const newCategorizedPurposes = isReconsentRequired ? {
2744
2821
  alreadyConsented: activeConfig.purposes.filter(
2745
2822
  (purpose) => {
@@ -2770,9 +2847,9 @@ var RedactoNoticeConsent = ({
2770
2847
  const initialDataElementState = activeConfig.purposes.reduce(
2771
2848
  (acc, purpose) => {
2772
2849
  purpose.data_elements.forEach((element) => {
2773
- var _a3, _b3;
2850
+ var _a3, _b2;
2774
2851
  const combinedId = `${purpose.uuid}-${element.uuid}`;
2775
- if ((_b3 = (_a3 = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b3[element.uuid]) {
2852
+ if ((_b2 = (_a3 = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b2[element.uuid]) {
2776
2853
  acc[combinedId] = purposeSelections[purpose.uuid].data_elements[element.uuid].selected;
2777
2854
  } else {
2778
2855
  acc[combinedId] = false;
@@ -2788,9 +2865,9 @@ var RedactoNoticeConsent = ({
2788
2865
  const initialSelections = {};
2789
2866
  newCategorizedPurposes.alreadyConsented.forEach((purpose) => {
2790
2867
  purpose.data_elements.forEach((element) => {
2791
- var _a3, _b3;
2868
+ var _a3, _b2;
2792
2869
  const combinedId = `${purpose.uuid}-${element.uuid}`;
2793
- if ((_b3 = (_a3 = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b3[element.uuid]) {
2870
+ if ((_b2 = (_a3 = purposeSelections == null ? void 0 : purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b2[element.uuid]) {
2794
2871
  initialSelections[combinedId] = purposeSelections[purpose.uuid].data_elements[element.uuid].selected;
2795
2872
  } else {
2796
2873
  initialSelections[combinedId] = false;
@@ -2811,9 +2888,9 @@ var RedactoNoticeConsent = ({
2811
2888
  activeConfig.purposes.forEach(
2812
2889
  (purpose) => {
2813
2890
  purpose.data_elements.forEach((element) => {
2814
- var _a3, _b3;
2891
+ var _a3, _b2;
2815
2892
  const combinedId = `${purpose.uuid}-${element.uuid}`;
2816
- if ((_b3 = (_a3 = purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b3[element.uuid]) {
2893
+ if ((_b2 = (_a3 = purposeSelections[purpose.uuid]) == null ? void 0 : _a3.data_elements) == null ? void 0 : _b2[element.uuid]) {
2817
2894
  initialSelections[combinedId] = purposeSelections[purpose.uuid].data_elements[element.uuid].selected;
2818
2895
  } else {
2819
2896
  initialSelections[combinedId] = false;
@@ -2861,8 +2938,10 @@ var RedactoNoticeConsent = ({
2861
2938
  noticeId,
2862
2939
  accessToken,
2863
2940
  refreshToken,
2941
+ sandboxParams,
2864
2942
  language,
2865
2943
  applicationId,
2944
+ ledgerBaseUrl,
2866
2945
  validateAgainst,
2867
2946
  includeFullyConsentedData
2868
2947
  // Removed onError and isRefreshingToken from dependencies to prevent duplicate API calls
@@ -2944,6 +3023,7 @@ var RedactoNoticeConsent = ({
2944
3023
  if (content) {
2945
3024
  await submitConsentEvent({
2946
3025
  accessToken,
3026
+ baseUrl,
2947
3027
  ledgerBaseUrl,
2948
3028
  noticeUuid: content.notice_uuid,
2949
3029
  purposes: content.purposes.map((purpose) => {
@@ -2976,7 +3056,8 @@ var RedactoNoticeConsent = ({
2976
3056
  meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
2977
3057
  guardianVerificationReference: verificationReference || void 0,
2978
3058
  selfDeclaredAdult: selfDeclaredAdult || void 0,
2979
- signal: submitController.signal
3059
+ signal: submitController.signal,
3060
+ ...sandboxParams
2980
3061
  });
2981
3062
  }
2982
3063
  onAccept == null ? void 0 : onAccept();
@@ -3159,7 +3240,7 @@ var RedactoNoticeConsent = ({
3159
3240
  } finally {
3160
3241
  setIsSubmittingGuardian(false);
3161
3242
  }
3162
- }, [accessToken, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
3243
+ }, [accessToken, sandboxParams, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
3163
3244
  const handleAgeVerificationYes = useCallback(() => {
3164
3245
  setShowAgeVerification(false);
3165
3246
  setIsMinorFlow(false);
@@ -3216,7 +3297,7 @@ var RedactoNoticeConsent = ({
3216
3297
  setIsPollingStatus(false);
3217
3298
  isPollingStatusRef.current = false;
3218
3299
  setIsInitiatingVerification(false);
3219
- }, [accessToken, baseUrl]);
3300
+ }, [accessToken, sandboxParams, baseUrl]);
3220
3301
  const startPopupMonitoring = useCallback((popup) => {
3221
3302
  popupCheckIntervalRef.current = window.setInterval(() => {
3222
3303
  if (popup.closed) {
@@ -3244,8 +3325,8 @@ var RedactoNoticeConsent = ({
3244
3325
  []
3245
3326
  );
3246
3327
  const startStatusPolling = useCallback(
3247
- (token) => {
3248
- verificationSessionTokenRef.current = token;
3328
+ (token2) => {
3329
+ verificationSessionTokenRef.current = token2;
3249
3330
  setIsPollingStatus(true);
3250
3331
  isPollingStatusRef.current = true;
3251
3332
  setVerificationError(null);
@@ -3297,7 +3378,7 @@ var RedactoNoticeConsent = ({
3297
3378
  const response = await verifyGuardianStatus({
3298
3379
  accessToken,
3299
3380
  baseUrl,
3300
- sessionToken: token
3381
+ sessionToken: token2
3301
3382
  });
3302
3383
  consecutiveErrors = 0;
3303
3384
  if (response.status === "verified") {
@@ -3367,7 +3448,7 @@ var RedactoNoticeConsent = ({
3367
3448
  };
3368
3449
  statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
3369
3450
  },
3370
- [accessToken, baseUrl, getVerificationErrorMessage]
3451
+ [accessToken, sandboxParams, baseUrl, getVerificationErrorMessage]
3371
3452
  );
3372
3453
  const handleBackToGuardianForm = useCallback((clearName = false) => {
3373
3454
  var _a2, _b2;
@@ -3707,9 +3788,11 @@ var RedactoNoticeConsent = ({
3707
3788
  fetchTTSAudioUrls({
3708
3789
  accessToken,
3709
3790
  baseUrl,
3791
+ ledgerBaseUrl,
3710
3792
  noticeUuid: content.notice_uuid,
3711
3793
  language: languageCode,
3712
- signal: ttsAbortController.signal
3794
+ signal: ttsAbortController.signal,
3795
+ ...sandboxParams
3713
3796
  }).then((response) => {
3714
3797
  setTtsAudioUrls(response.detail);
3715
3798
  setIsTTSAvailable(true);
@@ -3722,7 +3805,7 @@ var RedactoNoticeConsent = ({
3722
3805
  return () => {
3723
3806
  ttsAbortController.abort();
3724
3807
  };
3725
- }, [content, selectedLanguage, accessToken, baseUrl, getLanguageCode]);
3808
+ }, [content, selectedLanguage, accessToken, sandboxParams, baseUrl, ledgerBaseUrl, getLanguageCode]);
3726
3809
  const modalStyle = {
3727
3810
  borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
3728
3811
  backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff"
@@ -4696,12 +4779,16 @@ var fetchConsentContent2 = async ({
4696
4779
  org_uuid,
4697
4780
  workspace_uuid,
4698
4781
  notice_uuid,
4782
+ accessToken,
4699
4783
  baseUrl,
4700
- specific_uuid
4784
+ language,
4785
+ specific_uuid,
4786
+ signal
4701
4787
  }) => {
4702
4788
  const apiBaseUrl = baseUrl || BASE_URL2;
4789
+ const noticesUrl = `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices`;
4703
4790
  const url = new URL(
4704
- `${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices/get-notice/${notice_uuid}`
4791
+ accessToken ? `${noticesUrl}/${notice_uuid}` : `${noticesUrl}/get-notice/${notice_uuid}`
4705
4792
  );
4706
4793
  if (specific_uuid) {
4707
4794
  url.searchParams.append("specific_uuid", specific_uuid);
@@ -4709,8 +4796,11 @@ var fetchConsentContent2 = async ({
4709
4796
  const response = await fetch(url.toString(), {
4710
4797
  method: "GET",
4711
4798
  headers: {
4712
- "Content-Type": "application/json"
4713
- }
4799
+ "Content-Type": "application/json",
4800
+ "Accept-Language": language || "en",
4801
+ ...accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
4802
+ },
4803
+ signal
4714
4804
  });
4715
4805
  if (!response.ok) {
4716
4806
  throw await parseApiError(
@@ -4725,16 +4815,14 @@ var submitConsentEvent2 = async ({
4725
4815
  org_uuid,
4726
4816
  workspace_uuid,
4727
4817
  accessToken,
4818
+ baseUrl,
4728
4819
  ledgerBaseUrl,
4729
4820
  noticeUuid,
4730
4821
  purposes,
4731
4822
  declined,
4732
4823
  meta_data
4733
4824
  }) => {
4734
- if (!ledgerBaseUrl) {
4735
- throw new Error("ledgerBaseUrl is required to submit consent");
4736
- }
4737
- const apiBaseUrl = ledgerBaseUrl;
4825
+ const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL2;
4738
4826
  const payload = {
4739
4827
  notice_uuid: noticeUuid,
4740
4828
  purposes: purposes.map((purpose) => {
@@ -5202,6 +5290,9 @@ var RedactoConsentInlineComponent = ({
5202
5290
  const [selectedPurposes, setSelectedPurposes] = useState3({});
5203
5291
  const [selectedDataElements, setSelectedDataElements] = useState3({});
5204
5292
  const [hasAlreadyConsented, setHasAlreadyConsented] = useState3(false);
5293
+ const [isCheckingConsent, setIsCheckingConsent] = useState3(
5294
+ Boolean(ledgerBaseUrl) && !applicationId
5295
+ );
5205
5296
  const [fetchError, setFetchError] = useState3(null);
5206
5297
  const [errorMessage, setErrorMessage] = useState3(null);
5207
5298
  const hasSubmittedRef = useRef2(false);
@@ -5283,18 +5374,24 @@ var RedactoConsentInlineComponent = ({
5283
5374
  }
5284
5375
  return defaultText;
5285
5376
  };
5286
- const fetchNotice = async () => {
5377
+ const fetchNotice = async (signal) => {
5287
5378
  setIsLoading(true);
5288
5379
  setFetchError(null);
5380
+ setHasAlreadyConsented(false);
5289
5381
  try {
5290
5382
  const consentContentData = await fetchConsentContent2({
5291
5383
  org_uuid,
5292
5384
  workspace_uuid,
5293
5385
  notice_uuid,
5386
+ accessToken,
5294
5387
  baseUrl,
5295
5388
  language,
5296
- specific_uuid: applicationId
5389
+ specific_uuid: applicationId,
5390
+ signal
5297
5391
  });
5392
+ if (signal == null ? void 0 : signal.aborted) {
5393
+ return;
5394
+ }
5298
5395
  const activeConfig = consentContentData.detail.active_config;
5299
5396
  setContent(activeConfig);
5300
5397
  if (activeConfig.default_language) {
@@ -5330,6 +5427,9 @@ var RedactoConsentInlineComponent = ({
5330
5427
  );
5331
5428
  setSelectedPurposes(initialPurposeState);
5332
5429
  } catch (err) {
5430
+ if ((signal == null ? void 0 : signal.aborted) || err instanceof Error && err.name === "AbortError") {
5431
+ return;
5432
+ }
5333
5433
  const error = err;
5334
5434
  setFetchError(error);
5335
5435
  if (error.status === 409) {
@@ -5338,12 +5438,50 @@ var RedactoConsentInlineComponent = ({
5338
5438
  onError == null ? void 0 : onError(error);
5339
5439
  }
5340
5440
  } finally {
5341
- setIsLoading(false);
5441
+ if (!(signal == null ? void 0 : signal.aborted)) {
5442
+ setIsLoading(false);
5443
+ }
5342
5444
  }
5343
5445
  };
5344
5446
  useEffect3(() => {
5345
- fetchNotice();
5346
- }, [org_uuid, workspace_uuid, notice_uuid, language, applicationId]);
5447
+ const controller = new AbortController();
5448
+ void fetchNotice(controller.signal);
5449
+ return () => {
5450
+ controller.abort();
5451
+ };
5452
+ }, [org_uuid, workspace_uuid, notice_uuid, language, applicationId, accessToken]);
5453
+ useEffect3(() => {
5454
+ if (!ledgerBaseUrl || applicationId) {
5455
+ return;
5456
+ }
5457
+ if (!accessToken || !content) {
5458
+ return;
5459
+ }
5460
+ let active = true;
5461
+ const controller = new AbortController();
5462
+ const checkLedgerConsent = async () => {
5463
+ try {
5464
+ const ledgerStatus = await fetchNoticeConsentStatus({
5465
+ accessToken,
5466
+ ledgerBaseUrl,
5467
+ noticeUuid: notice_uuid,
5468
+ signal: controller.signal
5469
+ });
5470
+ if (active && ledgerStatus && isNoticeFullyConsented(ledgerStatus)) {
5471
+ setHasAlreadyConsented(true);
5472
+ }
5473
+ } finally {
5474
+ if (active) {
5475
+ setIsCheckingConsent(false);
5476
+ }
5477
+ }
5478
+ };
5479
+ checkLedgerConsent();
5480
+ return () => {
5481
+ active = false;
5482
+ controller.abort();
5483
+ };
5484
+ }, [ledgerBaseUrl, applicationId, accessToken, content, notice_uuid]);
5347
5485
  const togglePurposeCollapse = (purposeUuid) => {
5348
5486
  setCollapsedPurposes((prev) => ({
5349
5487
  ...prev,
@@ -5419,6 +5557,7 @@ var RedactoConsentInlineComponent = ({
5419
5557
  org_uuid,
5420
5558
  workspace_uuid,
5421
5559
  accessToken: tokenToUse,
5560
+ baseUrl,
5422
5561
  ledgerBaseUrl,
5423
5562
  noticeUuid: content.notice_uuid,
5424
5563
  purposes: content.purposes.map((purpose) => {
@@ -5466,7 +5605,7 @@ var RedactoConsentInlineComponent = ({
5466
5605
  ]
5467
5606
  );
5468
5607
  useEffect3(() => {
5469
- if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !hasSubmittedRef.current) {
5608
+ if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !isCheckingConsent && !hasAlreadyConsented && !hasSubmittedRef.current) {
5470
5609
  hasSubmittedRef.current = true;
5471
5610
  const autoSubmit = async () => {
5472
5611
  try {
@@ -5483,6 +5622,8 @@ var RedactoConsentInlineComponent = ({
5483
5622
  content,
5484
5623
  areAllRequiredElementsChecked,
5485
5624
  isSubmitting,
5625
+ isCheckingConsent,
5626
+ hasAlreadyConsented,
5486
5627
  handleAcceptWithToken
5487
5628
  ]);
5488
5629
  useEffect3(() => {
@@ -6743,6 +6884,7 @@ var submitAssistedConsent = async ({
6743
6884
  organisationUuid,
6744
6885
  workspaceUuid,
6745
6886
  baseUrl,
6887
+ ledgerBaseUrl,
6746
6888
  noticeUuid,
6747
6889
  purposes,
6748
6890
  language,
@@ -6773,7 +6915,7 @@ var submitAssistedConsent = async ({
6773
6915
  declined: false,
6774
6916
  language: language || void 0
6775
6917
  };
6776
- const url = `${publicScope(baseUrl, organisationUuid, workspaceUuid)}/submit-consent`;
6918
+ const url = `${publicScope(ledgerBaseUrl || baseUrl, organisationUuid, workspaceUuid)}/submit-consent`;
6777
6919
  const response = await fetch(url, {
6778
6920
  method: "POST",
6779
6921
  headers: {
@@ -7900,57 +8042,6 @@ var as = {
7900
8042
  tryAgain: "\u0985\u09A8\u09C1\u0997\u09CD\u09F0\u09B9 \u0995\u09F0\u09BF \u09AA\u09C1\u09A8\u09F0 \u099A\u09C7\u09B7\u09CD\u099F\u09BE \u0995\u09F0\u0995\u0964",
7901
8043
  close: "\u09AC\u09A8\u09CD\u09A7 \u0995\u09F0\u0995"
7902
8044
  };
7903
- var bho = {
7904
- useEmailInstead: "\u0908\u092E\u0947\u0932 \u0907\u0938\u094D\u0924\u0947\u092E\u093E\u0932 \u0915\u0930\u0940\u0902",
7905
- useMobileInstead: "\u092E\u094B\u092C\u093E\u0907\u0932 \u0907\u0938\u094D\u0924\u0947\u092E\u093E\u0932 \u0915\u0930\u0940\u0902",
7906
- emailAddress: "\u0908\u092E\u0947\u0932 \u092A\u0924\u093E",
7907
- otpHelperEmail: "\u0939\u092E\u0928\u0940 \u090F\u0939 \u0908\u092E\u0947\u0932 \u092A\u0930 \u090F\u0915 \u092C\u0947\u0930 \u0907\u0938\u094D\u0924\u0947\u092E\u093E\u0932 \u0939\u094B\u0916\u0947 \u0935\u093E\u0932\u093E \u092A\u093E\u0938\u0935\u0930\u094D\u0921 \u092D\u0947\u091C\u092C\u0964",
7908
- changeEmail: "\u0908\u092E\u0947\u0932 \u092C\u0926\u0932\u0940\u0902",
7909
- expandDetails: "{name} \u0915\u0947 \u0935\u093F\u0935\u0930\u0923 \u092B\u0948\u0932\u093E\u0908\u0902",
7910
- collapseDetails: "{name} \u0915\u0947 \u0935\u093F\u0935\u0930\u0923 \u0938\u092E\u0947\u091F\u0940\u0902",
7911
- selectAllFor: "{name} \u0916\u093E\u0924\u093F\u0930 \u0938\u092D \u0921\u0947\u091F\u093E \u0924\u0924\u094D\u0935 \u091A\u0941\u0928\u0940\u0902",
7912
- selectElement: "{name} \u091A\u0941\u0928\u0940\u0902",
7913
- selectElementRequired: "{name} \u091A\u0941\u0928\u0940\u0902 (\u091C\u0930\u0942\u0930\u0940)",
7914
- required: "\u091C\u0930\u0942\u0930\u0940",
7915
- logoAlt: "\u0932\u094B\u0917\u094B",
7916
- selectLanguage: "\u092D\u093E\u0937\u093E \u091A\u0941\u0928\u0940\u0902",
7917
- selectLanguageCurrent: "\u092D\u093E\u0937\u093E \u091A\u0941\u0928\u0940\u0902. \u092E\u094C\u091C\u0942\u0926\u093E \u092D\u093E\u0937\u093E: {lang}",
7918
- opensInNewTab: "\u0928\u092F\u093E \u091F\u0948\u092C \u092E\u0947\u0902 \u0916\u0941\u0932\u0947\u0932\u093E",
7919
- audioStart: "\u0911\u0921\u093F\u092F\u094B \u092A\u094D\u0932\u0947\u092C\u0948\u0915 \u0936\u0941\u0930\u0942 \u0915\u0930\u0940\u0902",
7920
- audioPause: "\u0911\u0921\u093F\u092F\u094B \u092A\u094D\u0932\u0947\u092C\u0948\u0915 \u0930\u094B\u0915\u0940\u0902",
7921
- talkbackStart: "\u091F\u0949\u0915\u092C\u0948\u0915 \u0936\u0941\u0930\u0942 \u0915\u0930\u0940\u0902",
7922
- talkbackPause: "\u091F\u0949\u0915\u092C\u0948\u0915 \u0930\u094B\u0915\u0940\u0902",
7923
- mobileNumber: "\u092E\u094B\u092C\u093E\u0907\u0932 \u0928\u0902\u092C\u0930",
7924
- otpHelper: "\u0939\u092E\u0928\u0940 \u090F\u0939 \u0928\u0902\u092C\u0930 \u092A\u0930 \u090F\u0915 \u092C\u0947\u0930 \u0907\u0938\u094D\u0924\u0947\u092E\u093E\u0932 \u0939\u094B\u0916\u0947 \u0935\u093E\u0932\u093E \u092A\u093E\u0938\u0935\u0930\u094D\u0921 \u092D\u0947\u091C\u092C\u0964",
7925
- otpSentTo: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u092D\u0947\u091C\u0932 \u0917\u0907\u0932",
7926
- changeMobile: "\u092E\u094B\u092C\u093E\u0907\u0932 \u0928\u0902\u092C\u0930 \u092C\u0926\u0932\u0940\u0902",
7927
- enterNDigitOtp: "{count}-\u0905\u0902\u0915 \u0915\u0947 \u0913\u091F\u0940\u092A\u0940 (OTP) \u0921\u093E\u0932\u0940\u0902",
7928
- otpDigit: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0905\u0902\u0915 {index}",
7929
- resendIn: "{seconds} \u0938\u0947\u0915\u0902\u0921 \u092E\u0947\u0902 \u0913\u091F\u0940\u092A\u0940 (OTP) \u092B\u0947\u0930 \u0938\u0947 \u092D\u0947\u091C\u0940\u0902",
7930
- sending: "\u092D\u0947\u091C\u0932 \u091C\u093E \u0930\u0939\u0932 \u092C\u093E\u2026",
7931
- resendOtp: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u092B\u0947\u0930 \u0938\u0947 \u092D\u0947\u091C\u0940\u0902",
7932
- getOtp: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u092A\u093E\u0908\u0902",
7933
- verifying: "\u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \u0915\u0907\u0932 \u091C\u093E \u0930\u0939\u0932 \u092C\u093E\u2026",
7934
- verifyOtp: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \u0915\u0930\u0940\u0902",
7935
- sendOtp: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u092D\u0947\u091C\u0940\u0902",
7936
- confirmOtp: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0915\u0947 \u092A\u0941\u0937\u094D\u091F\u093F \u0915\u0930\u0940\u0902",
7937
- verifyWithOtp: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0938\u0947 \u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \u0915\u0930\u0940\u0902",
7938
- editSelections: "\u091A\u0941\u0928\u093E\u0935 \u092E\u0947\u0902 \u092C\u0926\u0932\u093E\u0935 \u0915\u0930\u0940\u0902",
7939
- otpIncorrect: "\u0930\u0909\u0930\u093E \u0921\u093E\u0932\u0932 \u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0915\u094B\u0921 \u0917\u0932\u0924 \u092C\u093E\u0964 \u0915\u0943\u092A\u092F\u093E \u091C\u093E\u0901\u091A \u0915\u0930\u0940\u0902 \u0906 \u092B\u0947\u0930 \u0938\u0947 \u0915\u094B\u0936\u093F\u0936 \u0915\u0930\u0940\u0902\u0964",
7940
- otpExpired: "\u0930\u0909\u0930\u093E \u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0915\u094B\u0921 \u0915\u0947 \u092E\u093F\u092F\u093E\u0926 \u0916\u0924\u092E \u0939\u094B \u0917\u0907\u0932 \u092C\u093E\u0964 \u0915\u0943\u092A\u092F\u093E \u0928\u092F\u093E \u0915\u094B\u0921 \u092E\u093E\u0902\u0917\u0940\u0902\u0964",
7941
- otpNotFound: "\u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0915\u094B\u0921 \u0928\u093E \u092E\u093F\u0932\u0932\u0964 \u0915\u0943\u092A\u092F\u093E \u0928\u092F\u093E \u0915\u094B\u0921 \u092E\u093E\u0902\u0917\u0940\u0902\u0964",
7942
- otpVerifyFailed: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0915\u0947 \u0938\u0924\u094D\u092F\u093E\u092A\u0928 \u0928\u093E \u0939\u094B \u0938\u0915\u0932\u0964 \u0915\u0943\u092A\u092F\u093E \u092B\u0947\u0930 \u0938\u0947 \u0915\u094B\u0936\u093F\u0936 \u0915\u0930\u0940\u0902\u0964",
7943
- otpSendFailed: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0928\u093E \u092D\u0947\u091C\u0932 \u091C\u093E \u0938\u0915\u0932\u0964 \u0915\u0943\u092A\u092F\u093E \u092B\u0947\u0930 \u0938\u0947 \u0915\u094B\u0936\u093F\u0936 \u0915\u0930\u0940\u0902\u0964",
7944
- consentConfirmed: "\u0938\u0939\u092E\u0924\u093F \u0915\u0947 \u092A\u0941\u0937\u094D\u091F\u093F \u092D\u0907\u0932",
7945
- recordedUnder: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \xB7 {regulation} \u0915\u0947 \u0924\u0939\u0924 \u0926\u0930\u094D\u091C \u092D\u0907\u0932",
7946
- recordedUnderAt: "\u0913\u091F\u0940\u092A\u0940 (OTP) \u0938\u0924\u094D\u092F\u093E\u092A\u093F\u0924 \xB7 {regulation} \u0915\u0947 \u0924\u0939\u0924 {time} \u092C\u091C\u0947 \u0926\u0930\u094D\u091C \u092D\u0907\u0932",
7947
- consentReferenceId: "\u0938\u0939\u092E\u0924\u093F \u0938\u0902\u0926\u0930\u094D\u092D \u0906\u0908\u0921\u0940",
7948
- proceed: "\u0906\u0917\u0947 \u092C\u0922\u093C\u0940\u0902",
7949
- loadingNotice: "\u0928\u094B\u091F\u093F\u0938 \u0932\u094B\u0921 \u0939\u094B \u0930\u0939\u0932 \u092C\u093E",
7950
- loadFailedTitle: "\u0938\u0939\u092E\u0924\u093F \u0928\u094B\u091F\u093F\u0938 \u0932\u094B\u0921 \u0928\u093E \u0939\u094B \u0938\u0915\u0932",
7951
- tryAgain: "\u0915\u0943\u092A\u092F\u093E \u092B\u0947\u0930 \u0938\u0947 \u0915\u094B\u0938\u093F\u0938 \u0915\u0930\u0940\u0902\u0964",
7952
- close: "\u092C\u0902\u0926 \u0915\u0930\u0940\u0902"
7953
- };
7954
8045
  var brx = {
7955
8046
  useEmailInstead: "\u0907\u092E\u0947\u0932 \u092C\u093E\u0939\u093E\u092F",
7956
8047
  useMobileInstead: "\u092E\u092C\u093E\u0907\u0932 \u092C\u093E\u0939\u093E\u092F",
@@ -8075,7 +8166,6 @@ var STATIC_STRINGS = {
8075
8166
  te,
8076
8167
  ur,
8077
8168
  as,
8078
- bho,
8079
8169
  brx,
8080
8170
  doi
8081
8171
  };
@@ -8260,6 +8350,7 @@ var RedactoNoticeAssisted = ({
8260
8350
  workspaceUuid,
8261
8351
  noticeUuid,
8262
8352
  baseUrl,
8353
+ ledgerBaseUrl,
8263
8354
  onDecline,
8264
8355
  onComplete
8265
8356
  }) => {
@@ -8995,6 +9086,19 @@ var RedactoNoticeAssisted = ({
8995
9086
  return;
8996
9087
  }
8997
9088
  const token = verifyDetail.access_token;
9089
+ if (ledgerBaseUrl) {
9090
+ const ledgerStatus = await fetchNoticeConsentStatusForScope({
9091
+ accessToken: token,
9092
+ ledgerBaseUrl,
9093
+ organisationUuid,
9094
+ workspaceUuid,
9095
+ noticeUuid: content.notice_uuid
9096
+ });
9097
+ if (ledgerStatus && isNoticeFullyConsented(ledgerStatus)) {
9098
+ handleSuccess();
9099
+ return;
9100
+ }
9101
+ }
8998
9102
  const submitPurposes = content.purposes.map((purpose) => ({
8999
9103
  ...purpose,
9000
9104
  selected: selectedPurposes[purpose.uuid] || false,
@@ -9008,6 +9112,7 @@ var RedactoNoticeAssisted = ({
9008
9112
  organisationUuid,
9009
9113
  workspaceUuid,
9010
9114
  baseUrl,
9115
+ ledgerBaseUrl,
9011
9116
  noticeUuid: content.notice_uuid,
9012
9117
  purposes: submitPurposes,
9013
9118
  language: toBcp47Code(selectedLanguage)
@@ -9031,6 +9136,7 @@ var RedactoNoticeAssisted = ({
9031
9136
  otpUuid,
9032
9137
  otpValue,
9033
9138
  baseUrl,
9139
+ ledgerBaseUrl,
9034
9140
  selectedPurposes,
9035
9141
  selectedDataElements,
9036
9142
  selectedLanguage,