@redacto.io/consent-sdk-react-native 4.0.1-beta.0 → 5.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +186 -10
- package/dist/index.mjs +186 -10
- package/dist/privacy-center.d.mts +38 -7
- package/dist/privacy-center.d.ts +38 -7
- package/dist/privacy-center.js +195 -30
- package/dist/privacy-center.mjs +195 -30
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -136,6 +136,7 @@ import { RedactoNoticeConsent } from "@redacto.io/consent-sdk-react-native";
|
|
|
136
136
|
| `accessToken` | `string` | ✓ | JWT access token |
|
|
137
137
|
| `refreshToken` | `string` | ✓ | JWT refresh token |
|
|
138
138
|
| `baseUrl` | `string` | | Override API base URL |
|
|
139
|
+
| `ledgerBaseUrl` | `string` | | Go ledger base URL. When set, consent writes and prior-consent checks route through the ledger (falls back: ledger → baseUrl → default). Omit to keep the legacy consent-server path. |
|
|
139
140
|
| `settings` | `Partial<Settings>` | | UI customisation (colours, border radius, fonts) |
|
|
140
141
|
| `language` | `string` | | Initial language code (e.g. `"en"`) |
|
|
141
142
|
| `blockUI` | `boolean` | | Block the modal from being dismissed |
|
|
@@ -173,6 +174,7 @@ import { RedactoNoticeConsentInline } from "@redacto.io/consent-sdk-react-native
|
|
|
173
174
|
| `notice_uuid` | `string` | ✓ | Notice UUID |
|
|
174
175
|
| `accessToken` | `string` | | JWT access token (triggers auto-submit when set) |
|
|
175
176
|
| `baseUrl` | `string` | | Override API base URL |
|
|
177
|
+
| `ledgerBaseUrl` | `string` | | Go ledger base URL. When set, consent writes and already-consented checks route through the ledger. Omit for legacy behavior. |
|
|
176
178
|
| `language` | `string` | | Language code |
|
|
177
179
|
| `settings` | `Partial<Settings>` | | UI customisation |
|
|
178
180
|
| `applicationId` | `string` | | Application-specific UUID |
|
|
@@ -217,6 +219,7 @@ import { RedactoPrivacyCenter } from "@redacto.io/consent-sdk-react-native/priva
|
|
|
217
219
|
| Prop | Type | Required | Default | Description |
|
|
218
220
|
| -------------- | ----------------------------------------------------------------------------- | -------- | -------------------- | ---------------------------------------- |
|
|
219
221
|
| `baseUrl` | `string` | ✓ | - | Consent server base URL |
|
|
222
|
+
| `ledgerBaseUrl` | `string` | | - | Go ledger base URL. When set, user consents, group purposes, receipts, and manage-consent route through the ledger. Omit to use the legacy `/dsar/privacy-center/*` routes. See the note below on the DSAR form picker. |
|
|
220
223
|
| `slug` | `string` | ✓ | - | Workspace slug |
|
|
221
224
|
| `accessToken` | `string` | ✓ | - | JWT access token |
|
|
222
225
|
| `refreshToken` | `string` | ✓ | - | JWT refresh token |
|
|
@@ -274,6 +277,18 @@ For consumers who want fully custom UI, the headless core exposes the API client
|
|
|
274
277
|
- Keep API keys and server secrets on your backend only.
|
|
275
278
|
- In Expo apps, values read from `EXPO_PUBLIC_*` are bundled into the app and should only contain non-sensitive config like UUIDs and URLs.
|
|
276
279
|
- If you do not pass `baseUrl`, the SDK defaults to `https://api.redacto.io/consent` for both notice and Privacy Center surfaces.
|
|
280
|
+
- `ledgerBaseUrl` is optional and independent of `baseUrl` — pass both when routing consent through the Go ledger. Omitting it keeps the legacy consent-server behavior.
|
|
281
|
+
|
|
282
|
+
## Ledger mode
|
|
283
|
+
|
|
284
|
+
Passing `ledgerBaseUrl` routes consent-bearing reads and writes to the Go ledger:
|
|
285
|
+
|
|
286
|
+
- **Notice components** — `submit-consent` goes to the ledger, and the already-consented check uses the ledger's `check-consent` endpoint instead of the legacy HTTP 409 signal. Notice content, tokens, and TTS always stay on `baseUrl`.
|
|
287
|
+
- **Privacy Center** — user consents, group purposes, receipts (including the `/download` PDF path), and manage-consent (sent as a `partial: true` write) route to the ledger. DSAR form, cases, activities, OTP, and notifications stay on `baseUrl`.
|
|
288
|
+
|
|
289
|
+
Every ledger read degrades to the legacy path on failure, so a ledger outage does not break the consent flow.
|
|
290
|
+
|
|
291
|
+
> **Known limitation.** Unlike the React SDK, the DSAR form's product picker is **not** overlaid from ledger-served consents. Against a workspace cut over to the ledger — where the legacy `form/data` response carries no product groups — the picker renders empty. If your DSAR form depends on the product picker, stay on the legacy path until this is addressed.
|
|
277
292
|
|
|
278
293
|
## License
|
|
279
294
|
|
package/dist/index.d.mts
CHANGED
|
@@ -31,6 +31,8 @@ type Props$1 = Readonly<{
|
|
|
31
31
|
accessToken: string;
|
|
32
32
|
refreshToken: string;
|
|
33
33
|
baseUrl?: string;
|
|
34
|
+
/** Go ledger base URL — serves check-consent and the consent write; omit to use the legacy consent server. */
|
|
35
|
+
ledgerBaseUrl?: string;
|
|
34
36
|
settings?: Partial<Settings$1>;
|
|
35
37
|
language?: string;
|
|
36
38
|
blockUI?: boolean;
|
|
@@ -77,6 +79,7 @@ declare const RedactoConsentInline: React__default.NamedExoticComponent<Readonly
|
|
|
77
79
|
accessToken?: string;
|
|
78
80
|
refreshToken?: string;
|
|
79
81
|
baseUrl?: string;
|
|
82
|
+
ledgerBaseUrl?: string;
|
|
80
83
|
settings?: Partial<Settings>;
|
|
81
84
|
language?: string;
|
|
82
85
|
onAccept?: () => void;
|
|
@@ -93,6 +96,8 @@ type Props = Readonly<{
|
|
|
93
96
|
accessToken?: string;
|
|
94
97
|
refreshToken?: string;
|
|
95
98
|
baseUrl?: string;
|
|
99
|
+
/** Go ledger base URL — serves check-consent and the consent write; omit to use the legacy consent server. */
|
|
100
|
+
ledgerBaseUrl?: string;
|
|
96
101
|
settings?: Partial<Settings>;
|
|
97
102
|
language?: string;
|
|
98
103
|
onAccept?: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,8 @@ type Props$1 = Readonly<{
|
|
|
31
31
|
accessToken: string;
|
|
32
32
|
refreshToken: string;
|
|
33
33
|
baseUrl?: string;
|
|
34
|
+
/** Go ledger base URL — serves check-consent and the consent write; omit to use the legacy consent server. */
|
|
35
|
+
ledgerBaseUrl?: string;
|
|
34
36
|
settings?: Partial<Settings$1>;
|
|
35
37
|
language?: string;
|
|
36
38
|
blockUI?: boolean;
|
|
@@ -77,6 +79,7 @@ declare const RedactoConsentInline: React__default.NamedExoticComponent<Readonly
|
|
|
77
79
|
accessToken?: string;
|
|
78
80
|
refreshToken?: string;
|
|
79
81
|
baseUrl?: string;
|
|
82
|
+
ledgerBaseUrl?: string;
|
|
80
83
|
settings?: Partial<Settings>;
|
|
81
84
|
language?: string;
|
|
82
85
|
onAccept?: () => void;
|
|
@@ -93,6 +96,8 @@ type Props = Readonly<{
|
|
|
93
96
|
accessToken?: string;
|
|
94
97
|
refreshToken?: string;
|
|
95
98
|
baseUrl?: string;
|
|
99
|
+
/** Go ledger base URL — serves check-consent and the consent write; omit to use the legacy consent server. */
|
|
100
|
+
ledgerBaseUrl?: string;
|
|
96
101
|
settings?: Partial<Settings>;
|
|
97
102
|
language?: string;
|
|
98
103
|
onAccept?: () => void;
|
package/dist/index.js
CHANGED
|
@@ -147,6 +147,7 @@ var fetchConsentContent = async ({
|
|
|
147
147
|
var submitConsentEvent = async ({
|
|
148
148
|
accessToken,
|
|
149
149
|
baseUrl,
|
|
150
|
+
ledgerBaseUrl,
|
|
150
151
|
noticeUuid,
|
|
151
152
|
purposes,
|
|
152
153
|
declined,
|
|
@@ -166,7 +167,7 @@ var submitConsentEvent = async ({
|
|
|
166
167
|
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
167
168
|
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
168
169
|
}
|
|
169
|
-
const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
170
|
+
const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
170
171
|
const validatedPurposes = purposes.map((purpose) => {
|
|
171
172
|
if (!purpose.uuid) {
|
|
172
173
|
throw new Error("Invalid purpose data: missing uuid");
|
|
@@ -415,6 +416,122 @@ var verifyGuardianStatus = async ({
|
|
|
415
416
|
};
|
|
416
417
|
};
|
|
417
418
|
|
|
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
|
+
|
|
418
535
|
// src/RedactoNoticeConsent/components/Checkbox.tsx
|
|
419
536
|
var import_react_native = require("react-native");
|
|
420
537
|
var import_react_native_svg = __toESM(require("react-native-svg"));
|
|
@@ -1638,6 +1755,7 @@ var RedactoNoticeConsent = ({
|
|
|
1638
1755
|
accessToken,
|
|
1639
1756
|
refreshToken: _refreshToken,
|
|
1640
1757
|
baseUrl,
|
|
1758
|
+
ledgerBaseUrl,
|
|
1641
1759
|
settings,
|
|
1642
1760
|
language = "en",
|
|
1643
1761
|
blockUI = false,
|
|
@@ -1697,6 +1815,7 @@ var RedactoNoticeConsent = ({
|
|
|
1697
1815
|
const abortControllerRef = (0, import_react2.useRef)(null);
|
|
1698
1816
|
const hasBootstrappedLanguageRef = (0, import_react2.useRef)(false);
|
|
1699
1817
|
const fetchContent = (0, import_react2.useCallback)(async () => {
|
|
1818
|
+
var _a2, _b2;
|
|
1700
1819
|
if (abortControllerRef.current) {
|
|
1701
1820
|
abortControllerRef.current.abort();
|
|
1702
1821
|
}
|
|
@@ -1715,8 +1834,23 @@ var RedactoNoticeConsent = ({
|
|
|
1715
1834
|
signal: abortControllerRef.current.signal
|
|
1716
1835
|
});
|
|
1717
1836
|
const activeConfig2 = data.detail.active_config;
|
|
1718
|
-
|
|
1719
|
-
|
|
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
|
+
}
|
|
1720
1854
|
const noticeIsMinor = data.detail.is_minor || false;
|
|
1721
1855
|
setIsMinor(noticeIsMinor);
|
|
1722
1856
|
const initialCollapsed = {};
|
|
@@ -1729,9 +1863,9 @@ var RedactoNoticeConsent = ({
|
|
|
1729
1863
|
const purposeSelected = sel ? sel.selected : false;
|
|
1730
1864
|
initialPurposeState[purpose.uuid] = purposeSelected;
|
|
1731
1865
|
purpose.data_elements.forEach((el) => {
|
|
1732
|
-
var
|
|
1866
|
+
var _a3, _b3, _c2;
|
|
1733
1867
|
const combinedId = `${purpose.uuid}-${el.uuid}`;
|
|
1734
|
-
const elementSel = (_c2 = (
|
|
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;
|
|
1735
1869
|
initialDataElementState[combinedId] = elementSel;
|
|
1736
1870
|
initialDataElementSelectionsMap[combinedId] = elementSel;
|
|
1737
1871
|
});
|
|
@@ -1779,7 +1913,7 @@ var RedactoNoticeConsent = ({
|
|
|
1779
1913
|
} finally {
|
|
1780
1914
|
setIsLoading(false);
|
|
1781
1915
|
}
|
|
1782
|
-
}, [noticeId, accessToken, baseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
|
|
1916
|
+
}, [noticeId, accessToken, baseUrl, ledgerBaseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
|
|
1783
1917
|
(0, import_react2.useEffect)(() => {
|
|
1784
1918
|
hasBootstrappedLanguageRef.current = false;
|
|
1785
1919
|
}, [noticeId, accessToken]);
|
|
@@ -2182,6 +2316,7 @@ var RedactoNoticeConsent = ({
|
|
|
2182
2316
|
await submitConsentEvent({
|
|
2183
2317
|
accessToken,
|
|
2184
2318
|
baseUrl,
|
|
2319
|
+
ledgerBaseUrl,
|
|
2185
2320
|
noticeUuid: activeConfig2.notice_uuid,
|
|
2186
2321
|
purposes: activeConfig2.purposes.map((purpose) => ({
|
|
2187
2322
|
...purpose,
|
|
@@ -2209,7 +2344,7 @@ var RedactoNoticeConsent = ({
|
|
|
2209
2344
|
} finally {
|
|
2210
2345
|
setIsSubmitting(false);
|
|
2211
2346
|
}
|
|
2212
|
-
}, [content, accessToken, baseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
|
|
2347
|
+
}, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
|
|
2213
2348
|
const handleDecline = (0, import_react2.useCallback)(() => {
|
|
2214
2349
|
stopAudio();
|
|
2215
2350
|
stopPolling();
|
|
@@ -2857,13 +2992,14 @@ var submitConsentEvent2 = async ({
|
|
|
2857
2992
|
workspace_uuid,
|
|
2858
2993
|
accessToken,
|
|
2859
2994
|
baseUrl,
|
|
2995
|
+
ledgerBaseUrl,
|
|
2860
2996
|
noticeUuid,
|
|
2861
2997
|
purposes,
|
|
2862
2998
|
declined,
|
|
2863
2999
|
meta_data
|
|
2864
3000
|
}) => {
|
|
2865
3001
|
var _a, _b;
|
|
2866
|
-
const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
3002
|
+
const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
2867
3003
|
const payload = {
|
|
2868
3004
|
notice_uuid: noticeUuid,
|
|
2869
3005
|
purposes: purposes.map((purpose) => {
|
|
@@ -3185,6 +3321,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3185
3321
|
notice_uuid,
|
|
3186
3322
|
accessToken,
|
|
3187
3323
|
baseUrl,
|
|
3324
|
+
ledgerBaseUrl,
|
|
3188
3325
|
language = "en",
|
|
3189
3326
|
onAccept,
|
|
3190
3327
|
onDecline: _onDecline,
|
|
@@ -3203,6 +3340,9 @@ var RedactoConsentInlineComponent = ({
|
|
|
3203
3340
|
const [selectedPurposes, setSelectedPurposes] = (0, import_react3.useState)({});
|
|
3204
3341
|
const [selectedDataElements, setSelectedDataElements] = (0, import_react3.useState)({});
|
|
3205
3342
|
const [hasAlreadyConsented, setHasAlreadyConsented] = (0, import_react3.useState)(false);
|
|
3343
|
+
const [isCheckingConsent, setIsCheckingConsent] = (0, import_react3.useState)(
|
|
3344
|
+
Boolean(ledgerBaseUrl) && !applicationId
|
|
3345
|
+
);
|
|
3206
3346
|
const [fetchError, setFetchError] = (0, import_react3.useState)(null);
|
|
3207
3347
|
const [errorMessage, setErrorMessage] = (0, import_react3.useState)(null);
|
|
3208
3348
|
const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = (0, import_react3.useState)(false);
|
|
@@ -3323,6 +3463,40 @@ var RedactoConsentInlineComponent = ({
|
|
|
3323
3463
|
controller.abort();
|
|
3324
3464
|
};
|
|
3325
3465
|
}, [fetchNotice]);
|
|
3466
|
+
(0, import_react3.useEffect)(() => {
|
|
3467
|
+
if (!ledgerBaseUrl || applicationId) {
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
if (!accessToken || !content) {
|
|
3471
|
+
return;
|
|
3472
|
+
}
|
|
3473
|
+
let active = true;
|
|
3474
|
+
const controller = new AbortController();
|
|
3475
|
+
const checkLedgerConsent = async () => {
|
|
3476
|
+
try {
|
|
3477
|
+
const ledgerStatus = await fetchNoticeConsentStatusForScope({
|
|
3478
|
+
accessToken,
|
|
3479
|
+
ledgerBaseUrl,
|
|
3480
|
+
organisationUuid: org_uuid,
|
|
3481
|
+
workspaceUuid: workspace_uuid,
|
|
3482
|
+
noticeUuid: notice_uuid,
|
|
3483
|
+
signal: controller.signal
|
|
3484
|
+
});
|
|
3485
|
+
if (active && ledgerStatus && isNoticeFullyConsented(ledgerStatus)) {
|
|
3486
|
+
setHasAlreadyConsented(true);
|
|
3487
|
+
}
|
|
3488
|
+
} finally {
|
|
3489
|
+
if (active) {
|
|
3490
|
+
setIsCheckingConsent(false);
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
};
|
|
3494
|
+
void checkLedgerConsent();
|
|
3495
|
+
return () => {
|
|
3496
|
+
active = false;
|
|
3497
|
+
controller.abort();
|
|
3498
|
+
};
|
|
3499
|
+
}, [ledgerBaseUrl, applicationId, accessToken, content, org_uuid, workspace_uuid, notice_uuid]);
|
|
3326
3500
|
const togglePurposeCollapse = (0, import_react3.useCallback)((purposeUuid) => {
|
|
3327
3501
|
setCollapsedPurposes((prev) => ({ ...prev, [purposeUuid]: !prev[purposeUuid] }));
|
|
3328
3502
|
}, []);
|
|
@@ -3373,6 +3547,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3373
3547
|
workspace_uuid,
|
|
3374
3548
|
accessToken: tokenToUse,
|
|
3375
3549
|
baseUrl,
|
|
3550
|
+
ledgerBaseUrl,
|
|
3376
3551
|
noticeUuid: content.notice_uuid,
|
|
3377
3552
|
purposes: content.purposes.map((purpose) => {
|
|
3378
3553
|
const hasSelectedRequiredElement = purpose.data_elements.some(
|
|
@@ -3411,6 +3586,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3411
3586
|
org_uuid,
|
|
3412
3587
|
workspace_uuid,
|
|
3413
3588
|
baseUrl,
|
|
3589
|
+
ledgerBaseUrl,
|
|
3414
3590
|
selectedDataElements,
|
|
3415
3591
|
selectedPurposes,
|
|
3416
3592
|
applicationId,
|
|
@@ -3418,7 +3594,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3418
3594
|
]
|
|
3419
3595
|
);
|
|
3420
3596
|
(0, import_react3.useEffect)(() => {
|
|
3421
|
-
if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !hasSubmittedRef.current) {
|
|
3597
|
+
if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !isCheckingConsent && !hasAlreadyConsented && !hasSubmittedRef.current) {
|
|
3422
3598
|
hasSubmittedRef.current = true;
|
|
3423
3599
|
const autoSubmit = async () => {
|
|
3424
3600
|
try {
|
|
@@ -3430,7 +3606,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3430
3606
|
};
|
|
3431
3607
|
autoSubmit();
|
|
3432
3608
|
}
|
|
3433
|
-
}, [accessToken, content, areAllRequiredElementsChecked, isSubmitting, handleAcceptWithToken, onError]);
|
|
3609
|
+
}, [accessToken, content, areAllRequiredElementsChecked, isSubmitting, isCheckingConsent, hasAlreadyConsented, handleAcceptWithToken, onError]);
|
|
3434
3610
|
(0, import_react3.useEffect)(() => {
|
|
3435
3611
|
if (!accessToken) {
|
|
3436
3612
|
hasSubmittedRef.current = false;
|