@redacto.io/consent-sdk-react 3.4.0 → 3.6.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 +12 -0
- package/LICENSE +176 -0
- package/dist/index.d.mts +51 -4
- package/dist/index.d.ts +51 -4
- package/dist/index.js +1912 -345
- package/dist/index.mjs +1911 -345
- package/dist/privacy-center.d.mts +566 -0
- package/dist/privacy-center.d.ts +566 -0
- package/dist/privacy-center.js +17174 -0
- package/dist/privacy-center.mjs +17136 -0
- package/package.json +47 -3
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.test.tsx +201 -118
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +1194 -93
- package/src/RedactoNoticeConsent/api/index.ts +337 -246
- package/src/RedactoNoticeConsent/api/types.ts +140 -41
- package/src/RedactoNoticeConsent/components/DigiLockerCallback.tsx +602 -0
- package/src/RedactoNoticeConsent/components/index.ts +7 -0
- package/src/RedactoNoticeConsent/injectStyles.ts +11 -0
- package/src/RedactoNoticeConsent/language-codes.ts +61 -0
- package/src/RedactoNoticeConsent/services/storage.ts +122 -0
- package/src/RedactoNoticeConsent/types.ts +2 -0
- package/src/RedactoNoticeConsentInline/api/index.ts +26 -64
- package/src/RedactoNoticeConsentInline/api/types.ts +0 -25
- package/src/RedactoPrivacyCenter/PrivacyCenterActivityPage.tsx +19 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterConsentManagerPage.tsx +17 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterFormPage.tsx +79 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterHomePage.tsx +27 -0
- package/src/RedactoPrivacyCenter/PrivacyCenterLayout.tsx +142 -0
- package/src/RedactoPrivacyCenter/RedactoPrivacyCenter.tsx +51 -0
- package/src/RedactoPrivacyCenter/api/actions.ts +444 -0
- package/src/RedactoPrivacyCenter/api/client.ts +413 -0
- package/src/RedactoPrivacyCenter/api/config.ts +33 -0
- package/src/RedactoPrivacyCenter/api/fetcher.ts +181 -0
- package/src/RedactoPrivacyCenter/api/upload.ts +93 -0
- package/src/RedactoPrivacyCenter/assets/character.svg +31 -0
- package/src/RedactoPrivacyCenter/assets/fileAttach.svg +9 -0
- package/src/RedactoPrivacyCenter/assets/greenTick.svg +4 -0
- package/src/RedactoPrivacyCenter/assets/mail.svg +3 -0
- package/src/RedactoPrivacyCenter/assets/poweredByRedacto.svg +9 -0
- package/src/RedactoPrivacyCenter/assets/sentImg.svg +9 -0
- package/src/RedactoPrivacyCenter/assets/uploadFileIcon.svg +9 -0
- package/src/RedactoPrivacyCenter/components/ActivitiesList.tsx +272 -0
- package/src/RedactoPrivacyCenter/components/CaseDetailsModal.tsx +468 -0
- package/src/RedactoPrivacyCenter/components/CaseHistory.tsx +433 -0
- package/src/RedactoPrivacyCenter/components/ConsentManager.tsx +726 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerColumns.tsx +239 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerConstants.ts +7 -0
- package/src/RedactoPrivacyCenter/components/ConsentManagerTableSkeleton.tsx +155 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/CorrectionDataSection.tsx +189 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/GrievanceDataSection.tsx +118 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/NominationDataSection.tsx +66 -0
- package/src/RedactoPrivacyCenter/components/DataRequest/PurposeSelectionSection.tsx +305 -0
- package/src/RedactoPrivacyCenter/components/Form.tsx +1455 -0
- package/src/RedactoPrivacyCenter/components/GrievanceTable.tsx +176 -0
- package/src/RedactoPrivacyCenter/components/GrievanceTablePagination.tsx +330 -0
- package/src/RedactoPrivacyCenter/components/ModifyConsentModal.tsx +329 -0
- package/src/RedactoPrivacyCenter/components/Pagination.tsx +140 -0
- package/src/RedactoPrivacyCenter/components/PrivacyCenterLayout.tsx +302 -0
- package/src/RedactoPrivacyCenter/components/RequestSubmit.tsx +218 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideBarPC.tsx +475 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/SideMenuPC.tsx +412 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/constants.tsx +42 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/menuItemsPC.tsx +1 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/types.ts +40 -0
- package/src/RedactoPrivacyCenter/components/SideMenuBarPC/utils.ts +38 -0
- package/src/RedactoPrivacyCenter/components/ThemeTransitionOverlay.tsx +85 -0
- package/src/RedactoPrivacyCenter/components/activitiesColumns.tsx +141 -0
- package/src/RedactoPrivacyCenter/components/caseHistoryColumns.tsx +179 -0
- package/src/RedactoPrivacyCenter/components/constant.ts +20 -0
- package/src/RedactoPrivacyCenter/components/types.ts +68 -0
- package/src/RedactoPrivacyCenter/components/utils.tsx +10 -0
- package/src/RedactoPrivacyCenter/config/routes.ts +9 -0
- package/src/RedactoPrivacyCenter/config/table.ts +25 -0
- package/src/RedactoPrivacyCenter/context/AuthContext.tsx +123 -0
- package/src/RedactoPrivacyCenter/context/BaseUrlContext.tsx +44 -0
- package/src/RedactoPrivacyCenter/context/LocaleContext.tsx +11 -0
- package/src/RedactoPrivacyCenter/context/NavigationContext.tsx +64 -0
- package/src/RedactoPrivacyCenter/context/OrganizationContext.tsx +30 -0
- package/src/RedactoPrivacyCenter/context/PageChromeContext.tsx +60 -0
- package/src/RedactoPrivacyCenter/context/theme.tsx +127 -0
- package/src/RedactoPrivacyCenter/lib/api.ts +468 -0
- package/src/RedactoPrivacyCenter/lib/consent-manager/utils.tsx +63 -0
- package/src/RedactoPrivacyCenter/lib/constants.ts +116 -0
- package/src/RedactoPrivacyCenter/lib/i18n.ts +81 -0
- package/src/RedactoPrivacyCenter/lib/locales.ts +105 -0
- package/src/RedactoPrivacyCenter/lib/queries.ts +30 -0
- package/src/RedactoPrivacyCenter/lib/types.ts +346 -0
- package/src/RedactoPrivacyCenter/lib/useCurrentLanguage.ts +37 -0
- package/src/RedactoPrivacyCenter/lib/utils.ts +625 -0
- package/src/RedactoPrivacyCenter/locales/as/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/bho/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/bn/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/brx/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/doi/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/en/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/gom/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/gu/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/hi/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/kn/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ks/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/mai/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ml/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/mni-Mtei/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/mr/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ne/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/or/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/pa/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/sa/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/sat/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/sd/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ta/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/te/translation.json +188 -0
- package/src/RedactoPrivacyCenter/locales/ur/translation.json +188 -0
- package/src/RedactoPrivacyCenter/styles/base.css +117 -0
- package/src/RedactoPrivacyCenter/styles/injectStyles.ts +1000 -0
- package/src/RedactoPrivacyCenter/styles/pcStyles.ts +819 -0
- package/src/RedactoPrivacyCenter/styles/responsive.ts +138 -0
- package/src/RedactoPrivacyCenter/styles/variables.css +133 -0
- package/src/RedactoPrivacyCenter/table/AdvancedTable.tsx +365 -0
- package/src/RedactoPrivacyCenter/table/AdvancedTablePagination.tsx +479 -0
- package/src/RedactoPrivacyCenter/table/index.ts +2 -0
- package/src/RedactoPrivacyCenter/types/images.d.ts +29 -0
- package/src/RedactoPrivacyCenter/ui/Footer.tsx +73 -0
- package/src/RedactoPrivacyCenter/ui/FormBlockWrapper.tsx +54 -0
- package/src/RedactoPrivacyCenter/ui/PCAccordion.tsx +87 -0
- package/src/RedactoPrivacyCenter/ui/PCActionIcon.tsx +47 -0
- package/src/RedactoPrivacyCenter/ui/PCAvatar.tsx +69 -0
- package/src/RedactoPrivacyCenter/ui/PCBadge.tsx +48 -0
- package/src/RedactoPrivacyCenter/ui/PCButton.tsx +77 -0
- package/src/RedactoPrivacyCenter/ui/PCCheckbox.tsx +55 -0
- package/src/RedactoPrivacyCenter/ui/PCCollapse.tsx +97 -0
- package/src/RedactoPrivacyCenter/ui/PCEmpty.tsx +35 -0
- package/src/RedactoPrivacyCenter/ui/PCInput.tsx +128 -0
- package/src/RedactoPrivacyCenter/ui/PCLoader.tsx +30 -0
- package/src/RedactoPrivacyCenter/ui/PCModal.tsx +104 -0
- package/src/RedactoPrivacyCenter/ui/PCPopover.tsx +175 -0
- package/src/RedactoPrivacyCenter/ui/PCSelect.tsx +381 -0
- package/src/RedactoPrivacyCenter/ui/PCTable.tsx +137 -0
- package/src/RedactoPrivacyCenter/ui/PCText.tsx +39 -0
- package/src/RedactoPrivacyCenter/ui/PCTextarea.tsx +43 -0
- package/src/RedactoPrivacyCenter/ui/PCTitle.tsx +37 -0
- package/src/RedactoPrivacyCenter/ui/PCTooltip.tsx +119 -0
- package/src/RedactoPrivacyCenter/ui/SimpleBar.tsx +25 -0
- package/src/RedactoPrivacyCenter/ui/StatusBadge.tsx +55 -0
- package/src/RedactoPrivacyCenter/ui/ThemeToggle.tsx +70 -0
- package/src/RedactoPrivacyCenter/ui/index.ts +18 -0
- package/src/RedactoPrivacyCenter/utils/cn.ts +28 -0
- package/src/RedactoPrivacyCenter/utils/date.ts +48 -0
- package/src/RedactoPrivacyCenter/utils/status.ts +111 -0
- package/src/RedactoPrivacyCenter/utils/toast.ts +130 -0
- package/src/index.ts +10 -0
- package/src/privacy-center.ts +107 -0
- package/tsconfig.json +2 -0
- package/tsup.config.ts +16 -1
- package/src/utils/isLegacyApi.ts +0 -12
package/dist/index.mjs
CHANGED
|
@@ -3,21 +3,6 @@ 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/utils/isLegacyApi.ts
|
|
8
|
-
function isLegacyApi(baseUrl) {
|
|
9
|
-
try {
|
|
10
|
-
return new URL(baseUrl).hostname.endsWith(".redacto.io");
|
|
11
|
-
} catch {
|
|
12
|
-
try {
|
|
13
|
-
return new URL(`https://${baseUrl}`).hostname.endsWith(".redacto.io");
|
|
14
|
-
} catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// src/RedactoNoticeConsent/api/index.ts
|
|
21
6
|
var BASE_URL = "https://api.redacto.io/consent";
|
|
22
7
|
var apiCache = /* @__PURE__ */ new Map();
|
|
23
8
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
@@ -54,73 +39,66 @@ var fetchConsentContent = async ({
|
|
|
54
39
|
validate_against = "all",
|
|
55
40
|
include_fully_consented_data = false,
|
|
56
41
|
signal
|
|
57
|
-
// AbortSignal for request cancellation
|
|
58
42
|
}) => {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return cachedData;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
const url = new URL(
|
|
80
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
81
|
-
);
|
|
82
|
-
if (specific_uuid) {
|
|
83
|
-
url.searchParams.append("specific_uuid", specific_uuid);
|
|
84
|
-
}
|
|
85
|
-
url.searchParams.append("validate_against", validate_against);
|
|
86
|
-
if (include_fully_consented_data) {
|
|
87
|
-
url.searchParams.append("include_fully_consented_data", "true");
|
|
88
|
-
}
|
|
89
|
-
const response = await fetch(url.toString(), {
|
|
90
|
-
method: "GET",
|
|
91
|
-
headers: {
|
|
92
|
-
Authorization: `Bearer ${accessToken}`,
|
|
93
|
-
"Accept-Language": language,
|
|
94
|
-
"Content-Type": "application/json"
|
|
95
|
-
},
|
|
96
|
-
signal
|
|
97
|
-
// Add abort signal for request cancellation
|
|
98
|
-
});
|
|
99
|
-
if (!response.ok) {
|
|
100
|
-
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
101
|
-
if (response.status === 401) {
|
|
102
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
103
|
-
} else if (response.status === 403) {
|
|
104
|
-
errorMessage = "Forbidden: Access denied";
|
|
105
|
-
} else if (response.status === 404) {
|
|
106
|
-
errorMessage = "Notice not found";
|
|
107
|
-
} else if (response.status === 409) {
|
|
108
|
-
errorMessage = "User has already provided consent";
|
|
109
|
-
} else if (response.status >= 500) {
|
|
110
|
-
errorMessage = "Server error: Please try again later";
|
|
111
|
-
}
|
|
112
|
-
const error = new Error(errorMessage);
|
|
113
|
-
error.status = response.status;
|
|
114
|
-
throw error;
|
|
43
|
+
if (!noticeId || !accessToken || !validate_against) {
|
|
44
|
+
throw new Error("noticeId and accessToken are required");
|
|
45
|
+
}
|
|
46
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
47
|
+
if (!decodedToken) {
|
|
48
|
+
throw new Error("Invalid access token");
|
|
49
|
+
}
|
|
50
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
51
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
52
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
53
|
+
}
|
|
54
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
55
|
+
const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
|
|
56
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
57
|
+
const cachedData = getCachedData(cacheKey);
|
|
58
|
+
if (cachedData) {
|
|
59
|
+
return cachedData;
|
|
115
60
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
61
|
+
}
|
|
62
|
+
const url = new URL(
|
|
63
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
64
|
+
);
|
|
65
|
+
if (specific_uuid) {
|
|
66
|
+
url.searchParams.append("specific_uuid", specific_uuid);
|
|
67
|
+
}
|
|
68
|
+
url.searchParams.append("validate_against", validate_against);
|
|
69
|
+
if (include_fully_consented_data) {
|
|
70
|
+
url.searchParams.append("include_fully_consented_data", "true");
|
|
71
|
+
}
|
|
72
|
+
const response = await fetch(url.toString(), {
|
|
73
|
+
method: "GET",
|
|
74
|
+
headers: {
|
|
75
|
+
Authorization: `Bearer ${accessToken}`,
|
|
76
|
+
"Accept-Language": language
|
|
77
|
+
},
|
|
78
|
+
signal
|
|
79
|
+
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
82
|
+
if (response.status === 401) {
|
|
83
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
84
|
+
} else if (response.status === 403) {
|
|
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";
|
|
119
92
|
}
|
|
120
|
-
|
|
121
|
-
|
|
93
|
+
const error = new Error(errorMessage);
|
|
94
|
+
error.status = response.status;
|
|
122
95
|
throw error;
|
|
123
96
|
}
|
|
97
|
+
const data = await response.json();
|
|
98
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
99
|
+
setCachedData(cacheKey, data);
|
|
100
|
+
}
|
|
101
|
+
return data;
|
|
124
102
|
};
|
|
125
103
|
var submitConsentEvent = async ({
|
|
126
104
|
accessToken,
|
|
@@ -128,134 +106,154 @@ var submitConsentEvent = async ({
|
|
|
128
106
|
noticeUuid,
|
|
129
107
|
purposes,
|
|
130
108
|
declined,
|
|
109
|
+
language,
|
|
131
110
|
meta_data,
|
|
111
|
+
guardianVerificationReference,
|
|
112
|
+
selfDeclaredAdult,
|
|
132
113
|
signal
|
|
133
|
-
// AbortSignal for request cancellation
|
|
134
114
|
}) => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
115
|
+
if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
|
|
116
|
+
throw new Error("noticeUuid, accessToken, and purposes array are required");
|
|
117
|
+
}
|
|
118
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
119
|
+
if (!decodedToken) {
|
|
120
|
+
throw new Error("Invalid access token");
|
|
121
|
+
}
|
|
122
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
123
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
124
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
125
|
+
}
|
|
126
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
127
|
+
const validatedPurposes = purposes.map((purpose) => {
|
|
128
|
+
if (!purpose.uuid) {
|
|
129
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
146
130
|
}
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
};
|
|
179
|
-
} else {
|
|
180
|
-
const validatedPurposes = purposes.map((purpose) => {
|
|
181
|
-
if (!purpose.uuid) {
|
|
182
|
-
throw new Error(`Invalid purpose data: missing uuid`);
|
|
183
|
-
}
|
|
184
|
-
const dataElements = (purpose.data_elements || []).filter((element) => element.enabled).map((element) => ({
|
|
185
|
-
uuid: element.uuid,
|
|
186
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
187
|
-
}));
|
|
188
|
-
return {
|
|
189
|
-
purpose_uuid: purpose.uuid,
|
|
190
|
-
selected: Boolean(purpose.selected),
|
|
191
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
192
|
-
};
|
|
193
|
-
});
|
|
194
|
-
payload = {
|
|
195
|
-
notice_uuid: noticeUuid,
|
|
196
|
-
purposes: validatedPurposes,
|
|
197
|
-
select_all_mandatory: false,
|
|
198
|
-
source: "WEB",
|
|
199
|
-
declined: Boolean(declined),
|
|
200
|
-
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
|
|
201
|
-
};
|
|
131
|
+
const dataElements = (purpose.data_elements || []).filter((element) => element.enabled).map((element) => ({
|
|
132
|
+
uuid: element.uuid,
|
|
133
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
134
|
+
}));
|
|
135
|
+
return {
|
|
136
|
+
purpose_uuid: purpose.uuid,
|
|
137
|
+
selected: Boolean(purpose.selected),
|
|
138
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
const payload = {
|
|
142
|
+
notice_uuid: noticeUuid,
|
|
143
|
+
purposes: validatedPurposes,
|
|
144
|
+
select_all_mandatory: false,
|
|
145
|
+
source: "WEB",
|
|
146
|
+
declined: Boolean(declined),
|
|
147
|
+
language: language || void 0,
|
|
148
|
+
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : void 0,
|
|
149
|
+
guardian_verification_reference: guardianVerificationReference,
|
|
150
|
+
self_declared_adult: selfDeclaredAdult
|
|
151
|
+
};
|
|
152
|
+
const response = await fetch(
|
|
153
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
|
|
154
|
+
{
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: {
|
|
157
|
+
Authorization: `Bearer ${accessToken}`,
|
|
158
|
+
"Content-Type": "application/json"
|
|
159
|
+
},
|
|
160
|
+
body: JSON.stringify(payload),
|
|
161
|
+
signal
|
|
202
162
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
body: JSON.stringify(payload),
|
|
212
|
-
signal
|
|
213
|
-
// Add abort signal for request cancellation
|
|
214
|
-
}
|
|
215
|
-
);
|
|
216
|
-
if (!response.ok) {
|
|
217
|
-
let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
|
|
218
|
-
if (response.status === 400) {
|
|
163
|
+
);
|
|
164
|
+
if (!response.ok) {
|
|
165
|
+
let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
|
|
166
|
+
if (response.status === 400) {
|
|
167
|
+
try {
|
|
168
|
+
const errorData = await response.json();
|
|
169
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
170
|
+
} catch {
|
|
219
171
|
errorMessage = "Invalid request data";
|
|
220
|
-
} else if (response.status === 401) {
|
|
221
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
222
|
-
} else if (response.status === 403) {
|
|
223
|
-
errorMessage = "Forbidden: Access denied";
|
|
224
|
-
} else if (response.status === 404) {
|
|
225
|
-
errorMessage = "Notice not found";
|
|
226
|
-
} else if (response.status >= 500) {
|
|
227
|
-
errorMessage = "Server error: Please try again later";
|
|
228
172
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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";
|
|
232
181
|
}
|
|
233
|
-
|
|
234
|
-
|
|
182
|
+
const error = new Error(errorMessage);
|
|
183
|
+
error.status = response.status;
|
|
184
|
+
throw error;
|
|
185
|
+
}
|
|
186
|
+
apiCache.clear();
|
|
187
|
+
};
|
|
188
|
+
var fetchTTSAudioUrls = async ({
|
|
189
|
+
accessToken,
|
|
190
|
+
baseUrl,
|
|
191
|
+
noticeUuid,
|
|
192
|
+
language,
|
|
193
|
+
signal
|
|
194
|
+
}) => {
|
|
195
|
+
if (!accessToken || !noticeUuid || !language) {
|
|
196
|
+
throw new Error("accessToken, noticeUuid, and language are required");
|
|
197
|
+
}
|
|
198
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
199
|
+
if (!decodedToken) {
|
|
200
|
+
throw new Error("Invalid access token");
|
|
201
|
+
}
|
|
202
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
203
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
204
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
205
|
+
}
|
|
206
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
207
|
+
const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
|
|
208
|
+
const response = await fetch(url, {
|
|
209
|
+
method: "GET",
|
|
210
|
+
headers: {
|
|
211
|
+
Authorization: `Bearer ${accessToken}`,
|
|
212
|
+
Accept: "application/json"
|
|
213
|
+
},
|
|
214
|
+
signal
|
|
215
|
+
});
|
|
216
|
+
if (!response.ok) {
|
|
217
|
+
let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
|
|
218
|
+
if (response.status === 401) {
|
|
219
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
220
|
+
} else if (response.status === 403) {
|
|
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;
|
|
235
229
|
throw error;
|
|
236
230
|
}
|
|
231
|
+
const data = await response.json();
|
|
232
|
+
return data;
|
|
237
233
|
};
|
|
238
|
-
var
|
|
234
|
+
var initiateGuardianVerification = async ({
|
|
239
235
|
accessToken,
|
|
240
236
|
baseUrl,
|
|
241
237
|
guardianName,
|
|
242
238
|
guardianContact,
|
|
243
239
|
guardianRelationship,
|
|
240
|
+
frontendCallbackUrl,
|
|
241
|
+
metadata,
|
|
244
242
|
signal
|
|
245
|
-
// AbortSignal for request cancellation
|
|
246
243
|
}) => {
|
|
244
|
+
var _a;
|
|
247
245
|
try {
|
|
248
246
|
if (!accessToken) {
|
|
249
247
|
throw new Error("accessToken is required");
|
|
250
248
|
}
|
|
251
249
|
if (!(guardianName == null ? void 0 : guardianName.trim())) {
|
|
252
|
-
throw new Error("
|
|
250
|
+
throw new Error("Guardian name is required");
|
|
253
251
|
}
|
|
254
252
|
if (!(guardianContact == null ? void 0 : guardianContact.trim())) {
|
|
255
|
-
throw new Error("
|
|
253
|
+
throw new Error("Guardian contact is required");
|
|
256
254
|
}
|
|
257
255
|
if (!(guardianRelationship == null ? void 0 : guardianRelationship.trim())) {
|
|
258
|
-
throw new Error("
|
|
256
|
+
throw new Error("Guardian relationship is required");
|
|
259
257
|
}
|
|
260
258
|
const decodedToken = decodeTokenSafely(accessToken);
|
|
261
259
|
if (!decodedToken) {
|
|
@@ -265,14 +263,20 @@ var submitGuardianInfo = async ({
|
|
|
265
263
|
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
266
264
|
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
267
265
|
}
|
|
266
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
268
267
|
const payload = {
|
|
269
268
|
guardian_name: guardianName.trim(),
|
|
270
269
|
guardian_contact: guardianContact.trim(),
|
|
271
270
|
guardian_relationship: guardianRelationship.trim()
|
|
272
271
|
};
|
|
273
|
-
|
|
272
|
+
if (frontendCallbackUrl) {
|
|
273
|
+
payload.frontend_callback_url = frontendCallbackUrl;
|
|
274
|
+
}
|
|
275
|
+
if (metadata) {
|
|
276
|
+
payload.metadata = metadata;
|
|
277
|
+
}
|
|
274
278
|
const response = await fetch(
|
|
275
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian-
|
|
279
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/initiate-verification`,
|
|
276
280
|
{
|
|
277
281
|
method: "POST",
|
|
278
282
|
headers: {
|
|
@@ -281,24 +285,26 @@ var submitGuardianInfo = async ({
|
|
|
281
285
|
},
|
|
282
286
|
body: JSON.stringify(payload),
|
|
283
287
|
signal
|
|
284
|
-
// Add abort signal for request cancellation
|
|
285
288
|
}
|
|
286
289
|
);
|
|
287
290
|
if (!response.ok) {
|
|
288
|
-
let errorMessage = `Failed to
|
|
291
|
+
let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;
|
|
289
292
|
if (response.status === 400) {
|
|
290
|
-
|
|
293
|
+
try {
|
|
294
|
+
const errorData = await response.json();
|
|
295
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
296
|
+
} catch {
|
|
297
|
+
errorMessage = "Invalid request data";
|
|
298
|
+
}
|
|
291
299
|
} else if (response.status === 401) {
|
|
292
300
|
errorMessage = "Unauthorized: Invalid or expired token";
|
|
293
|
-
} else if (response.status === 403) {
|
|
294
|
-
errorMessage = "Forbidden: Access denied";
|
|
295
301
|
} else if (response.status === 404) {
|
|
296
302
|
errorMessage = "Organization or workspace not found";
|
|
297
303
|
} else if (response.status === 422) {
|
|
298
304
|
try {
|
|
299
305
|
const errorData = await response.json();
|
|
300
|
-
errorMessage = errorData.message || "Validation error";
|
|
301
|
-
} catch
|
|
306
|
+
errorMessage = errorData.message || "Validation error: Please check your input";
|
|
307
|
+
} catch {
|
|
302
308
|
errorMessage = "Validation error: Please check your input";
|
|
303
309
|
}
|
|
304
310
|
} else if (response.status >= 500) {
|
|
@@ -308,63 +314,98 @@ var submitGuardianInfo = async ({
|
|
|
308
314
|
error.status = response.status;
|
|
309
315
|
throw error;
|
|
310
316
|
}
|
|
317
|
+
const responseData = await response.json();
|
|
318
|
+
const detail = responseData.detail || responseData;
|
|
319
|
+
if (detail.already_verified) {
|
|
320
|
+
return {
|
|
321
|
+
success: true,
|
|
322
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
323
|
+
already_verified: true,
|
|
324
|
+
verification_reference: detail.verification_reference
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
if (!detail.session_token || !detail.digilocker_redirect_url) {
|
|
328
|
+
throw new Error("Invalid response: missing session_token or digilocker_redirect_url");
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
success: (_a = detail.success) != null ? _a : true,
|
|
332
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
333
|
+
already_verified: false,
|
|
334
|
+
session_token: detail.session_token,
|
|
335
|
+
digilocker_redirect_url: detail.digilocker_redirect_url,
|
|
336
|
+
expires_at: detail.expires_at
|
|
337
|
+
};
|
|
311
338
|
} catch (error) {
|
|
312
|
-
console.error("Error
|
|
339
|
+
console.error("Error initiating guardian verification:", error instanceof Error ? error.message : error);
|
|
313
340
|
throw error;
|
|
314
341
|
}
|
|
315
342
|
};
|
|
316
|
-
var
|
|
343
|
+
var verifyGuardianStatus = async ({
|
|
317
344
|
accessToken,
|
|
318
345
|
baseUrl,
|
|
319
|
-
|
|
320
|
-
language,
|
|
346
|
+
sessionToken,
|
|
321
347
|
signal
|
|
322
|
-
// AbortSignal for request cancellation
|
|
323
348
|
}) => {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
349
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
350
|
+
if (!accessToken || !sessionToken) {
|
|
351
|
+
throw new Error("accessToken and sessionToken are required");
|
|
352
|
+
}
|
|
353
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
354
|
+
if (!decodedToken) {
|
|
355
|
+
throw new Error("Invalid access token");
|
|
356
|
+
}
|
|
357
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
358
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
359
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
360
|
+
}
|
|
361
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
362
|
+
const response = await fetch(
|
|
363
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/verify-status`,
|
|
364
|
+
{
|
|
365
|
+
method: "POST",
|
|
340
366
|
headers: {
|
|
341
367
|
Authorization: `Bearer ${accessToken}`,
|
|
342
|
-
Accept: "application/json",
|
|
343
368
|
"Content-Type": "application/json"
|
|
344
369
|
},
|
|
370
|
+
body: JSON.stringify({
|
|
371
|
+
session_token: sessionToken
|
|
372
|
+
}),
|
|
345
373
|
signal
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
errorMessage =
|
|
354
|
-
}
|
|
355
|
-
errorMessage = "
|
|
356
|
-
} else if (response.status >= 500) {
|
|
357
|
-
errorMessage = "Server error: Please try again later";
|
|
374
|
+
}
|
|
375
|
+
);
|
|
376
|
+
if (!response.ok) {
|
|
377
|
+
let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;
|
|
378
|
+
if (response.status === 400) {
|
|
379
|
+
try {
|
|
380
|
+
const errorData = await response.json();
|
|
381
|
+
errorMessage = errorData.message || ((_a = errorData.detail) == null ? void 0 : _a.message) || "Invalid session token";
|
|
382
|
+
} catch {
|
|
383
|
+
errorMessage = "Invalid session token";
|
|
358
384
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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";
|
|
362
393
|
}
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
} catch (error) {
|
|
394
|
+
const error = new Error(errorMessage);
|
|
395
|
+
error.status = response.status;
|
|
366
396
|
throw error;
|
|
367
397
|
}
|
|
398
|
+
const responseData = await response.json();
|
|
399
|
+
const detail = responseData.detail || responseData;
|
|
400
|
+
return {
|
|
401
|
+
status: (_b = detail.status) != null ? _b : "in_progress",
|
|
402
|
+
guardian_info_uuid: (_c = detail.guardian_info_uuid) != null ? _c : null,
|
|
403
|
+
verification_reference: (_d = detail.verification_reference) != null ? _d : null,
|
|
404
|
+
guardian_details: (_e = detail.guardian_details) != null ? _e : null,
|
|
405
|
+
error: (_f = detail.error) != null ? _f : null,
|
|
406
|
+
error_code: (_g = detail.error_code) != null ? _g : null,
|
|
407
|
+
can_retry: (_h = detail.can_retry) != null ? _h : true
|
|
408
|
+
};
|
|
368
409
|
};
|
|
369
410
|
|
|
370
411
|
// src/RedactoNoticeConsent/assets/redacto-logo.png
|
|
@@ -382,6 +423,52 @@ var DPO_AUDIO_ELEMENT_MAP = [
|
|
|
382
423
|
{ audioKey: "dpo_anchor_text_audio_url", elementId: "dpo-dpo-link" }
|
|
383
424
|
];
|
|
384
425
|
|
|
426
|
+
// src/RedactoNoticeConsent/language-codes.ts
|
|
427
|
+
var LANGUAGE_NAME_TO_BCP47 = {
|
|
428
|
+
English: "en",
|
|
429
|
+
Assamese: "as",
|
|
430
|
+
Bengali: "bn",
|
|
431
|
+
Bodo: "brx",
|
|
432
|
+
Dogri: "doi",
|
|
433
|
+
Gujarati: "gu",
|
|
434
|
+
Hindi: "hi",
|
|
435
|
+
Kannada: "kn",
|
|
436
|
+
Kashmiri: "ks",
|
|
437
|
+
Konkani: "gom",
|
|
438
|
+
Maithili: "mai",
|
|
439
|
+
Malayalam: "ml",
|
|
440
|
+
Manipuri: "mni-Mtei",
|
|
441
|
+
Marathi: "mr",
|
|
442
|
+
Nepali: "ne",
|
|
443
|
+
Odia: "or",
|
|
444
|
+
Punjabi: "pa",
|
|
445
|
+
Sanskrit: "sa",
|
|
446
|
+
Santali: "sat",
|
|
447
|
+
Sindhi: "sd",
|
|
448
|
+
Tamil: "ta",
|
|
449
|
+
Telugu: "te",
|
|
450
|
+
Urdu: "ur"
|
|
451
|
+
};
|
|
452
|
+
var KNOWN_BCP47_CODES = new Set(Object.values(LANGUAGE_NAME_TO_BCP47));
|
|
453
|
+
var toBcp47Code = (language) => {
|
|
454
|
+
if (LANGUAGE_NAME_TO_BCP47[language]) {
|
|
455
|
+
return LANGUAGE_NAME_TO_BCP47[language];
|
|
456
|
+
}
|
|
457
|
+
if (KNOWN_BCP47_CODES.has(language)) {
|
|
458
|
+
return language;
|
|
459
|
+
}
|
|
460
|
+
const lower = language.toLowerCase();
|
|
461
|
+
for (const [name, code] of Object.entries(LANGUAGE_NAME_TO_BCP47)) {
|
|
462
|
+
if (name.toLowerCase() === lower) {
|
|
463
|
+
return code;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if (/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(language)) {
|
|
467
|
+
return language;
|
|
468
|
+
}
|
|
469
|
+
return "en";
|
|
470
|
+
};
|
|
471
|
+
|
|
385
472
|
// src/RedactoNoticeConsent/injectStyles.ts
|
|
386
473
|
var stylesInjected = false;
|
|
387
474
|
var injectCheckboxStyles = () => {
|
|
@@ -512,6 +599,17 @@ var injectCheckboxStyles = () => {
|
|
|
512
599
|
outline: 3px solid #FFF9C4 !important;
|
|
513
600
|
outline-offset: 2px !important;
|
|
514
601
|
}
|
|
602
|
+
|
|
603
|
+
/* Spinner animation for verification screens */
|
|
604
|
+
@keyframes spin {
|
|
605
|
+
from { transform: rotate(0deg); }
|
|
606
|
+
to { transform: rotate(360deg); }
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/* DigiLocker callback retry button hover */
|
|
610
|
+
.redacto-dl-retry-btn:hover {
|
|
611
|
+
background-color: #2563eb !important;
|
|
612
|
+
}
|
|
515
613
|
`;
|
|
516
614
|
document.head.appendChild(style);
|
|
517
615
|
stylesInjected = true;
|
|
@@ -894,6 +992,69 @@ var useMediaQuery = (query) => {
|
|
|
894
992
|
return matches;
|
|
895
993
|
};
|
|
896
994
|
|
|
995
|
+
// src/RedactoNoticeConsent/services/storage.ts
|
|
996
|
+
var STORAGE_KEY = "redacto_consent_sdk_state";
|
|
997
|
+
var STATE_EXPIRY_MS = 30 * 60 * 1e3;
|
|
998
|
+
var isBrowser = () => {
|
|
999
|
+
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
1000
|
+
};
|
|
1001
|
+
var saveConsentState = (state) => {
|
|
1002
|
+
if (!isBrowser()) {
|
|
1003
|
+
console.warn("SessionStorage not available - state not persisted");
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
try {
|
|
1007
|
+
const stateWithTimestamp = {
|
|
1008
|
+
...state,
|
|
1009
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1010
|
+
};
|
|
1011
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));
|
|
1012
|
+
} catch (error) {
|
|
1013
|
+
console.error("Failed to save consent state:", error);
|
|
1014
|
+
}
|
|
1015
|
+
};
|
|
1016
|
+
var getConsentState = () => {
|
|
1017
|
+
if (!isBrowser()) {
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
try {
|
|
1021
|
+
const savedState = sessionStorage.getItem(STORAGE_KEY);
|
|
1022
|
+
if (!savedState) {
|
|
1023
|
+
return null;
|
|
1024
|
+
}
|
|
1025
|
+
const parsed = JSON.parse(savedState);
|
|
1026
|
+
const stateAge = Date.now() - new Date(parsed.timestamp).getTime();
|
|
1027
|
+
if (stateAge > STATE_EXPIRY_MS) {
|
|
1028
|
+
clearConsentState();
|
|
1029
|
+
return null;
|
|
1030
|
+
}
|
|
1031
|
+
return parsed;
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
console.error("Failed to get consent state:", error);
|
|
1034
|
+
return null;
|
|
1035
|
+
}
|
|
1036
|
+
};
|
|
1037
|
+
var clearConsentState = () => {
|
|
1038
|
+
if (!isBrowser()) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
try {
|
|
1042
|
+
sessionStorage.removeItem(STORAGE_KEY);
|
|
1043
|
+
} catch (error) {
|
|
1044
|
+
console.error("Failed to clear consent state:", error);
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
var updateConsentState = (updates) => {
|
|
1048
|
+
const currentState = getConsentState();
|
|
1049
|
+
if (currentState) {
|
|
1050
|
+
saveConsentState({
|
|
1051
|
+
...currentState,
|
|
1052
|
+
...updates,
|
|
1053
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
|
|
897
1058
|
// src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
|
|
898
1059
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
899
1060
|
var PurposeItem = ({
|
|
@@ -1201,6 +1362,12 @@ var PurposeItem = ({
|
|
|
1201
1362
|
)
|
|
1202
1363
|
] }, purpose.uuid);
|
|
1203
1364
|
};
|
|
1365
|
+
var RELATIONSHIP_OPTIONS = [
|
|
1366
|
+
{ value: "Father", label: "Father" },
|
|
1367
|
+
{ value: "Mother", label: "Mother" },
|
|
1368
|
+
{ value: "Legal Guardian", label: "Legal Guardian" },
|
|
1369
|
+
{ value: "Grandparent", label: "Grandparent" }
|
|
1370
|
+
];
|
|
1204
1371
|
var GuardianForm = ({
|
|
1205
1372
|
formData,
|
|
1206
1373
|
errors,
|
|
@@ -1217,34 +1384,128 @@ var GuardianForm = ({
|
|
|
1217
1384
|
declineButtonStyle,
|
|
1218
1385
|
logoUrl
|
|
1219
1386
|
}) => {
|
|
1387
|
+
var _a, _b, _c, _d, _e;
|
|
1388
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState2(false);
|
|
1389
|
+
const [focusedIndex, setFocusedIndex] = useState2(-1);
|
|
1390
|
+
const [openUpward, setOpenUpward] = useState2(false);
|
|
1391
|
+
const dropdownRef = useRef(null);
|
|
1392
|
+
const optionsRef = useRef(null);
|
|
1393
|
+
useEffect2(() => {
|
|
1394
|
+
if (!isDropdownOpen) return;
|
|
1395
|
+
const handleClickOutside = (e) => {
|
|
1396
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1397
|
+
setIsDropdownOpen(false);
|
|
1398
|
+
setFocusedIndex(-1);
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1401
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1402
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1403
|
+
}, [isDropdownOpen]);
|
|
1404
|
+
useEffect2(() => {
|
|
1405
|
+
if (!isDropdownOpen || !dropdownRef.current) return;
|
|
1406
|
+
const rect = dropdownRef.current.getBoundingClientRect();
|
|
1407
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1408
|
+
const dropdownHeight = 220;
|
|
1409
|
+
setOpenUpward(spaceBelow < dropdownHeight && rect.top > dropdownHeight);
|
|
1410
|
+
}, [isDropdownOpen]);
|
|
1411
|
+
const handleSelect = (value) => {
|
|
1412
|
+
onChange("guardianRelationship", value);
|
|
1413
|
+
setIsDropdownOpen(false);
|
|
1414
|
+
setFocusedIndex(-1);
|
|
1415
|
+
};
|
|
1416
|
+
const handleKeyDown = (e) => {
|
|
1417
|
+
if (!isDropdownOpen) {
|
|
1418
|
+
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
|
|
1419
|
+
e.preventDefault();
|
|
1420
|
+
setIsDropdownOpen(true);
|
|
1421
|
+
setFocusedIndex(0);
|
|
1422
|
+
}
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
switch (e.key) {
|
|
1426
|
+
case "ArrowDown":
|
|
1427
|
+
e.preventDefault();
|
|
1428
|
+
setFocusedIndex((prev) => Math.min(prev + 1, RELATIONSHIP_OPTIONS.length - 1));
|
|
1429
|
+
break;
|
|
1430
|
+
case "ArrowUp":
|
|
1431
|
+
e.preventDefault();
|
|
1432
|
+
setFocusedIndex((prev) => Math.max(prev - 1, 0));
|
|
1433
|
+
break;
|
|
1434
|
+
case "Enter":
|
|
1435
|
+
case " ":
|
|
1436
|
+
e.preventDefault();
|
|
1437
|
+
if (focusedIndex >= 0) handleSelect(RELATIONSHIP_OPTIONS[focusedIndex].value);
|
|
1438
|
+
break;
|
|
1439
|
+
case "Escape":
|
|
1440
|
+
case "Tab":
|
|
1441
|
+
setIsDropdownOpen(false);
|
|
1442
|
+
setFocusedIndex(-1);
|
|
1443
|
+
break;
|
|
1444
|
+
}
|
|
1445
|
+
};
|
|
1446
|
+
useEffect2(() => {
|
|
1447
|
+
var _a2;
|
|
1448
|
+
if (focusedIndex >= 0 && optionsRef.current) {
|
|
1449
|
+
const option = optionsRef.current.children[focusedIndex];
|
|
1450
|
+
(_a2 = option == null ? void 0 : option.scrollIntoView) == null ? void 0 : _a2.call(option, { block: "nearest" });
|
|
1451
|
+
}
|
|
1452
|
+
}, [focusedIndex]);
|
|
1453
|
+
const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
|
|
1454
|
+
const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
|
|
1455
|
+
const bgColor = (settings == null ? void 0 : settings.backgroundColor) || "#ffffff";
|
|
1456
|
+
const radius = (settings == null ? void 0 : settings.borderRadius) || "8px";
|
|
1457
|
+
const font = (settings == null ? void 0 : settings.font) || "inherit";
|
|
1220
1458
|
const inputStyle = {
|
|
1221
1459
|
width: "100%",
|
|
1222
1460
|
padding: "10px 12px",
|
|
1223
|
-
border: `1px solid ${
|
|
1224
|
-
borderRadius:
|
|
1461
|
+
border: `1px solid ${borderColor}`,
|
|
1462
|
+
borderRadius: radius,
|
|
1225
1463
|
fontSize: "13px",
|
|
1226
|
-
fontFamily:
|
|
1227
|
-
color:
|
|
1228
|
-
backgroundColor:
|
|
1229
|
-
marginBottom: "
|
|
1230
|
-
boxSizing: "border-box"
|
|
1464
|
+
fontFamily: font,
|
|
1465
|
+
color: textColor,
|
|
1466
|
+
backgroundColor: bgColor,
|
|
1467
|
+
marginBottom: "2px",
|
|
1468
|
+
boxSizing: "border-box",
|
|
1469
|
+
outline: "none"
|
|
1231
1470
|
};
|
|
1232
1471
|
const errorStyle = {
|
|
1233
1472
|
color: "#DC2626",
|
|
1234
|
-
fontSize: "
|
|
1473
|
+
fontSize: "11px",
|
|
1235
1474
|
marginTop: "4px",
|
|
1236
|
-
marginBottom: "
|
|
1475
|
+
marginBottom: "0px"
|
|
1237
1476
|
};
|
|
1238
1477
|
const labelStyle = {
|
|
1239
1478
|
...componentTextStyle,
|
|
1240
1479
|
fontSize: "13px",
|
|
1241
1480
|
fontWeight: "500",
|
|
1242
|
-
marginBottom: "
|
|
1481
|
+
marginBottom: "4px",
|
|
1243
1482
|
display: "block"
|
|
1244
1483
|
};
|
|
1484
|
+
const hintStyle = {
|
|
1485
|
+
fontSize: "11px",
|
|
1486
|
+
color: "#667085",
|
|
1487
|
+
marginTop: "2px",
|
|
1488
|
+
marginBottom: "0px",
|
|
1489
|
+
lineHeight: "1.4"
|
|
1490
|
+
};
|
|
1491
|
+
const infoBannerStyle = {
|
|
1492
|
+
display: "flex",
|
|
1493
|
+
alignItems: "flex-start",
|
|
1494
|
+
gap: "8px",
|
|
1495
|
+
padding: "10px 12px",
|
|
1496
|
+
backgroundColor: "#EFF6FF",
|
|
1497
|
+
border: "1px solid #BFDBFE",
|
|
1498
|
+
borderRadius: radius,
|
|
1499
|
+
marginBottom: "16px",
|
|
1500
|
+
fontSize: "12px",
|
|
1501
|
+
lineHeight: "1.5",
|
|
1502
|
+
color: "#1E40AF"
|
|
1503
|
+
};
|
|
1504
|
+
const selectedLabel = (_a = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)) == null ? void 0 : _a.label;
|
|
1505
|
+
const hasError = Boolean(errors.guardianRelationship);
|
|
1245
1506
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1246
1507
|
/* @__PURE__ */ jsx("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ jsxs("div", { style: styles3.topLeft, children: [
|
|
1247
|
-
/* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "
|
|
1508
|
+
/* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1248
1509
|
/* @__PURE__ */ jsx(
|
|
1249
1510
|
"h2",
|
|
1250
1511
|
{
|
|
@@ -1256,7 +1517,7 @@ var GuardianForm = ({
|
|
|
1256
1517
|
fontSize: "16px",
|
|
1257
1518
|
fontWeight: 600
|
|
1258
1519
|
},
|
|
1259
|
-
children: "Guardian
|
|
1520
|
+
children: "Guardian Verification"
|
|
1260
1521
|
}
|
|
1261
1522
|
)
|
|
1262
1523
|
] }) }),
|
|
@@ -1276,31 +1537,49 @@ var GuardianForm = ({
|
|
|
1276
1537
|
...styles3.privacyText,
|
|
1277
1538
|
...responsiveStyles.privacyText,
|
|
1278
1539
|
...componentTextStyle,
|
|
1279
|
-
fontSize: "
|
|
1280
|
-
lineHeight: "1.
|
|
1540
|
+
fontSize: "13px",
|
|
1541
|
+
lineHeight: "1.5",
|
|
1542
|
+
marginBottom: "12px"
|
|
1281
1543
|
},
|
|
1282
|
-
children: "
|
|
1544
|
+
children: "Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed."
|
|
1283
1545
|
}
|
|
1284
1546
|
),
|
|
1547
|
+
/* @__PURE__ */ jsxs("div", { style: infoBannerStyle, children: [
|
|
1548
|
+
/* @__PURE__ */ jsxs(
|
|
1549
|
+
"svg",
|
|
1550
|
+
{
|
|
1551
|
+
width: "16",
|
|
1552
|
+
height: "16",
|
|
1553
|
+
viewBox: "0 0 24 24",
|
|
1554
|
+
fill: "none",
|
|
1555
|
+
stroke: "#2563EB",
|
|
1556
|
+
strokeWidth: "2",
|
|
1557
|
+
strokeLinecap: "round",
|
|
1558
|
+
strokeLinejoin: "round",
|
|
1559
|
+
style: { flexShrink: 0, marginTop: "1px" },
|
|
1560
|
+
children: [
|
|
1561
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1562
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
1563
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
1564
|
+
]
|
|
1565
|
+
}
|
|
1566
|
+
),
|
|
1567
|
+
/* @__PURE__ */ jsx("span", { children: "The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document." })
|
|
1568
|
+
] }),
|
|
1285
1569
|
/* @__PURE__ */ jsxs(
|
|
1286
1570
|
"div",
|
|
1287
1571
|
{
|
|
1288
1572
|
style: {
|
|
1289
1573
|
display: "flex",
|
|
1290
1574
|
flexDirection: "column",
|
|
1291
|
-
gap: "
|
|
1292
|
-
marginTop: "16px"
|
|
1575
|
+
gap: "14px"
|
|
1293
1576
|
},
|
|
1294
1577
|
children: [
|
|
1295
1578
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1296
|
-
/* @__PURE__ */
|
|
1297
|
-
"
|
|
1298
|
-
{
|
|
1299
|
-
|
|
1300
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1301
|
-
children: "Name of Guardian *"
|
|
1302
|
-
}
|
|
1303
|
-
),
|
|
1579
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "guardianName", style: labelStyle, children: [
|
|
1580
|
+
"Guardian's Full Name ",
|
|
1581
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1582
|
+
] }),
|
|
1304
1583
|
/* @__PURE__ */ jsx(
|
|
1305
1584
|
"input",
|
|
1306
1585
|
{
|
|
@@ -1310,62 +1589,170 @@ var GuardianForm = ({
|
|
|
1310
1589
|
onChange: (e) => onChange("guardianName", e.target.value),
|
|
1311
1590
|
style: {
|
|
1312
1591
|
...inputStyle,
|
|
1313
|
-
borderColor: errors.guardianName ? "#DC2626" :
|
|
1592
|
+
borderColor: errors.guardianName ? "#DC2626" : borderColor
|
|
1314
1593
|
},
|
|
1315
|
-
placeholder: "
|
|
1594
|
+
placeholder: "e.g. Rajesh Kumar",
|
|
1595
|
+
autoComplete: "name",
|
|
1596
|
+
"aria-describedby": "guardianName-hint"
|
|
1316
1597
|
}
|
|
1317
1598
|
),
|
|
1318
|
-
|
|
1599
|
+
/* @__PURE__ */ jsx("p", { id: "guardianName-hint", style: hintStyle, children: "Enter the full name as per government ID (Aadhaar, PAN, etc.)" }),
|
|
1600
|
+
errors.guardianName && /* @__PURE__ */ jsx("div", { style: errorStyle, role: "alert", children: errors.guardianName })
|
|
1319
1601
|
] }),
|
|
1320
1602
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1321
|
-
/* @__PURE__ */
|
|
1322
|
-
"
|
|
1323
|
-
{
|
|
1324
|
-
|
|
1325
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1326
|
-
children: "Contact of Guardian *"
|
|
1327
|
-
}
|
|
1328
|
-
),
|
|
1603
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "guardianContact", style: labelStyle, children: [
|
|
1604
|
+
"Guardian's Phone Number ",
|
|
1605
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1606
|
+
] }),
|
|
1329
1607
|
/* @__PURE__ */ jsx(
|
|
1330
1608
|
"input",
|
|
1331
1609
|
{
|
|
1332
1610
|
id: "guardianContact",
|
|
1333
|
-
type: "
|
|
1611
|
+
type: "tel",
|
|
1612
|
+
inputMode: "tel",
|
|
1334
1613
|
value: formData.guardianContact,
|
|
1335
1614
|
onChange: (e) => onChange("guardianContact", e.target.value),
|
|
1336
1615
|
style: {
|
|
1337
1616
|
...inputStyle,
|
|
1338
|
-
borderColor: errors.guardianContact ? "#DC2626" :
|
|
1617
|
+
borderColor: errors.guardianContact ? "#DC2626" : borderColor
|
|
1339
1618
|
},
|
|
1340
|
-
placeholder: "
|
|
1619
|
+
placeholder: "e.g. 9876543210",
|
|
1620
|
+
autoComplete: "tel",
|
|
1621
|
+
"aria-describedby": "guardianContact-hint"
|
|
1341
1622
|
}
|
|
1342
1623
|
),
|
|
1343
|
-
|
|
1624
|
+
/* @__PURE__ */ jsx("p", { id: "guardianContact-hint", style: hintStyle, children: "Mobile number linked to guardian's Aadhaar" }),
|
|
1625
|
+
errors.guardianContact && /* @__PURE__ */ jsx("div", { style: errorStyle, role: "alert", children: errors.guardianContact })
|
|
1344
1626
|
] }),
|
|
1345
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1346
|
-
/* @__PURE__ */
|
|
1347
|
-
"
|
|
1627
|
+
/* @__PURE__ */ jsxs("div", { ref: dropdownRef, style: { position: "relative" }, children: [
|
|
1628
|
+
/* @__PURE__ */ jsxs("label", { id: "guardianRelationship-label", style: labelStyle, children: [
|
|
1629
|
+
"Relationship ",
|
|
1630
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1631
|
+
] }),
|
|
1632
|
+
/* @__PURE__ */ jsxs(
|
|
1633
|
+
"div",
|
|
1348
1634
|
{
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1635
|
+
role: "combobox",
|
|
1636
|
+
"aria-expanded": isDropdownOpen,
|
|
1637
|
+
"aria-haspopup": "listbox",
|
|
1638
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1639
|
+
"aria-controls": "guardianRelationship-listbox",
|
|
1640
|
+
"aria-activedescendant": focusedIndex >= 0 ? `guardianRelationship-option-${focusedIndex}` : void 0,
|
|
1641
|
+
tabIndex: 0,
|
|
1642
|
+
onClick: () => {
|
|
1643
|
+
setIsDropdownOpen((prev) => !prev);
|
|
1644
|
+
setFocusedIndex(-1);
|
|
1645
|
+
},
|
|
1646
|
+
onKeyDown: handleKeyDown,
|
|
1647
|
+
style: {
|
|
1648
|
+
...inputStyle,
|
|
1649
|
+
borderColor: hasError ? "#DC2626" : isDropdownOpen ? ((_c = (_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.backgroundColor) || "#3b82f6" : borderColor,
|
|
1650
|
+
boxShadow: isDropdownOpen ? `0 0 0 1px ${((_e = (_d = settings == null ? void 0 : settings.button) == null ? void 0 : _d.accept) == null ? void 0 : _e.backgroundColor) || "#3b82f6"}` : "none",
|
|
1651
|
+
color: selectedLabel ? textColor : "#9CA3AF",
|
|
1652
|
+
cursor: "pointer",
|
|
1653
|
+
display: "flex",
|
|
1654
|
+
alignItems: "center",
|
|
1655
|
+
justifyContent: "space-between",
|
|
1656
|
+
userSelect: "none",
|
|
1657
|
+
transition: "border-color 0.15s, box-shadow 0.15s"
|
|
1658
|
+
},
|
|
1659
|
+
children: [
|
|
1660
|
+
/* @__PURE__ */ jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selectedLabel || "Select relationship" }),
|
|
1661
|
+
/* @__PURE__ */ jsx(
|
|
1662
|
+
"svg",
|
|
1663
|
+
{
|
|
1664
|
+
width: "14",
|
|
1665
|
+
height: "14",
|
|
1666
|
+
viewBox: "0 0 24 24",
|
|
1667
|
+
fill: "none",
|
|
1668
|
+
stroke: "#667085",
|
|
1669
|
+
strokeWidth: "2",
|
|
1670
|
+
strokeLinecap: "round",
|
|
1671
|
+
strokeLinejoin: "round",
|
|
1672
|
+
style: {
|
|
1673
|
+
flexShrink: 0,
|
|
1674
|
+
marginLeft: "8px",
|
|
1675
|
+
transform: isDropdownOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
1676
|
+
transition: "transform 0.2s"
|
|
1677
|
+
},
|
|
1678
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
|
|
1679
|
+
}
|
|
1680
|
+
)
|
|
1681
|
+
]
|
|
1352
1682
|
}
|
|
1353
1683
|
),
|
|
1354
|
-
/* @__PURE__ */ jsx(
|
|
1355
|
-
"
|
|
1684
|
+
isDropdownOpen && /* @__PURE__ */ jsx(
|
|
1685
|
+
"div",
|
|
1356
1686
|
{
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1687
|
+
ref: optionsRef,
|
|
1688
|
+
id: "guardianRelationship-listbox",
|
|
1689
|
+
role: "listbox",
|
|
1690
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1361
1691
|
style: {
|
|
1362
|
-
|
|
1363
|
-
|
|
1692
|
+
position: "absolute",
|
|
1693
|
+
...openUpward ? { bottom: "calc(100% + 4px)" } : { top: "calc(100% + 4px)" },
|
|
1694
|
+
left: 0,
|
|
1695
|
+
right: 0,
|
|
1696
|
+
backgroundColor: bgColor,
|
|
1697
|
+
border: `1px solid ${borderColor}`,
|
|
1698
|
+
borderRadius: radius,
|
|
1699
|
+
boxShadow: openUpward ? "0 -4px 12px rgba(0, 0, 0, 0.1), 0 -1px 3px rgba(0, 0, 0, 0.06)" : "0 4px 12px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.06)",
|
|
1700
|
+
zIndex: 50,
|
|
1701
|
+
overflow: "hidden",
|
|
1702
|
+
padding: "4px 0",
|
|
1703
|
+
maxHeight: "220px",
|
|
1704
|
+
overflowY: "auto"
|
|
1364
1705
|
},
|
|
1365
|
-
|
|
1706
|
+
children: RELATIONSHIP_OPTIONS.map((option, index) => {
|
|
1707
|
+
var _a2, _b2;
|
|
1708
|
+
const isSelected = formData.guardianRelationship === option.value;
|
|
1709
|
+
const isFocused = focusedIndex === index;
|
|
1710
|
+
const accentColor = ((_b2 = (_a2 = settings == null ? void 0 : settings.button) == null ? void 0 : _a2.accept) == null ? void 0 : _b2.backgroundColor) || "#3b82f6";
|
|
1711
|
+
return /* @__PURE__ */ jsxs(
|
|
1712
|
+
"div",
|
|
1713
|
+
{
|
|
1714
|
+
id: `guardianRelationship-option-${index}`,
|
|
1715
|
+
role: "option",
|
|
1716
|
+
"aria-selected": isSelected,
|
|
1717
|
+
onClick: () => handleSelect(option.value),
|
|
1718
|
+
onMouseEnter: () => setFocusedIndex(index),
|
|
1719
|
+
style: {
|
|
1720
|
+
padding: "9px 12px",
|
|
1721
|
+
fontSize: "13px",
|
|
1722
|
+
fontFamily: font,
|
|
1723
|
+
color: isSelected ? accentColor : textColor,
|
|
1724
|
+
backgroundColor: isFocused ? "#F3F4F6" : "transparent",
|
|
1725
|
+
cursor: "pointer",
|
|
1726
|
+
display: "flex",
|
|
1727
|
+
alignItems: "center",
|
|
1728
|
+
justifyContent: "space-between",
|
|
1729
|
+
transition: "background-color 0.1s"
|
|
1730
|
+
},
|
|
1731
|
+
children: [
|
|
1732
|
+
/* @__PURE__ */ jsx("span", { children: option.label }),
|
|
1733
|
+
isSelected && /* @__PURE__ */ jsx(
|
|
1734
|
+
"svg",
|
|
1735
|
+
{
|
|
1736
|
+
width: "14",
|
|
1737
|
+
height: "14",
|
|
1738
|
+
viewBox: "0 0 24 24",
|
|
1739
|
+
fill: "none",
|
|
1740
|
+
stroke: accentColor,
|
|
1741
|
+
strokeWidth: "2.5",
|
|
1742
|
+
strokeLinecap: "round",
|
|
1743
|
+
strokeLinejoin: "round",
|
|
1744
|
+
style: { flexShrink: 0 },
|
|
1745
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
1746
|
+
}
|
|
1747
|
+
)
|
|
1748
|
+
]
|
|
1749
|
+
},
|
|
1750
|
+
option.value
|
|
1751
|
+
);
|
|
1752
|
+
})
|
|
1366
1753
|
}
|
|
1367
1754
|
),
|
|
1368
|
-
errors.guardianRelationship && /* @__PURE__ */ jsx("div", { style: errorStyle, children: errors.guardianRelationship })
|
|
1755
|
+
errors.guardianRelationship && /* @__PURE__ */ jsx("div", { style: errorStyle, role: "alert", children: errors.guardianRelationship })
|
|
1369
1756
|
] })
|
|
1370
1757
|
]
|
|
1371
1758
|
}
|
|
@@ -1376,7 +1763,7 @@ var GuardianForm = ({
|
|
|
1376
1763
|
role: "alert",
|
|
1377
1764
|
style: {
|
|
1378
1765
|
color: "#DC2626",
|
|
1379
|
-
fontSize: "
|
|
1766
|
+
fontSize: "13px",
|
|
1380
1767
|
marginTop: "16px",
|
|
1381
1768
|
padding: "12px",
|
|
1382
1769
|
borderRadius: "6px",
|
|
@@ -1412,8 +1799,8 @@ var GuardianForm = ({
|
|
|
1412
1799
|
onClick: onNext,
|
|
1413
1800
|
disabled: isSubmitting,
|
|
1414
1801
|
type: "button",
|
|
1415
|
-
"aria-label": isSubmitting ? "
|
|
1416
|
-
children: isSubmitting ? "
|
|
1802
|
+
"aria-label": isSubmitting ? "Verifying guardian identity" : "Proceed to guardian verification",
|
|
1803
|
+
children: isSubmitting ? "Verifying..." : "Verify via DigiLocker"
|
|
1417
1804
|
}
|
|
1418
1805
|
),
|
|
1419
1806
|
/* @__PURE__ */ jsx(
|
|
@@ -1427,7 +1814,7 @@ var GuardianForm = ({
|
|
|
1427
1814
|
},
|
|
1428
1815
|
onClick: onDecline,
|
|
1429
1816
|
type: "button",
|
|
1430
|
-
"aria-label": "Cancel
|
|
1817
|
+
"aria-label": "Cancel",
|
|
1431
1818
|
children: "Cancel"
|
|
1432
1819
|
}
|
|
1433
1820
|
)
|
|
@@ -1436,6 +1823,266 @@ var GuardianForm = ({
|
|
|
1436
1823
|
)
|
|
1437
1824
|
] });
|
|
1438
1825
|
};
|
|
1826
|
+
var VerificationScreen = ({
|
|
1827
|
+
onBack,
|
|
1828
|
+
onContinue,
|
|
1829
|
+
isInitiating,
|
|
1830
|
+
isPolling,
|
|
1831
|
+
isVerificationComplete,
|
|
1832
|
+
isAutoTransitioning,
|
|
1833
|
+
error,
|
|
1834
|
+
errorCode,
|
|
1835
|
+
canRetry,
|
|
1836
|
+
styles: styles3,
|
|
1837
|
+
responsiveStyles,
|
|
1838
|
+
settings,
|
|
1839
|
+
componentHeadingStyle,
|
|
1840
|
+
componentTextStyle,
|
|
1841
|
+
acceptButtonStyle,
|
|
1842
|
+
declineButtonStyle,
|
|
1843
|
+
logoUrl
|
|
1844
|
+
}) => {
|
|
1845
|
+
var _a, _b;
|
|
1846
|
+
const errorStyle = {
|
|
1847
|
+
color: "#DC2626",
|
|
1848
|
+
fontSize: "14px",
|
|
1849
|
+
marginTop: "16px",
|
|
1850
|
+
padding: "12px",
|
|
1851
|
+
borderRadius: "6px",
|
|
1852
|
+
border: "1px solid #FCA5A5",
|
|
1853
|
+
backgroundColor: "#FEF2F2",
|
|
1854
|
+
textAlign: "center"
|
|
1855
|
+
};
|
|
1856
|
+
const statusStyle = {
|
|
1857
|
+
color: "#059669",
|
|
1858
|
+
fontSize: "14px",
|
|
1859
|
+
marginTop: "16px",
|
|
1860
|
+
padding: "12px",
|
|
1861
|
+
borderRadius: "6px",
|
|
1862
|
+
border: "1px solid #A7F3D0",
|
|
1863
|
+
backgroundColor: "#D1FAE5",
|
|
1864
|
+
textAlign: "center"
|
|
1865
|
+
};
|
|
1866
|
+
const spinnerStyle = {
|
|
1867
|
+
width: "48px",
|
|
1868
|
+
height: "48px",
|
|
1869
|
+
border: "4px solid #e5e7eb",
|
|
1870
|
+
borderTopColor: ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || "#3b82f6",
|
|
1871
|
+
borderRadius: "50%",
|
|
1872
|
+
animation: "spin 1s linear infinite",
|
|
1873
|
+
margin: "24px auto"
|
|
1874
|
+
};
|
|
1875
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1876
|
+
/* @__PURE__ */ jsx("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ jsxs("div", { style: styles3.topLeft, children: [
|
|
1877
|
+
/* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1878
|
+
/* @__PURE__ */ jsx(
|
|
1879
|
+
"h2",
|
|
1880
|
+
{
|
|
1881
|
+
id: "verification-title",
|
|
1882
|
+
style: {
|
|
1883
|
+
...styles3.title,
|
|
1884
|
+
...responsiveStyles.title,
|
|
1885
|
+
...componentHeadingStyle,
|
|
1886
|
+
fontSize: "16px",
|
|
1887
|
+
fontWeight: 600
|
|
1888
|
+
},
|
|
1889
|
+
children: "Guardian Verification"
|
|
1890
|
+
}
|
|
1891
|
+
)
|
|
1892
|
+
] }) }),
|
|
1893
|
+
/* @__PURE__ */ jsxs(
|
|
1894
|
+
"div",
|
|
1895
|
+
{
|
|
1896
|
+
style: {
|
|
1897
|
+
...styles3.middleSection,
|
|
1898
|
+
...responsiveStyles.middleSection,
|
|
1899
|
+
...componentTextStyle,
|
|
1900
|
+
textAlign: "center"
|
|
1901
|
+
},
|
|
1902
|
+
children: [
|
|
1903
|
+
isVerificationComplete && !error ? /* @__PURE__ */ jsxs(
|
|
1904
|
+
"div",
|
|
1905
|
+
{
|
|
1906
|
+
style: {
|
|
1907
|
+
display: "flex",
|
|
1908
|
+
flexDirection: "column",
|
|
1909
|
+
alignItems: "center",
|
|
1910
|
+
justifyContent: "center",
|
|
1911
|
+
flex: 1
|
|
1912
|
+
},
|
|
1913
|
+
children: [
|
|
1914
|
+
/* @__PURE__ */ jsx(
|
|
1915
|
+
"div",
|
|
1916
|
+
{
|
|
1917
|
+
style: {
|
|
1918
|
+
width: "64px",
|
|
1919
|
+
height: "64px",
|
|
1920
|
+
borderRadius: "50%",
|
|
1921
|
+
backgroundColor: "#D1FAE5",
|
|
1922
|
+
display: "flex",
|
|
1923
|
+
alignItems: "center",
|
|
1924
|
+
justifyContent: "center"
|
|
1925
|
+
},
|
|
1926
|
+
children: /* @__PURE__ */ jsx(
|
|
1927
|
+
"svg",
|
|
1928
|
+
{
|
|
1929
|
+
width: "32",
|
|
1930
|
+
height: "32",
|
|
1931
|
+
viewBox: "0 0 24 24",
|
|
1932
|
+
fill: "none",
|
|
1933
|
+
stroke: "#059669",
|
|
1934
|
+
strokeWidth: "2",
|
|
1935
|
+
strokeLinecap: "round",
|
|
1936
|
+
strokeLinejoin: "round",
|
|
1937
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
1938
|
+
}
|
|
1939
|
+
)
|
|
1940
|
+
}
|
|
1941
|
+
),
|
|
1942
|
+
/* @__PURE__ */ jsx(
|
|
1943
|
+
"p",
|
|
1944
|
+
{
|
|
1945
|
+
style: {
|
|
1946
|
+
...componentHeadingStyle,
|
|
1947
|
+
fontSize: "16px",
|
|
1948
|
+
fontWeight: 600,
|
|
1949
|
+
lineHeight: "1.5",
|
|
1950
|
+
marginTop: "12px",
|
|
1951
|
+
marginBottom: "24px"
|
|
1952
|
+
},
|
|
1953
|
+
children: "Verification Completed"
|
|
1954
|
+
}
|
|
1955
|
+
)
|
|
1956
|
+
]
|
|
1957
|
+
}
|
|
1958
|
+
) : (isInitiating || isPolling) && !error ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1959
|
+
/* @__PURE__ */ jsx("div", { style: spinnerStyle }),
|
|
1960
|
+
/* @__PURE__ */ jsx("div", { style: statusStyle, children: isInitiating ? "Opening DigiLocker in a new tab..." : "Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete." })
|
|
1961
|
+
] }) : null,
|
|
1962
|
+
error && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1963
|
+
/* @__PURE__ */ jsx(
|
|
1964
|
+
"div",
|
|
1965
|
+
{
|
|
1966
|
+
style: {
|
|
1967
|
+
width: "64px",
|
|
1968
|
+
height: "64px",
|
|
1969
|
+
borderRadius: "50%",
|
|
1970
|
+
backgroundColor: "#fee2e2",
|
|
1971
|
+
display: "flex",
|
|
1972
|
+
alignItems: "center",
|
|
1973
|
+
justifyContent: "center",
|
|
1974
|
+
margin: "24px auto"
|
|
1975
|
+
},
|
|
1976
|
+
children: /* @__PURE__ */ jsxs(
|
|
1977
|
+
"svg",
|
|
1978
|
+
{
|
|
1979
|
+
width: "32",
|
|
1980
|
+
height: "32",
|
|
1981
|
+
viewBox: "0 0 24 24",
|
|
1982
|
+
fill: "none",
|
|
1983
|
+
stroke: "#dc2626",
|
|
1984
|
+
strokeWidth: "2",
|
|
1985
|
+
strokeLinecap: "round",
|
|
1986
|
+
strokeLinejoin: "round",
|
|
1987
|
+
children: [
|
|
1988
|
+
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1989
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1990
|
+
]
|
|
1991
|
+
}
|
|
1992
|
+
)
|
|
1993
|
+
}
|
|
1994
|
+
),
|
|
1995
|
+
/* @__PURE__ */ jsx(
|
|
1996
|
+
"p",
|
|
1997
|
+
{
|
|
1998
|
+
style: {
|
|
1999
|
+
...styles3.privacyText,
|
|
2000
|
+
...responsiveStyles.privacyText,
|
|
2001
|
+
...componentTextStyle,
|
|
2002
|
+
fontSize: "14px",
|
|
2003
|
+
lineHeight: "1.5",
|
|
2004
|
+
marginBottom: "12px"
|
|
2005
|
+
},
|
|
2006
|
+
children: "Verification failed"
|
|
2007
|
+
}
|
|
2008
|
+
),
|
|
2009
|
+
/* @__PURE__ */ jsx("div", { style: errorStyle, children: error })
|
|
2010
|
+
] })
|
|
2011
|
+
]
|
|
2012
|
+
}
|
|
2013
|
+
),
|
|
2014
|
+
isAutoTransitioning ? null : /* @__PURE__ */ jsx(
|
|
2015
|
+
"div",
|
|
2016
|
+
{
|
|
2017
|
+
style: {
|
|
2018
|
+
...styles3.bottomSection,
|
|
2019
|
+
...responsiveStyles.bottomSection,
|
|
2020
|
+
...componentTextStyle,
|
|
2021
|
+
paddingTop: "12px",
|
|
2022
|
+
display: "flex",
|
|
2023
|
+
gap: "12px",
|
|
2024
|
+
justifyContent: "center"
|
|
2025
|
+
},
|
|
2026
|
+
children: isVerificationComplete && !error ? /* @__PURE__ */ jsx(
|
|
2027
|
+
"button",
|
|
2028
|
+
{
|
|
2029
|
+
style: {
|
|
2030
|
+
...styles3.button,
|
|
2031
|
+
...responsiveStyles.button,
|
|
2032
|
+
...acceptButtonStyle
|
|
2033
|
+
},
|
|
2034
|
+
onClick: onContinue,
|
|
2035
|
+
type: "button",
|
|
2036
|
+
"aria-label": "Continue to consent form",
|
|
2037
|
+
children: "Continue"
|
|
2038
|
+
}
|
|
2039
|
+
) : error && canRetry ? /* @__PURE__ */ jsx(
|
|
2040
|
+
"button",
|
|
2041
|
+
{
|
|
2042
|
+
style: {
|
|
2043
|
+
...styles3.button,
|
|
2044
|
+
...responsiveStyles.button,
|
|
2045
|
+
...styles3.acceptButton,
|
|
2046
|
+
...acceptButtonStyle
|
|
2047
|
+
},
|
|
2048
|
+
onClick: () => onBack(errorCode === "GUARDIAN_UNDER_18"),
|
|
2049
|
+
type: "button",
|
|
2050
|
+
"aria-label": errorCode === "GUARDIAN_UNDER_18" ? "Change guardian details" : "Try verification again",
|
|
2051
|
+
children: errorCode === "GUARDIAN_UNDER_18" ? "Change Guardian" : "Try Again"
|
|
2052
|
+
}
|
|
2053
|
+
) : error ? /* @__PURE__ */ jsx(
|
|
2054
|
+
"button",
|
|
2055
|
+
{
|
|
2056
|
+
style: {
|
|
2057
|
+
...styles3.button,
|
|
2058
|
+
...responsiveStyles.button,
|
|
2059
|
+
...styles3.cancelButton,
|
|
2060
|
+
...declineButtonStyle
|
|
2061
|
+
},
|
|
2062
|
+
onClick: () => onBack(false),
|
|
2063
|
+
type: "button",
|
|
2064
|
+
"aria-label": "Go back",
|
|
2065
|
+
children: "Go Back"
|
|
2066
|
+
}
|
|
2067
|
+
) : /* @__PURE__ */ jsx(
|
|
2068
|
+
"button",
|
|
2069
|
+
{
|
|
2070
|
+
style: {
|
|
2071
|
+
...styles3.button,
|
|
2072
|
+
...responsiveStyles.button,
|
|
2073
|
+
...styles3.cancelButton,
|
|
2074
|
+
...declineButtonStyle
|
|
2075
|
+
},
|
|
2076
|
+
onClick: () => onBack(false),
|
|
2077
|
+
type: "button",
|
|
2078
|
+
"aria-label": "Cancel verification",
|
|
2079
|
+
children: "Cancel"
|
|
2080
|
+
}
|
|
2081
|
+
)
|
|
2082
|
+
}
|
|
2083
|
+
)
|
|
2084
|
+
] });
|
|
2085
|
+
};
|
|
1439
2086
|
var AgeVerification = ({
|
|
1440
2087
|
onYes,
|
|
1441
2088
|
onNo,
|
|
@@ -1598,6 +2245,10 @@ var RedactoNoticeConsent = ({
|
|
|
1598
2245
|
settings,
|
|
1599
2246
|
applicationId,
|
|
1600
2247
|
validateAgainst = "all",
|
|
2248
|
+
digilockerMode = "redirect",
|
|
2249
|
+
// Default to full page redirect (DigiLocker blocks iframe embedding)
|
|
2250
|
+
digilockerCallbackUrl = "/digilocker-callback",
|
|
2251
|
+
// Default callback path
|
|
1601
2252
|
includeFullyConsentedData = false,
|
|
1602
2253
|
reviewModeButtonText = "Continue"
|
|
1603
2254
|
}) => {
|
|
@@ -1653,6 +2304,8 @@ var RedactoNoticeConsent = ({
|
|
|
1653
2304
|
const [currentAudioIndex, setCurrentAudioIndex] = useState2(0);
|
|
1654
2305
|
const [highlightedElementId, setHighlightedElementId] = useState2(null);
|
|
1655
2306
|
const [showAgeVerification, setShowAgeVerification] = useState2(false);
|
|
2307
|
+
const [isMinorFlow, setIsMinorFlow] = useState2(false);
|
|
2308
|
+
const [selfDeclaredAdult, setSelfDeclaredAdult] = useState2(false);
|
|
1656
2309
|
const [showGuardianForm, setShowGuardianForm] = useState2(false);
|
|
1657
2310
|
const [isSubmittingGuardian, setIsSubmittingGuardian] = useState2(false);
|
|
1658
2311
|
const [guardianFormData, setGuardianFormData] = useState2({
|
|
@@ -1661,12 +2314,32 @@ var RedactoNoticeConsent = ({
|
|
|
1661
2314
|
guardianRelationship: ""
|
|
1662
2315
|
});
|
|
1663
2316
|
const [guardianFormErrors, setGuardianFormErrors] = useState2({});
|
|
2317
|
+
const [showVerificationScreen, setShowVerificationScreen] = useState2(false);
|
|
2318
|
+
const [verificationReference, setVerificationReference] = useState2(null);
|
|
2319
|
+
const [isInitiatingVerification, setIsInitiatingVerification] = useState2(false);
|
|
2320
|
+
const [verificationError, setVerificationError] = useState2(
|
|
2321
|
+
null
|
|
2322
|
+
);
|
|
2323
|
+
const [verificationErrorCode, setVerificationErrorCode] = useState2(null);
|
|
2324
|
+
const [canRetryVerification, setCanRetryVerification] = useState2(false);
|
|
2325
|
+
const [isPollingStatus, setIsPollingStatus] = useState2(false);
|
|
2326
|
+
const [isVerificationComplete, setIsVerificationComplete] = useState2(false);
|
|
2327
|
+
const [isAutoTransitioning, setIsAutoTransitioning] = useState2(false);
|
|
1664
2328
|
const modalRef = useRef(null);
|
|
1665
2329
|
const firstFocusableRef = useRef(null);
|
|
1666
2330
|
const lastFocusableRef = useRef(null);
|
|
1667
2331
|
const abortControllerRef = useRef(null);
|
|
1668
2332
|
const isRequestInProgressRef = useRef(false);
|
|
1669
2333
|
const currentAudioRef = useRef(null);
|
|
2334
|
+
const popupCheckIntervalRef = useRef(null);
|
|
2335
|
+
const statusPollIntervalRef = useRef(null);
|
|
2336
|
+
const verificationPopupRef = useRef(null);
|
|
2337
|
+
const pollingCleanupRef = useRef(null);
|
|
2338
|
+
const autoTransitionTimerRef = useRef(null);
|
|
2339
|
+
const digilockerRedirectTimeoutRef = useRef(null);
|
|
2340
|
+
const isInitialMountRef = useRef(true);
|
|
2341
|
+
const isPollingStatusRef = useRef(false);
|
|
2342
|
+
const verificationSessionTokenRef = useRef(null);
|
|
1670
2343
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
1671
2344
|
const responsiveStyles = useMemo(
|
|
1672
2345
|
() => ({
|
|
@@ -1774,6 +2447,7 @@ var RedactoNoticeConsent = ({
|
|
|
1774
2447
|
}, [content, selectedDataElements]);
|
|
1775
2448
|
const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
|
|
1776
2449
|
useEffect2(() => {
|
|
2450
|
+
var _a2, _b2;
|
|
1777
2451
|
clearApiCache();
|
|
1778
2452
|
isRequestInProgressRef.current = false;
|
|
1779
2453
|
setContent(null);
|
|
@@ -1789,6 +2463,8 @@ var RedactoNoticeConsent = ({
|
|
|
1789
2463
|
setIsSubmittingAccept(false);
|
|
1790
2464
|
setIsSubmittingDecline(false);
|
|
1791
2465
|
setShowAgeVerification(false);
|
|
2466
|
+
setIsMinorFlow(false);
|
|
2467
|
+
setSelfDeclaredAdult(false);
|
|
1792
2468
|
setShowGuardianForm(false);
|
|
1793
2469
|
setIsSubmittingGuardian(false);
|
|
1794
2470
|
setGuardianFormData({
|
|
@@ -1797,6 +2473,41 @@ var RedactoNoticeConsent = ({
|
|
|
1797
2473
|
guardianRelationship: ""
|
|
1798
2474
|
});
|
|
1799
2475
|
setGuardianFormErrors({});
|
|
2476
|
+
setShowVerificationScreen(false);
|
|
2477
|
+
setVerificationReference(null);
|
|
2478
|
+
setIsInitiatingVerification(false);
|
|
2479
|
+
setVerificationError(null);
|
|
2480
|
+
setVerificationErrorCode(null);
|
|
2481
|
+
setCanRetryVerification(false);
|
|
2482
|
+
setIsVerificationComplete(false);
|
|
2483
|
+
setIsAutoTransitioning(false);
|
|
2484
|
+
setIsPollingStatus(false);
|
|
2485
|
+
isPollingStatusRef.current = false;
|
|
2486
|
+
verificationSessionTokenRef.current = null;
|
|
2487
|
+
if (popupCheckIntervalRef.current) {
|
|
2488
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
2489
|
+
popupCheckIntervalRef.current = null;
|
|
2490
|
+
}
|
|
2491
|
+
if (statusPollIntervalRef.current) {
|
|
2492
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
2493
|
+
statusPollIntervalRef.current = null;
|
|
2494
|
+
}
|
|
2495
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
2496
|
+
pollingCleanupRef.current = null;
|
|
2497
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
2498
|
+
verificationPopupRef.current = null;
|
|
2499
|
+
if (autoTransitionTimerRef.current) {
|
|
2500
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
2501
|
+
autoTransitionTimerRef.current = null;
|
|
2502
|
+
}
|
|
2503
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
2504
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
2505
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
2506
|
+
}
|
|
2507
|
+
if (!isInitialMountRef.current) {
|
|
2508
|
+
clearConsentState();
|
|
2509
|
+
}
|
|
2510
|
+
isInitialMountRef.current = false;
|
|
1800
2511
|
}, [accessToken]);
|
|
1801
2512
|
useEffect2(() => {
|
|
1802
2513
|
if (hasAlreadyConsented) {
|
|
@@ -2005,7 +2716,11 @@ var RedactoNoticeConsent = ({
|
|
|
2005
2716
|
setInitialDataElementSelections({});
|
|
2006
2717
|
}
|
|
2007
2718
|
if (consentContentData.detail.is_minor) {
|
|
2008
|
-
|
|
2719
|
+
setIsMinorFlow(true);
|
|
2720
|
+
const persistedState = getConsentState();
|
|
2721
|
+
if (!(persistedState == null ? void 0 : persistedState.sessionToken) && !(persistedState == null ? void 0 : persistedState.verificationReference)) {
|
|
2722
|
+
setShowAgeVerification(true);
|
|
2723
|
+
}
|
|
2009
2724
|
}
|
|
2010
2725
|
setIsLoading(false);
|
|
2011
2726
|
} catch (err) {
|
|
@@ -2104,6 +2819,10 @@ var RedactoNoticeConsent = ({
|
|
|
2104
2819
|
const handleAccept = async () => {
|
|
2105
2820
|
const submitController = new AbortController();
|
|
2106
2821
|
try {
|
|
2822
|
+
if (isMinorFlow && !verificationReference) {
|
|
2823
|
+
setErrorMessage("Guardian verification is required before consent can be submitted.");
|
|
2824
|
+
return;
|
|
2825
|
+
}
|
|
2107
2826
|
setIsSubmittingAccept(true);
|
|
2108
2827
|
setIsSubmitting(true);
|
|
2109
2828
|
setErrorMessage(null);
|
|
@@ -2138,7 +2857,10 @@ var RedactoNoticeConsent = ({
|
|
|
2138
2857
|
};
|
|
2139
2858
|
}),
|
|
2140
2859
|
declined: false,
|
|
2860
|
+
language: toBcp47Code(selectedLanguage),
|
|
2141
2861
|
meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
|
|
2862
|
+
guardianVerificationReference: verificationReference || void 0,
|
|
2863
|
+
selfDeclaredAdult: selfDeclaredAdult || void 0,
|
|
2142
2864
|
signal: submitController.signal
|
|
2143
2865
|
});
|
|
2144
2866
|
}
|
|
@@ -2203,17 +2925,102 @@ var RedactoNoticeConsent = ({
|
|
|
2203
2925
|
try {
|
|
2204
2926
|
setIsSubmittingGuardian(true);
|
|
2205
2927
|
setGuardianFormErrors({});
|
|
2206
|
-
|
|
2928
|
+
setVerificationError(null);
|
|
2929
|
+
const callbackUrl = digilockerMode === "popup" ? new URL(digilockerCallbackUrl, window.location.origin).href : void 0;
|
|
2930
|
+
const response = await initiateGuardianVerification({
|
|
2207
2931
|
accessToken,
|
|
2208
2932
|
baseUrl,
|
|
2209
2933
|
guardianName: guardianFormData.guardianName,
|
|
2210
2934
|
guardianContact: guardianFormData.guardianContact,
|
|
2211
2935
|
guardianRelationship: guardianFormData.guardianRelationship,
|
|
2936
|
+
frontendCallbackUrl: callbackUrl,
|
|
2937
|
+
// Only for popup mode
|
|
2212
2938
|
signal: guardianController.signal
|
|
2213
2939
|
});
|
|
2940
|
+
setIsSubmittingGuardian(false);
|
|
2941
|
+
if (response.already_verified && response.verification_reference) {
|
|
2942
|
+
setVerificationReference(response.verification_reference);
|
|
2943
|
+
setShowGuardianForm(false);
|
|
2944
|
+
setShowVerificationScreen(true);
|
|
2945
|
+
setIsInitiatingVerification(false);
|
|
2946
|
+
setIsVerificationComplete(true);
|
|
2947
|
+
setIsAutoTransitioning(true);
|
|
2948
|
+
autoTransitionTimerRef.current = setTimeout(() => {
|
|
2949
|
+
setShowVerificationScreen(false);
|
|
2950
|
+
setIsVerificationComplete(false);
|
|
2951
|
+
setIsAutoTransitioning(false);
|
|
2952
|
+
autoTransitionTimerRef.current = null;
|
|
2953
|
+
}, 1e3);
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
if (!response.session_token || !response.digilocker_redirect_url) {
|
|
2957
|
+
throw new Error("Invalid response from server: missing required fields");
|
|
2958
|
+
}
|
|
2214
2959
|
setShowGuardianForm(false);
|
|
2960
|
+
setShowVerificationScreen(true);
|
|
2961
|
+
setIsInitiatingVerification(true);
|
|
2962
|
+
if (digilockerMode === "redirect") {
|
|
2963
|
+
saveConsentState({
|
|
2964
|
+
flowState: "digilocker-pending",
|
|
2965
|
+
sessionToken: response.session_token,
|
|
2966
|
+
guardianInfoUuid: response.guardian_info_uuid,
|
|
2967
|
+
selectedPurposes,
|
|
2968
|
+
selectedDataElements,
|
|
2969
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2970
|
+
originalUrl: window.location.href,
|
|
2971
|
+
noticeId,
|
|
2972
|
+
baseUrl
|
|
2973
|
+
});
|
|
2974
|
+
try {
|
|
2975
|
+
const openedWindow = window.open(
|
|
2976
|
+
response.digilocker_redirect_url,
|
|
2977
|
+
"_blank"
|
|
2978
|
+
);
|
|
2979
|
+
if (!openedWindow) {
|
|
2980
|
+
console.warn("Popup blocked \u2014 cannot open DigiLocker in new tab");
|
|
2981
|
+
setIsInitiatingVerification(false);
|
|
2982
|
+
setVerificationError(
|
|
2983
|
+
"Unable to open DigiLocker in a new tab. Please allow popups for this site and try again."
|
|
2984
|
+
);
|
|
2985
|
+
return;
|
|
2986
|
+
}
|
|
2987
|
+
try {
|
|
2988
|
+
openedWindow.opener = null;
|
|
2989
|
+
} catch {
|
|
2990
|
+
}
|
|
2991
|
+
} catch (error) {
|
|
2992
|
+
console.error("Failed to open DigiLocker in new tab:", error);
|
|
2993
|
+
setIsInitiatingVerification(false);
|
|
2994
|
+
setVerificationError(
|
|
2995
|
+
"Unable to open DigiLocker. Please allow popups for this site and try again."
|
|
2996
|
+
);
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
setIsInitiatingVerification(false);
|
|
3000
|
+
setIsPollingStatus(true);
|
|
3001
|
+
isPollingStatusRef.current = true;
|
|
3002
|
+
startStatusPolling(response.session_token);
|
|
3003
|
+
} else {
|
|
3004
|
+
setIsInitiatingVerification(true);
|
|
3005
|
+
const popup = window.open(
|
|
3006
|
+
response.digilocker_redirect_url,
|
|
3007
|
+
"digilocker_verification",
|
|
3008
|
+
"width=600,height=700,scrollbars=yes,resizable=yes"
|
|
3009
|
+
);
|
|
3010
|
+
if (popup) {
|
|
3011
|
+
verificationPopupRef.current = popup;
|
|
3012
|
+
startPopupMonitoring(popup);
|
|
3013
|
+
startStatusPolling(response.session_token);
|
|
3014
|
+
} else {
|
|
3015
|
+
setIsInitiatingVerification(false);
|
|
3016
|
+
setVerificationError(
|
|
3017
|
+
"Popup blocked. Please allow popups for this site or use redirect mode."
|
|
3018
|
+
);
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
2215
3021
|
} catch (error) {
|
|
2216
3022
|
const err = error;
|
|
3023
|
+
setIsInitiatingVerification(false);
|
|
2217
3024
|
if (err.status === 422) {
|
|
2218
3025
|
if (err.message.includes("guardian_contact")) {
|
|
2219
3026
|
setGuardianFormErrors({ guardianContact: err.message });
|
|
@@ -2224,23 +3031,265 @@ var RedactoNoticeConsent = ({
|
|
|
2224
3031
|
} else {
|
|
2225
3032
|
setGuardianFormErrors({ general: err.message });
|
|
2226
3033
|
}
|
|
3034
|
+
setShowVerificationScreen(false);
|
|
3035
|
+
setShowGuardianForm(true);
|
|
2227
3036
|
} else {
|
|
2228
3037
|
setGuardianFormErrors({
|
|
2229
|
-
general: err.message || "Failed to
|
|
3038
|
+
general: err.message || "Failed to initiate verification. Please try again."
|
|
2230
3039
|
});
|
|
3040
|
+
setShowVerificationScreen(false);
|
|
3041
|
+
setShowGuardianForm(true);
|
|
2231
3042
|
onError == null ? void 0 : onError(err);
|
|
2232
3043
|
}
|
|
2233
3044
|
} finally {
|
|
2234
3045
|
setIsSubmittingGuardian(false);
|
|
2235
3046
|
}
|
|
2236
|
-
}, [accessToken, baseUrl, guardianFormData, onError]);
|
|
3047
|
+
}, [accessToken, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
|
|
2237
3048
|
const handleAgeVerificationYes = useCallback(() => {
|
|
2238
3049
|
setShowAgeVerification(false);
|
|
3050
|
+
setIsMinorFlow(false);
|
|
3051
|
+
setSelfDeclaredAdult(true);
|
|
2239
3052
|
}, []);
|
|
2240
3053
|
const handleAgeVerificationNo = useCallback(() => {
|
|
2241
3054
|
setShowAgeVerification(false);
|
|
2242
3055
|
setShowGuardianForm(true);
|
|
2243
3056
|
}, []);
|
|
3057
|
+
const handleVerificationContinue = useCallback(() => {
|
|
3058
|
+
setShowVerificationScreen(false);
|
|
3059
|
+
setIsVerificationComplete(false);
|
|
3060
|
+
}, []);
|
|
3061
|
+
const handlePopupClosed = useCallback(async () => {
|
|
3062
|
+
var _a2, _b2;
|
|
3063
|
+
if (popupCheckIntervalRef.current) {
|
|
3064
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3065
|
+
popupCheckIntervalRef.current = null;
|
|
3066
|
+
}
|
|
3067
|
+
if (statusPollIntervalRef.current) {
|
|
3068
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3069
|
+
statusPollIntervalRef.current = null;
|
|
3070
|
+
}
|
|
3071
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3072
|
+
pollingCleanupRef.current = null;
|
|
3073
|
+
verificationPopupRef.current = null;
|
|
3074
|
+
if (!isPollingStatusRef.current) return;
|
|
3075
|
+
const sessionToken = verificationSessionTokenRef.current;
|
|
3076
|
+
if (sessionToken) {
|
|
3077
|
+
try {
|
|
3078
|
+
const response = await verifyGuardianStatus({
|
|
3079
|
+
accessToken,
|
|
3080
|
+
baseUrl,
|
|
3081
|
+
sessionToken
|
|
3082
|
+
});
|
|
3083
|
+
if (response.status === "verified") {
|
|
3084
|
+
const ref = response.verification_reference || ((_b2 = response.guardian_details) == null ? void 0 : _b2.verification_reference);
|
|
3085
|
+
if (ref) {
|
|
3086
|
+
setVerificationReference(ref);
|
|
3087
|
+
setIsVerificationComplete(true);
|
|
3088
|
+
setIsPollingStatus(false);
|
|
3089
|
+
isPollingStatusRef.current = false;
|
|
3090
|
+
setIsInitiatingVerification(false);
|
|
3091
|
+
clearConsentState();
|
|
3092
|
+
return;
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
} catch {
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
3098
|
+
setVerificationError(
|
|
3099
|
+
"Verification window was closed. Please try again."
|
|
3100
|
+
);
|
|
3101
|
+
setIsPollingStatus(false);
|
|
3102
|
+
isPollingStatusRef.current = false;
|
|
3103
|
+
setIsInitiatingVerification(false);
|
|
3104
|
+
}, [accessToken, baseUrl]);
|
|
3105
|
+
const startPopupMonitoring = useCallback((popup) => {
|
|
3106
|
+
popupCheckIntervalRef.current = window.setInterval(() => {
|
|
3107
|
+
if (popup.closed) {
|
|
3108
|
+
handlePopupClosed();
|
|
3109
|
+
}
|
|
3110
|
+
}, 500);
|
|
3111
|
+
}, [handlePopupClosed]);
|
|
3112
|
+
const getVerificationErrorMessage = useCallback(
|
|
3113
|
+
(errorCode, fallbackError) => {
|
|
3114
|
+
switch (errorCode) {
|
|
3115
|
+
case "GUARDIAN_UNDER_18":
|
|
3116
|
+
return "The guardian must be 18 years or older. Please provide details of a different guardian.";
|
|
3117
|
+
case "TOKEN_FAILED":
|
|
3118
|
+
return "DigiLocker verification could not be completed. Please try again.";
|
|
3119
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
3120
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
3121
|
+
case "NO_AUTH_CODE":
|
|
3122
|
+
return "DigiLocker did not return an authorization code. Please try again.";
|
|
3123
|
+
case "SESSION_EXPIRED":
|
|
3124
|
+
return "Verification session has expired. Please try again.";
|
|
3125
|
+
default:
|
|
3126
|
+
return fallbackError || "Verification failed. Please try again.";
|
|
3127
|
+
}
|
|
3128
|
+
},
|
|
3129
|
+
[]
|
|
3130
|
+
);
|
|
3131
|
+
const startStatusPolling = useCallback(
|
|
3132
|
+
(token) => {
|
|
3133
|
+
verificationSessionTokenRef.current = token;
|
|
3134
|
+
setIsPollingStatus(true);
|
|
3135
|
+
isPollingStatusRef.current = true;
|
|
3136
|
+
setVerificationError(null);
|
|
3137
|
+
setVerificationErrorCode(null);
|
|
3138
|
+
setCanRetryVerification(false);
|
|
3139
|
+
let attempts = 0;
|
|
3140
|
+
let consecutiveErrors = 0;
|
|
3141
|
+
let paused = false;
|
|
3142
|
+
const MAX_ATTEMPTS = 40;
|
|
3143
|
+
const MAX_CONSECUTIVE_ERRORS = 3;
|
|
3144
|
+
const POLL_INTERVAL = 3e3;
|
|
3145
|
+
const stopPolling = () => {
|
|
3146
|
+
var _a2;
|
|
3147
|
+
if (statusPollIntervalRef.current) {
|
|
3148
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3149
|
+
statusPollIntervalRef.current = null;
|
|
3150
|
+
}
|
|
3151
|
+
if (popupCheckIntervalRef.current) {
|
|
3152
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3153
|
+
popupCheckIntervalRef.current = null;
|
|
3154
|
+
}
|
|
3155
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3156
|
+
verificationPopupRef.current = null;
|
|
3157
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3158
|
+
pollingCleanupRef.current = null;
|
|
3159
|
+
setIsPollingStatus(false);
|
|
3160
|
+
isPollingStatusRef.current = false;
|
|
3161
|
+
setIsInitiatingVerification(false);
|
|
3162
|
+
};
|
|
3163
|
+
const setError = (message, errorCode, canRetry) => {
|
|
3164
|
+
stopPolling();
|
|
3165
|
+
setVerificationError(message);
|
|
3166
|
+
setVerificationErrorCode(errorCode);
|
|
3167
|
+
setCanRetryVerification(canRetry);
|
|
3168
|
+
};
|
|
3169
|
+
const poll = async () => {
|
|
3170
|
+
var _a2;
|
|
3171
|
+
if (paused) return;
|
|
3172
|
+
attempts++;
|
|
3173
|
+
if (attempts > MAX_ATTEMPTS) {
|
|
3174
|
+
setError(
|
|
3175
|
+
"Verification is taking longer than expected. Please try again.",
|
|
3176
|
+
"SESSION_EXPIRED",
|
|
3177
|
+
true
|
|
3178
|
+
);
|
|
3179
|
+
return;
|
|
3180
|
+
}
|
|
3181
|
+
try {
|
|
3182
|
+
const response = await verifyGuardianStatus({
|
|
3183
|
+
accessToken,
|
|
3184
|
+
baseUrl,
|
|
3185
|
+
sessionToken: token
|
|
3186
|
+
});
|
|
3187
|
+
consecutiveErrors = 0;
|
|
3188
|
+
if (response.status === "verified") {
|
|
3189
|
+
stopPolling();
|
|
3190
|
+
const ref = response.verification_reference || ((_a2 = response.guardian_details) == null ? void 0 : _a2.verification_reference);
|
|
3191
|
+
if (!ref) {
|
|
3192
|
+
setError(
|
|
3193
|
+
"Verification completed but no reference received. Please try again.",
|
|
3194
|
+
null,
|
|
3195
|
+
true
|
|
3196
|
+
);
|
|
3197
|
+
return;
|
|
3198
|
+
}
|
|
3199
|
+
setVerificationReference(ref);
|
|
3200
|
+
setIsVerificationComplete(true);
|
|
3201
|
+
clearConsentState();
|
|
3202
|
+
return;
|
|
3203
|
+
}
|
|
3204
|
+
if (response.status === "failed" || response.status === "expired") {
|
|
3205
|
+
setError(
|
|
3206
|
+
getVerificationErrorMessage(response.error_code, response.error),
|
|
3207
|
+
response.error_code,
|
|
3208
|
+
response.can_retry
|
|
3209
|
+
);
|
|
3210
|
+
return;
|
|
3211
|
+
}
|
|
3212
|
+
if (!paused) {
|
|
3213
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3214
|
+
}
|
|
3215
|
+
} catch (error) {
|
|
3216
|
+
const err = error;
|
|
3217
|
+
if (err.status === 404 || err.status === 410) {
|
|
3218
|
+
setError(
|
|
3219
|
+
"Verification session not found or expired. Please try again.",
|
|
3220
|
+
"SESSION_EXPIRED",
|
|
3221
|
+
true
|
|
3222
|
+
);
|
|
3223
|
+
return;
|
|
3224
|
+
}
|
|
3225
|
+
consecutiveErrors++;
|
|
3226
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
3227
|
+
setError(
|
|
3228
|
+
err.message || "Unable to check verification status. Please try again.",
|
|
3229
|
+
null,
|
|
3230
|
+
true
|
|
3231
|
+
);
|
|
3232
|
+
return;
|
|
3233
|
+
}
|
|
3234
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3235
|
+
}
|
|
3236
|
+
};
|
|
3237
|
+
const onVisibilityChange = () => {
|
|
3238
|
+
if (document.hidden) {
|
|
3239
|
+
paused = true;
|
|
3240
|
+
if (statusPollIntervalRef.current) {
|
|
3241
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3242
|
+
statusPollIntervalRef.current = null;
|
|
3243
|
+
}
|
|
3244
|
+
} else {
|
|
3245
|
+
paused = false;
|
|
3246
|
+
poll();
|
|
3247
|
+
}
|
|
3248
|
+
};
|
|
3249
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
3250
|
+
pollingCleanupRef.current = () => {
|
|
3251
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3252
|
+
};
|
|
3253
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3254
|
+
},
|
|
3255
|
+
[accessToken, baseUrl, getVerificationErrorMessage]
|
|
3256
|
+
);
|
|
3257
|
+
const handleBackToGuardianForm = useCallback((clearName = false) => {
|
|
3258
|
+
var _a2, _b2;
|
|
3259
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3260
|
+
verificationPopupRef.current = null;
|
|
3261
|
+
if (popupCheckIntervalRef.current) {
|
|
3262
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3263
|
+
popupCheckIntervalRef.current = null;
|
|
3264
|
+
}
|
|
3265
|
+
if (statusPollIntervalRef.current) {
|
|
3266
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3267
|
+
statusPollIntervalRef.current = null;
|
|
3268
|
+
}
|
|
3269
|
+
if (autoTransitionTimerRef.current) {
|
|
3270
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3271
|
+
autoTransitionTimerRef.current = null;
|
|
3272
|
+
}
|
|
3273
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3274
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3275
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3276
|
+
}
|
|
3277
|
+
(_b2 = pollingCleanupRef.current) == null ? void 0 : _b2.call(pollingCleanupRef);
|
|
3278
|
+
pollingCleanupRef.current = null;
|
|
3279
|
+
setShowVerificationScreen(false);
|
|
3280
|
+
setShowGuardianForm(true);
|
|
3281
|
+
setVerificationError(null);
|
|
3282
|
+
setVerificationErrorCode(null);
|
|
3283
|
+
setCanRetryVerification(false);
|
|
3284
|
+
setIsInitiatingVerification(false);
|
|
3285
|
+
setIsPollingStatus(false);
|
|
3286
|
+
isPollingStatusRef.current = false;
|
|
3287
|
+
setIsVerificationComplete(false);
|
|
3288
|
+
if (clearName) {
|
|
3289
|
+
setGuardianFormData((prev) => ({ ...prev, guardianName: "" }));
|
|
3290
|
+
}
|
|
3291
|
+
clearConsentState();
|
|
3292
|
+
}, []);
|
|
2244
3293
|
const availableLanguages = useMemo(() => {
|
|
2245
3294
|
if (!content) return [language];
|
|
2246
3295
|
const languages = ["English"];
|
|
@@ -2650,12 +3699,67 @@ var RedactoNoticeConsent = ({
|
|
|
2650
3699
|
}, [content, stopAudio]);
|
|
2651
3700
|
useEffect2(() => {
|
|
2652
3701
|
return () => {
|
|
3702
|
+
var _a2, _b2;
|
|
2653
3703
|
if (abortControllerRef.current) {
|
|
2654
3704
|
abortControllerRef.current.abort();
|
|
2655
3705
|
}
|
|
2656
3706
|
stopAudio();
|
|
3707
|
+
if (popupCheckIntervalRef.current) {
|
|
3708
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3709
|
+
}
|
|
3710
|
+
if (statusPollIntervalRef.current) {
|
|
3711
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3712
|
+
}
|
|
3713
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3714
|
+
pollingCleanupRef.current = null;
|
|
3715
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
3716
|
+
if (autoTransitionTimerRef.current) {
|
|
3717
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3718
|
+
autoTransitionTimerRef.current = null;
|
|
3719
|
+
}
|
|
3720
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3721
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3722
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3723
|
+
}
|
|
2657
3724
|
};
|
|
2658
3725
|
}, [stopAudio]);
|
|
3726
|
+
useEffect2(() => {
|
|
3727
|
+
const persistedState = getConsentState();
|
|
3728
|
+
if (!persistedState) return;
|
|
3729
|
+
if (persistedState.noticeId && persistedState.noticeId !== noticeId) {
|
|
3730
|
+
clearConsentState();
|
|
3731
|
+
return;
|
|
3732
|
+
}
|
|
3733
|
+
const REDIRECT_STATE_MAX_AGE_MS = 15 * 60 * 1e3;
|
|
3734
|
+
if (persistedState.timestamp) {
|
|
3735
|
+
const stateAge = Date.now() - new Date(persistedState.timestamp).getTime();
|
|
3736
|
+
if (stateAge > REDIRECT_STATE_MAX_AGE_MS) {
|
|
3737
|
+
clearConsentState();
|
|
3738
|
+
return;
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
if (persistedState.flowState === "digilocker-pending" && persistedState.sessionToken) {
|
|
3742
|
+
setShowVerificationScreen(true);
|
|
3743
|
+
setShowGuardianForm(false);
|
|
3744
|
+
setShowAgeVerification(false);
|
|
3745
|
+
startStatusPolling(persistedState.sessionToken);
|
|
3746
|
+
} else if (persistedState.verificationResult === "verified" && persistedState.verificationReference) {
|
|
3747
|
+
setVerificationReference(persistedState.verificationReference);
|
|
3748
|
+
setShowVerificationScreen(true);
|
|
3749
|
+
setIsVerificationComplete(true);
|
|
3750
|
+
setShowGuardianForm(false);
|
|
3751
|
+
setShowAgeVerification(false);
|
|
3752
|
+
clearConsentState();
|
|
3753
|
+
} else if (persistedState.verificationResult === "failed" || persistedState.verificationResult === "expired") {
|
|
3754
|
+
setShowVerificationScreen(true);
|
|
3755
|
+
setShowGuardianForm(false);
|
|
3756
|
+
setShowAgeVerification(false);
|
|
3757
|
+
setVerificationError(
|
|
3758
|
+
persistedState.verificationResult === "expired" ? "Verification session has expired. Please try again." : "Verification failed. Please try again."
|
|
3759
|
+
);
|
|
3760
|
+
clearConsentState();
|
|
3761
|
+
}
|
|
3762
|
+
}, [startStatusPolling, noticeId]);
|
|
2659
3763
|
return /* @__PURE__ */ jsx(Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2660
3764
|
blockUI && /* @__PURE__ */ jsx(
|
|
2661
3765
|
"div",
|
|
@@ -2841,6 +3945,27 @@ var RedactoNoticeConsent = ({
|
|
|
2841
3945
|
declineButtonStyle,
|
|
2842
3946
|
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
2843
3947
|
}
|
|
3948
|
+
) }) : showVerificationScreen ? /* @__PURE__ */ jsx("div", { style: { ...styles.content, ...responsiveStyles.content }, children: /* @__PURE__ */ jsx(
|
|
3949
|
+
VerificationScreen,
|
|
3950
|
+
{
|
|
3951
|
+
onBack: handleBackToGuardianForm,
|
|
3952
|
+
onContinue: handleVerificationContinue,
|
|
3953
|
+
isInitiating: isInitiatingVerification,
|
|
3954
|
+
isPolling: isPollingStatus,
|
|
3955
|
+
isVerificationComplete,
|
|
3956
|
+
isAutoTransitioning,
|
|
3957
|
+
error: verificationError,
|
|
3958
|
+
errorCode: verificationErrorCode,
|
|
3959
|
+
canRetry: canRetryVerification,
|
|
3960
|
+
styles,
|
|
3961
|
+
responsiveStyles,
|
|
3962
|
+
settings,
|
|
3963
|
+
componentHeadingStyle,
|
|
3964
|
+
componentTextStyle,
|
|
3965
|
+
acceptButtonStyle,
|
|
3966
|
+
declineButtonStyle,
|
|
3967
|
+
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
3968
|
+
}
|
|
2844
3969
|
) }) : /* @__PURE__ */ jsxs("div", { style: { ...styles.content, ...responsiveStyles.content }, children: [
|
|
2845
3970
|
errorMessage && /* @__PURE__ */ jsxs(
|
|
2846
3971
|
"div",
|
|
@@ -3474,60 +4599,27 @@ var submitConsentEvent2 = async ({
|
|
|
3474
4599
|
var _a, _b;
|
|
3475
4600
|
try {
|
|
3476
4601
|
const apiBaseUrl = baseUrl || BASE_URL2;
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
name: element.name,
|
|
3499
|
-
enabled: Boolean(element.enabled),
|
|
3500
|
-
required: Boolean(element.required),
|
|
3501
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
3502
|
-
}))
|
|
3503
|
-
};
|
|
3504
|
-
})
|
|
3505
|
-
},
|
|
3506
|
-
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
|
|
3507
|
-
};
|
|
3508
|
-
} else {
|
|
3509
|
-
payload = {
|
|
3510
|
-
notice_uuid: noticeUuid,
|
|
3511
|
-
purposes: purposes.map((purpose) => {
|
|
3512
|
-
if (!purpose.uuid) {
|
|
3513
|
-
throw new Error(`Invalid purpose data: missing uuid`);
|
|
3514
|
-
}
|
|
3515
|
-
const dataElements = purpose.data_elements.filter((element) => element.enabled).map((element) => ({
|
|
3516
|
-
uuid: element.uuid,
|
|
3517
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
3518
|
-
}));
|
|
3519
|
-
return {
|
|
3520
|
-
purpose_uuid: purpose.uuid,
|
|
3521
|
-
selected: Boolean(purpose.selected),
|
|
3522
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
3523
|
-
};
|
|
3524
|
-
}),
|
|
3525
|
-
select_all_mandatory: false,
|
|
3526
|
-
source: "WEB",
|
|
3527
|
-
declined,
|
|
3528
|
-
meta_data
|
|
3529
|
-
};
|
|
3530
|
-
}
|
|
4602
|
+
const payload = {
|
|
4603
|
+
notice_uuid: noticeUuid,
|
|
4604
|
+
purposes: purposes.map((purpose) => {
|
|
4605
|
+
if (!purpose.uuid) {
|
|
4606
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
4607
|
+
}
|
|
4608
|
+
const dataElements = purpose.data_elements.filter((element) => element.enabled).map((element) => ({
|
|
4609
|
+
uuid: element.uuid,
|
|
4610
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
4611
|
+
}));
|
|
4612
|
+
return {
|
|
4613
|
+
purpose_uuid: purpose.uuid,
|
|
4614
|
+
selected: Boolean(purpose.selected),
|
|
4615
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
4616
|
+
};
|
|
4617
|
+
}),
|
|
4618
|
+
select_all_mandatory: false,
|
|
4619
|
+
source: "WEB",
|
|
4620
|
+
declined,
|
|
4621
|
+
meta_data
|
|
4622
|
+
};
|
|
3531
4623
|
const response = await fetch(
|
|
3532
4624
|
`${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
|
|
3533
4625
|
{
|
|
@@ -4477,7 +5569,481 @@ var RedactoConsentInlineComponent = ({
|
|
|
4477
5569
|
};
|
|
4478
5570
|
RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
|
|
4479
5571
|
var RedactoConsentInline = memo(RedactoConsentInlineComponent);
|
|
5572
|
+
|
|
5573
|
+
// src/RedactoNoticeConsent/components/DigiLockerCallback.tsx
|
|
5574
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef3, useState as useState5 } from "react";
|
|
5575
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5576
|
+
var DigiLockerCallback = ({
|
|
5577
|
+
accessToken: propAccessToken,
|
|
5578
|
+
baseUrl,
|
|
5579
|
+
onSuccess,
|
|
5580
|
+
onError
|
|
5581
|
+
}) => {
|
|
5582
|
+
const [status, setStatus] = useState5("processing");
|
|
5583
|
+
const [message, setMessage] = useState5("Verifying your guardian...");
|
|
5584
|
+
const [errorDetail, setErrorDetail] = useState5(null);
|
|
5585
|
+
const retryTimeoutRef = useRef3(null);
|
|
5586
|
+
const redirectTimeoutRef = useRef3(null);
|
|
5587
|
+
const isMountedRef = useRef3(true);
|
|
5588
|
+
const getErrorMessage = (errorCode) => {
|
|
5589
|
+
switch (errorCode) {
|
|
5590
|
+
case "GUARDIAN_UNDER_18":
|
|
5591
|
+
return "Guardian verification failed: The guardian must be 18 years or older.";
|
|
5592
|
+
case "SESSION_EXPIRED":
|
|
5593
|
+
return "Verification session has expired. Please restart the verification process.";
|
|
5594
|
+
case "TOKEN_FAILED":
|
|
5595
|
+
return "DigiLocker authentication failed. Please try again.";
|
|
5596
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
5597
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
5598
|
+
case "NO_AUTH_CODE":
|
|
5599
|
+
return "Missing authorization code from DigiLocker. Please try again.";
|
|
5600
|
+
default:
|
|
5601
|
+
return "Verification failed. Please try again.";
|
|
5602
|
+
}
|
|
5603
|
+
};
|
|
5604
|
+
const redirectToOriginalPage = useCallback3(
|
|
5605
|
+
(originalUrl, verificationResult, verificationReference) => {
|
|
5606
|
+
updateConsentState({
|
|
5607
|
+
verificationResult,
|
|
5608
|
+
verificationReference,
|
|
5609
|
+
flowState: verificationResult === "verified" ? "consent-form" : "error"
|
|
5610
|
+
});
|
|
5611
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5612
|
+
window.location.href = originalUrl;
|
|
5613
|
+
}, 1500);
|
|
5614
|
+
},
|
|
5615
|
+
[]
|
|
5616
|
+
);
|
|
5617
|
+
const handleCallback = useCallback3(async () => {
|
|
5618
|
+
var _a, _b;
|
|
5619
|
+
try {
|
|
5620
|
+
const params = new URLSearchParams(window.location.search);
|
|
5621
|
+
const sessionToken = params.get("session_token");
|
|
5622
|
+
const urlStatus = params.get("status");
|
|
5623
|
+
const verificationReference = params.get("verification_reference");
|
|
5624
|
+
const errorCode = params.get("error_code");
|
|
5625
|
+
const persistedState = getConsentState();
|
|
5626
|
+
const originalUrl = (persistedState == null ? void 0 : persistedState.originalUrl) || "/";
|
|
5627
|
+
const storedBaseUrl = persistedState == null ? void 0 : persistedState.baseUrl;
|
|
5628
|
+
const storedSessionToken = persistedState == null ? void 0 : persistedState.sessionToken;
|
|
5629
|
+
const accessToken = propAccessToken;
|
|
5630
|
+
if (!accessToken) {
|
|
5631
|
+
throw new Error("Access token not provided. Please pass accessToken as a prop.");
|
|
5632
|
+
}
|
|
5633
|
+
const activeSessionToken = sessionToken || storedSessionToken;
|
|
5634
|
+
if (!activeSessionToken) {
|
|
5635
|
+
throw new Error("Session token not found. Please restart the verification process.");
|
|
5636
|
+
}
|
|
5637
|
+
let isInIframe = false;
|
|
5638
|
+
try {
|
|
5639
|
+
isInIframe = window.self !== window.top;
|
|
5640
|
+
} catch {
|
|
5641
|
+
isInIframe = true;
|
|
5642
|
+
}
|
|
5643
|
+
if (urlStatus === "verified" && verificationReference) {
|
|
5644
|
+
setStatus("success");
|
|
5645
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5646
|
+
onSuccess == null ? void 0 : onSuccess(verificationReference);
|
|
5647
|
+
if (isInIframe && window.parent) {
|
|
5648
|
+
window.parent.postMessage(
|
|
5649
|
+
{
|
|
5650
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5651
|
+
status: "verified",
|
|
5652
|
+
verificationReference
|
|
5653
|
+
},
|
|
5654
|
+
window.location.origin
|
|
5655
|
+
);
|
|
5656
|
+
return;
|
|
5657
|
+
}
|
|
5658
|
+
redirectToOriginalPage(originalUrl, "verified", verificationReference);
|
|
5659
|
+
return;
|
|
5660
|
+
}
|
|
5661
|
+
if (urlStatus === "failed" || urlStatus === "expired") {
|
|
5662
|
+
const urlErrorCode = errorCode != null ? errorCode : void 0;
|
|
5663
|
+
const errorMessage = getErrorMessage(urlErrorCode);
|
|
5664
|
+
setStatus("error");
|
|
5665
|
+
setMessage("Verification failed");
|
|
5666
|
+
setErrorDetail(errorMessage);
|
|
5667
|
+
onError == null ? void 0 : onError(new Error(errorMessage), urlErrorCode);
|
|
5668
|
+
if (isInIframe && window.parent) {
|
|
5669
|
+
window.parent.postMessage(
|
|
5670
|
+
{
|
|
5671
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5672
|
+
status: urlStatus,
|
|
5673
|
+
errorCode: urlErrorCode,
|
|
5674
|
+
error: errorMessage
|
|
5675
|
+
},
|
|
5676
|
+
window.location.origin
|
|
5677
|
+
);
|
|
5678
|
+
return;
|
|
5679
|
+
}
|
|
5680
|
+
redirectToOriginalPage(originalUrl, urlStatus);
|
|
5681
|
+
return;
|
|
5682
|
+
}
|
|
5683
|
+
setMessage("Processing verification...");
|
|
5684
|
+
const apiBaseUrl = baseUrl || storedBaseUrl;
|
|
5685
|
+
const response = await verifyGuardianStatus({
|
|
5686
|
+
accessToken,
|
|
5687
|
+
baseUrl: apiBaseUrl,
|
|
5688
|
+
sessionToken: activeSessionToken
|
|
5689
|
+
});
|
|
5690
|
+
if (!isMountedRef.current) return;
|
|
5691
|
+
if (response.status === "verified") {
|
|
5692
|
+
const verificationRef = response.verification_reference || ((_a = response.guardian_details) == null ? void 0 : _a.verification_reference) || void 0;
|
|
5693
|
+
if (!verificationRef) {
|
|
5694
|
+
setStatus("error");
|
|
5695
|
+
setMessage("Verification failed");
|
|
5696
|
+
setErrorDetail("Verification completed but no reference received. Please try again.");
|
|
5697
|
+
onError == null ? void 0 : onError(new Error("Verification completed but no reference received."));
|
|
5698
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5699
|
+
return;
|
|
5700
|
+
}
|
|
5701
|
+
setStatus("success");
|
|
5702
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5703
|
+
onSuccess == null ? void 0 : onSuccess(verificationRef);
|
|
5704
|
+
if (isInIframe && window.parent) {
|
|
5705
|
+
window.parent.postMessage(
|
|
5706
|
+
{
|
|
5707
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5708
|
+
status: "verified",
|
|
5709
|
+
verificationReference: verificationRef
|
|
5710
|
+
},
|
|
5711
|
+
window.location.origin
|
|
5712
|
+
);
|
|
5713
|
+
return;
|
|
5714
|
+
}
|
|
5715
|
+
redirectToOriginalPage(originalUrl, "verified", verificationRef);
|
|
5716
|
+
} else if (response.status === "failed" || response.status === "expired") {
|
|
5717
|
+
const responseErrorCode = (_b = response.error_code) != null ? _b : void 0;
|
|
5718
|
+
const errorMessage = response.error || getErrorMessage(responseErrorCode);
|
|
5719
|
+
setStatus("error");
|
|
5720
|
+
setMessage("Verification failed");
|
|
5721
|
+
setErrorDetail(errorMessage);
|
|
5722
|
+
onError == null ? void 0 : onError(new Error(errorMessage), responseErrorCode);
|
|
5723
|
+
if (isInIframe && window.parent) {
|
|
5724
|
+
window.parent.postMessage(
|
|
5725
|
+
{
|
|
5726
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5727
|
+
status: response.status,
|
|
5728
|
+
errorCode: responseErrorCode,
|
|
5729
|
+
error: errorMessage
|
|
5730
|
+
},
|
|
5731
|
+
window.location.origin
|
|
5732
|
+
);
|
|
5733
|
+
return;
|
|
5734
|
+
}
|
|
5735
|
+
redirectToOriginalPage(originalUrl, response.status);
|
|
5736
|
+
} else {
|
|
5737
|
+
setMessage("Verification is still in progress. Please wait...");
|
|
5738
|
+
const MAX_RETRIES = 3;
|
|
5739
|
+
let retryCount = 0;
|
|
5740
|
+
const attemptRetry = () => {
|
|
5741
|
+
retryCount++;
|
|
5742
|
+
const delay = 3e3 * Math.pow(2, retryCount - 1);
|
|
5743
|
+
retryTimeoutRef.current = setTimeout(async () => {
|
|
5744
|
+
var _a2, _b2;
|
|
5745
|
+
if (!isMountedRef.current) return;
|
|
5746
|
+
try {
|
|
5747
|
+
const retryResponse = await verifyGuardianStatus({
|
|
5748
|
+
accessToken,
|
|
5749
|
+
baseUrl: apiBaseUrl,
|
|
5750
|
+
sessionToken: activeSessionToken
|
|
5751
|
+
});
|
|
5752
|
+
if (!isMountedRef.current) return;
|
|
5753
|
+
const retryRef = retryResponse.verification_reference || ((_a2 = retryResponse.guardian_details) == null ? void 0 : _a2.verification_reference) || void 0;
|
|
5754
|
+
if (retryResponse.status === "verified" && retryRef) {
|
|
5755
|
+
setStatus("success");
|
|
5756
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5757
|
+
onSuccess == null ? void 0 : onSuccess(retryRef);
|
|
5758
|
+
if (isInIframe && window.parent) {
|
|
5759
|
+
window.parent.postMessage(
|
|
5760
|
+
{
|
|
5761
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5762
|
+
status: "verified",
|
|
5763
|
+
verificationReference: retryRef
|
|
5764
|
+
},
|
|
5765
|
+
window.location.origin
|
|
5766
|
+
);
|
|
5767
|
+
return;
|
|
5768
|
+
}
|
|
5769
|
+
redirectToOriginalPage(originalUrl, "verified", retryRef);
|
|
5770
|
+
} else if (retryResponse.status === "failed" || retryResponse.status === "expired") {
|
|
5771
|
+
const retryErrorCode = (_b2 = retryResponse.error_code) != null ? _b2 : void 0;
|
|
5772
|
+
const retryErrorMessage = retryResponse.error || getErrorMessage(retryErrorCode) || "Verification could not be completed. Please try again.";
|
|
5773
|
+
setStatus("error");
|
|
5774
|
+
setMessage("Verification failed");
|
|
5775
|
+
setErrorDetail(retryErrorMessage);
|
|
5776
|
+
onError == null ? void 0 : onError(new Error(retryErrorMessage), retryErrorCode);
|
|
5777
|
+
if (isInIframe && window.parent) {
|
|
5778
|
+
window.parent.postMessage(
|
|
5779
|
+
{
|
|
5780
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5781
|
+
status: retryResponse.status,
|
|
5782
|
+
errorCode: retryErrorCode,
|
|
5783
|
+
error: retryErrorMessage
|
|
5784
|
+
},
|
|
5785
|
+
window.location.origin
|
|
5786
|
+
);
|
|
5787
|
+
return;
|
|
5788
|
+
}
|
|
5789
|
+
redirectToOriginalPage(originalUrl, retryResponse.status);
|
|
5790
|
+
} else if (retryCount < MAX_RETRIES) {
|
|
5791
|
+
setMessage("Verification taking longer than expected. Please wait...");
|
|
5792
|
+
attemptRetry();
|
|
5793
|
+
} else {
|
|
5794
|
+
const timeoutMessage = "Verification could not be completed in time. Please try again.";
|
|
5795
|
+
setStatus("error");
|
|
5796
|
+
setMessage("Verification failed");
|
|
5797
|
+
setErrorDetail(timeoutMessage);
|
|
5798
|
+
onError == null ? void 0 : onError(new Error(timeoutMessage));
|
|
5799
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5800
|
+
}
|
|
5801
|
+
} catch (retryErr) {
|
|
5802
|
+
if (!isMountedRef.current) return;
|
|
5803
|
+
if (retryCount < MAX_RETRIES) {
|
|
5804
|
+
attemptRetry();
|
|
5805
|
+
} else {
|
|
5806
|
+
setStatus("error");
|
|
5807
|
+
setMessage("Verification failed");
|
|
5808
|
+
setErrorDetail(retryErr.message);
|
|
5809
|
+
onError == null ? void 0 : onError(retryErr);
|
|
5810
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5811
|
+
}
|
|
5812
|
+
}
|
|
5813
|
+
}, delay);
|
|
5814
|
+
};
|
|
5815
|
+
attemptRetry();
|
|
5816
|
+
}
|
|
5817
|
+
} catch (error) {
|
|
5818
|
+
console.error("DigiLocker callback error:", error);
|
|
5819
|
+
setStatus("error");
|
|
5820
|
+
const err = error;
|
|
5821
|
+
setMessage("Verification failed");
|
|
5822
|
+
setErrorDetail(err.message || "An error occurred during verification");
|
|
5823
|
+
onError == null ? void 0 : onError(err);
|
|
5824
|
+
const persistedState = getConsentState();
|
|
5825
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5826
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5827
|
+
redirectToOriginalPage(persistedState.originalUrl, "failed");
|
|
5828
|
+
}, 3e3);
|
|
5829
|
+
}
|
|
5830
|
+
}
|
|
5831
|
+
}, [propAccessToken, baseUrl, onSuccess, onError, redirectToOriginalPage]);
|
|
5832
|
+
useEffect5(() => {
|
|
5833
|
+
injectCheckboxStyles();
|
|
5834
|
+
handleCallback();
|
|
5835
|
+
return () => {
|
|
5836
|
+
isMountedRef.current = false;
|
|
5837
|
+
if (retryTimeoutRef.current) clearTimeout(retryTimeoutRef.current);
|
|
5838
|
+
if (redirectTimeoutRef.current) clearTimeout(redirectTimeoutRef.current);
|
|
5839
|
+
};
|
|
5840
|
+
}, [handleCallback]);
|
|
5841
|
+
const handleRetry = useCallback3(() => {
|
|
5842
|
+
const persistedState = getConsentState();
|
|
5843
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5844
|
+
clearConsentState();
|
|
5845
|
+
window.location.href = persistedState.originalUrl;
|
|
5846
|
+
} else {
|
|
5847
|
+
window.location.href = "/";
|
|
5848
|
+
}
|
|
5849
|
+
}, []);
|
|
5850
|
+
const containerStyle = {
|
|
5851
|
+
display: "flex",
|
|
5852
|
+
alignItems: "center",
|
|
5853
|
+
justifyContent: "center",
|
|
5854
|
+
minHeight: "100vh",
|
|
5855
|
+
backgroundColor: "#f8fafc",
|
|
5856
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
5857
|
+
padding: "24px",
|
|
5858
|
+
boxSizing: "border-box"
|
|
5859
|
+
};
|
|
5860
|
+
const cardStyle = {
|
|
5861
|
+
backgroundColor: "#ffffff",
|
|
5862
|
+
borderRadius: "16px",
|
|
5863
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.08), 0 8px 30px rgba(0, 0, 0, 0.06)",
|
|
5864
|
+
padding: "48px 40px 40px",
|
|
5865
|
+
textAlign: "center",
|
|
5866
|
+
maxWidth: "420px",
|
|
5867
|
+
width: "100%"
|
|
5868
|
+
};
|
|
5869
|
+
const spinnerContainerStyle = {
|
|
5870
|
+
width: "72px",
|
|
5871
|
+
height: "72px",
|
|
5872
|
+
margin: "0 auto 28px",
|
|
5873
|
+
position: "relative"
|
|
5874
|
+
};
|
|
5875
|
+
const spinnerStyle = {
|
|
5876
|
+
width: "72px",
|
|
5877
|
+
height: "72px",
|
|
5878
|
+
border: "3px solid #e5e7eb",
|
|
5879
|
+
borderTopColor: "#4f87ff",
|
|
5880
|
+
borderRadius: "50%",
|
|
5881
|
+
animation: "redacto-dl-spin 0.8s linear infinite",
|
|
5882
|
+
boxSizing: "border-box"
|
|
5883
|
+
};
|
|
5884
|
+
const iconContainerStyle = {
|
|
5885
|
+
width: "72px",
|
|
5886
|
+
height: "72px",
|
|
5887
|
+
borderRadius: "50%",
|
|
5888
|
+
display: "flex",
|
|
5889
|
+
alignItems: "center",
|
|
5890
|
+
justifyContent: "center",
|
|
5891
|
+
margin: "0 auto 28px",
|
|
5892
|
+
animation: "redacto-dl-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards",
|
|
5893
|
+
position: "relative"
|
|
5894
|
+
};
|
|
5895
|
+
const successIconStyle = {
|
|
5896
|
+
...iconContainerStyle,
|
|
5897
|
+
backgroundColor: "#d1fae5",
|
|
5898
|
+
color: "#059669"
|
|
5899
|
+
};
|
|
5900
|
+
const errorIconStyle = {
|
|
5901
|
+
...iconContainerStyle,
|
|
5902
|
+
backgroundColor: "#fee2e2",
|
|
5903
|
+
color: "#dc2626"
|
|
5904
|
+
};
|
|
5905
|
+
const titleStyle = {
|
|
5906
|
+
fontSize: "22px",
|
|
5907
|
+
fontWeight: 700,
|
|
5908
|
+
color: "#111827",
|
|
5909
|
+
margin: "0 0 8px 0",
|
|
5910
|
+
letterSpacing: "-0.01em"
|
|
5911
|
+
};
|
|
5912
|
+
const messageStyle = {
|
|
5913
|
+
fontSize: "14px",
|
|
5914
|
+
color: "#6b7280",
|
|
5915
|
+
marginBottom: "0",
|
|
5916
|
+
lineHeight: 1.6
|
|
5917
|
+
};
|
|
5918
|
+
const subtextStyle = {
|
|
5919
|
+
fontSize: "13px",
|
|
5920
|
+
color: "#9ca3af",
|
|
5921
|
+
marginTop: "16px",
|
|
5922
|
+
lineHeight: 1.5
|
|
5923
|
+
};
|
|
5924
|
+
const errorDetailStyle = {
|
|
5925
|
+
fontSize: "13px",
|
|
5926
|
+
color: "#dc2626",
|
|
5927
|
+
marginTop: "16px",
|
|
5928
|
+
padding: "12px 16px",
|
|
5929
|
+
backgroundColor: "#fef2f2",
|
|
5930
|
+
borderRadius: "10px",
|
|
5931
|
+
border: "1px solid #fecaca",
|
|
5932
|
+
lineHeight: 1.5,
|
|
5933
|
+
textAlign: "left"
|
|
5934
|
+
};
|
|
5935
|
+
const buttonStyle = {
|
|
5936
|
+
marginTop: "24px",
|
|
5937
|
+
padding: "12px 28px",
|
|
5938
|
+
backgroundColor: "#4f87ff",
|
|
5939
|
+
color: "#ffffff",
|
|
5940
|
+
border: "none",
|
|
5941
|
+
borderRadius: "10px",
|
|
5942
|
+
fontSize: "15px",
|
|
5943
|
+
fontWeight: 600,
|
|
5944
|
+
cursor: "pointer",
|
|
5945
|
+
transition: "background-color 0.2s, transform 0.15s",
|
|
5946
|
+
width: "100%"
|
|
5947
|
+
};
|
|
5948
|
+
const keyframesStyle = `
|
|
5949
|
+
@keyframes redacto-dl-spin {
|
|
5950
|
+
to { transform: rotate(360deg); }
|
|
5951
|
+
}
|
|
5952
|
+
@keyframes redacto-dl-pop {
|
|
5953
|
+
0% { transform: scale(0.3); opacity: 0; }
|
|
5954
|
+
60% { transform: scale(1.08); opacity: 1; }
|
|
5955
|
+
100% { transform: scale(1); opacity: 1; }
|
|
5956
|
+
}
|
|
5957
|
+
@keyframes redacto-dl-check {
|
|
5958
|
+
0% { stroke-dashoffset: 24; }
|
|
5959
|
+
100% { stroke-dashoffset: 0; }
|
|
5960
|
+
}
|
|
5961
|
+
@keyframes redacto-dl-pulse {
|
|
5962
|
+
0%, 100% { transform: scale(1); opacity: 0.6; }
|
|
5963
|
+
50% { transform: scale(1.15); opacity: 0; }
|
|
5964
|
+
}
|
|
5965
|
+
.redacto-dl-retry-btn:hover {
|
|
5966
|
+
background-color: #3d6fdb !important;
|
|
5967
|
+
transform: translateY(-1px);
|
|
5968
|
+
}
|
|
5969
|
+
.redacto-dl-retry-btn:active {
|
|
5970
|
+
transform: translateY(0);
|
|
5971
|
+
}
|
|
5972
|
+
`;
|
|
5973
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
5974
|
+
/* @__PURE__ */ jsx3("style", { dangerouslySetInnerHTML: { __html: keyframesStyle } }),
|
|
5975
|
+
/* @__PURE__ */ jsx3("div", { style: containerStyle, children: /* @__PURE__ */ jsxs3("div", { style: cardStyle, children: [
|
|
5976
|
+
status === "processing" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
5977
|
+
/* @__PURE__ */ jsx3("div", { style: spinnerContainerStyle, children: /* @__PURE__ */ jsx3("div", { style: spinnerStyle }) }),
|
|
5978
|
+
/* @__PURE__ */ jsx3("h2", { style: titleStyle, children: "Processing Verification" }),
|
|
5979
|
+
/* @__PURE__ */ jsx3("p", { style: messageStyle, children: message }),
|
|
5980
|
+
/* @__PURE__ */ jsx3("p", { style: subtextStyle, children: "Please wait while we verify your guardian's identity..." })
|
|
5981
|
+
] }),
|
|
5982
|
+
status === "success" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
5983
|
+
/* @__PURE__ */ jsxs3("div", { style: { position: "relative", width: "72px", height: "72px", margin: "0 auto 28px" }, children: [
|
|
5984
|
+
/* @__PURE__ */ jsx3("div", { style: {
|
|
5985
|
+
position: "absolute",
|
|
5986
|
+
inset: "-8px",
|
|
5987
|
+
borderRadius: "50%",
|
|
5988
|
+
border: "2px solid #d1fae5",
|
|
5989
|
+
animation: "redacto-dl-pulse 1.5s ease-out infinite"
|
|
5990
|
+
} }),
|
|
5991
|
+
/* @__PURE__ */ jsx3("div", { style: successIconStyle, children: /* @__PURE__ */ jsx3(
|
|
5992
|
+
"svg",
|
|
5993
|
+
{
|
|
5994
|
+
width: "30",
|
|
5995
|
+
height: "30",
|
|
5996
|
+
viewBox: "0 0 24 24",
|
|
5997
|
+
fill: "none",
|
|
5998
|
+
stroke: "currentColor",
|
|
5999
|
+
strokeWidth: "2.5",
|
|
6000
|
+
strokeLinecap: "round",
|
|
6001
|
+
strokeLinejoin: "round",
|
|
6002
|
+
style: { strokeDasharray: 24, animation: "redacto-dl-check 0.4s ease-out 0.3s forwards", strokeDashoffset: 24 },
|
|
6003
|
+
children: /* @__PURE__ */ jsx3("polyline", { points: "20 6 9 17 4 12" })
|
|
6004
|
+
}
|
|
6005
|
+
) })
|
|
6006
|
+
] }),
|
|
6007
|
+
/* @__PURE__ */ jsx3("h2", { style: titleStyle, children: "Verification Successful" }),
|
|
6008
|
+
/* @__PURE__ */ jsx3("p", { style: messageStyle, children: message }),
|
|
6009
|
+
/* @__PURE__ */ jsx3("p", { style: subtextStyle, children: "You will be redirected automatically." })
|
|
6010
|
+
] }),
|
|
6011
|
+
status === "error" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
6012
|
+
/* @__PURE__ */ jsx3("div", { style: errorIconStyle, children: /* @__PURE__ */ jsxs3(
|
|
6013
|
+
"svg",
|
|
6014
|
+
{
|
|
6015
|
+
width: "30",
|
|
6016
|
+
height: "30",
|
|
6017
|
+
viewBox: "0 0 24 24",
|
|
6018
|
+
fill: "none",
|
|
6019
|
+
stroke: "currentColor",
|
|
6020
|
+
strokeWidth: "2.5",
|
|
6021
|
+
strokeLinecap: "round",
|
|
6022
|
+
strokeLinejoin: "round",
|
|
6023
|
+
children: [
|
|
6024
|
+
/* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
6025
|
+
/* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
6026
|
+
]
|
|
6027
|
+
}
|
|
6028
|
+
) }),
|
|
6029
|
+
/* @__PURE__ */ jsx3("h2", { style: titleStyle, children: "Verification Failed" }),
|
|
6030
|
+
/* @__PURE__ */ jsx3("p", { style: messageStyle, children: message }),
|
|
6031
|
+
errorDetail && /* @__PURE__ */ jsx3("p", { style: errorDetailStyle, children: errorDetail }),
|
|
6032
|
+
/* @__PURE__ */ jsx3(
|
|
6033
|
+
"button",
|
|
6034
|
+
{
|
|
6035
|
+
className: "redacto-dl-retry-btn",
|
|
6036
|
+
style: buttonStyle,
|
|
6037
|
+
onClick: handleRetry,
|
|
6038
|
+
children: "Try Again"
|
|
6039
|
+
}
|
|
6040
|
+
)
|
|
6041
|
+
] })
|
|
6042
|
+
] }) })
|
|
6043
|
+
] });
|
|
6044
|
+
};
|
|
4480
6045
|
export {
|
|
6046
|
+
DigiLockerCallback,
|
|
4481
6047
|
RedactoNoticeConsent,
|
|
4482
6048
|
RedactoConsentInline as RedactoNoticeConsentInline
|
|
4483
6049
|
};
|