@redacto.io/consent-sdk-react-native 4.0.0 → 5.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +186 -10
- package/dist/index.mjs +186 -10
- package/dist/privacy-center.d.mts +148 -117
- package/dist/privacy-center.d.ts +148 -117
- package/dist/privacy-center.js +149 -482
- package/dist/privacy-center.mjs +149 -482
- package/package.json +5 -3
package/dist/index.mjs
CHANGED
|
@@ -131,6 +131,7 @@ var fetchConsentContent = async ({
|
|
|
131
131
|
var submitConsentEvent = async ({
|
|
132
132
|
accessToken,
|
|
133
133
|
baseUrl,
|
|
134
|
+
ledgerBaseUrl,
|
|
134
135
|
noticeUuid,
|
|
135
136
|
purposes,
|
|
136
137
|
declined,
|
|
@@ -150,7 +151,7 @@ var submitConsentEvent = async ({
|
|
|
150
151
|
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
151
152
|
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
152
153
|
}
|
|
153
|
-
const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
154
|
+
const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
154
155
|
const validatedPurposes = purposes.map((purpose) => {
|
|
155
156
|
if (!purpose.uuid) {
|
|
156
157
|
throw new Error("Invalid purpose data: missing uuid");
|
|
@@ -399,6 +400,122 @@ var verifyGuardianStatus = async ({
|
|
|
399
400
|
};
|
|
400
401
|
};
|
|
401
402
|
|
|
403
|
+
// src/shared/notice-consent-status.ts
|
|
404
|
+
import { jwtDecode as jwtDecode2 } from "jwt-decode";
|
|
405
|
+
var decodeNoticeConsentToken = (token) => {
|
|
406
|
+
try {
|
|
407
|
+
return jwtDecode2(token);
|
|
408
|
+
} catch {
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
var fetchNoticeConsentStatusForScope = async ({
|
|
413
|
+
accessToken,
|
|
414
|
+
ledgerBaseUrl,
|
|
415
|
+
organisationUuid,
|
|
416
|
+
workspaceUuid,
|
|
417
|
+
noticeUuid,
|
|
418
|
+
signal
|
|
419
|
+
}) => {
|
|
420
|
+
if (!accessToken || !ledgerBaseUrl || !organisationUuid || !workspaceUuid || !noticeUuid) {
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
try {
|
|
424
|
+
const response = await fetch(
|
|
425
|
+
`${ledgerBaseUrl}/public/organisations/${organisationUuid}/workspaces/${workspaceUuid}/notices/${noticeUuid}/check-consent`,
|
|
426
|
+
{
|
|
427
|
+
method: "POST",
|
|
428
|
+
headers: {
|
|
429
|
+
Authorization: `Bearer ${accessToken}`,
|
|
430
|
+
"Content-Type": "application/json"
|
|
431
|
+
},
|
|
432
|
+
body: "{}",
|
|
433
|
+
signal
|
|
434
|
+
}
|
|
435
|
+
);
|
|
436
|
+
if (!response.ok) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
const data = await response.json();
|
|
440
|
+
const body = data && typeof data === "object" && "detail" in data && data.detail ? data.detail : data;
|
|
441
|
+
if (!body || !Array.isArray(body.purposes)) {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
444
|
+
return body;
|
|
445
|
+
} catch {
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
var fetchNoticeConsentStatus = async ({
|
|
450
|
+
accessToken,
|
|
451
|
+
ledgerBaseUrl,
|
|
452
|
+
noticeUuid,
|
|
453
|
+
signal
|
|
454
|
+
}) => {
|
|
455
|
+
if (!accessToken || !ledgerBaseUrl || !noticeUuid) {
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
const decodedToken = decodeNoticeConsentToken(accessToken);
|
|
459
|
+
if (!decodedToken) {
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
const {
|
|
463
|
+
organisation_uuid: ORGANISATION_UUID,
|
|
464
|
+
workspace_uuid: WORKSPACE_UUID
|
|
465
|
+
} = decodedToken;
|
|
466
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
return fetchNoticeConsentStatusForScope({
|
|
470
|
+
accessToken,
|
|
471
|
+
ledgerBaseUrl,
|
|
472
|
+
organisationUuid: ORGANISATION_UUID,
|
|
473
|
+
workspaceUuid: WORKSPACE_UUID,
|
|
474
|
+
noticeUuid,
|
|
475
|
+
signal
|
|
476
|
+
});
|
|
477
|
+
};
|
|
478
|
+
var isNoticeFullyConsented = (status) => status.consented && status.all_mandatory_active;
|
|
479
|
+
var buildLedgerConsentOverlay = (status, configPurposes) => {
|
|
480
|
+
var _a, _b;
|
|
481
|
+
const byUuid = new Map(status.purposes.map((p) => [p.uuid, p]));
|
|
482
|
+
const hasHistory = status.purposes.some(
|
|
483
|
+
(p) => (p.status || "INACTIVE") !== "INACTIVE"
|
|
484
|
+
);
|
|
485
|
+
if (!hasHistory) {
|
|
486
|
+
return null;
|
|
487
|
+
}
|
|
488
|
+
const purpose_selections = {};
|
|
489
|
+
for (const cp of configPurposes) {
|
|
490
|
+
const lp = byUuid.get(cp.uuid);
|
|
491
|
+
const purposeStatus = (lp == null ? void 0 : lp.status) || "INACTIVE";
|
|
492
|
+
const selectedByUuid = new Map(
|
|
493
|
+
((lp == null ? void 0 : lp.data_elements) || []).map((de) => [de.uuid, de.selected])
|
|
494
|
+
);
|
|
495
|
+
const data_elements = {};
|
|
496
|
+
for (const de of cp.data_elements) {
|
|
497
|
+
data_elements[de.uuid] = {
|
|
498
|
+
selected: (_a = selectedByUuid.get(de.uuid)) != null ? _a : false,
|
|
499
|
+
enabled: de.enabled,
|
|
500
|
+
required: de.required
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
purpose_selections[cp.uuid] = {
|
|
504
|
+
selected: (_b = lp == null ? void 0 : lp.selected) != null ? _b : false,
|
|
505
|
+
status: purposeStatus,
|
|
506
|
+
needs_reconsent: purposeStatus !== "ACTIVE",
|
|
507
|
+
data_elements
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
const reconsent_required = configPurposes.some(
|
|
511
|
+
(cp) => {
|
|
512
|
+
var _a2;
|
|
513
|
+
return (((_a2 = purpose_selections[cp.uuid]) == null ? void 0 : _a2.status) || "INACTIVE") !== "ACTIVE";
|
|
514
|
+
}
|
|
515
|
+
);
|
|
516
|
+
return { reconsent_required, purpose_selections };
|
|
517
|
+
};
|
|
518
|
+
|
|
402
519
|
// src/RedactoNoticeConsent/components/Checkbox.tsx
|
|
403
520
|
import { TouchableOpacity, View, StyleSheet } from "react-native";
|
|
404
521
|
import Svg, { Path } from "react-native-svg";
|
|
@@ -1629,6 +1746,7 @@ var RedactoNoticeConsent = ({
|
|
|
1629
1746
|
accessToken,
|
|
1630
1747
|
refreshToken: _refreshToken,
|
|
1631
1748
|
baseUrl,
|
|
1749
|
+
ledgerBaseUrl,
|
|
1632
1750
|
settings,
|
|
1633
1751
|
language = "en",
|
|
1634
1752
|
blockUI = false,
|
|
@@ -1688,6 +1806,7 @@ var RedactoNoticeConsent = ({
|
|
|
1688
1806
|
const abortControllerRef = useRef2(null);
|
|
1689
1807
|
const hasBootstrappedLanguageRef = useRef2(false);
|
|
1690
1808
|
const fetchContent = useCallback(async () => {
|
|
1809
|
+
var _a2, _b2;
|
|
1691
1810
|
if (abortControllerRef.current) {
|
|
1692
1811
|
abortControllerRef.current.abort();
|
|
1693
1812
|
}
|
|
@@ -1706,8 +1825,23 @@ var RedactoNoticeConsent = ({
|
|
|
1706
1825
|
signal: abortControllerRef.current.signal
|
|
1707
1826
|
});
|
|
1708
1827
|
const activeConfig2 = data.detail.active_config;
|
|
1709
|
-
|
|
1710
|
-
|
|
1828
|
+
let purposeSelections = data.detail.purpose_selections;
|
|
1829
|
+
let reconsentRequired = data.detail.reconsent_required || false;
|
|
1830
|
+
if (ledgerBaseUrl && !applicationId) {
|
|
1831
|
+
const ledgerStatus = await fetchNoticeConsentStatus({
|
|
1832
|
+
accessToken,
|
|
1833
|
+
ledgerBaseUrl,
|
|
1834
|
+
noticeUuid: noticeId,
|
|
1835
|
+
signal: (_a2 = abortControllerRef.current) == null ? void 0 : _a2.signal
|
|
1836
|
+
});
|
|
1837
|
+
if (ledgerStatus) {
|
|
1838
|
+
const overlay = buildLedgerConsentOverlay(ledgerStatus, activeConfig2.purposes);
|
|
1839
|
+
reconsentRequired = (_b2 = overlay == null ? void 0 : overlay.reconsent_required) != null ? _b2 : false;
|
|
1840
|
+
purposeSelections = overlay == null ? void 0 : overlay.purpose_selections;
|
|
1841
|
+
data.detail.purpose_selections = purposeSelections;
|
|
1842
|
+
data.detail.reconsent_required = reconsentRequired;
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1711
1845
|
const noticeIsMinor = data.detail.is_minor || false;
|
|
1712
1846
|
setIsMinor(noticeIsMinor);
|
|
1713
1847
|
const initialCollapsed = {};
|
|
@@ -1720,9 +1854,9 @@ var RedactoNoticeConsent = ({
|
|
|
1720
1854
|
const purposeSelected = sel ? sel.selected : false;
|
|
1721
1855
|
initialPurposeState[purpose.uuid] = purposeSelected;
|
|
1722
1856
|
purpose.data_elements.forEach((el) => {
|
|
1723
|
-
var
|
|
1857
|
+
var _a3, _b3, _c2;
|
|
1724
1858
|
const combinedId = `${purpose.uuid}-${el.uuid}`;
|
|
1725
|
-
const elementSel = (_c2 = (
|
|
1859
|
+
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;
|
|
1726
1860
|
initialDataElementState[combinedId] = elementSel;
|
|
1727
1861
|
initialDataElementSelectionsMap[combinedId] = elementSel;
|
|
1728
1862
|
});
|
|
@@ -1770,7 +1904,7 @@ var RedactoNoticeConsent = ({
|
|
|
1770
1904
|
} finally {
|
|
1771
1905
|
setIsLoading(false);
|
|
1772
1906
|
}
|
|
1773
|
-
}, [noticeId, accessToken, baseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
|
|
1907
|
+
}, [noticeId, accessToken, baseUrl, ledgerBaseUrl, validateAgainst, includeFullyConsentedData, applicationId, onAccept, onError]);
|
|
1774
1908
|
useEffect2(() => {
|
|
1775
1909
|
hasBootstrappedLanguageRef.current = false;
|
|
1776
1910
|
}, [noticeId, accessToken]);
|
|
@@ -2173,6 +2307,7 @@ var RedactoNoticeConsent = ({
|
|
|
2173
2307
|
await submitConsentEvent({
|
|
2174
2308
|
accessToken,
|
|
2175
2309
|
baseUrl,
|
|
2310
|
+
ledgerBaseUrl,
|
|
2176
2311
|
noticeUuid: activeConfig2.notice_uuid,
|
|
2177
2312
|
purposes: activeConfig2.purposes.map((purpose) => ({
|
|
2178
2313
|
...purpose,
|
|
@@ -2200,7 +2335,7 @@ var RedactoNoticeConsent = ({
|
|
|
2200
2335
|
} finally {
|
|
2201
2336
|
setIsSubmitting(false);
|
|
2202
2337
|
}
|
|
2203
|
-
}, [content, accessToken, baseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
|
|
2338
|
+
}, [content, accessToken, baseUrl, ledgerBaseUrl, applicationId, selectedPurposes, selectedDataElements, stopAudio, onAccept, onError]);
|
|
2204
2339
|
const handleDecline = useCallback(() => {
|
|
2205
2340
|
stopAudio();
|
|
2206
2341
|
stopPolling();
|
|
@@ -2861,13 +2996,14 @@ var submitConsentEvent2 = async ({
|
|
|
2861
2996
|
workspace_uuid,
|
|
2862
2997
|
accessToken,
|
|
2863
2998
|
baseUrl,
|
|
2999
|
+
ledgerBaseUrl,
|
|
2864
3000
|
noticeUuid,
|
|
2865
3001
|
purposes,
|
|
2866
3002
|
declined,
|
|
2867
3003
|
meta_data
|
|
2868
3004
|
}) => {
|
|
2869
3005
|
var _a, _b;
|
|
2870
|
-
const apiBaseUrl = baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
3006
|
+
const apiBaseUrl = ledgerBaseUrl || baseUrl || DEFAULT_CONSENT_API_BASE_URL;
|
|
2871
3007
|
const payload = {
|
|
2872
3008
|
notice_uuid: noticeUuid,
|
|
2873
3009
|
purposes: purposes.map((purpose) => {
|
|
@@ -3189,6 +3325,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3189
3325
|
notice_uuid,
|
|
3190
3326
|
accessToken,
|
|
3191
3327
|
baseUrl,
|
|
3328
|
+
ledgerBaseUrl,
|
|
3192
3329
|
language = "en",
|
|
3193
3330
|
onAccept,
|
|
3194
3331
|
onDecline: _onDecline,
|
|
@@ -3207,6 +3344,9 @@ var RedactoConsentInlineComponent = ({
|
|
|
3207
3344
|
const [selectedPurposes, setSelectedPurposes] = useState2({});
|
|
3208
3345
|
const [selectedDataElements, setSelectedDataElements] = useState2({});
|
|
3209
3346
|
const [hasAlreadyConsented, setHasAlreadyConsented] = useState2(false);
|
|
3347
|
+
const [isCheckingConsent, setIsCheckingConsent] = useState2(
|
|
3348
|
+
Boolean(ledgerBaseUrl) && !applicationId
|
|
3349
|
+
);
|
|
3210
3350
|
const [fetchError, setFetchError] = useState2(null);
|
|
3211
3351
|
const [errorMessage, setErrorMessage] = useState2(null);
|
|
3212
3352
|
const [isLanguageDropdownOpen, setIsLanguageDropdownOpen] = useState2(false);
|
|
@@ -3327,6 +3467,40 @@ var RedactoConsentInlineComponent = ({
|
|
|
3327
3467
|
controller.abort();
|
|
3328
3468
|
};
|
|
3329
3469
|
}, [fetchNotice]);
|
|
3470
|
+
useEffect3(() => {
|
|
3471
|
+
if (!ledgerBaseUrl || applicationId) {
|
|
3472
|
+
return;
|
|
3473
|
+
}
|
|
3474
|
+
if (!accessToken || !content) {
|
|
3475
|
+
return;
|
|
3476
|
+
}
|
|
3477
|
+
let active = true;
|
|
3478
|
+
const controller = new AbortController();
|
|
3479
|
+
const checkLedgerConsent = async () => {
|
|
3480
|
+
try {
|
|
3481
|
+
const ledgerStatus = await fetchNoticeConsentStatusForScope({
|
|
3482
|
+
accessToken,
|
|
3483
|
+
ledgerBaseUrl,
|
|
3484
|
+
organisationUuid: org_uuid,
|
|
3485
|
+
workspaceUuid: workspace_uuid,
|
|
3486
|
+
noticeUuid: notice_uuid,
|
|
3487
|
+
signal: controller.signal
|
|
3488
|
+
});
|
|
3489
|
+
if (active && ledgerStatus && isNoticeFullyConsented(ledgerStatus)) {
|
|
3490
|
+
setHasAlreadyConsented(true);
|
|
3491
|
+
}
|
|
3492
|
+
} finally {
|
|
3493
|
+
if (active) {
|
|
3494
|
+
setIsCheckingConsent(false);
|
|
3495
|
+
}
|
|
3496
|
+
}
|
|
3497
|
+
};
|
|
3498
|
+
void checkLedgerConsent();
|
|
3499
|
+
return () => {
|
|
3500
|
+
active = false;
|
|
3501
|
+
controller.abort();
|
|
3502
|
+
};
|
|
3503
|
+
}, [ledgerBaseUrl, applicationId, accessToken, content, org_uuid, workspace_uuid, notice_uuid]);
|
|
3330
3504
|
const togglePurposeCollapse = useCallback2((purposeUuid) => {
|
|
3331
3505
|
setCollapsedPurposes((prev) => ({ ...prev, [purposeUuid]: !prev[purposeUuid] }));
|
|
3332
3506
|
}, []);
|
|
@@ -3377,6 +3551,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3377
3551
|
workspace_uuid,
|
|
3378
3552
|
accessToken: tokenToUse,
|
|
3379
3553
|
baseUrl,
|
|
3554
|
+
ledgerBaseUrl,
|
|
3380
3555
|
noticeUuid: content.notice_uuid,
|
|
3381
3556
|
purposes: content.purposes.map((purpose) => {
|
|
3382
3557
|
const hasSelectedRequiredElement = purpose.data_elements.some(
|
|
@@ -3415,6 +3590,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3415
3590
|
org_uuid,
|
|
3416
3591
|
workspace_uuid,
|
|
3417
3592
|
baseUrl,
|
|
3593
|
+
ledgerBaseUrl,
|
|
3418
3594
|
selectedDataElements,
|
|
3419
3595
|
selectedPurposes,
|
|
3420
3596
|
applicationId,
|
|
@@ -3422,7 +3598,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3422
3598
|
]
|
|
3423
3599
|
);
|
|
3424
3600
|
useEffect3(() => {
|
|
3425
|
-
if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !hasSubmittedRef.current) {
|
|
3601
|
+
if (accessToken && content && areAllRequiredElementsChecked && !isSubmitting && !isCheckingConsent && !hasAlreadyConsented && !hasSubmittedRef.current) {
|
|
3426
3602
|
hasSubmittedRef.current = true;
|
|
3427
3603
|
const autoSubmit = async () => {
|
|
3428
3604
|
try {
|
|
@@ -3434,7 +3610,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
3434
3610
|
};
|
|
3435
3611
|
autoSubmit();
|
|
3436
3612
|
}
|
|
3437
|
-
}, [accessToken, content, areAllRequiredElementsChecked, isSubmitting, handleAcceptWithToken, onError]);
|
|
3613
|
+
}, [accessToken, content, areAllRequiredElementsChecked, isSubmitting, isCheckingConsent, hasAlreadyConsented, handleAcceptWithToken, onError]);
|
|
3438
3614
|
useEffect3(() => {
|
|
3439
3615
|
if (!accessToken) {
|
|
3440
3616
|
hasSubmittedRef.current = false;
|