@redacto.io/consent-sdk-react 10.0.0-beta.8 → 10.0.0-beta.9

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 (30) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/{chunk-6A665OPR.mjs → chunk-OGL6OC3A.mjs} +4 -0
  3. package/dist/index.d.mts +29 -3
  4. package/dist/index.d.ts +29 -3
  5. package/dist/index.js +162 -56
  6. package/dist/index.mjs +161 -57
  7. package/dist/privacy-center.d.mts +51 -10
  8. package/dist/privacy-center.d.ts +51 -10
  9. package/dist/privacy-center.js +250 -70
  10. package/dist/privacy-center.mjs +249 -71
  11. package/package.json +1 -1
  12. package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +55 -5
  13. package/src/RedactoNoticeConsent/api/index.ts +78 -48
  14. package/src/RedactoNoticeConsent/api/sandbox.ts +150 -0
  15. package/src/RedactoNoticeConsent/api/types.ts +57 -11
  16. package/src/RedactoNoticeConsent/types.ts +28 -2
  17. package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +37 -2
  18. package/src/RedactoPrivacyCenter/api/client.ts +116 -24
  19. package/src/RedactoPrivacyCenter/api/fetcher.ts +24 -9
  20. package/src/RedactoPrivacyCenter/components/Form.tsx +55 -30
  21. package/src/RedactoPrivacyCenter/components/SelectUserGate.tsx +8 -0
  22. package/src/RedactoPrivacyCenter/components/groupHelpers.ts +42 -6
  23. package/src/RedactoPrivacyCenter/context/AuthContext.tsx +131 -39
  24. package/src/RedactoPrivacyCenter/context/types.ts +38 -0
  25. package/src/RedactoPrivacyCenter/lib/constants.ts +12 -5
  26. package/src/RedactoPrivacyCenter/lib/sandbox.ts +104 -0
  27. package/src/RedactoPrivacyCenter/lib/types.ts +20 -0
  28. package/src/RedactoPrivacyCenter/lib/utils.ts +15 -0
  29. package/src/shared/sandbox.ts +6 -0
  30. package/tests/Form.test.tsx +142 -5
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @redacto.io/consent-sdk-react
2
2
 
3
+ ## 10.0.0-beta.9
4
+
5
+ ### Patch Changes
6
+
7
+ - e44b1a3: Privacy Center: fix the DSAR request form showing "No products available" against the legacy Python backend. The request-form product picker is now sourced from `user-consents` on **both** backends — the Go ledger's `/public/.../user-consents` when `ledgerBaseUrl` is configured, Python's `/dsar/privacy-center/user-consents` otherwise (the same read the Manage Consent view already used in both modes) — instead of being skipped entirely without a ledger, which left the picker dependent on `form/data` product groups that Python no longer emits.
8
+
9
+ Two related gaps are closed: a successful-but-empty `user-consents` response no longer overwrites the product groups `form/data` did supply, and a backend that returns only the legacy flat `purposes` list now renders those purposes under a single "Your data" group instead of the empty state. Cases raised from that fallback group are submitted without a `product_uuid` anchor, matching the pre-grouping org-level case shape.
10
+
11
+ - source Privacy Center DSAR product picker from user-consents on both backends
12
+
3
13
  ## 10.0.0-beta.8
4
14
 
5
15
  ### Patch Changes
@@ -25,6 +25,10 @@ var useMediaQuery = (query) => {
25
25
  return matches;
26
26
  };
27
27
 
28
+ // src/shared/sandbox.ts
29
+ var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
30
+
28
31
  export {
32
+ SANDBOX_TOKEN_HEADER,
29
33
  useMediaQuery
30
34
  };
