@redacto.io/consent-sdk-react 5.2.0 → 5.3.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/CHANGELOG.md +6 -0
- package/dist/index.d.mts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +149 -206
- package/dist/index.mjs +148 -206
- package/dist/privacy-center.d.mts +81 -2
- package/dist/privacy-center.d.ts +81 -2
- package/dist/privacy-center.js +2823 -1272
- package/dist/privacy-center.mjs +2813 -1263
- package/package.json +1 -1
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +16 -20
- package/src/RedactoNoticeConsent/api/index.ts +21 -103
- package/src/RedactoNoticeConsentInline/RedactoNoticeConsentInline.tsx +5 -4
- package/src/RedactoNoticeConsentInline/api/index.ts +64 -117
- package/src/RedactoPrivacyCenter/NotificationsPage.tsx +174 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +3 -0
- package/src/RedactoPrivacyCenter/api/actions.ts +84 -0
- package/src/RedactoPrivacyCenter/api/client.ts +118 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/PurposeSelectionSection.tsx +15 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationBell.tsx +160 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationCTAButton.tsx +18 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationDropdown.tsx +54 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationDropdownItem.tsx +57 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationIcon.tsx +19 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationListPanel.tsx +92 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationRefreshButton.tsx +20 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/NotificationRow.tsx +58 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/StatCard.tsx +10 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/useNotificationActions.ts +112 -0
- package/src/RedactoPrivacyCenter/components/NotificationHub/utils.ts +27 -0
- package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +3 -2
- package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +2 -2
- package/src/RedactoPrivacyCenter/lib/api.ts +77 -0
- package/src/RedactoPrivacyCenter/lib/constants.ts +78 -1
- package/src/RedactoPrivacyCenter/lib/types.ts +148 -0
- package/src/RedactoPrivacyCenter/lib/utils.ts +3 -0
- package/src/RedactoPrivacyCenter/locales/en/translation.json +27 -1
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +505 -0
- package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +23 -1
- package/src/index.ts +5 -0
- package/src/privacy-center.ts +1 -0
- package/src/shared/api-errors.ts +171 -0
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,64 @@ import { useCallback, useEffect as useEffect2, useMemo, useRef, useState as useS
|
|
|
3
3
|
|
|
4
4
|
// src/RedactoNoticeConsent/api/index.ts
|
|
5
5
|
import { jwtDecode } from "jwt-decode";
|
|
6
|
+
|
|
7
|
+
// src/shared/api-errors.ts
|
|
8
|
+
var ApiError = class extends Error {
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
super(opts.message);
|
|
11
|
+
this.name = "ApiError";
|
|
12
|
+
this.status = opts.status;
|
|
13
|
+
this.code = opts.code;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function statusFallback(status) {
|
|
17
|
+
if (status === 401) {
|
|
18
|
+
return "Your session has expired. Please request a new access link.";
|
|
19
|
+
}
|
|
20
|
+
if (status === 403) {
|
|
21
|
+
return "You do not have access to this resource.";
|
|
22
|
+
}
|
|
23
|
+
if (status >= 500) {
|
|
24
|
+
return "Something went wrong on our end. Please try again later.";
|
|
25
|
+
}
|
|
26
|
+
return void 0;
|
|
27
|
+
}
|
|
28
|
+
function extractFromDetail(detail) {
|
|
29
|
+
var _a;
|
|
30
|
+
if (typeof detail === "string") {
|
|
31
|
+
return { message: detail };
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(detail)) {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
if (detail && typeof detail === "object") {
|
|
37
|
+
const obj = detail;
|
|
38
|
+
return { message: (_a = obj.message) != null ? _a : obj.detail, code: obj.error_code };
|
|
39
|
+
}
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
async function parseApiError(response, fallbackMessage) {
|
|
43
|
+
var _a, _b, _c, _d;
|
|
44
|
+
let body;
|
|
45
|
+
let parsedBody = false;
|
|
46
|
+
try {
|
|
47
|
+
body = await response.json();
|
|
48
|
+
parsedBody = true;
|
|
49
|
+
} catch {
|
|
50
|
+
body = void 0;
|
|
51
|
+
}
|
|
52
|
+
const fromDetail = extractFromDetail(body == null ? void 0 : body.detail);
|
|
53
|
+
const serverMessage = (_a = body == null ? void 0 : body.message) != null ? _a : fromDetail.message;
|
|
54
|
+
const message = (_b = serverMessage != null ? serverMessage : parsedBody ? statusFallback(response.status) : void 0) != null ? _b : fallbackMessage;
|
|
55
|
+
const code = (_d = (_c = body == null ? void 0 : body.error_code) != null ? _c : fromDetail.code) != null ? _d : void 0;
|
|
56
|
+
return new ApiError({
|
|
57
|
+
status: response.status,
|
|
58
|
+
code,
|
|
59
|
+
message
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/RedactoNoticeConsent/api/index.ts
|
|
6
64
|
var BASE_URL = "https://api.redacto.io/consent";
|
|
7
65
|
var apiCache = /* @__PURE__ */ new Map();
|
|
8
66
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
@@ -78,21 +136,10 @@ var fetchConsentContent = async ({
|
|
|
78
136
|
signal
|
|
79
137
|
});
|
|
80
138
|
if (!response.ok) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
errorMessage = "Forbidden: Access denied";
|
|
86
|
-
} else if (response.status === 404) {
|
|
87
|
-
errorMessage = "Notice not found";
|
|
88
|
-
} else if (response.status === 409) {
|
|
89
|
-
errorMessage = "User has already provided consent";
|
|
90
|
-
} else if (response.status >= 500) {
|
|
91
|
-
errorMessage = "Server error: Please try again later";
|
|
92
|
-
}
|
|
93
|
-
const error = new Error(errorMessage);
|
|
94
|
-
error.status = response.status;
|
|
95
|
-
throw error;
|
|
139
|
+
throw await parseApiError(
|
|
140
|
+
response,
|
|
141
|
+
"Could not load the consent notice. Please try again."
|
|
142
|
+
);
|
|
96
143
|
}
|
|
97
144
|
const data = await response.json();
|
|
98
145
|
if (validate_against === "all" && !specific_uuid) {
|
|
@@ -162,26 +209,10 @@ var submitConsentEvent = async ({
|
|
|
162
209
|
}
|
|
163
210
|
);
|
|
164
211
|
if (!response.ok) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
try
|
|
168
|
-
|
|
169
|
-
errorMessage = errorData.message || "Invalid request data";
|
|
170
|
-
} catch {
|
|
171
|
-
errorMessage = "Invalid request data";
|
|
172
|
-
}
|
|
173
|
-
} else if (response.status === 401) {
|
|
174
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
175
|
-
} else if (response.status === 403) {
|
|
176
|
-
errorMessage = "Forbidden: Access denied";
|
|
177
|
-
} else if (response.status === 404) {
|
|
178
|
-
errorMessage = "Notice not found";
|
|
179
|
-
} else if (response.status >= 500) {
|
|
180
|
-
errorMessage = "Server error: Please try again later";
|
|
181
|
-
}
|
|
182
|
-
const error = new Error(errorMessage);
|
|
183
|
-
error.status = response.status;
|
|
184
|
-
throw error;
|
|
212
|
+
throw await parseApiError(
|
|
213
|
+
response,
|
|
214
|
+
"Could not submit your consent. Please try again."
|
|
215
|
+
);
|
|
185
216
|
}
|
|
186
217
|
apiCache.clear();
|
|
187
218
|
};
|
|
@@ -214,19 +245,10 @@ var fetchTTSAudioUrls = async ({
|
|
|
214
245
|
signal
|
|
215
246
|
});
|
|
216
247
|
if (!response.ok) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
errorMessage = "Forbidden: Access denied";
|
|
222
|
-
} else if (response.status === 404) {
|
|
223
|
-
errorMessage = "Notice or audio not found";
|
|
224
|
-
} else if (response.status >= 500) {
|
|
225
|
-
errorMessage = "Server error: Please try again later";
|
|
226
|
-
}
|
|
227
|
-
const error = new Error(errorMessage);
|
|
228
|
-
error.status = response.status;
|
|
229
|
-
throw error;
|
|
248
|
+
throw await parseApiError(
|
|
249
|
+
response,
|
|
250
|
+
"Could not load audio narration. Please try again."
|
|
251
|
+
);
|
|
230
252
|
}
|
|
231
253
|
const data = await response.json();
|
|
232
254
|
return data;
|
|
@@ -288,31 +310,10 @@ var initiateGuardianVerification = async ({
|
|
|
288
310
|
}
|
|
289
311
|
);
|
|
290
312
|
if (!response.ok) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
try
|
|
294
|
-
|
|
295
|
-
errorMessage = errorData.message || "Invalid request data";
|
|
296
|
-
} catch {
|
|
297
|
-
errorMessage = "Invalid request data";
|
|
298
|
-
}
|
|
299
|
-
} else if (response.status === 401) {
|
|
300
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
301
|
-
} else if (response.status === 404) {
|
|
302
|
-
errorMessage = "Organization or workspace not found";
|
|
303
|
-
} else if (response.status === 422) {
|
|
304
|
-
try {
|
|
305
|
-
const errorData = await response.json();
|
|
306
|
-
errorMessage = errorData.message || "Validation error: Please check your input";
|
|
307
|
-
} catch {
|
|
308
|
-
errorMessage = "Validation error: Please check your input";
|
|
309
|
-
}
|
|
310
|
-
} else if (response.status >= 500) {
|
|
311
|
-
errorMessage = "Server error: Please try again later";
|
|
312
|
-
}
|
|
313
|
-
const error = new Error(errorMessage);
|
|
314
|
-
error.status = response.status;
|
|
315
|
-
throw error;
|
|
313
|
+
throw await parseApiError(
|
|
314
|
+
response,
|
|
315
|
+
"Could not start guardian verification. Please try again."
|
|
316
|
+
);
|
|
316
317
|
}
|
|
317
318
|
const responseData = await response.json();
|
|
318
319
|
const detail = responseData.detail || responseData;
|
|
@@ -346,7 +347,7 @@ var verifyGuardianStatus = async ({
|
|
|
346
347
|
sessionToken,
|
|
347
348
|
signal
|
|
348
349
|
}) => {
|
|
349
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
350
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
350
351
|
if (!accessToken || !sessionToken) {
|
|
351
352
|
throw new Error("accessToken and sessionToken are required");
|
|
352
353
|
}
|
|
@@ -374,37 +375,21 @@ var verifyGuardianStatus = async ({
|
|
|
374
375
|
}
|
|
375
376
|
);
|
|
376
377
|
if (!response.ok) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
try
|
|
380
|
-
|
|
381
|
-
errorMessage = errorData.message || ((_a = errorData.detail) == null ? void 0 : _a.message) || "Invalid session token";
|
|
382
|
-
} catch {
|
|
383
|
-
errorMessage = "Invalid session token";
|
|
384
|
-
}
|
|
385
|
-
} else if (response.status === 401) {
|
|
386
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
387
|
-
} else if (response.status === 404) {
|
|
388
|
-
errorMessage = "Verification session not found or expired. Please restart the verification process.";
|
|
389
|
-
} else if (response.status === 410) {
|
|
390
|
-
errorMessage = "Verification session has expired. Please restart the verification process.";
|
|
391
|
-
} else if (response.status >= 500) {
|
|
392
|
-
errorMessage = "Server error: Please try again later";
|
|
393
|
-
}
|
|
394
|
-
const error = new Error(errorMessage);
|
|
395
|
-
error.status = response.status;
|
|
396
|
-
throw error;
|
|
378
|
+
throw await parseApiError(
|
|
379
|
+
response,
|
|
380
|
+
"Could not check verification status. Please try again."
|
|
381
|
+
);
|
|
397
382
|
}
|
|
398
383
|
const responseData = await response.json();
|
|
399
384
|
const detail = responseData.detail || responseData;
|
|
400
385
|
return {
|
|
401
|
-
status: (
|
|
402
|
-
guardian_info_uuid: (
|
|
403
|
-
verification_reference: (
|
|
404
|
-
guardian_details: (
|
|
405
|
-
error: (
|
|
406
|
-
error_code: (
|
|
407
|
-
can_retry: (
|
|
386
|
+
status: (_a = detail.status) != null ? _a : "in_progress",
|
|
387
|
+
guardian_info_uuid: (_b = detail.guardian_info_uuid) != null ? _b : null,
|
|
388
|
+
verification_reference: (_c = detail.verification_reference) != null ? _c : null,
|
|
389
|
+
guardian_details: (_d = detail.guardian_details) != null ? _d : null,
|
|
390
|
+
error: (_e = detail.error) != null ? _e : null,
|
|
391
|
+
error_code: (_f = detail.error_code) != null ? _f : null,
|
|
392
|
+
can_retry: (_g = detail.can_retry) != null ? _g : true
|
|
408
393
|
};
|
|
409
394
|
};
|
|
410
395
|
|
|
@@ -2901,7 +2886,7 @@ var RedactoNoticeConsent = ({
|
|
|
2901
2886
|
return;
|
|
2902
2887
|
}
|
|
2903
2888
|
const err = error;
|
|
2904
|
-
const message = err.
|
|
2889
|
+
const message = err.message || "Failed to submit consent. Please try again.";
|
|
2905
2890
|
setErrorMessage(message);
|
|
2906
2891
|
onError == null ? void 0 : onError(error);
|
|
2907
2892
|
} finally {
|
|
@@ -3323,20 +3308,12 @@ var RedactoNoticeConsent = ({
|
|
|
3323
3308
|
}, []);
|
|
3324
3309
|
const availableLanguages = useMemo(() => {
|
|
3325
3310
|
if (!content) return [language];
|
|
3326
|
-
const
|
|
3311
|
+
const pinned = ["English"];
|
|
3327
3312
|
if (content.default_language && content.default_language !== "English" && content.default_language !== "en") {
|
|
3328
|
-
|
|
3313
|
+
pinned.push(content.default_language);
|
|
3329
3314
|
}
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
(lang) => {
|
|
3333
|
-
if (!languages.includes(lang)) {
|
|
3334
|
-
languages.push(lang);
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
|
-
);
|
|
3338
|
-
}
|
|
3339
|
-
return languages;
|
|
3315
|
+
const rest = content.supported_languages_and_translations ? Object.keys(content.supported_languages_and_translations).filter((lang) => !pinned.includes(lang)).sort((a, b) => a.localeCompare(b, "en")) : [];
|
|
3316
|
+
return [...pinned, ...rest];
|
|
3340
3317
|
}, [content, language]);
|
|
3341
3318
|
const getLanguageCode = useCallback(
|
|
3342
3319
|
(displayLanguage) => {
|
|
@@ -4581,40 +4558,27 @@ var fetchConsentContent2 = async ({
|
|
|
4581
4558
|
baseUrl,
|
|
4582
4559
|
specific_uuid
|
|
4583
4560
|
}) => {
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
"Content-Type": "application/json"
|
|
4596
|
-
}
|
|
4597
|
-
});
|
|
4598
|
-
if (response.status === 401) {
|
|
4599
|
-
const error = new Error("Unauthorized");
|
|
4600
|
-
error.status = 401;
|
|
4601
|
-
throw error;
|
|
4602
|
-
}
|
|
4603
|
-
if (response.status === 409) {
|
|
4604
|
-
const error = new Error("User has already provided consent");
|
|
4605
|
-
error.status = 409;
|
|
4606
|
-
throw error;
|
|
4607
|
-
}
|
|
4608
|
-
if (!response.ok) {
|
|
4609
|
-
throw new Error(
|
|
4610
|
-
`Failed to fetch consent content: ${response.statusText}`
|
|
4611
|
-
);
|
|
4561
|
+
const apiBaseUrl = baseUrl || BASE_URL2;
|
|
4562
|
+
const url = new URL(
|
|
4563
|
+
`${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/notices/get-notice/${notice_uuid}`
|
|
4564
|
+
);
|
|
4565
|
+
if (specific_uuid) {
|
|
4566
|
+
url.searchParams.append("specific_uuid", specific_uuid);
|
|
4567
|
+
}
|
|
4568
|
+
const response = await fetch(url.toString(), {
|
|
4569
|
+
method: "GET",
|
|
4570
|
+
headers: {
|
|
4571
|
+
"Content-Type": "application/json"
|
|
4612
4572
|
}
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4573
|
+
});
|
|
4574
|
+
if (!response.ok) {
|
|
4575
|
+
throw await parseApiError(
|
|
4576
|
+
response,
|
|
4577
|
+
"Could not load the consent notice. Please try again."
|
|
4578
|
+
);
|
|
4617
4579
|
}
|
|
4580
|
+
const data = await response.json();
|
|
4581
|
+
return data;
|
|
4618
4582
|
};
|
|
4619
4583
|
var submitConsentEvent2 = async ({
|
|
4620
4584
|
org_uuid,
|
|
@@ -4626,67 +4590,44 @@ var submitConsentEvent2 = async ({
|
|
|
4626
4590
|
declined,
|
|
4627
4591
|
meta_data
|
|
4628
4592
|
}) => {
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
if (!purpose.uuid) {
|
|
4636
|
-
throw new Error(`Invalid purpose data: missing uuid`);
|
|
4637
|
-
}
|
|
4638
|
-
const dataElements = purpose.data_elements.filter((element) => element.enabled).map((element) => ({
|
|
4639
|
-
uuid: element.uuid,
|
|
4640
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
4641
|
-
}));
|
|
4642
|
-
return {
|
|
4643
|
-
purpose_uuid: purpose.uuid,
|
|
4644
|
-
selected: Boolean(purpose.selected),
|
|
4645
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
4646
|
-
};
|
|
4647
|
-
}),
|
|
4648
|
-
select_all_mandatory: false,
|
|
4649
|
-
source: "WEB",
|
|
4650
|
-
declined,
|
|
4651
|
-
meta_data
|
|
4652
|
-
};
|
|
4653
|
-
const response = await fetch(
|
|
4654
|
-
`${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
|
|
4655
|
-
{
|
|
4656
|
-
method: "POST",
|
|
4657
|
-
headers: {
|
|
4658
|
-
Authorization: `Bearer ${accessToken}`,
|
|
4659
|
-
"Content-Type": "application/json"
|
|
4660
|
-
},
|
|
4661
|
-
body: JSON.stringify(payload)
|
|
4662
|
-
}
|
|
4663
|
-
);
|
|
4664
|
-
if (!response.ok) {
|
|
4665
|
-
let errorData;
|
|
4666
|
-
try {
|
|
4667
|
-
errorData = await response.json();
|
|
4668
|
-
} catch {
|
|
4669
|
-
errorData = { message: response.statusText };
|
|
4670
|
-
}
|
|
4671
|
-
if (response.status === 409) {
|
|
4672
|
-
const error2 = new Error(
|
|
4673
|
-
((_a = errorData.detail) == null ? void 0 : _a.message) || errorData.message || "User has already provided consent"
|
|
4674
|
-
);
|
|
4675
|
-
error2.status = 409;
|
|
4676
|
-
error2.code = errorData.code || 409;
|
|
4677
|
-
error2.detail = errorData.detail;
|
|
4678
|
-
throw error2;
|
|
4593
|
+
const apiBaseUrl = baseUrl || BASE_URL2;
|
|
4594
|
+
const payload = {
|
|
4595
|
+
notice_uuid: noticeUuid,
|
|
4596
|
+
purposes: purposes.map((purpose) => {
|
|
4597
|
+
if (!purpose.uuid) {
|
|
4598
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
4679
4599
|
}
|
|
4680
|
-
const
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4600
|
+
const dataElements = purpose.data_elements.filter((element) => element.enabled).map((element) => ({
|
|
4601
|
+
uuid: element.uuid,
|
|
4602
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
4603
|
+
}));
|
|
4604
|
+
return {
|
|
4605
|
+
purpose_uuid: purpose.uuid,
|
|
4606
|
+
selected: Boolean(purpose.selected),
|
|
4607
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
4608
|
+
};
|
|
4609
|
+
}),
|
|
4610
|
+
select_all_mandatory: false,
|
|
4611
|
+
source: "WEB",
|
|
4612
|
+
declined,
|
|
4613
|
+
meta_data
|
|
4614
|
+
};
|
|
4615
|
+
const response = await fetch(
|
|
4616
|
+
`${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
|
|
4617
|
+
{
|
|
4618
|
+
method: "POST",
|
|
4619
|
+
headers: {
|
|
4620
|
+
Authorization: `Bearer ${accessToken}`,
|
|
4621
|
+
"Content-Type": "application/json"
|
|
4622
|
+
},
|
|
4623
|
+
body: JSON.stringify(payload)
|
|
4687
4624
|
}
|
|
4688
|
-
|
|
4689
|
-
|
|
4625
|
+
);
|
|
4626
|
+
if (!response.ok) {
|
|
4627
|
+
throw await parseApiError(
|
|
4628
|
+
response,
|
|
4629
|
+
"Could not submit your consent. Please try again."
|
|
4630
|
+
);
|
|
4690
4631
|
}
|
|
4691
4632
|
};
|
|
4692
4633
|
|
|
@@ -5359,7 +5300,7 @@ var RedactoConsentInlineComponent = ({
|
|
|
5359
5300
|
hasSubmittedRef.current = false;
|
|
5360
5301
|
} catch (error) {
|
|
5361
5302
|
const err = error;
|
|
5362
|
-
const message = err.
|
|
5303
|
+
const message = err.message || "Failed to submit consent. Please try again.";
|
|
5363
5304
|
setErrorMessage(message);
|
|
5364
5305
|
hasSubmittedRef.current = false;
|
|
5365
5306
|
throw error;
|
|
@@ -6072,6 +6013,7 @@ var DigiLockerCallback = ({
|
|
|
6072
6013
|
] });
|
|
6073
6014
|
};
|
|
6074
6015
|
export {
|
|
6016
|
+
ApiError,
|
|
6075
6017
|
DigiLockerCallback,
|
|
6076
6018
|
RedactoNoticeConsent,
|
|
6077
6019
|
RedactoConsentInline as RedactoNoticeConsentInline
|
|
@@ -102,6 +102,30 @@ declare function createConsentClient(baseUrl: string): {
|
|
|
102
102
|
* Get document info/download URL for a case document (privacy center)
|
|
103
103
|
*/
|
|
104
104
|
getCaseDocument(baseRequest: BaseRequest, caseUuid: string, documentUuid: string, authToken?: string): Promise<MessageDocument>;
|
|
105
|
+
/**
|
|
106
|
+
* List notifications (paginated, with filters)
|
|
107
|
+
*/
|
|
108
|
+
getNotifications(baseRequest: BaseRequest, params?: NotificationQueryParams, authToken?: string): Promise<NotificationListResponse>;
|
|
109
|
+
/**
|
|
110
|
+
* Get notification summary (aggregated counts only)
|
|
111
|
+
*/
|
|
112
|
+
getNotificationSummary(baseRequest: BaseRequest, authToken?: string): Promise<NotificationSummary>;
|
|
113
|
+
/**
|
|
114
|
+
* Get unread notification count (lightweight, for badge)
|
|
115
|
+
*/
|
|
116
|
+
getUnreadCount(baseRequest: BaseRequest, authToken?: string): Promise<UnreadCountResponse>;
|
|
117
|
+
/**
|
|
118
|
+
* Mark a single notification as read
|
|
119
|
+
*/
|
|
120
|
+
markNotificationRead(baseRequest: BaseRequest, notificationUuid: string, authToken?: string): Promise<NotificationActionResponse>;
|
|
121
|
+
/**
|
|
122
|
+
* Mark all notifications as read
|
|
123
|
+
*/
|
|
124
|
+
markAllNotificationsRead(baseRequest: BaseRequest, authToken?: string): Promise<NotificationActionResponse>;
|
|
125
|
+
/**
|
|
126
|
+
* Acknowledge a notification (sets is_read and is_acknowledged to true)
|
|
127
|
+
*/
|
|
128
|
+
acknowledgeNotification(baseRequest: BaseRequest, notificationUuid: string, authToken?: string): Promise<NotificationActionResponse>;
|
|
105
129
|
};
|
|
106
130
|
|
|
107
131
|
type Workspace = {
|
|
@@ -440,8 +464,61 @@ type UploadDocumentResponse = {
|
|
|
440
464
|
allow_ai_processing: boolean;
|
|
441
465
|
metadata: Record<string, string> | null;
|
|
442
466
|
};
|
|
467
|
+
type NotificationType = 'guardian_verification_request' | 'consent_expiry_warning' | 'new_consent_notice' | 'consent_withdrawal_confirmation' | 'data_request_status_update' | 'case_message' | 'grievance_status_update' | 'consent_regrant_prompt';
|
|
468
|
+
type NotificationCategory = 'consent' | 'request' | 'system';
|
|
469
|
+
type NotificationCTA = {
|
|
470
|
+
label: string;
|
|
471
|
+
style: 'primary' | 'secondary' | 'danger';
|
|
472
|
+
action_type: 'link' | 'acknowledge';
|
|
473
|
+
url?: string;
|
|
474
|
+
};
|
|
475
|
+
type Notification = {
|
|
476
|
+
uuid: string;
|
|
477
|
+
notification_type: NotificationType;
|
|
478
|
+
category: NotificationCategory;
|
|
479
|
+
title: string;
|
|
480
|
+
description: string;
|
|
481
|
+
is_read: boolean;
|
|
482
|
+
is_acknowledged: boolean;
|
|
483
|
+
source_type: string;
|
|
484
|
+
source_uuid: string | null;
|
|
485
|
+
request_type: string;
|
|
486
|
+
request_type_display?: string | null;
|
|
487
|
+
status_label: string;
|
|
488
|
+
status_label_display?: string | null;
|
|
489
|
+
ctas: NotificationCTA[];
|
|
490
|
+
created_at: string;
|
|
491
|
+
};
|
|
492
|
+
type NotificationSummary = {
|
|
493
|
+
total: number;
|
|
494
|
+
unread: number;
|
|
495
|
+
action_needed: number;
|
|
496
|
+
acknowledged: number;
|
|
497
|
+
};
|
|
498
|
+
type NotificationListResponse = {
|
|
499
|
+
data: Notification[];
|
|
500
|
+
total: number;
|
|
501
|
+
skip: number;
|
|
502
|
+
limit: number;
|
|
503
|
+
summary: NotificationSummary | null;
|
|
504
|
+
};
|
|
505
|
+
type UnreadCountResponse = {
|
|
506
|
+
count: number;
|
|
507
|
+
};
|
|
508
|
+
type NotificationActionResponse = {
|
|
509
|
+
message: string;
|
|
510
|
+
};
|
|
511
|
+
type NotificationQueryParams = {
|
|
512
|
+
category?: NotificationCategory;
|
|
513
|
+
notification_type?: NotificationType;
|
|
514
|
+
is_read?: boolean;
|
|
515
|
+
skip?: number;
|
|
516
|
+
limit?: number;
|
|
517
|
+
include_summary?: boolean;
|
|
518
|
+
language?: string;
|
|
519
|
+
};
|
|
443
520
|
|
|
444
|
-
type InternalPage = 'consent-manager' | 'form' | 'activity' | 'case-details';
|
|
521
|
+
type InternalPage = 'consent-manager' | 'form' | 'activity' | 'case-details' | 'notifications';
|
|
445
522
|
interface NavigationContextType {
|
|
446
523
|
currentPage: InternalPage;
|
|
447
524
|
navigateTo: (page: InternalPage) => void;
|
|
@@ -485,6 +562,8 @@ declare function PrivacyCenterActivityPage(): react_jsx_runtime.JSX.Element;
|
|
|
485
562
|
|
|
486
563
|
declare const PrivacyCenterCaseDetailsPage: () => react_jsx_runtime.JSX.Element | null;
|
|
487
564
|
|
|
565
|
+
declare const NotificationsPage: () => react_jsx_runtime.JSX.Element;
|
|
566
|
+
|
|
488
567
|
type AuthContextValue = Readonly<{
|
|
489
568
|
accessToken: string;
|
|
490
569
|
refreshToken: string;
|
|
@@ -646,4 +725,4 @@ declare const useAuth: () => AuthContextValue;
|
|
|
646
725
|
*/
|
|
647
726
|
declare const injectPCStyles: () => void;
|
|
648
727
|
|
|
649
|
-
export { type Activity, type ActivityBadgeStatus$1 as ActivityBadgeStatus, type ActivityDetail, type ActivityResponse, type ApiFetchOptions, type ApiResponse, type AuthContext, AuthProvider, type BaseRequest, BaseUrlProvider, type CaseHistoryDetail, type CaseHistoryResponse, type CaseRequest, type ConsentAction, type ConsentDataElement, type ConsentHistoryStatusSummary, ConsentStatusEnum, type CreateCaseResponse, type DataElement, type FetchOrgParams, type FormData, type FormDataResponse, type GrievanceOptions, type GrievanceTypeElement, GrievanceTypeEnum, type GrievanceValue, type InternalPage, type ManageConsentParams, type ManageConsentResponse, NavigationProvider, type NominatedPurposesGroup, type NominationData, type NominatorInfo, type OrganizationDetail, type OrganizationResponse, type OtpResponse, type OtpVerificationResponse, type Pagination, PrivacyCenterActivityPage, PrivacyCenterCaseDetailsPage, PrivacyCenterConsentManagerPage, PrivacyCenterFormPage, PrivacyCenterHomePage, PrivacyCenterLayout, type ProductConsentHistoryGroup, type Purpose, type RawPurposeWrapper, RedactoPrivacyCenter, RequestTypeEnum, type TokenExchangeResponse, type UpdateCorrectionDataItem, type UpdatePurpose, type UpdateRequestDetails, type UserConsent, type UserConsentDetail, type UserConsentResponse, type UserDataRequest, type Workspace, checkAndRefreshAuth, compareEmails, createCaseRequest, createConsentClient, createOtpServer as createOtp, decodeJwtToken, ensureValidToken, exchangeTokenServer as exchangeToken, fetchActivities, fetchCaseHistory, fetchProducts, fetchUserConsents, formatActivityType, getActivityTypeStatus, getCookieValue, getFormData, getInitialState, injectPCStyles, isJwtExpired, isUserAuthenticated, manageConsent, setRefreshTokenCookie, signOutPrivacyCenter, useAuth, useBaseUrl, useCaseHistory, useInternalNavigation, verifyOtpServer as verifyOtp };
|
|
728
|
+
export { type Activity, type ActivityBadgeStatus$1 as ActivityBadgeStatus, type ActivityDetail, type ActivityResponse, type ApiFetchOptions, type ApiResponse, type AuthContext, AuthProvider, type BaseRequest, BaseUrlProvider, type CaseHistoryDetail, type CaseHistoryResponse, type CaseRequest, type ConsentAction, type ConsentDataElement, type ConsentHistoryStatusSummary, ConsentStatusEnum, type CreateCaseResponse, type DataElement, type FetchOrgParams, type FormData, type FormDataResponse, type GrievanceOptions, type GrievanceTypeElement, GrievanceTypeEnum, type GrievanceValue, type InternalPage, type ManageConsentParams, type ManageConsentResponse, NavigationProvider, type NominatedPurposesGroup, type NominationData, type NominatorInfo, NotificationsPage, type OrganizationDetail, type OrganizationResponse, type OtpResponse, type OtpVerificationResponse, type Pagination, PrivacyCenterActivityPage, PrivacyCenterCaseDetailsPage, PrivacyCenterConsentManagerPage, PrivacyCenterFormPage, PrivacyCenterHomePage, PrivacyCenterLayout, type ProductConsentHistoryGroup, type Purpose, type RawPurposeWrapper, RedactoPrivacyCenter, RequestTypeEnum, type TokenExchangeResponse, type UpdateCorrectionDataItem, type UpdatePurpose, type UpdateRequestDetails, type UserConsent, type UserConsentDetail, type UserConsentResponse, type UserDataRequest, type Workspace, checkAndRefreshAuth, compareEmails, createCaseRequest, createConsentClient, createOtpServer as createOtp, decodeJwtToken, ensureValidToken, exchangeTokenServer as exchangeToken, fetchActivities, fetchCaseHistory, fetchProducts, fetchUserConsents, formatActivityType, getActivityTypeStatus, getCookieValue, getFormData, getInitialState, injectPCStyles, isJwtExpired, isUserAuthenticated, manageConsent, setRefreshTokenCookie, signOutPrivacyCenter, useAuth, useBaseUrl, useCaseHistory, useInternalNavigation, verifyOtpServer as verifyOtp };
|
package/dist/privacy-center.d.ts
CHANGED
|
@@ -102,6 +102,30 @@ declare function createConsentClient(baseUrl: string): {
|
|
|
102
102
|
* Get document info/download URL for a case document (privacy center)
|
|
103
103
|
*/
|
|
104
104
|
getCaseDocument(baseRequest: BaseRequest, caseUuid: string, documentUuid: string, authToken?: string): Promise<MessageDocument>;
|
|
105
|
+
/**
|
|
106
|
+
* List notifications (paginated, with filters)
|
|
107
|
+
*/
|
|
108
|
+
getNotifications(baseRequest: BaseRequest, params?: NotificationQueryParams, authToken?: string): Promise<NotificationListResponse>;
|
|
109
|
+
/**
|
|
110
|
+
* Get notification summary (aggregated counts only)
|
|
111
|
+
*/
|
|
112
|
+
getNotificationSummary(baseRequest: BaseRequest, authToken?: string): Promise<NotificationSummary>;
|
|
113
|
+
/**
|
|
114
|
+
* Get unread notification count (lightweight, for badge)
|
|
115
|
+
*/
|
|
116
|
+
getUnreadCount(baseRequest: BaseRequest, authToken?: string): Promise<UnreadCountResponse>;
|
|
117
|
+
/**
|
|
118
|
+
* Mark a single notification as read
|
|
119
|
+
*/
|
|
120
|
+
markNotificationRead(baseRequest: BaseRequest, notificationUuid: string, authToken?: string): Promise<NotificationActionResponse>;
|
|
121
|
+
/**
|
|
122
|
+
* Mark all notifications as read
|
|
123
|
+
*/
|
|
124
|
+
markAllNotificationsRead(baseRequest: BaseRequest, authToken?: string): Promise<NotificationActionResponse>;
|
|
125
|
+
/**
|
|
126
|
+
* Acknowledge a notification (sets is_read and is_acknowledged to true)
|
|
127
|
+
*/
|
|
128
|
+
acknowledgeNotification(baseRequest: BaseRequest, notificationUuid: string, authToken?: string): Promise<NotificationActionResponse>;
|
|
105
129
|
};
|
|
106
130
|
|
|
107
131
|
type Workspace = {
|
|
@@ -440,8 +464,61 @@ type UploadDocumentResponse = {
|
|
|
440
464
|
allow_ai_processing: boolean;
|
|
441
465
|
metadata: Record<string, string> | null;
|
|
442
466
|
};
|
|
467
|
+
type NotificationType = 'guardian_verification_request' | 'consent_expiry_warning' | 'new_consent_notice' | 'consent_withdrawal_confirmation' | 'data_request_status_update' | 'case_message' | 'grievance_status_update' | 'consent_regrant_prompt';
|
|
468
|
+
type NotificationCategory = 'consent' | 'request' | 'system';
|
|
469
|
+
type NotificationCTA = {
|
|
470
|
+
label: string;
|
|
471
|
+
style: 'primary' | 'secondary' | 'danger';
|
|
472
|
+
action_type: 'link' | 'acknowledge';
|
|
473
|
+
url?: string;
|
|
474
|
+
};
|
|
475
|
+
type Notification = {
|
|
476
|
+
uuid: string;
|
|
477
|
+
notification_type: NotificationType;
|
|
478
|
+
category: NotificationCategory;
|
|
479
|
+
title: string;
|
|
480
|
+
description: string;
|
|
481
|
+
is_read: boolean;
|
|
482
|
+
is_acknowledged: boolean;
|
|
483
|
+
source_type: string;
|
|
484
|
+
source_uuid: string | null;
|
|
485
|
+
request_type: string;
|
|
486
|
+
request_type_display?: string | null;
|
|
487
|
+
status_label: string;
|
|
488
|
+
status_label_display?: string | null;
|
|
489
|
+
ctas: NotificationCTA[];
|
|
490
|
+
created_at: string;
|
|
491
|
+
};
|
|
492
|
+
type NotificationSummary = {
|
|
493
|
+
total: number;
|
|
494
|
+
unread: number;
|
|
495
|
+
action_needed: number;
|
|
496
|
+
acknowledged: number;
|
|
497
|
+
};
|
|
498
|
+
type NotificationListResponse = {
|
|
499
|
+
data: Notification[];
|
|
500
|
+
total: number;
|
|
501
|
+
skip: number;
|
|
502
|
+
limit: number;
|
|
503
|
+
summary: NotificationSummary | null;
|
|
504
|
+
};
|
|
505
|
+
type UnreadCountResponse = {
|
|
506
|
+
count: number;
|
|
507
|
+
};
|
|
508
|
+
type NotificationActionResponse = {
|
|
509
|
+
message: string;
|
|
510
|
+
};
|
|
511
|
+
type NotificationQueryParams = {
|
|
512
|
+
category?: NotificationCategory;
|
|
513
|
+
notification_type?: NotificationType;
|
|
514
|
+
is_read?: boolean;
|
|
515
|
+
skip?: number;
|
|
516
|
+
limit?: number;
|
|
517
|
+
include_summary?: boolean;
|
|
518
|
+
language?: string;
|
|
519
|
+
};
|
|
443
520
|
|
|
444
|
-
type InternalPage = 'consent-manager' | 'form' | 'activity' | 'case-details';
|
|
521
|
+
type InternalPage = 'consent-manager' | 'form' | 'activity' | 'case-details' | 'notifications';
|
|
445
522
|
interface NavigationContextType {
|
|
446
523
|
currentPage: InternalPage;
|
|
447
524
|
navigateTo: (page: InternalPage) => void;
|
|
@@ -485,6 +562,8 @@ declare function PrivacyCenterActivityPage(): react_jsx_runtime.JSX.Element;
|
|
|
485
562
|
|
|
486
563
|
declare const PrivacyCenterCaseDetailsPage: () => react_jsx_runtime.JSX.Element | null;
|
|
487
564
|
|
|
565
|
+
declare const NotificationsPage: () => react_jsx_runtime.JSX.Element;
|
|
566
|
+
|
|
488
567
|
type AuthContextValue = Readonly<{
|
|
489
568
|
accessToken: string;
|
|
490
569
|
refreshToken: string;
|
|
@@ -646,4 +725,4 @@ declare const useAuth: () => AuthContextValue;
|
|
|
646
725
|
*/
|
|
647
726
|
declare const injectPCStyles: () => void;
|
|
648
727
|
|
|
649
|
-
export { type Activity, type ActivityBadgeStatus$1 as ActivityBadgeStatus, type ActivityDetail, type ActivityResponse, type ApiFetchOptions, type ApiResponse, type AuthContext, AuthProvider, type BaseRequest, BaseUrlProvider, type CaseHistoryDetail, type CaseHistoryResponse, type CaseRequest, type ConsentAction, type ConsentDataElement, type ConsentHistoryStatusSummary, ConsentStatusEnum, type CreateCaseResponse, type DataElement, type FetchOrgParams, type FormData, type FormDataResponse, type GrievanceOptions, type GrievanceTypeElement, GrievanceTypeEnum, type GrievanceValue, type InternalPage, type ManageConsentParams, type ManageConsentResponse, NavigationProvider, type NominatedPurposesGroup, type NominationData, type NominatorInfo, type OrganizationDetail, type OrganizationResponse, type OtpResponse, type OtpVerificationResponse, type Pagination, PrivacyCenterActivityPage, PrivacyCenterCaseDetailsPage, PrivacyCenterConsentManagerPage, PrivacyCenterFormPage, PrivacyCenterHomePage, PrivacyCenterLayout, type ProductConsentHistoryGroup, type Purpose, type RawPurposeWrapper, RedactoPrivacyCenter, RequestTypeEnum, type TokenExchangeResponse, type UpdateCorrectionDataItem, type UpdatePurpose, type UpdateRequestDetails, type UserConsent, type UserConsentDetail, type UserConsentResponse, type UserDataRequest, type Workspace, checkAndRefreshAuth, compareEmails, createCaseRequest, createConsentClient, createOtpServer as createOtp, decodeJwtToken, ensureValidToken, exchangeTokenServer as exchangeToken, fetchActivities, fetchCaseHistory, fetchProducts, fetchUserConsents, formatActivityType, getActivityTypeStatus, getCookieValue, getFormData, getInitialState, injectPCStyles, isJwtExpired, isUserAuthenticated, manageConsent, setRefreshTokenCookie, signOutPrivacyCenter, useAuth, useBaseUrl, useCaseHistory, useInternalNavigation, verifyOtpServer as verifyOtp };
|
|
728
|
+
export { type Activity, type ActivityBadgeStatus$1 as ActivityBadgeStatus, type ActivityDetail, type ActivityResponse, type ApiFetchOptions, type ApiResponse, type AuthContext, AuthProvider, type BaseRequest, BaseUrlProvider, type CaseHistoryDetail, type CaseHistoryResponse, type CaseRequest, type ConsentAction, type ConsentDataElement, type ConsentHistoryStatusSummary, ConsentStatusEnum, type CreateCaseResponse, type DataElement, type FetchOrgParams, type FormData, type FormDataResponse, type GrievanceOptions, type GrievanceTypeElement, GrievanceTypeEnum, type GrievanceValue, type InternalPage, type ManageConsentParams, type ManageConsentResponse, NavigationProvider, type NominatedPurposesGroup, type NominationData, type NominatorInfo, NotificationsPage, type OrganizationDetail, type OrganizationResponse, type OtpResponse, type OtpVerificationResponse, type Pagination, PrivacyCenterActivityPage, PrivacyCenterCaseDetailsPage, PrivacyCenterConsentManagerPage, PrivacyCenterFormPage, PrivacyCenterHomePage, PrivacyCenterLayout, type ProductConsentHistoryGroup, type Purpose, type RawPurposeWrapper, RedactoPrivacyCenter, RequestTypeEnum, type TokenExchangeResponse, type UpdateCorrectionDataItem, type UpdatePurpose, type UpdateRequestDetails, type UserConsent, type UserConsentDetail, type UserConsentResponse, type UserDataRequest, type Workspace, checkAndRefreshAuth, compareEmails, createCaseRequest, createConsentClient, createOtpServer as createOtp, decodeJwtToken, ensureValidToken, exchangeTokenServer as exchangeToken, fetchActivities, fetchCaseHistory, fetchProducts, fetchUserConsents, formatActivityType, getActivityTypeStatus, getCookieValue, getFormData, getInitialState, injectPCStyles, isJwtExpired, isUserAuthenticated, manageConsent, setRefreshTokenCookie, signOutPrivacyCenter, useAuth, useBaseUrl, useCaseHistory, useInternalNavigation, verifyOtpServer as verifyOtp };
|