package/dist/index.d.mts CHANGED
@@ -43,8 +43,34 @@ type DigiLockerCallbackProps = {
43
43
 
44
44
  type Props$1 = Readonly<{
45
45
  noticeId: string;
46
- accessToken: string;
47
- refreshToken: string;
46
+ /**
47
+ * JWT access token. Optional so sandbox integrations (see `token`) can
48
+ * omit it. Required in the normal JWT flow.
49
+ */
50
+ accessToken?: string;
51
+ /** JWT refresh token. Optional; accepted for source-compat, currently unused. */
52
+ refreshToken?: string;
53
+ /**
54
+ * Sandbox PoC: a pasted static token. When set, the SDK runs against the
55
+ * sandbox with no JWT — it sends the single `X-Consent-Token` header, carries
56
+ * the acting identity (`email` || `mobile`) in each request's own payload,
57
+ * takes org/workspace from `organisationUuid`/`workspaceUuid`, and does no
58
+ * token refresh.
59
+ */
60
+ token?: string;
61
+ /** Sandbox test subject email (carried in the request payload when set). */
62
+ email?: string;
63
+ /** Sandbox test subject mobile (fallback subject when `email` is absent). */
64
+ mobile?: string;
65
+ /**
66
+ * Sandbox UCIC: the client's own user id / org_user_id, e.g. a UUID or
67
+ * customer code; optional third identifier alongside email/mobile.
68
+ */
69
+ ucic?: string;
70
+ /** Sandbox org UUID (replaces the JWT-decoded org in sandbox mode). */
71
+ organisationUuid?: string;
72
+ /** Sandbox workspace UUID (replaces the JWT-decoded workspace in sandbox mode). */
73
+ workspaceUuid?: string;
48
74
  baseUrl?: string;
49
75
  ledgerBaseUrl?: string;
50
76
  settings?: Partial<Settings$1>;
@@ -76,7 +102,7 @@ type Props$1 = Readonly<{
76
102
  * to view and manage their consent preferences. Supports both initial consent
77
103
  * collection and reconsent flows.
78
104
  */
79
- declare const RedactoNoticeConsent: ({ noticeId, accessToken, refreshToken, baseUrl, ledgerBaseUrl, language, blockUI, onAccept, onDecline, onError, settings, applicationId, validateAgainst, digilockerMode, digilockerCallbackUrl, includeFullyConsentedData, reviewModeButtonText, }: Props$1) => react__default.JSX.Element;
105
+ declare const RedactoNoticeConsent: ({ noticeId, accessToken, refreshToken, token, email, mobile, ucic, organisationUuid, workspaceUuid, baseUrl, ledgerBaseUrl, language, blockUI, onAccept, onDecline, onError, settings, applicationId, validateAgainst, digilockerMode, digilockerCallbackUrl, includeFullyConsentedData, reviewModeButtonText, }: Props$1) => react__default.JSX.Element;
80
106
 
81
107
  type Settings = {
82
108
  button: {
package/dist/index.d.ts CHANGED
@@ -43,8 +43,34 @@ type DigiLockerCallbackProps = {
43
43
 
44
44
  type Props$1 = Readonly<{
45
45
  noticeId: string;
46
- accessToken: string;
47
- refreshToken: string;
46
+ /**
47
+ * JWT access token. Optional so sandbox integrations (see `token`) can
48
+ * omit it. Required in the normal JWT flow.
49
+ */
50
+ accessToken?: string;
51
+ /** JWT refresh token. Optional; accepted for source-compat, currently unused. */
52
+ refreshToken?: string;
53
+ /**
54
+ * Sandbox PoC: a pasted static token. When set, the SDK runs against the
55
+ * sandbox with no JWT — it sends the single `X-Consent-Token` header, carries
56
+ * the acting identity (`email` || `mobile`) in each request's own payload,
57
+ * takes org/workspace from `organisationUuid`/`workspaceUuid`, and does no
58
+ * token refresh.
59
+ */
60
+ token?: string;
61
+ /** Sandbox test subject email (carried in the request payload when set). */
62
+ email?: string;
63
+ /** Sandbox test subject mobile (fallback subject when `email` is absent). */
64
+ mobile?: string;
65
+ /**
66
+ * Sandbox UCIC: the client's own user id / org_user_id, e.g. a UUID or
67
+ * customer code; optional third identifier alongside email/mobile.
68
+ */
69
+ ucic?: string;
70
+ /** Sandbox org UUID (replaces the JWT-decoded org in sandbox mode). */
71
+ organisationUuid?: string;
72
+ /** Sandbox workspace UUID (replaces the JWT-decoded workspace in sandbox mode). */
73
+ workspaceUuid?: string;
48
74
  baseUrl?: string;
49
75
  ledgerBaseUrl?: string;
50
76
  settings?: Partial<Settings$1>;
@@ -76,7 +102,7 @@ type Props$1 = Readonly<{
76
102
  * to view and manage their consent preferences. Supports both initial consent
77
103
  * collection and reconsent flows.
78
104
  */
79
- declare const RedactoNoticeConsent: ({ noticeId, accessToken, refreshToken, baseUrl, ledgerBaseUrl, language, blockUI, onAccept, onDecline, onError, settings, applicationId, validateAgainst, digilockerMode, digilockerCallbackUrl, includeFullyConsentedData, reviewModeButtonText, }: Props$1) => react__default.JSX.Element;
105
+ declare const RedactoNoticeConsent: ({ noticeId, accessToken, refreshToken, token, email, mobile, ucic, organisationUuid, workspaceUuid, baseUrl, ledgerBaseUrl, language, blockUI, onAccept, onDecline, onError, settings, applicationId, validateAgainst, digilockerMode, digilockerCallbackUrl, includeFullyConsentedData, reviewModeButtonText, }: Props$1) => react__default.JSX.Element;
80
106
 
81
107
  type Settings = {
82
108
  button: {
package/dist/index.js CHANGED
@@ -92,6 +92,67 @@ async function parseApiError(response, fallbackMessage) {
92
92
  });
93
93
  }
94
94
 
95
+ // src/shared/sandbox.ts
96
+ var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
97
+
98
+ // src/RedactoNoticeConsent/api/sandbox.ts
99
+ var resolveSandboxAuth = (params) => {
100
+ var _a, _b, _c, _d, _e;
101
+ const token = (_a = params.token) == null ? void 0 : _a.trim();
102
+ if (!token) {
103
+ return null;
104
+ }
105
+ const organisationUuid = (_b = params.organisationUuid) == null ? void 0 : _b.trim();
106
+ const workspaceUuid = (_c = params.workspaceUuid) == null ? void 0 : _c.trim();
107
+ const ucic = (_d = params.sandboxUcic) == null ? void 0 : _d.trim();
108
+ const subject = (_e = params.sandboxSubject) == null ? void 0 : _e.trim();
109
+ if (!organisationUuid || !workspaceUuid) {
110
+ throw new Error(
111
+ "Sandbox mode requires organisationUuid and workspaceUuid props"
112
+ );
113
+ }
114
+ if (!ucic && !subject) {
115
+ throw new Error("Sandbox mode requires a UCIC, email, or mobile");
116
+ }
117
+ return { token, ucic, subject: subject != null ? subject : "", organisationUuid, workspaceUuid };
118
+ };
119
+ var resolveRequestAuth = (accessToken, sandboxParams, decodeTokenSafely2) => {
120
+ const sandbox = resolveSandboxAuth(sandboxParams);
121
+ if (sandbox) {
122
+ return {
123
+ organisationUuid: sandbox.organisationUuid,
124
+ workspaceUuid: sandbox.workspaceUuid,
125
+ sandbox
126
+ };
127
+ }
128
+ const decodedToken = accessToken ? decodeTokenSafely2(accessToken) : null;
129
+ if (!decodedToken) {
130
+ throw new Error("Invalid access token");
131
+ }
132
+ const { organisation_uuid, workspace_uuid } = decodedToken;
133
+ if (!organisation_uuid || !workspace_uuid) {
134
+ throw new Error("Invalid token: missing organization or workspace UUID");
135
+ }
136
+ return {
137
+ organisationUuid: organisation_uuid,
138
+ workspaceUuid: workspace_uuid,
139
+ sandbox: null
140
+ };
141
+ };
142
+ var buildAuthHeaders = (accessToken, sandbox) => {
143
+ if (sandbox) {
144
+ return { [SANDBOX_TOKEN_HEADER]: sandbox.token };
145
+ }
146
+ return { Authorization: `Bearer ${accessToken}` };
147
+ };
148
+ var sandboxBodyIdentity = (sandbox) => {
149
+ if (sandbox.ucic) {
150
+ return { org_user_id: sandbox.ucic };
151
+ }
152
+ return sandbox.subject.includes("@") ? { primary_email: sandbox.subject } : { primary_mobile: sandbox.subject };
153
+ };
154
+ var sandboxQueryIdentity = (sandbox) => sandboxBodyIdentity(sandbox);
155
+
95
156
  // src/shared/notice-consent-status.ts
96
157
  var import_jwt_decode = require("jwt-decode");
97
158
  var decodeNoticeConsentToken = (token) => {
@@ -205,21 +266,19 @@ var fetchConsentContent = async ({
205
266
  specific_uuid,
206
267
  validate_against = "all",
207
268
  include_fully_consented_data = false,
208
- signal
269
+ signal,
270
+ ...sandboxParams
209
271
  }) => {
210
- if (!noticeId || !accessToken || !validate_against) {
211
- throw new Error("noticeId and accessToken are required");
212
- }
213
- const decodedToken = decodeTokenSafely(accessToken);
214
- if (!decodedToken) {
215
- throw new Error("Invalid access token");
272
+ if (!noticeId || !validate_against) {
273
+ throw new Error("noticeId is required");
216
274
  }
217
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
218
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
219
- throw new Error("Invalid token: missing organization or workspace UUID");
275
+ if (!accessToken && !sandboxParams.token) {
276
+ throw new Error("accessToken or token is required");
220
277
  }
278
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
221
279
  const apiBaseUrl = baseUrl || BASE_URL;
222
- const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
280
+ const cacheIdentity = sandbox ? `sandbox:${sandbox.organisationUuid}:${sandbox.workspaceUuid}:${sandbox.ucic || sandbox.subject}` : accessToken;
281
+ const cacheKey = `${cacheIdentity}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
223
282
  if (validate_against === "all" && !specific_uuid) {
224
283
  const cachedData = getCachedData(cacheKey);
225
284
  if (cachedData) {
@@ -236,10 +295,15 @@ var fetchConsentContent = async ({
236
295
  if (include_fully_consented_data) {
237
296
  url.searchParams.append("include_fully_consented_data", "true");
238
297
  }
298
+ if (sandbox) {
299
+ for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {
300
+ url.searchParams.append(key, value);
301
+ }
302
+ }
239
303
  const response = await fetch(url.toString(), {
240
304
  method: "GET",
241
305
  headers: {
242
- Authorization: `Bearer ${accessToken}`,
306
+ ...buildAuthHeaders(accessToken, sandbox),
243
307
  "Accept-Language": language
244
308
  },
245
309
  signal
@@ -267,20 +331,17 @@ var submitConsentEvent = async ({
267
331
  meta_data,
268
332
  guardianVerificationReference,
269
333
  selfDeclaredAdult,
270
- signal
334
+ signal,
335
+ ...sandboxParams
271
336
  }) => {
272
- if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
273
- throw new Error("noticeUuid, accessToken, and purposes array are required");
337
+ if (!noticeUuid || !Array.isArray(purposes)) {
338
+ throw new Error("noticeUuid and purposes array are required");
274
339
  }
275
- const decodedToken = decodeTokenSafely(accessToken);
276
- if (!decodedToken) {
277
- throw new Error("Invalid access token");
340
+ if (!accessToken && !sandboxParams.token) {
341
+ throw new Error("accessToken or token is required");
278
342
  }
279
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
280
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
281
- throw new Error("Invalid token: missing organization or workspace UUID");
282
- }
283
- const apiBaseUrl = ledgerBaseUrl || baseUrl || BASE_URL;
343
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
344
+ const apiBaseUrl = (sandbox ? null : ledgerBaseUrl) || baseUrl || BASE_URL;
284
345
  const validatedPurposes = purposes.map((purpose) => {
285
346
  if (!purpose.uuid) {
286
347
  throw new Error(`Invalid purpose data: missing uuid`);
@@ -306,15 +367,16 @@ var submitConsentEvent = async ({
306
367
  guardian_verification_reference: guardianVerificationReference,
307
368
  self_declared_adult: selfDeclaredAdult
308
369
  };
370
+ const requestBody = sandbox ? { ...payload, ...sandboxBodyIdentity(sandbox) } : payload;
309
371
  const response = await fetch(
310
372
  `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
311
373
  {
312
374
  method: "POST",
313
375
  headers: {
314
- Authorization: `Bearer ${accessToken}`,
376
+ ...buildAuthHeaders(accessToken, sandbox),
315
377
  "Content-Type": "application/json"
316
378
  },
317
- body: JSON.stringify(payload),
379
+ body: JSON.stringify(requestBody),
318
380
  signal
319
381
  }
320
382
  );
@@ -370,25 +432,26 @@ var fetchTTSAudioUrls = async ({
370
432
  baseUrl,
371
433
  noticeUuid,
372
434
  language,
373
- signal
435
+ signal,
436
+ ...sandboxParams
374
437
  }) => {
375
- if (!accessToken || !noticeUuid || !language) {
376
- throw new Error("accessToken, noticeUuid, and language are required");
377
- }
378
- const decodedToken = decodeTokenSafely(accessToken);
379
- if (!decodedToken) {
380
- throw new Error("Invalid access token");
381
- }
382
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
383
- if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
384
- throw new Error("Invalid token: missing organization or workspace UUID");
438
+ if (!accessToken && !sandboxParams.token || !noticeUuid || !language) {
439
+ throw new Error("accessToken (or token), noticeUuid, and language are required");
385
440
  }
441
+ const { organisationUuid: ORGANISATION_UUID, workspaceUuid: WORKSPACE_UUID, sandbox } = resolveRequestAuth(accessToken, sandboxParams, decodeTokenSafely);
386
442
  const apiBaseUrl = baseUrl || BASE_URL;
387
- const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
388
- const response = await fetch(url, {
443
+ const url = new URL(
444
+ `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`
445
+ );
446
+ if (sandbox) {
447
+ for (const [key, value] of Object.entries(sandboxQueryIdentity(sandbox))) {
448
+ url.searchParams.append(key, value);
449
+ }
450
+ }
451
+ const response = await fetch(url.toString(), {
389
452
  method: "GET",
390
453
  headers: {
391
- Authorization: `Bearer ${accessToken}`,
454
+ ...buildAuthHeaders(accessToken, sandbox),
392
455
  Accept: "application/json"
393
456
  },
394
457
  signal
@@ -430,7 +493,10 @@ var initiateGuardianVerification = async ({
430
493
  if (!decodedToken) {
431
494
  throw new Error("Invalid access token");
432
495
  }
433
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
496
+ const {
497
+ organisation_uuid: ORGANISATION_UUID,
498
+ workspace_uuid: WORKSPACE_UUID
499
+ } = decodedToken;
434
500
  if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
435
501
  throw new Error("Invalid token: missing organization or workspace UUID");
436
502
  }
@@ -504,7 +570,10 @@ var verifyGuardianStatus = async ({
504
570
  if (!decodedToken) {
505
571
  throw new Error("Invalid access token");
506
572
  }
507
- const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
573
+ const {
574
+ organisation_uuid: ORGANISATION_UUID,
575
+ workspace_uuid: WORKSPACE_UUID
576
+ } = decodedToken;
508
577
  if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
509
578
  throw new Error("Invalid token: missing organization or workspace UUID");
510
579
  }
@@ -517,9 +586,7 @@ var verifyGuardianStatus = async ({
517
586
  Authorization: `Bearer ${accessToken}`,
518
587
  "Content-Type": "application/json"
519
588
  },
520
- body: JSON.stringify({
521
- session_token: sessionToken
522
- }),
589
+ body: JSON.stringify({ session_token: sessionToken }),
523
590
  signal
524
591
  }
525
592
  );
@@ -2408,6 +2475,12 @@ var RedactoNoticeConsent = ({
2408
2475
  noticeId,
2409
2476
  accessToken,
2410
2477
  refreshToken,
2478
+ token,
2479
+ email,
2480
+ mobile,
2481
+ ucic,
2482
+ organisationUuid,
2483
+ workspaceUuid,
2411
2484
  baseUrl,
2412
2485
  ledgerBaseUrl,
2413
2486
  language = "en",
@@ -2426,15 +2499,43 @@ var RedactoNoticeConsent = ({
2426
2499
  reviewModeButtonText = "Continue"
2427
2500
  }) => {
2428
2501
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2502
+ const sandboxParams = (0, import_react2.useMemo)(
2503
+ () => ({
2504
+ token,
2505
+ sandboxUcic: ucic,
2506
+ sandboxSubject: email || mobile,
2507
+ organisationUuid,
2508
+ workspaceUuid
2509
+ }),
2510
+ [token, ucic, email, mobile, organisationUuid, workspaceUuid]
2511
+ );
2429
2512
  const propValidationError = (0, import_react2.useMemo)(() => {
2430
2513
  if (!(noticeId == null ? void 0 : noticeId.trim())) {
2431
2514
  return "RedactoNoticeConsent: 'noticeId' prop is required and cannot be empty";
2432
2515
  }
2516
+ if (token == null ? void 0 : token.trim()) {
2517
+ if (!(organisationUuid == null ? void 0 : organisationUuid.trim()) || !(workspaceUuid == null ? void 0 : workspaceUuid.trim())) {
2518
+ return "RedactoNoticeConsent: sandbox mode requires 'organisationUuid' and 'workspaceUuid'";
2519
+ }
2520
+ if (!(email == null ? void 0 : email.trim()) && !(mobile == null ? void 0 : mobile.trim()) && !(ucic == null ? void 0 : ucic.trim())) {
2521
+ return "RedactoNoticeConsent: sandbox mode requires 'email', 'mobile', or 'ucic'";
2522
+ }
2523
+ return null;
2524
+ }
2433
2525
  if (!(accessToken == null ? void 0 : accessToken.trim())) {
2434
2526
  return "RedactoNoticeConsent: 'accessToken' prop is required and cannot be empty";
2435
2527
  }
2436
2528
  return null;
2437
- }, [noticeId, accessToken]);
2529
+ }, [
2530
+ noticeId,
2531
+ accessToken,
2532
+ token,
2533
+ organisationUuid,
2534
+ workspaceUuid,
2535
+ email,
2536
+ mobile,
2537
+ ucic
2538
+ ]);
2438
2539
  if (propValidationError) {
2439
2540
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
2440
2541
  "div",
@@ -2787,7 +2888,8 @@ var RedactoNoticeConsent = ({
2787
2888
  specific_uuid: applicationId,
2788
2889
  validate_against: validateAgainst,
2789
2890
  include_fully_consented_data: includeFullyConsentedData,
2790
- signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal
2891
+ signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal,
2892
+ ...sandboxParams
2791
2893
  });
2792
2894
  const activeConfig = consentContentData.detail.active_config;
2793
2895
  setContent(activeConfig);
@@ -2812,7 +2914,8 @@ var RedactoNoticeConsent = ({
2812
2914
  accessToken,
2813
2915
  ledgerBaseUrl,
2814
2916
  noticeUuid: noticeId,
2815
- signal: (_b2 = abortControllerRef.current) == null ? void 0 : _b2.signal
2917
+ signal: (_b2 = abortControllerRef.current) == null ? void 0 : _b2.signal,
2918
+ ...sandboxParams
2816
2919
  });
2817
2920
  if (ledgerStatus) {
2818
2921
  const overlay = buildLedgerConsentOverlay(
@@ -2944,6 +3047,7 @@ var RedactoNoticeConsent = ({
2944
3047
  noticeId,
2945
3048
  accessToken,
2946
3049
  refreshToken,
3050
+ sandboxParams,
2947
3051
  language,
2948
3052
  applicationId,
2949
3053
  validateAgainst,
@@ -3060,7 +3164,8 @@ var RedactoNoticeConsent = ({
3060
3164
  meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
3061
3165
  guardianVerificationReference: verificationReference || void 0,
3062
3166
  selfDeclaredAdult: selfDeclaredAdult || void 0,
3063
- signal: submitController.signal
3167
+ signal: submitController.signal,
3168
+ ...sandboxParams
3064
3169
  });
3065
3170
  }
3066
3171
  onAccept == null ? void 0 : onAccept();
@@ -3243,7 +3348,7 @@ var RedactoNoticeConsent = ({
3243
3348
  } finally {
3244
3349
  setIsSubmittingGuardian(false);
3245
3350
  }
3246
- }, [accessToken, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
3351
+ }, [accessToken, sandboxParams, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
3247
3352
  const handleAgeVerificationYes = (0, import_react2.useCallback)(() => {
3248
3353
  setShowAgeVerification(false);
3249
3354
  setIsMinorFlow(false);
@@ -3300,7 +3405,7 @@ var RedactoNoticeConsent = ({
3300
3405
  setIsPollingStatus(false);
3301
3406
  isPollingStatusRef.current = false;
3302
3407
  setIsInitiatingVerification(false);
3303
- }, [accessToken, baseUrl]);
3408
+ }, [accessToken, sandboxParams, baseUrl]);
3304
3409
  const startPopupMonitoring = (0, import_react2.useCallback)((popup) => {
3305
3410
  popupCheckIntervalRef.current = window.setInterval(() => {
3306
3411
  if (popup.closed) {
@@ -3328,8 +3433,8 @@ var RedactoNoticeConsent = ({
3328
3433
  []
3329
3434
  );
3330
3435
  const startStatusPolling = (0, import_react2.useCallback)(
3331
- (token) => {
3332
- verificationSessionTokenRef.current = token;
3436
+ (token2) => {
3437
+ verificationSessionTokenRef.current = token2;
3333
3438
  setIsPollingStatus(true);
3334
3439
  isPollingStatusRef.current = true;
3335
3440
  setVerificationError(null);
@@ -3381,7 +3486,7 @@ var RedactoNoticeConsent = ({
3381
3486
  const response = await verifyGuardianStatus({
3382
3487
  accessToken,
3383
3488
  baseUrl,
3384
- sessionToken: token
3489
+ sessionToken: token2
3385
3490
  });
3386
3491
  consecutiveErrors = 0;
3387
3492
  if (response.status === "verified") {
@@ -3451,7 +3556,7 @@ var RedactoNoticeConsent = ({
3451
3556
  };
3452
3557
  statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
3453
3558
  },
3454
- [accessToken, baseUrl, getVerificationErrorMessage]
3559
+ [accessToken, sandboxParams, baseUrl, getVerificationErrorMessage]
3455
3560
  );
3456
3561
  const handleBackToGuardianForm = (0, import_react2.useCallback)((clearName = false) => {
3457
3562
  var _a2, _b2;
@@ -3793,7 +3898,8 @@ var RedactoNoticeConsent = ({
3793
3898
  baseUrl,
3794
3899
  noticeUuid: content.notice_uuid,
3795
3900
  language: languageCode,
3796
- signal: ttsAbortController.signal
3901
+ signal: ttsAbortController.signal,
3902
+ ...sandboxParams
3797
3903
  }).then((response) => {
3798
3904
  setTtsAudioUrls(response.detail);
3799
3905
  setIsTTSAvailable(true);
@@ -3806,7 +3912,7 @@ var RedactoNoticeConsent = ({
3806
3912
  return () => {
3807
3913
  ttsAbortController.abort();
3808
3914
  };
3809
- }, [content, selectedLanguage, accessToken, baseUrl, getLanguageCode]);
3915
+ }, [content, selectedLanguage, accessToken, sandboxParams, baseUrl, getLanguageCode]);
3810
3916
  const modalStyle = {
3811
3917
  borderRadius: (settings == null ? void 0 : settings.borderRadius) || "8px",
3812
3918
  backgroundColor: (settings == null ? void 0 : settings.backgroundColor) || "#ffffff"