@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.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
DigiLockerCallback: () => DigiLockerCallback,
|
|
23
24
|
RedactoNoticeConsent: () => RedactoNoticeConsent,
|
|
24
25
|
RedactoNoticeConsentInline: () => RedactoConsentInline
|
|
25
26
|
});
|
|
@@ -30,21 +31,6 @@ var import_react2 = require("react");
|
|
|
30
31
|
|
|
31
32
|
// src/RedactoNoticeConsent/api/index.ts
|
|
32
33
|
var import_jwt_decode = require("jwt-decode");
|
|
33
|
-
|
|
34
|
-
// src/utils/isLegacyApi.ts
|
|
35
|
-
function isLegacyApi(baseUrl) {
|
|
36
|
-
try {
|
|
37
|
-
return new URL(baseUrl).hostname.endsWith(".redacto.io");
|
|
38
|
-
} catch {
|
|
39
|
-
try {
|
|
40
|
-
return new URL(`https://${baseUrl}`).hostname.endsWith(".redacto.io");
|
|
41
|
-
} catch {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// src/RedactoNoticeConsent/api/index.ts
|
|
48
34
|
var BASE_URL = "https://api.redacto.io/consent";
|
|
49
35
|
var apiCache = /* @__PURE__ */ new Map();
|
|
50
36
|
var CACHE_TTL = 5 * 60 * 1e3;
|
|
@@ -81,73 +67,66 @@ var fetchConsentContent = async ({
|
|
|
81
67
|
validate_against = "all",
|
|
82
68
|
include_fully_consented_data = false,
|
|
83
69
|
signal
|
|
84
|
-
// AbortSignal for request cancellation
|
|
85
70
|
}) => {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return cachedData;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
const url = new URL(
|
|
107
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
108
|
-
);
|
|
109
|
-
if (specific_uuid) {
|
|
110
|
-
url.searchParams.append("specific_uuid", specific_uuid);
|
|
111
|
-
}
|
|
112
|
-
url.searchParams.append("validate_against", validate_against);
|
|
113
|
-
if (include_fully_consented_data) {
|
|
114
|
-
url.searchParams.append("include_fully_consented_data", "true");
|
|
115
|
-
}
|
|
116
|
-
const response = await fetch(url.toString(), {
|
|
117
|
-
method: "GET",
|
|
118
|
-
headers: {
|
|
119
|
-
Authorization: `Bearer ${accessToken}`,
|
|
120
|
-
"Accept-Language": language,
|
|
121
|
-
"Content-Type": "application/json"
|
|
122
|
-
},
|
|
123
|
-
signal
|
|
124
|
-
// Add abort signal for request cancellation
|
|
125
|
-
});
|
|
126
|
-
if (!response.ok) {
|
|
127
|
-
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
128
|
-
if (response.status === 401) {
|
|
129
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
130
|
-
} else if (response.status === 403) {
|
|
131
|
-
errorMessage = "Forbidden: Access denied";
|
|
132
|
-
} else if (response.status === 404) {
|
|
133
|
-
errorMessage = "Notice not found";
|
|
134
|
-
} else if (response.status === 409) {
|
|
135
|
-
errorMessage = "User has already provided consent";
|
|
136
|
-
} else if (response.status >= 500) {
|
|
137
|
-
errorMessage = "Server error: Please try again later";
|
|
138
|
-
}
|
|
139
|
-
const error = new Error(errorMessage);
|
|
140
|
-
error.status = response.status;
|
|
141
|
-
throw error;
|
|
71
|
+
if (!noticeId || !accessToken || !validate_against) {
|
|
72
|
+
throw new Error("noticeId and accessToken are required");
|
|
73
|
+
}
|
|
74
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
75
|
+
if (!decodedToken) {
|
|
76
|
+
throw new Error("Invalid access token");
|
|
77
|
+
}
|
|
78
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
79
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
80
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
81
|
+
}
|
|
82
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
83
|
+
const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
|
|
84
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
85
|
+
const cachedData = getCachedData(cacheKey);
|
|
86
|
+
if (cachedData) {
|
|
87
|
+
return cachedData;
|
|
142
88
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
89
|
+
}
|
|
90
|
+
const url = new URL(
|
|
91
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
92
|
+
);
|
|
93
|
+
if (specific_uuid) {
|
|
94
|
+
url.searchParams.append("specific_uuid", specific_uuid);
|
|
95
|
+
}
|
|
96
|
+
url.searchParams.append("validate_against", validate_against);
|
|
97
|
+
if (include_fully_consented_data) {
|
|
98
|
+
url.searchParams.append("include_fully_consented_data", "true");
|
|
99
|
+
}
|
|
100
|
+
const response = await fetch(url.toString(), {
|
|
101
|
+
method: "GET",
|
|
102
|
+
headers: {
|
|
103
|
+
Authorization: `Bearer ${accessToken}`,
|
|
104
|
+
"Accept-Language": language
|
|
105
|
+
},
|
|
106
|
+
signal
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
110
|
+
if (response.status === 401) {
|
|
111
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
112
|
+
} else if (response.status === 403) {
|
|
113
|
+
errorMessage = "Forbidden: Access denied";
|
|
114
|
+
} else if (response.status === 404) {
|
|
115
|
+
errorMessage = "Notice not found";
|
|
116
|
+
} else if (response.status === 409) {
|
|
117
|
+
errorMessage = "User has already provided consent";
|
|
118
|
+
} else if (response.status >= 500) {
|
|
119
|
+
errorMessage = "Server error: Please try again later";
|
|
146
120
|
}
|
|
147
|
-
|
|
148
|
-
|
|
121
|
+
const error = new Error(errorMessage);
|
|
122
|
+
error.status = response.status;
|
|
149
123
|
throw error;
|
|
150
124
|
}
|
|
125
|
+
const data = await response.json();
|
|
126
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
127
|
+
setCachedData(cacheKey, data);
|
|
128
|
+
}
|
|
129
|
+
return data;
|
|
151
130
|
};
|
|
152
131
|
var submitConsentEvent = async ({
|
|
153
132
|
accessToken,
|
|
@@ -155,134 +134,154 @@ var submitConsentEvent = async ({
|
|
|
155
134
|
noticeUuid,
|
|
156
135
|
purposes,
|
|
157
136
|
declined,
|
|
137
|
+
language,
|
|
158
138
|
meta_data,
|
|
139
|
+
guardianVerificationReference,
|
|
140
|
+
selfDeclaredAdult,
|
|
159
141
|
signal
|
|
160
|
-
// AbortSignal for request cancellation
|
|
161
142
|
}) => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
143
|
+
if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
|
|
144
|
+
throw new Error("noticeUuid, accessToken, and purposes array are required");
|
|
145
|
+
}
|
|
146
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
147
|
+
if (!decodedToken) {
|
|
148
|
+
throw new Error("Invalid access token");
|
|
149
|
+
}
|
|
150
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
151
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
152
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
153
|
+
}
|
|
154
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
155
|
+
const validatedPurposes = purposes.map((purpose) => {
|
|
156
|
+
if (!purpose.uuid) {
|
|
157
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
173
158
|
}
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
};
|
|
206
|
-
} else {
|
|
207
|
-
const validatedPurposes = purposes.map((purpose) => {
|
|
208
|
-
if (!purpose.uuid) {
|
|
209
|
-
throw new Error(`Invalid purpose data: missing uuid`);
|
|
210
|
-
}
|
|
211
|
-
const dataElements = (purpose.data_elements || []).filter((element) => element.enabled).map((element) => ({
|
|
212
|
-
uuid: element.uuid,
|
|
213
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
214
|
-
}));
|
|
215
|
-
return {
|
|
216
|
-
purpose_uuid: purpose.uuid,
|
|
217
|
-
selected: Boolean(purpose.selected),
|
|
218
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
219
|
-
};
|
|
220
|
-
});
|
|
221
|
-
payload = {
|
|
222
|
-
notice_uuid: noticeUuid,
|
|
223
|
-
purposes: validatedPurposes,
|
|
224
|
-
select_all_mandatory: false,
|
|
225
|
-
source: "WEB",
|
|
226
|
-
declined: Boolean(declined),
|
|
227
|
-
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
|
|
228
|
-
};
|
|
159
|
+
const dataElements = (purpose.data_elements || []).filter((element) => element.enabled).map((element) => ({
|
|
160
|
+
uuid: element.uuid,
|
|
161
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
162
|
+
}));
|
|
163
|
+
return {
|
|
164
|
+
purpose_uuid: purpose.uuid,
|
|
165
|
+
selected: Boolean(purpose.selected),
|
|
166
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
167
|
+
};
|
|
168
|
+
});
|
|
169
|
+
const payload = {
|
|
170
|
+
notice_uuid: noticeUuid,
|
|
171
|
+
purposes: validatedPurposes,
|
|
172
|
+
select_all_mandatory: false,
|
|
173
|
+
source: "WEB",
|
|
174
|
+
declined: Boolean(declined),
|
|
175
|
+
language: language || void 0,
|
|
176
|
+
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : void 0,
|
|
177
|
+
guardian_verification_reference: guardianVerificationReference,
|
|
178
|
+
self_declared_adult: selfDeclaredAdult
|
|
179
|
+
};
|
|
180
|
+
const response = await fetch(
|
|
181
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
|
|
182
|
+
{
|
|
183
|
+
method: "POST",
|
|
184
|
+
headers: {
|
|
185
|
+
Authorization: `Bearer ${accessToken}`,
|
|
186
|
+
"Content-Type": "application/json"
|
|
187
|
+
},
|
|
188
|
+
body: JSON.stringify(payload),
|
|
189
|
+
signal
|
|
229
190
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
body: JSON.stringify(payload),
|
|
239
|
-
signal
|
|
240
|
-
// Add abort signal for request cancellation
|
|
241
|
-
}
|
|
242
|
-
);
|
|
243
|
-
if (!response.ok) {
|
|
244
|
-
let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
|
|
245
|
-
if (response.status === 400) {
|
|
191
|
+
);
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
|
|
194
|
+
if (response.status === 400) {
|
|
195
|
+
try {
|
|
196
|
+
const errorData = await response.json();
|
|
197
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
198
|
+
} catch {
|
|
246
199
|
errorMessage = "Invalid request data";
|
|
247
|
-
} else if (response.status === 401) {
|
|
248
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
249
|
-
} else if (response.status === 403) {
|
|
250
|
-
errorMessage = "Forbidden: Access denied";
|
|
251
|
-
} else if (response.status === 404) {
|
|
252
|
-
errorMessage = "Notice not found";
|
|
253
|
-
} else if (response.status >= 500) {
|
|
254
|
-
errorMessage = "Server error: Please try again later";
|
|
255
200
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
201
|
+
} else if (response.status === 401) {
|
|
202
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
203
|
+
} else if (response.status === 403) {
|
|
204
|
+
errorMessage = "Forbidden: Access denied";
|
|
205
|
+
} else if (response.status === 404) {
|
|
206
|
+
errorMessage = "Notice not found";
|
|
207
|
+
} else if (response.status >= 500) {
|
|
208
|
+
errorMessage = "Server error: Please try again later";
|
|
259
209
|
}
|
|
260
|
-
|
|
261
|
-
|
|
210
|
+
const error = new Error(errorMessage);
|
|
211
|
+
error.status = response.status;
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
apiCache.clear();
|
|
215
|
+
};
|
|
216
|
+
var fetchTTSAudioUrls = async ({
|
|
217
|
+
accessToken,
|
|
218
|
+
baseUrl,
|
|
219
|
+
noticeUuid,
|
|
220
|
+
language,
|
|
221
|
+
signal
|
|
222
|
+
}) => {
|
|
223
|
+
if (!accessToken || !noticeUuid || !language) {
|
|
224
|
+
throw new Error("accessToken, noticeUuid, and language are required");
|
|
225
|
+
}
|
|
226
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
227
|
+
if (!decodedToken) {
|
|
228
|
+
throw new Error("Invalid access token");
|
|
229
|
+
}
|
|
230
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
231
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
232
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
233
|
+
}
|
|
234
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
235
|
+
const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
|
|
236
|
+
const response = await fetch(url, {
|
|
237
|
+
method: "GET",
|
|
238
|
+
headers: {
|
|
239
|
+
Authorization: `Bearer ${accessToken}`,
|
|
240
|
+
Accept: "application/json"
|
|
241
|
+
},
|
|
242
|
+
signal
|
|
243
|
+
});
|
|
244
|
+
if (!response.ok) {
|
|
245
|
+
let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
|
|
246
|
+
if (response.status === 401) {
|
|
247
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
248
|
+
} else if (response.status === 403) {
|
|
249
|
+
errorMessage = "Forbidden: Access denied";
|
|
250
|
+
} else if (response.status === 404) {
|
|
251
|
+
errorMessage = "Notice or audio not found";
|
|
252
|
+
} else if (response.status >= 500) {
|
|
253
|
+
errorMessage = "Server error: Please try again later";
|
|
254
|
+
}
|
|
255
|
+
const error = new Error(errorMessage);
|
|
256
|
+
error.status = response.status;
|
|
262
257
|
throw error;
|
|
263
258
|
}
|
|
259
|
+
const data = await response.json();
|
|
260
|
+
return data;
|
|
264
261
|
};
|
|
265
|
-
var
|
|
262
|
+
var initiateGuardianVerification = async ({
|
|
266
263
|
accessToken,
|
|
267
264
|
baseUrl,
|
|
268
265
|
guardianName,
|
|
269
266
|
guardianContact,
|
|
270
267
|
guardianRelationship,
|
|
268
|
+
frontendCallbackUrl,
|
|
269
|
+
metadata,
|
|
271
270
|
signal
|
|
272
|
-
// AbortSignal for request cancellation
|
|
273
271
|
}) => {
|
|
272
|
+
var _a;
|
|
274
273
|
try {
|
|
275
274
|
if (!accessToken) {
|
|
276
275
|
throw new Error("accessToken is required");
|
|
277
276
|
}
|
|
278
277
|
if (!(guardianName == null ? void 0 : guardianName.trim())) {
|
|
279
|
-
throw new Error("
|
|
278
|
+
throw new Error("Guardian name is required");
|
|
280
279
|
}
|
|
281
280
|
if (!(guardianContact == null ? void 0 : guardianContact.trim())) {
|
|
282
|
-
throw new Error("
|
|
281
|
+
throw new Error("Guardian contact is required");
|
|
283
282
|
}
|
|
284
283
|
if (!(guardianRelationship == null ? void 0 : guardianRelationship.trim())) {
|
|
285
|
-
throw new Error("
|
|
284
|
+
throw new Error("Guardian relationship is required");
|
|
286
285
|
}
|
|
287
286
|
const decodedToken = decodeTokenSafely(accessToken);
|
|
288
287
|
if (!decodedToken) {
|
|
@@ -292,14 +291,20 @@ var submitGuardianInfo = async ({
|
|
|
292
291
|
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
293
292
|
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
294
293
|
}
|
|
294
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
295
295
|
const payload = {
|
|
296
296
|
guardian_name: guardianName.trim(),
|
|
297
297
|
guardian_contact: guardianContact.trim(),
|
|
298
298
|
guardian_relationship: guardianRelationship.trim()
|
|
299
299
|
};
|
|
300
|
-
|
|
300
|
+
if (frontendCallbackUrl) {
|
|
301
|
+
payload.frontend_callback_url = frontendCallbackUrl;
|
|
302
|
+
}
|
|
303
|
+
if (metadata) {
|
|
304
|
+
payload.metadata = metadata;
|
|
305
|
+
}
|
|
301
306
|
const response = await fetch(
|
|
302
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian-
|
|
307
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/initiate-verification`,
|
|
303
308
|
{
|
|
304
309
|
method: "POST",
|
|
305
310
|
headers: {
|
|
@@ -308,24 +313,26 @@ var submitGuardianInfo = async ({
|
|
|
308
313
|
},
|
|
309
314
|
body: JSON.stringify(payload),
|
|
310
315
|
signal
|
|
311
|
-
// Add abort signal for request cancellation
|
|
312
316
|
}
|
|
313
317
|
);
|
|
314
318
|
if (!response.ok) {
|
|
315
|
-
let errorMessage = `Failed to
|
|
319
|
+
let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;
|
|
316
320
|
if (response.status === 400) {
|
|
317
|
-
|
|
321
|
+
try {
|
|
322
|
+
const errorData = await response.json();
|
|
323
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
324
|
+
} catch {
|
|
325
|
+
errorMessage = "Invalid request data";
|
|
326
|
+
}
|
|
318
327
|
} else if (response.status === 401) {
|
|
319
328
|
errorMessage = "Unauthorized: Invalid or expired token";
|
|
320
|
-
} else if (response.status === 403) {
|
|
321
|
-
errorMessage = "Forbidden: Access denied";
|
|
322
329
|
} else if (response.status === 404) {
|
|
323
330
|
errorMessage = "Organization or workspace not found";
|
|
324
331
|
} else if (response.status === 422) {
|
|
325
332
|
try {
|
|
326
333
|
const errorData = await response.json();
|
|
327
|
-
errorMessage = errorData.message || "Validation error";
|
|
328
|
-
} catch
|
|
334
|
+
errorMessage = errorData.message || "Validation error: Please check your input";
|
|
335
|
+
} catch {
|
|
329
336
|
errorMessage = "Validation error: Please check your input";
|
|
330
337
|
}
|
|
331
338
|
} else if (response.status >= 500) {
|
|
@@ -335,63 +342,98 @@ var submitGuardianInfo = async ({
|
|
|
335
342
|
error.status = response.status;
|
|
336
343
|
throw error;
|
|
337
344
|
}
|
|
345
|
+
const responseData = await response.json();
|
|
346
|
+
const detail = responseData.detail || responseData;
|
|
347
|
+
if (detail.already_verified) {
|
|
348
|
+
return {
|
|
349
|
+
success: true,
|
|
350
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
351
|
+
already_verified: true,
|
|
352
|
+
verification_reference: detail.verification_reference
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
if (!detail.session_token || !detail.digilocker_redirect_url) {
|
|
356
|
+
throw new Error("Invalid response: missing session_token or digilocker_redirect_url");
|
|
357
|
+
}
|
|
358
|
+
return {
|
|
359
|
+
success: (_a = detail.success) != null ? _a : true,
|
|
360
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
361
|
+
already_verified: false,
|
|
362
|
+
session_token: detail.session_token,
|
|
363
|
+
digilocker_redirect_url: detail.digilocker_redirect_url,
|
|
364
|
+
expires_at: detail.expires_at
|
|
365
|
+
};
|
|
338
366
|
} catch (error) {
|
|
339
|
-
console.error("Error
|
|
367
|
+
console.error("Error initiating guardian verification:", error instanceof Error ? error.message : error);
|
|
340
368
|
throw error;
|
|
341
369
|
}
|
|
342
370
|
};
|
|
343
|
-
var
|
|
371
|
+
var verifyGuardianStatus = async ({
|
|
344
372
|
accessToken,
|
|
345
373
|
baseUrl,
|
|
346
|
-
|
|
347
|
-
language,
|
|
374
|
+
sessionToken,
|
|
348
375
|
signal
|
|
349
|
-
// AbortSignal for request cancellation
|
|
350
376
|
}) => {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
377
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
378
|
+
if (!accessToken || !sessionToken) {
|
|
379
|
+
throw new Error("accessToken and sessionToken are required");
|
|
380
|
+
}
|
|
381
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
382
|
+
if (!decodedToken) {
|
|
383
|
+
throw new Error("Invalid access token");
|
|
384
|
+
}
|
|
385
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
386
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
387
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
388
|
+
}
|
|
389
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
390
|
+
const response = await fetch(
|
|
391
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/verify-status`,
|
|
392
|
+
{
|
|
393
|
+
method: "POST",
|
|
367
394
|
headers: {
|
|
368
395
|
Authorization: `Bearer ${accessToken}`,
|
|
369
|
-
Accept: "application/json",
|
|
370
396
|
"Content-Type": "application/json"
|
|
371
397
|
},
|
|
398
|
+
body: JSON.stringify({
|
|
399
|
+
session_token: sessionToken
|
|
400
|
+
}),
|
|
372
401
|
signal
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
errorMessage =
|
|
381
|
-
}
|
|
382
|
-
errorMessage = "
|
|
383
|
-
} else if (response.status >= 500) {
|
|
384
|
-
errorMessage = "Server error: Please try again later";
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
if (!response.ok) {
|
|
405
|
+
let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;
|
|
406
|
+
if (response.status === 400) {
|
|
407
|
+
try {
|
|
408
|
+
const errorData = await response.json();
|
|
409
|
+
errorMessage = errorData.message || ((_a = errorData.detail) == null ? void 0 : _a.message) || "Invalid session token";
|
|
410
|
+
} catch {
|
|
411
|
+
errorMessage = "Invalid session token";
|
|
385
412
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
413
|
+
} else if (response.status === 401) {
|
|
414
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
415
|
+
} else if (response.status === 404) {
|
|
416
|
+
errorMessage = "Verification session not found or expired. Please restart the verification process.";
|
|
417
|
+
} else if (response.status === 410) {
|
|
418
|
+
errorMessage = "Verification session has expired. Please restart the verification process.";
|
|
419
|
+
} else if (response.status >= 500) {
|
|
420
|
+
errorMessage = "Server error: Please try again later";
|
|
389
421
|
}
|
|
390
|
-
const
|
|
391
|
-
|
|
392
|
-
} catch (error) {
|
|
422
|
+
const error = new Error(errorMessage);
|
|
423
|
+
error.status = response.status;
|
|
393
424
|
throw error;
|
|
394
425
|
}
|
|
426
|
+
const responseData = await response.json();
|
|
427
|
+
const detail = responseData.detail || responseData;
|
|
428
|
+
return {
|
|
429
|
+
status: (_b = detail.status) != null ? _b : "in_progress",
|
|
430
|
+
guardian_info_uuid: (_c = detail.guardian_info_uuid) != null ? _c : null,
|
|
431
|
+
verification_reference: (_d = detail.verification_reference) != null ? _d : null,
|
|
432
|
+
guardian_details: (_e = detail.guardian_details) != null ? _e : null,
|
|
433
|
+
error: (_f = detail.error) != null ? _f : null,
|
|
434
|
+
error_code: (_g = detail.error_code) != null ? _g : null,
|
|
435
|
+
can_retry: (_h = detail.can_retry) != null ? _h : true
|
|
436
|
+
};
|
|
395
437
|
};
|
|
396
438
|
|
|
397
439
|
// src/RedactoNoticeConsent/assets/redacto-logo.png
|
|
@@ -409,6 +451,52 @@ var DPO_AUDIO_ELEMENT_MAP = [
|
|
|
409
451
|
{ audioKey: "dpo_anchor_text_audio_url", elementId: "dpo-dpo-link" }
|
|
410
452
|
];
|
|
411
453
|
|
|
454
|
+
// src/RedactoNoticeConsent/language-codes.ts
|
|
455
|
+
var LANGUAGE_NAME_TO_BCP47 = {
|
|
456
|
+
English: "en",
|
|
457
|
+
Assamese: "as",
|
|
458
|
+
Bengali: "bn",
|
|
459
|
+
Bodo: "brx",
|
|
460
|
+
Dogri: "doi",
|
|
461
|
+
Gujarati: "gu",
|
|
462
|
+
Hindi: "hi",
|
|
463
|
+
Kannada: "kn",
|
|
464
|
+
Kashmiri: "ks",
|
|
465
|
+
Konkani: "gom",
|
|
466
|
+
Maithili: "mai",
|
|
467
|
+
Malayalam: "ml",
|
|
468
|
+
Manipuri: "mni-Mtei",
|
|
469
|
+
Marathi: "mr",
|
|
470
|
+
Nepali: "ne",
|
|
471
|
+
Odia: "or",
|
|
472
|
+
Punjabi: "pa",
|
|
473
|
+
Sanskrit: "sa",
|
|
474
|
+
Santali: "sat",
|
|
475
|
+
Sindhi: "sd",
|
|
476
|
+
Tamil: "ta",
|
|
477
|
+
Telugu: "te",
|
|
478
|
+
Urdu: "ur"
|
|
479
|
+
};
|
|
480
|
+
var KNOWN_BCP47_CODES = new Set(Object.values(LANGUAGE_NAME_TO_BCP47));
|
|
481
|
+
var toBcp47Code = (language) => {
|
|
482
|
+
if (LANGUAGE_NAME_TO_BCP47[language]) {
|
|
483
|
+
return LANGUAGE_NAME_TO_BCP47[language];
|
|
484
|
+
}
|
|
485
|
+
if (KNOWN_BCP47_CODES.has(language)) {
|
|
486
|
+
return language;
|
|
487
|
+
}
|
|
488
|
+
const lower = language.toLowerCase();
|
|
489
|
+
for (const [name, code] of Object.entries(LANGUAGE_NAME_TO_BCP47)) {
|
|
490
|
+
if (name.toLowerCase() === lower) {
|
|
491
|
+
return code;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/.test(language)) {
|
|
495
|
+
return language;
|
|
496
|
+
}
|
|
497
|
+
return "en";
|
|
498
|
+
};
|
|
499
|
+
|
|
412
500
|
// src/RedactoNoticeConsent/injectStyles.ts
|
|
413
501
|
var stylesInjected = false;
|
|
414
502
|
var injectCheckboxStyles = () => {
|
|
@@ -539,6 +627,17 @@ var injectCheckboxStyles = () => {
|
|
|
539
627
|
outline: 3px solid #FFF9C4 !important;
|
|
540
628
|
outline-offset: 2px !important;
|
|
541
629
|
}
|
|
630
|
+
|
|
631
|
+
/* Spinner animation for verification screens */
|
|
632
|
+
@keyframes spin {
|
|
633
|
+
from { transform: rotate(0deg); }
|
|
634
|
+
to { transform: rotate(360deg); }
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/* DigiLocker callback retry button hover */
|
|
638
|
+
.redacto-dl-retry-btn:hover {
|
|
639
|
+
background-color: #2563eb !important;
|
|
640
|
+
}
|
|
542
641
|
`;
|
|
543
642
|
document.head.appendChild(style);
|
|
544
643
|
stylesInjected = true;
|
|
@@ -921,6 +1020,69 @@ var useMediaQuery = (query) => {
|
|
|
921
1020
|
return matches;
|
|
922
1021
|
};
|
|
923
1022
|
|
|
1023
|
+
// src/RedactoNoticeConsent/services/storage.ts
|
|
1024
|
+
var STORAGE_KEY = "redacto_consent_sdk_state";
|
|
1025
|
+
var STATE_EXPIRY_MS = 30 * 60 * 1e3;
|
|
1026
|
+
var isBrowser = () => {
|
|
1027
|
+
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
1028
|
+
};
|
|
1029
|
+
var saveConsentState = (state) => {
|
|
1030
|
+
if (!isBrowser()) {
|
|
1031
|
+
console.warn("SessionStorage not available - state not persisted");
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
try {
|
|
1035
|
+
const stateWithTimestamp = {
|
|
1036
|
+
...state,
|
|
1037
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1038
|
+
};
|
|
1039
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
console.error("Failed to save consent state:", error);
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
var getConsentState = () => {
|
|
1045
|
+
if (!isBrowser()) {
|
|
1046
|
+
return null;
|
|
1047
|
+
}
|
|
1048
|
+
try {
|
|
1049
|
+
const savedState = sessionStorage.getItem(STORAGE_KEY);
|
|
1050
|
+
if (!savedState) {
|
|
1051
|
+
return null;
|
|
1052
|
+
}
|
|
1053
|
+
const parsed = JSON.parse(savedState);
|
|
1054
|
+
const stateAge = Date.now() - new Date(parsed.timestamp).getTime();
|
|
1055
|
+
if (stateAge > STATE_EXPIRY_MS) {
|
|
1056
|
+
clearConsentState();
|
|
1057
|
+
return null;
|
|
1058
|
+
}
|
|
1059
|
+
return parsed;
|
|
1060
|
+
} catch (error) {
|
|
1061
|
+
console.error("Failed to get consent state:", error);
|
|
1062
|
+
return null;
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
var clearConsentState = () => {
|
|
1066
|
+
if (!isBrowser()) {
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
try {
|
|
1070
|
+
sessionStorage.removeItem(STORAGE_KEY);
|
|
1071
|
+
} catch (error) {
|
|
1072
|
+
console.error("Failed to clear consent state:", error);
|
|
1073
|
+
}
|
|
1074
|
+
};
|
|
1075
|
+
var updateConsentState = (updates) => {
|
|
1076
|
+
const currentState = getConsentState();
|
|
1077
|
+
if (currentState) {
|
|
1078
|
+
saveConsentState({
|
|
1079
|
+
...currentState,
|
|
1080
|
+
...updates,
|
|
1081
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1082
|
+
});
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
924
1086
|
// src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
|
|
925
1087
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
926
1088
|
var PurposeItem = ({
|
|
@@ -1228,6 +1390,12 @@ var PurposeItem = ({
|
|
|
1228
1390
|
)
|
|
1229
1391
|
] }, purpose.uuid);
|
|
1230
1392
|
};
|
|
1393
|
+
var RELATIONSHIP_OPTIONS = [
|
|
1394
|
+
{ value: "Father", label: "Father" },
|
|
1395
|
+
{ value: "Mother", label: "Mother" },
|
|
1396
|
+
{ value: "Legal Guardian", label: "Legal Guardian" },
|
|
1397
|
+
{ value: "Grandparent", label: "Grandparent" }
|
|
1398
|
+
];
|
|
1231
1399
|
var GuardianForm = ({
|
|
1232
1400
|
formData,
|
|
1233
1401
|
errors,
|
|
@@ -1244,34 +1412,128 @@ var GuardianForm = ({
|
|
|
1244
1412
|
declineButtonStyle,
|
|
1245
1413
|
logoUrl
|
|
1246
1414
|
}) => {
|
|
1415
|
+
var _a, _b, _c, _d, _e;
|
|
1416
|
+
const [isDropdownOpen, setIsDropdownOpen] = (0, import_react2.useState)(false);
|
|
1417
|
+
const [focusedIndex, setFocusedIndex] = (0, import_react2.useState)(-1);
|
|
1418
|
+
const [openUpward, setOpenUpward] = (0, import_react2.useState)(false);
|
|
1419
|
+
const dropdownRef = (0, import_react2.useRef)(null);
|
|
1420
|
+
const optionsRef = (0, import_react2.useRef)(null);
|
|
1421
|
+
(0, import_react2.useEffect)(() => {
|
|
1422
|
+
if (!isDropdownOpen) return;
|
|
1423
|
+
const handleClickOutside = (e) => {
|
|
1424
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1425
|
+
setIsDropdownOpen(false);
|
|
1426
|
+
setFocusedIndex(-1);
|
|
1427
|
+
}
|
|
1428
|
+
};
|
|
1429
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1430
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1431
|
+
}, [isDropdownOpen]);
|
|
1432
|
+
(0, import_react2.useEffect)(() => {
|
|
1433
|
+
if (!isDropdownOpen || !dropdownRef.current) return;
|
|
1434
|
+
const rect = dropdownRef.current.getBoundingClientRect();
|
|
1435
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1436
|
+
const dropdownHeight = 220;
|
|
1437
|
+
setOpenUpward(spaceBelow < dropdownHeight && rect.top > dropdownHeight);
|
|
1438
|
+
}, [isDropdownOpen]);
|
|
1439
|
+
const handleSelect = (value) => {
|
|
1440
|
+
onChange("guardianRelationship", value);
|
|
1441
|
+
setIsDropdownOpen(false);
|
|
1442
|
+
setFocusedIndex(-1);
|
|
1443
|
+
};
|
|
1444
|
+
const handleKeyDown = (e) => {
|
|
1445
|
+
if (!isDropdownOpen) {
|
|
1446
|
+
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
|
|
1447
|
+
e.preventDefault();
|
|
1448
|
+
setIsDropdownOpen(true);
|
|
1449
|
+
setFocusedIndex(0);
|
|
1450
|
+
}
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
switch (e.key) {
|
|
1454
|
+
case "ArrowDown":
|
|
1455
|
+
e.preventDefault();
|
|
1456
|
+
setFocusedIndex((prev) => Math.min(prev + 1, RELATIONSHIP_OPTIONS.length - 1));
|
|
1457
|
+
break;
|
|
1458
|
+
case "ArrowUp":
|
|
1459
|
+
e.preventDefault();
|
|
1460
|
+
setFocusedIndex((prev) => Math.max(prev - 1, 0));
|
|
1461
|
+
break;
|
|
1462
|
+
case "Enter":
|
|
1463
|
+
case " ":
|
|
1464
|
+
e.preventDefault();
|
|
1465
|
+
if (focusedIndex >= 0) handleSelect(RELATIONSHIP_OPTIONS[focusedIndex].value);
|
|
1466
|
+
break;
|
|
1467
|
+
case "Escape":
|
|
1468
|
+
case "Tab":
|
|
1469
|
+
setIsDropdownOpen(false);
|
|
1470
|
+
setFocusedIndex(-1);
|
|
1471
|
+
break;
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
(0, import_react2.useEffect)(() => {
|
|
1475
|
+
var _a2;
|
|
1476
|
+
if (focusedIndex >= 0 && optionsRef.current) {
|
|
1477
|
+
const option = optionsRef.current.children[focusedIndex];
|
|
1478
|
+
(_a2 = option == null ? void 0 : option.scrollIntoView) == null ? void 0 : _a2.call(option, { block: "nearest" });
|
|
1479
|
+
}
|
|
1480
|
+
}, [focusedIndex]);
|
|
1481
|
+
const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
|
|
1482
|
+
const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
|
|
1483
|
+
const bgColor = (settings == null ? void 0 : settings.backgroundColor) || "#ffffff";
|
|
1484
|
+
const radius = (settings == null ? void 0 : settings.borderRadius) || "8px";
|
|
1485
|
+
const font = (settings == null ? void 0 : settings.font) || "inherit";
|
|
1247
1486
|
const inputStyle = {
|
|
1248
1487
|
width: "100%",
|
|
1249
1488
|
padding: "10px 12px",
|
|
1250
|
-
border: `1px solid ${
|
|
1251
|
-
borderRadius:
|
|
1489
|
+
border: `1px solid ${borderColor}`,
|
|
1490
|
+
borderRadius: radius,
|
|
1252
1491
|
fontSize: "13px",
|
|
1253
|
-
fontFamily:
|
|
1254
|
-
color:
|
|
1255
|
-
backgroundColor:
|
|
1256
|
-
marginBottom: "
|
|
1257
|
-
boxSizing: "border-box"
|
|
1492
|
+
fontFamily: font,
|
|
1493
|
+
color: textColor,
|
|
1494
|
+
backgroundColor: bgColor,
|
|
1495
|
+
marginBottom: "2px",
|
|
1496
|
+
boxSizing: "border-box",
|
|
1497
|
+
outline: "none"
|
|
1258
1498
|
};
|
|
1259
1499
|
const errorStyle = {
|
|
1260
1500
|
color: "#DC2626",
|
|
1261
|
-
fontSize: "
|
|
1501
|
+
fontSize: "11px",
|
|
1262
1502
|
marginTop: "4px",
|
|
1263
|
-
marginBottom: "
|
|
1503
|
+
marginBottom: "0px"
|
|
1264
1504
|
};
|
|
1265
1505
|
const labelStyle = {
|
|
1266
1506
|
...componentTextStyle,
|
|
1267
1507
|
fontSize: "13px",
|
|
1268
1508
|
fontWeight: "500",
|
|
1269
|
-
marginBottom: "
|
|
1509
|
+
marginBottom: "4px",
|
|
1270
1510
|
display: "block"
|
|
1271
1511
|
};
|
|
1512
|
+
const hintStyle = {
|
|
1513
|
+
fontSize: "11px",
|
|
1514
|
+
color: "#667085",
|
|
1515
|
+
marginTop: "2px",
|
|
1516
|
+
marginBottom: "0px",
|
|
1517
|
+
lineHeight: "1.4"
|
|
1518
|
+
};
|
|
1519
|
+
const infoBannerStyle = {
|
|
1520
|
+
display: "flex",
|
|
1521
|
+
alignItems: "flex-start",
|
|
1522
|
+
gap: "8px",
|
|
1523
|
+
padding: "10px 12px",
|
|
1524
|
+
backgroundColor: "#EFF6FF",
|
|
1525
|
+
border: "1px solid #BFDBFE",
|
|
1526
|
+
borderRadius: radius,
|
|
1527
|
+
marginBottom: "16px",
|
|
1528
|
+
fontSize: "12px",
|
|
1529
|
+
lineHeight: "1.5",
|
|
1530
|
+
color: "#1E40AF"
|
|
1531
|
+
};
|
|
1532
|
+
const selectedLabel = (_a = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)) == null ? void 0 : _a.label;
|
|
1533
|
+
const hasError = Boolean(errors.guardianRelationship);
|
|
1272
1534
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1273
1535
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles3.topLeft, children: [
|
|
1274
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { style: styles3.logo, src: logoUrl, alt: "
|
|
1536
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1275
1537
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1276
1538
|
"h2",
|
|
1277
1539
|
{
|
|
@@ -1283,7 +1545,7 @@ var GuardianForm = ({
|
|
|
1283
1545
|
fontSize: "16px",
|
|
1284
1546
|
fontWeight: 600
|
|
1285
1547
|
},
|
|
1286
|
-
children: "Guardian
|
|
1548
|
+
children: "Guardian Verification"
|
|
1287
1549
|
}
|
|
1288
1550
|
)
|
|
1289
1551
|
] }) }),
|
|
@@ -1303,31 +1565,49 @@ var GuardianForm = ({
|
|
|
1303
1565
|
...styles3.privacyText,
|
|
1304
1566
|
...responsiveStyles.privacyText,
|
|
1305
1567
|
...componentTextStyle,
|
|
1306
|
-
fontSize: "
|
|
1307
|
-
lineHeight: "1.
|
|
1568
|
+
fontSize: "13px",
|
|
1569
|
+
lineHeight: "1.5",
|
|
1570
|
+
marginBottom: "12px"
|
|
1308
1571
|
},
|
|
1309
|
-
children: "
|
|
1572
|
+
children: "Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed."
|
|
1310
1573
|
}
|
|
1311
1574
|
),
|
|
1575
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: infoBannerStyle, children: [
|
|
1576
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1577
|
+
"svg",
|
|
1578
|
+
{
|
|
1579
|
+
width: "16",
|
|
1580
|
+
height: "16",
|
|
1581
|
+
viewBox: "0 0 24 24",
|
|
1582
|
+
fill: "none",
|
|
1583
|
+
stroke: "#2563EB",
|
|
1584
|
+
strokeWidth: "2",
|
|
1585
|
+
strokeLinecap: "round",
|
|
1586
|
+
strokeLinejoin: "round",
|
|
1587
|
+
style: { flexShrink: 0, marginTop: "1px" },
|
|
1588
|
+
children: [
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
1592
|
+
]
|
|
1593
|
+
}
|
|
1594
|
+
),
|
|
1595
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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." })
|
|
1596
|
+
] }),
|
|
1312
1597
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1313
1598
|
"div",
|
|
1314
1599
|
{
|
|
1315
1600
|
style: {
|
|
1316
1601
|
display: "flex",
|
|
1317
1602
|
flexDirection: "column",
|
|
1318
|
-
gap: "
|
|
1319
|
-
marginTop: "16px"
|
|
1603
|
+
gap: "14px"
|
|
1320
1604
|
},
|
|
1321
1605
|
children: [
|
|
1322
1606
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1323
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1324
|
-
"
|
|
1325
|
-
{
|
|
1326
|
-
|
|
1327
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1328
|
-
children: "Name of Guardian *"
|
|
1329
|
-
}
|
|
1330
|
-
),
|
|
1607
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "guardianName", style: labelStyle, children: [
|
|
1608
|
+
"Guardian's Full Name ",
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1610
|
+
] }),
|
|
1331
1611
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1332
1612
|
"input",
|
|
1333
1613
|
{
|
|
@@ -1337,62 +1617,170 @@ var GuardianForm = ({
|
|
|
1337
1617
|
onChange: (e) => onChange("guardianName", e.target.value),
|
|
1338
1618
|
style: {
|
|
1339
1619
|
...inputStyle,
|
|
1340
|
-
borderColor: errors.guardianName ? "#DC2626" :
|
|
1620
|
+
borderColor: errors.guardianName ? "#DC2626" : borderColor
|
|
1341
1621
|
},
|
|
1342
|
-
placeholder: "
|
|
1622
|
+
placeholder: "e.g. Rajesh Kumar",
|
|
1623
|
+
autoComplete: "name",
|
|
1624
|
+
"aria-describedby": "guardianName-hint"
|
|
1343
1625
|
}
|
|
1344
1626
|
),
|
|
1345
|
-
|
|
1627
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "guardianName-hint", style: hintStyle, children: "Enter the full name as per government ID (Aadhaar, PAN, etc.)" }),
|
|
1628
|
+
errors.guardianName && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, role: "alert", children: errors.guardianName })
|
|
1346
1629
|
] }),
|
|
1347
1630
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1348
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1349
|
-
"
|
|
1350
|
-
{
|
|
1351
|
-
|
|
1352
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1353
|
-
children: "Contact of Guardian *"
|
|
1354
|
-
}
|
|
1355
|
-
),
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "guardianContact", style: labelStyle, children: [
|
|
1632
|
+
"Guardian's Phone Number ",
|
|
1633
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1634
|
+
] }),
|
|
1356
1635
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1357
1636
|
"input",
|
|
1358
1637
|
{
|
|
1359
1638
|
id: "guardianContact",
|
|
1360
|
-
type: "
|
|
1639
|
+
type: "tel",
|
|
1640
|
+
inputMode: "tel",
|
|
1361
1641
|
value: formData.guardianContact,
|
|
1362
1642
|
onChange: (e) => onChange("guardianContact", e.target.value),
|
|
1363
1643
|
style: {
|
|
1364
1644
|
...inputStyle,
|
|
1365
|
-
borderColor: errors.guardianContact ? "#DC2626" :
|
|
1645
|
+
borderColor: errors.guardianContact ? "#DC2626" : borderColor
|
|
1366
1646
|
},
|
|
1367
|
-
placeholder: "
|
|
1647
|
+
placeholder: "e.g. 9876543210",
|
|
1648
|
+
autoComplete: "tel",
|
|
1649
|
+
"aria-describedby": "guardianContact-hint"
|
|
1368
1650
|
}
|
|
1369
1651
|
),
|
|
1370
|
-
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "guardianContact-hint", style: hintStyle, children: "Mobile number linked to guardian's Aadhaar" }),
|
|
1653
|
+
errors.guardianContact && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, role: "alert", children: errors.guardianContact })
|
|
1371
1654
|
] }),
|
|
1372
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
1373
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1374
|
-
"
|
|
1655
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: dropdownRef, style: { position: "relative" }, children: [
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { id: "guardianRelationship-label", style: labelStyle, children: [
|
|
1657
|
+
"Relationship ",
|
|
1658
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1659
|
+
] }),
|
|
1660
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1661
|
+
"div",
|
|
1375
1662
|
{
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1663
|
+
role: "combobox",
|
|
1664
|
+
"aria-expanded": isDropdownOpen,
|
|
1665
|
+
"aria-haspopup": "listbox",
|
|
1666
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1667
|
+
"aria-controls": "guardianRelationship-listbox",
|
|
1668
|
+
"aria-activedescendant": focusedIndex >= 0 ? `guardianRelationship-option-${focusedIndex}` : void 0,
|
|
1669
|
+
tabIndex: 0,
|
|
1670
|
+
onClick: () => {
|
|
1671
|
+
setIsDropdownOpen((prev) => !prev);
|
|
1672
|
+
setFocusedIndex(-1);
|
|
1673
|
+
},
|
|
1674
|
+
onKeyDown: handleKeyDown,
|
|
1675
|
+
style: {
|
|
1676
|
+
...inputStyle,
|
|
1677
|
+
borderColor: hasError ? "#DC2626" : isDropdownOpen ? ((_c = (_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.backgroundColor) || "#3b82f6" : borderColor,
|
|
1678
|
+
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",
|
|
1679
|
+
color: selectedLabel ? textColor : "#9CA3AF",
|
|
1680
|
+
cursor: "pointer",
|
|
1681
|
+
display: "flex",
|
|
1682
|
+
alignItems: "center",
|
|
1683
|
+
justifyContent: "space-between",
|
|
1684
|
+
userSelect: "none",
|
|
1685
|
+
transition: "border-color 0.15s, box-shadow 0.15s"
|
|
1686
|
+
},
|
|
1687
|
+
children: [
|
|
1688
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selectedLabel || "Select relationship" }),
|
|
1689
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1690
|
+
"svg",
|
|
1691
|
+
{
|
|
1692
|
+
width: "14",
|
|
1693
|
+
height: "14",
|
|
1694
|
+
viewBox: "0 0 24 24",
|
|
1695
|
+
fill: "none",
|
|
1696
|
+
stroke: "#667085",
|
|
1697
|
+
strokeWidth: "2",
|
|
1698
|
+
strokeLinecap: "round",
|
|
1699
|
+
strokeLinejoin: "round",
|
|
1700
|
+
style: {
|
|
1701
|
+
flexShrink: 0,
|
|
1702
|
+
marginLeft: "8px",
|
|
1703
|
+
transform: isDropdownOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
1704
|
+
transition: "transform 0.2s"
|
|
1705
|
+
},
|
|
1706
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "6 9 12 15 18 9" })
|
|
1707
|
+
}
|
|
1708
|
+
)
|
|
1709
|
+
]
|
|
1379
1710
|
}
|
|
1380
1711
|
),
|
|
1381
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1382
|
-
"
|
|
1712
|
+
isDropdownOpen && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1713
|
+
"div",
|
|
1383
1714
|
{
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1715
|
+
ref: optionsRef,
|
|
1716
|
+
id: "guardianRelationship-listbox",
|
|
1717
|
+
role: "listbox",
|
|
1718
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1388
1719
|
style: {
|
|
1389
|
-
|
|
1390
|
-
|
|
1720
|
+
position: "absolute",
|
|
1721
|
+
...openUpward ? { bottom: "calc(100% + 4px)" } : { top: "calc(100% + 4px)" },
|
|
1722
|
+
left: 0,
|
|
1723
|
+
right: 0,
|
|
1724
|
+
backgroundColor: bgColor,
|
|
1725
|
+
border: `1px solid ${borderColor}`,
|
|
1726
|
+
borderRadius: radius,
|
|
1727
|
+
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)",
|
|
1728
|
+
zIndex: 50,
|
|
1729
|
+
overflow: "hidden",
|
|
1730
|
+
padding: "4px 0",
|
|
1731
|
+
maxHeight: "220px",
|
|
1732
|
+
overflowY: "auto"
|
|
1391
1733
|
},
|
|
1392
|
-
|
|
1734
|
+
children: RELATIONSHIP_OPTIONS.map((option, index) => {
|
|
1735
|
+
var _a2, _b2;
|
|
1736
|
+
const isSelected = formData.guardianRelationship === option.value;
|
|
1737
|
+
const isFocused = focusedIndex === index;
|
|
1738
|
+
const accentColor = ((_b2 = (_a2 = settings == null ? void 0 : settings.button) == null ? void 0 : _a2.accept) == null ? void 0 : _b2.backgroundColor) || "#3b82f6";
|
|
1739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1740
|
+
"div",
|
|
1741
|
+
{
|
|
1742
|
+
id: `guardianRelationship-option-${index}`,
|
|
1743
|
+
role: "option",
|
|
1744
|
+
"aria-selected": isSelected,
|
|
1745
|
+
onClick: () => handleSelect(option.value),
|
|
1746
|
+
onMouseEnter: () => setFocusedIndex(index),
|
|
1747
|
+
style: {
|
|
1748
|
+
padding: "9px 12px",
|
|
1749
|
+
fontSize: "13px",
|
|
1750
|
+
fontFamily: font,
|
|
1751
|
+
color: isSelected ? accentColor : textColor,
|
|
1752
|
+
backgroundColor: isFocused ? "#F3F4F6" : "transparent",
|
|
1753
|
+
cursor: "pointer",
|
|
1754
|
+
display: "flex",
|
|
1755
|
+
alignItems: "center",
|
|
1756
|
+
justifyContent: "space-between",
|
|
1757
|
+
transition: "background-color 0.1s"
|
|
1758
|
+
},
|
|
1759
|
+
children: [
|
|
1760
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: option.label }),
|
|
1761
|
+
isSelected && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1762
|
+
"svg",
|
|
1763
|
+
{
|
|
1764
|
+
width: "14",
|
|
1765
|
+
height: "14",
|
|
1766
|
+
viewBox: "0 0 24 24",
|
|
1767
|
+
fill: "none",
|
|
1768
|
+
stroke: accentColor,
|
|
1769
|
+
strokeWidth: "2.5",
|
|
1770
|
+
strokeLinecap: "round",
|
|
1771
|
+
strokeLinejoin: "round",
|
|
1772
|
+
style: { flexShrink: 0 },
|
|
1773
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
1774
|
+
}
|
|
1775
|
+
)
|
|
1776
|
+
]
|
|
1777
|
+
},
|
|
1778
|
+
option.value
|
|
1779
|
+
);
|
|
1780
|
+
})
|
|
1393
1781
|
}
|
|
1394
1782
|
),
|
|
1395
|
-
errors.guardianRelationship && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, children: errors.guardianRelationship })
|
|
1783
|
+
errors.guardianRelationship && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, role: "alert", children: errors.guardianRelationship })
|
|
1396
1784
|
] })
|
|
1397
1785
|
]
|
|
1398
1786
|
}
|
|
@@ -1403,7 +1791,7 @@ var GuardianForm = ({
|
|
|
1403
1791
|
role: "alert",
|
|
1404
1792
|
style: {
|
|
1405
1793
|
color: "#DC2626",
|
|
1406
|
-
fontSize: "
|
|
1794
|
+
fontSize: "13px",
|
|
1407
1795
|
marginTop: "16px",
|
|
1408
1796
|
padding: "12px",
|
|
1409
1797
|
borderRadius: "6px",
|
|
@@ -1439,8 +1827,8 @@ var GuardianForm = ({
|
|
|
1439
1827
|
onClick: onNext,
|
|
1440
1828
|
disabled: isSubmitting,
|
|
1441
1829
|
type: "button",
|
|
1442
|
-
"aria-label": isSubmitting ? "
|
|
1443
|
-
children: isSubmitting ? "
|
|
1830
|
+
"aria-label": isSubmitting ? "Verifying guardian identity" : "Proceed to guardian verification",
|
|
1831
|
+
children: isSubmitting ? "Verifying..." : "Verify via DigiLocker"
|
|
1444
1832
|
}
|
|
1445
1833
|
),
|
|
1446
1834
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1454,7 +1842,7 @@ var GuardianForm = ({
|
|
|
1454
1842
|
},
|
|
1455
1843
|
onClick: onDecline,
|
|
1456
1844
|
type: "button",
|
|
1457
|
-
"aria-label": "Cancel
|
|
1845
|
+
"aria-label": "Cancel",
|
|
1458
1846
|
children: "Cancel"
|
|
1459
1847
|
}
|
|
1460
1848
|
)
|
|
@@ -1463,6 +1851,266 @@ var GuardianForm = ({
|
|
|
1463
1851
|
)
|
|
1464
1852
|
] });
|
|
1465
1853
|
};
|
|
1854
|
+
var VerificationScreen = ({
|
|
1855
|
+
onBack,
|
|
1856
|
+
onContinue,
|
|
1857
|
+
isInitiating,
|
|
1858
|
+
isPolling,
|
|
1859
|
+
isVerificationComplete,
|
|
1860
|
+
isAutoTransitioning,
|
|
1861
|
+
error,
|
|
1862
|
+
errorCode,
|
|
1863
|
+
canRetry,
|
|
1864
|
+
styles: styles3,
|
|
1865
|
+
responsiveStyles,
|
|
1866
|
+
settings,
|
|
1867
|
+
componentHeadingStyle,
|
|
1868
|
+
componentTextStyle,
|
|
1869
|
+
acceptButtonStyle,
|
|
1870
|
+
declineButtonStyle,
|
|
1871
|
+
logoUrl
|
|
1872
|
+
}) => {
|
|
1873
|
+
var _a, _b;
|
|
1874
|
+
const errorStyle = {
|
|
1875
|
+
color: "#DC2626",
|
|
1876
|
+
fontSize: "14px",
|
|
1877
|
+
marginTop: "16px",
|
|
1878
|
+
padding: "12px",
|
|
1879
|
+
borderRadius: "6px",
|
|
1880
|
+
border: "1px solid #FCA5A5",
|
|
1881
|
+
backgroundColor: "#FEF2F2",
|
|
1882
|
+
textAlign: "center"
|
|
1883
|
+
};
|
|
1884
|
+
const statusStyle = {
|
|
1885
|
+
color: "#059669",
|
|
1886
|
+
fontSize: "14px",
|
|
1887
|
+
marginTop: "16px",
|
|
1888
|
+
padding: "12px",
|
|
1889
|
+
borderRadius: "6px",
|
|
1890
|
+
border: "1px solid #A7F3D0",
|
|
1891
|
+
backgroundColor: "#D1FAE5",
|
|
1892
|
+
textAlign: "center"
|
|
1893
|
+
};
|
|
1894
|
+
const spinnerStyle = {
|
|
1895
|
+
width: "48px",
|
|
1896
|
+
height: "48px",
|
|
1897
|
+
border: "4px solid #e5e7eb",
|
|
1898
|
+
borderTopColor: ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || "#3b82f6",
|
|
1899
|
+
borderRadius: "50%",
|
|
1900
|
+
animation: "spin 1s linear infinite",
|
|
1901
|
+
margin: "24px auto"
|
|
1902
|
+
};
|
|
1903
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles3.topLeft, children: [
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1907
|
+
"h2",
|
|
1908
|
+
{
|
|
1909
|
+
id: "verification-title",
|
|
1910
|
+
style: {
|
|
1911
|
+
...styles3.title,
|
|
1912
|
+
...responsiveStyles.title,
|
|
1913
|
+
...componentHeadingStyle,
|
|
1914
|
+
fontSize: "16px",
|
|
1915
|
+
fontWeight: 600
|
|
1916
|
+
},
|
|
1917
|
+
children: "Guardian Verification"
|
|
1918
|
+
}
|
|
1919
|
+
)
|
|
1920
|
+
] }) }),
|
|
1921
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1922
|
+
"div",
|
|
1923
|
+
{
|
|
1924
|
+
style: {
|
|
1925
|
+
...styles3.middleSection,
|
|
1926
|
+
...responsiveStyles.middleSection,
|
|
1927
|
+
...componentTextStyle,
|
|
1928
|
+
textAlign: "center"
|
|
1929
|
+
},
|
|
1930
|
+
children: [
|
|
1931
|
+
isVerificationComplete && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1932
|
+
"div",
|
|
1933
|
+
{
|
|
1934
|
+
style: {
|
|
1935
|
+
display: "flex",
|
|
1936
|
+
flexDirection: "column",
|
|
1937
|
+
alignItems: "center",
|
|
1938
|
+
justifyContent: "center",
|
|
1939
|
+
flex: 1
|
|
1940
|
+
},
|
|
1941
|
+
children: [
|
|
1942
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1943
|
+
"div",
|
|
1944
|
+
{
|
|
1945
|
+
style: {
|
|
1946
|
+
width: "64px",
|
|
1947
|
+
height: "64px",
|
|
1948
|
+
borderRadius: "50%",
|
|
1949
|
+
backgroundColor: "#D1FAE5",
|
|
1950
|
+
display: "flex",
|
|
1951
|
+
alignItems: "center",
|
|
1952
|
+
justifyContent: "center"
|
|
1953
|
+
},
|
|
1954
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1955
|
+
"svg",
|
|
1956
|
+
{
|
|
1957
|
+
width: "32",
|
|
1958
|
+
height: "32",
|
|
1959
|
+
viewBox: "0 0 24 24",
|
|
1960
|
+
fill: "none",
|
|
1961
|
+
stroke: "#059669",
|
|
1962
|
+
strokeWidth: "2",
|
|
1963
|
+
strokeLinecap: "round",
|
|
1964
|
+
strokeLinejoin: "round",
|
|
1965
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
1966
|
+
}
|
|
1967
|
+
)
|
|
1968
|
+
}
|
|
1969
|
+
),
|
|
1970
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1971
|
+
"p",
|
|
1972
|
+
{
|
|
1973
|
+
style: {
|
|
1974
|
+
...componentHeadingStyle,
|
|
1975
|
+
fontSize: "16px",
|
|
1976
|
+
fontWeight: 600,
|
|
1977
|
+
lineHeight: "1.5",
|
|
1978
|
+
marginTop: "12px",
|
|
1979
|
+
marginBottom: "24px"
|
|
1980
|
+
},
|
|
1981
|
+
children: "Verification Completed"
|
|
1982
|
+
}
|
|
1983
|
+
)
|
|
1984
|
+
]
|
|
1985
|
+
}
|
|
1986
|
+
) : (isInitiating || isPolling) && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1987
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: spinnerStyle }),
|
|
1988
|
+
/* @__PURE__ */ (0, import_jsx_runtime.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." })
|
|
1989
|
+
] }) : null,
|
|
1990
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1991
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1992
|
+
"div",
|
|
1993
|
+
{
|
|
1994
|
+
style: {
|
|
1995
|
+
width: "64px",
|
|
1996
|
+
height: "64px",
|
|
1997
|
+
borderRadius: "50%",
|
|
1998
|
+
backgroundColor: "#fee2e2",
|
|
1999
|
+
display: "flex",
|
|
2000
|
+
alignItems: "center",
|
|
2001
|
+
justifyContent: "center",
|
|
2002
|
+
margin: "24px auto"
|
|
2003
|
+
},
|
|
2004
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2005
|
+
"svg",
|
|
2006
|
+
{
|
|
2007
|
+
width: "32",
|
|
2008
|
+
height: "32",
|
|
2009
|
+
viewBox: "0 0 24 24",
|
|
2010
|
+
fill: "none",
|
|
2011
|
+
stroke: "#dc2626",
|
|
2012
|
+
strokeWidth: "2",
|
|
2013
|
+
strokeLinecap: "round",
|
|
2014
|
+
strokeLinejoin: "round",
|
|
2015
|
+
children: [
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2017
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2018
|
+
]
|
|
2019
|
+
}
|
|
2020
|
+
)
|
|
2021
|
+
}
|
|
2022
|
+
),
|
|
2023
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2024
|
+
"p",
|
|
2025
|
+
{
|
|
2026
|
+
style: {
|
|
2027
|
+
...styles3.privacyText,
|
|
2028
|
+
...responsiveStyles.privacyText,
|
|
2029
|
+
...componentTextStyle,
|
|
2030
|
+
fontSize: "14px",
|
|
2031
|
+
lineHeight: "1.5",
|
|
2032
|
+
marginBottom: "12px"
|
|
2033
|
+
},
|
|
2034
|
+
children: "Verification failed"
|
|
2035
|
+
}
|
|
2036
|
+
),
|
|
2037
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: errorStyle, children: error })
|
|
2038
|
+
] })
|
|
2039
|
+
]
|
|
2040
|
+
}
|
|
2041
|
+
),
|
|
2042
|
+
isAutoTransitioning ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2043
|
+
"div",
|
|
2044
|
+
{
|
|
2045
|
+
style: {
|
|
2046
|
+
...styles3.bottomSection,
|
|
2047
|
+
...responsiveStyles.bottomSection,
|
|
2048
|
+
...componentTextStyle,
|
|
2049
|
+
paddingTop: "12px",
|
|
2050
|
+
display: "flex",
|
|
2051
|
+
gap: "12px",
|
|
2052
|
+
justifyContent: "center"
|
|
2053
|
+
},
|
|
2054
|
+
children: isVerificationComplete && !error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2055
|
+
"button",
|
|
2056
|
+
{
|
|
2057
|
+
style: {
|
|
2058
|
+
...styles3.button,
|
|
2059
|
+
...responsiveStyles.button,
|
|
2060
|
+
...acceptButtonStyle
|
|
2061
|
+
},
|
|
2062
|
+
onClick: onContinue,
|
|
2063
|
+
type: "button",
|
|
2064
|
+
"aria-label": "Continue to consent form",
|
|
2065
|
+
children: "Continue"
|
|
2066
|
+
}
|
|
2067
|
+
) : error && canRetry ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2068
|
+
"button",
|
|
2069
|
+
{
|
|
2070
|
+
style: {
|
|
2071
|
+
...styles3.button,
|
|
2072
|
+
...responsiveStyles.button,
|
|
2073
|
+
...styles3.acceptButton,
|
|
2074
|
+
...acceptButtonStyle
|
|
2075
|
+
},
|
|
2076
|
+
onClick: () => onBack(errorCode === "GUARDIAN_UNDER_18"),
|
|
2077
|
+
type: "button",
|
|
2078
|
+
"aria-label": errorCode === "GUARDIAN_UNDER_18" ? "Change guardian details" : "Try verification again",
|
|
2079
|
+
children: errorCode === "GUARDIAN_UNDER_18" ? "Change Guardian" : "Try Again"
|
|
2080
|
+
}
|
|
2081
|
+
) : error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2082
|
+
"button",
|
|
2083
|
+
{
|
|
2084
|
+
style: {
|
|
2085
|
+
...styles3.button,
|
|
2086
|
+
...responsiveStyles.button,
|
|
2087
|
+
...styles3.cancelButton,
|
|
2088
|
+
...declineButtonStyle
|
|
2089
|
+
},
|
|
2090
|
+
onClick: () => onBack(false),
|
|
2091
|
+
type: "button",
|
|
2092
|
+
"aria-label": "Go back",
|
|
2093
|
+
children: "Go Back"
|
|
2094
|
+
}
|
|
2095
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2096
|
+
"button",
|
|
2097
|
+
{
|
|
2098
|
+
style: {
|
|
2099
|
+
...styles3.button,
|
|
2100
|
+
...responsiveStyles.button,
|
|
2101
|
+
...styles3.cancelButton,
|
|
2102
|
+
...declineButtonStyle
|
|
2103
|
+
},
|
|
2104
|
+
onClick: () => onBack(false),
|
|
2105
|
+
type: "button",
|
|
2106
|
+
"aria-label": "Cancel verification",
|
|
2107
|
+
children: "Cancel"
|
|
2108
|
+
}
|
|
2109
|
+
)
|
|
2110
|
+
}
|
|
2111
|
+
)
|
|
2112
|
+
] });
|
|
2113
|
+
};
|
|
1466
2114
|
var AgeVerification = ({
|
|
1467
2115
|
onYes,
|
|
1468
2116
|
onNo,
|
|
@@ -1625,6 +2273,10 @@ var RedactoNoticeConsent = ({
|
|
|
1625
2273
|
settings,
|
|
1626
2274
|
applicationId,
|
|
1627
2275
|
validateAgainst = "all",
|
|
2276
|
+
digilockerMode = "redirect",
|
|
2277
|
+
// Default to full page redirect (DigiLocker blocks iframe embedding)
|
|
2278
|
+
digilockerCallbackUrl = "/digilocker-callback",
|
|
2279
|
+
// Default callback path
|
|
1628
2280
|
includeFullyConsentedData = false,
|
|
1629
2281
|
reviewModeButtonText = "Continue"
|
|
1630
2282
|
}) => {
|
|
@@ -1680,6 +2332,8 @@ var RedactoNoticeConsent = ({
|
|
|
1680
2332
|
const [currentAudioIndex, setCurrentAudioIndex] = (0, import_react2.useState)(0);
|
|
1681
2333
|
const [highlightedElementId, setHighlightedElementId] = (0, import_react2.useState)(null);
|
|
1682
2334
|
const [showAgeVerification, setShowAgeVerification] = (0, import_react2.useState)(false);
|
|
2335
|
+
const [isMinorFlow, setIsMinorFlow] = (0, import_react2.useState)(false);
|
|
2336
|
+
const [selfDeclaredAdult, setSelfDeclaredAdult] = (0, import_react2.useState)(false);
|
|
1683
2337
|
const [showGuardianForm, setShowGuardianForm] = (0, import_react2.useState)(false);
|
|
1684
2338
|
const [isSubmittingGuardian, setIsSubmittingGuardian] = (0, import_react2.useState)(false);
|
|
1685
2339
|
const [guardianFormData, setGuardianFormData] = (0, import_react2.useState)({
|
|
@@ -1688,12 +2342,32 @@ var RedactoNoticeConsent = ({
|
|
|
1688
2342
|
guardianRelationship: ""
|
|
1689
2343
|
});
|
|
1690
2344
|
const [guardianFormErrors, setGuardianFormErrors] = (0, import_react2.useState)({});
|
|
2345
|
+
const [showVerificationScreen, setShowVerificationScreen] = (0, import_react2.useState)(false);
|
|
2346
|
+
const [verificationReference, setVerificationReference] = (0, import_react2.useState)(null);
|
|
2347
|
+
const [isInitiatingVerification, setIsInitiatingVerification] = (0, import_react2.useState)(false);
|
|
2348
|
+
const [verificationError, setVerificationError] = (0, import_react2.useState)(
|
|
2349
|
+
null
|
|
2350
|
+
);
|
|
2351
|
+
const [verificationErrorCode, setVerificationErrorCode] = (0, import_react2.useState)(null);
|
|
2352
|
+
const [canRetryVerification, setCanRetryVerification] = (0, import_react2.useState)(false);
|
|
2353
|
+
const [isPollingStatus, setIsPollingStatus] = (0, import_react2.useState)(false);
|
|
2354
|
+
const [isVerificationComplete, setIsVerificationComplete] = (0, import_react2.useState)(false);
|
|
2355
|
+
const [isAutoTransitioning, setIsAutoTransitioning] = (0, import_react2.useState)(false);
|
|
1691
2356
|
const modalRef = (0, import_react2.useRef)(null);
|
|
1692
2357
|
const firstFocusableRef = (0, import_react2.useRef)(null);
|
|
1693
2358
|
const lastFocusableRef = (0, import_react2.useRef)(null);
|
|
1694
2359
|
const abortControllerRef = (0, import_react2.useRef)(null);
|
|
1695
2360
|
const isRequestInProgressRef = (0, import_react2.useRef)(false);
|
|
1696
2361
|
const currentAudioRef = (0, import_react2.useRef)(null);
|
|
2362
|
+
const popupCheckIntervalRef = (0, import_react2.useRef)(null);
|
|
2363
|
+
const statusPollIntervalRef = (0, import_react2.useRef)(null);
|
|
2364
|
+
const verificationPopupRef = (0, import_react2.useRef)(null);
|
|
2365
|
+
const pollingCleanupRef = (0, import_react2.useRef)(null);
|
|
2366
|
+
const autoTransitionTimerRef = (0, import_react2.useRef)(null);
|
|
2367
|
+
const digilockerRedirectTimeoutRef = (0, import_react2.useRef)(null);
|
|
2368
|
+
const isInitialMountRef = (0, import_react2.useRef)(true);
|
|
2369
|
+
const isPollingStatusRef = (0, import_react2.useRef)(false);
|
|
2370
|
+
const verificationSessionTokenRef = (0, import_react2.useRef)(null);
|
|
1697
2371
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
1698
2372
|
const responsiveStyles = (0, import_react2.useMemo)(
|
|
1699
2373
|
() => ({
|
|
@@ -1801,6 +2475,7 @@ var RedactoNoticeConsent = ({
|
|
|
1801
2475
|
}, [content, selectedDataElements]);
|
|
1802
2476
|
const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
|
|
1803
2477
|
(0, import_react2.useEffect)(() => {
|
|
2478
|
+
var _a2, _b2;
|
|
1804
2479
|
clearApiCache();
|
|
1805
2480
|
isRequestInProgressRef.current = false;
|
|
1806
2481
|
setContent(null);
|
|
@@ -1816,6 +2491,8 @@ var RedactoNoticeConsent = ({
|
|
|
1816
2491
|
setIsSubmittingAccept(false);
|
|
1817
2492
|
setIsSubmittingDecline(false);
|
|
1818
2493
|
setShowAgeVerification(false);
|
|
2494
|
+
setIsMinorFlow(false);
|
|
2495
|
+
setSelfDeclaredAdult(false);
|
|
1819
2496
|
setShowGuardianForm(false);
|
|
1820
2497
|
setIsSubmittingGuardian(false);
|
|
1821
2498
|
setGuardianFormData({
|
|
@@ -1824,6 +2501,41 @@ var RedactoNoticeConsent = ({
|
|
|
1824
2501
|
guardianRelationship: ""
|
|
1825
2502
|
});
|
|
1826
2503
|
setGuardianFormErrors({});
|
|
2504
|
+
setShowVerificationScreen(false);
|
|
2505
|
+
setVerificationReference(null);
|
|
2506
|
+
setIsInitiatingVerification(false);
|
|
2507
|
+
setVerificationError(null);
|
|
2508
|
+
setVerificationErrorCode(null);
|
|
2509
|
+
setCanRetryVerification(false);
|
|
2510
|
+
setIsVerificationComplete(false);
|
|
2511
|
+
setIsAutoTransitioning(false);
|
|
2512
|
+
setIsPollingStatus(false);
|
|
2513
|
+
isPollingStatusRef.current = false;
|
|
2514
|
+
verificationSessionTokenRef.current = null;
|
|
2515
|
+
if (popupCheckIntervalRef.current) {
|
|
2516
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
2517
|
+
popupCheckIntervalRef.current = null;
|
|
2518
|
+
}
|
|
2519
|
+
if (statusPollIntervalRef.current) {
|
|
2520
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
2521
|
+
statusPollIntervalRef.current = null;
|
|
2522
|
+
}
|
|
2523
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
2524
|
+
pollingCleanupRef.current = null;
|
|
2525
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
2526
|
+
verificationPopupRef.current = null;
|
|
2527
|
+
if (autoTransitionTimerRef.current) {
|
|
2528
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
2529
|
+
autoTransitionTimerRef.current = null;
|
|
2530
|
+
}
|
|
2531
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
2532
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
2533
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
2534
|
+
}
|
|
2535
|
+
if (!isInitialMountRef.current) {
|
|
2536
|
+
clearConsentState();
|
|
2537
|
+
}
|
|
2538
|
+
isInitialMountRef.current = false;
|
|
1827
2539
|
}, [accessToken]);
|
|
1828
2540
|
(0, import_react2.useEffect)(() => {
|
|
1829
2541
|
if (hasAlreadyConsented) {
|
|
@@ -2032,7 +2744,11 @@ var RedactoNoticeConsent = ({
|
|
|
2032
2744
|
setInitialDataElementSelections({});
|
|
2033
2745
|
}
|
|
2034
2746
|
if (consentContentData.detail.is_minor) {
|
|
2035
|
-
|
|
2747
|
+
setIsMinorFlow(true);
|
|
2748
|
+
const persistedState = getConsentState();
|
|
2749
|
+
if (!(persistedState == null ? void 0 : persistedState.sessionToken) && !(persistedState == null ? void 0 : persistedState.verificationReference)) {
|
|
2750
|
+
setShowAgeVerification(true);
|
|
2751
|
+
}
|
|
2036
2752
|
}
|
|
2037
2753
|
setIsLoading(false);
|
|
2038
2754
|
} catch (err) {
|
|
@@ -2131,6 +2847,10 @@ var RedactoNoticeConsent = ({
|
|
|
2131
2847
|
const handleAccept = async () => {
|
|
2132
2848
|
const submitController = new AbortController();
|
|
2133
2849
|
try {
|
|
2850
|
+
if (isMinorFlow && !verificationReference) {
|
|
2851
|
+
setErrorMessage("Guardian verification is required before consent can be submitted.");
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2134
2854
|
setIsSubmittingAccept(true);
|
|
2135
2855
|
setIsSubmitting(true);
|
|
2136
2856
|
setErrorMessage(null);
|
|
@@ -2165,7 +2885,10 @@ var RedactoNoticeConsent = ({
|
|
|
2165
2885
|
};
|
|
2166
2886
|
}),
|
|
2167
2887
|
declined: false,
|
|
2888
|
+
language: toBcp47Code(selectedLanguage),
|
|
2168
2889
|
meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
|
|
2890
|
+
guardianVerificationReference: verificationReference || void 0,
|
|
2891
|
+
selfDeclaredAdult: selfDeclaredAdult || void 0,
|
|
2169
2892
|
signal: submitController.signal
|
|
2170
2893
|
});
|
|
2171
2894
|
}
|
|
@@ -2230,17 +2953,102 @@ var RedactoNoticeConsent = ({
|
|
|
2230
2953
|
try {
|
|
2231
2954
|
setIsSubmittingGuardian(true);
|
|
2232
2955
|
setGuardianFormErrors({});
|
|
2233
|
-
|
|
2956
|
+
setVerificationError(null);
|
|
2957
|
+
const callbackUrl = digilockerMode === "popup" ? new URL(digilockerCallbackUrl, window.location.origin).href : void 0;
|
|
2958
|
+
const response = await initiateGuardianVerification({
|
|
2234
2959
|
accessToken,
|
|
2235
2960
|
baseUrl,
|
|
2236
2961
|
guardianName: guardianFormData.guardianName,
|
|
2237
2962
|
guardianContact: guardianFormData.guardianContact,
|
|
2238
2963
|
guardianRelationship: guardianFormData.guardianRelationship,
|
|
2964
|
+
frontendCallbackUrl: callbackUrl,
|
|
2965
|
+
// Only for popup mode
|
|
2239
2966
|
signal: guardianController.signal
|
|
2240
2967
|
});
|
|
2968
|
+
setIsSubmittingGuardian(false);
|
|
2969
|
+
if (response.already_verified && response.verification_reference) {
|
|
2970
|
+
setVerificationReference(response.verification_reference);
|
|
2971
|
+
setShowGuardianForm(false);
|
|
2972
|
+
setShowVerificationScreen(true);
|
|
2973
|
+
setIsInitiatingVerification(false);
|
|
2974
|
+
setIsVerificationComplete(true);
|
|
2975
|
+
setIsAutoTransitioning(true);
|
|
2976
|
+
autoTransitionTimerRef.current = setTimeout(() => {
|
|
2977
|
+
setShowVerificationScreen(false);
|
|
2978
|
+
setIsVerificationComplete(false);
|
|
2979
|
+
setIsAutoTransitioning(false);
|
|
2980
|
+
autoTransitionTimerRef.current = null;
|
|
2981
|
+
}, 1e3);
|
|
2982
|
+
return;
|
|
2983
|
+
}
|
|
2984
|
+
if (!response.session_token || !response.digilocker_redirect_url) {
|
|
2985
|
+
throw new Error("Invalid response from server: missing required fields");
|
|
2986
|
+
}
|
|
2241
2987
|
setShowGuardianForm(false);
|
|
2988
|
+
setShowVerificationScreen(true);
|
|
2989
|
+
setIsInitiatingVerification(true);
|
|
2990
|
+
if (digilockerMode === "redirect") {
|
|
2991
|
+
saveConsentState({
|
|
2992
|
+
flowState: "digilocker-pending",
|
|
2993
|
+
sessionToken: response.session_token,
|
|
2994
|
+
guardianInfoUuid: response.guardian_info_uuid,
|
|
2995
|
+
selectedPurposes,
|
|
2996
|
+
selectedDataElements,
|
|
2997
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2998
|
+
originalUrl: window.location.href,
|
|
2999
|
+
noticeId,
|
|
3000
|
+
baseUrl
|
|
3001
|
+
});
|
|
3002
|
+
try {
|
|
3003
|
+
const openedWindow = window.open(
|
|
3004
|
+
response.digilocker_redirect_url,
|
|
3005
|
+
"_blank"
|
|
3006
|
+
);
|
|
3007
|
+
if (!openedWindow) {
|
|
3008
|
+
console.warn("Popup blocked \u2014 cannot open DigiLocker in new tab");
|
|
3009
|
+
setIsInitiatingVerification(false);
|
|
3010
|
+
setVerificationError(
|
|
3011
|
+
"Unable to open DigiLocker in a new tab. Please allow popups for this site and try again."
|
|
3012
|
+
);
|
|
3013
|
+
return;
|
|
3014
|
+
}
|
|
3015
|
+
try {
|
|
3016
|
+
openedWindow.opener = null;
|
|
3017
|
+
} catch {
|
|
3018
|
+
}
|
|
3019
|
+
} catch (error) {
|
|
3020
|
+
console.error("Failed to open DigiLocker in new tab:", error);
|
|
3021
|
+
setIsInitiatingVerification(false);
|
|
3022
|
+
setVerificationError(
|
|
3023
|
+
"Unable to open DigiLocker. Please allow popups for this site and try again."
|
|
3024
|
+
);
|
|
3025
|
+
return;
|
|
3026
|
+
}
|
|
3027
|
+
setIsInitiatingVerification(false);
|
|
3028
|
+
setIsPollingStatus(true);
|
|
3029
|
+
isPollingStatusRef.current = true;
|
|
3030
|
+
startStatusPolling(response.session_token);
|
|
3031
|
+
} else {
|
|
3032
|
+
setIsInitiatingVerification(true);
|
|
3033
|
+
const popup = window.open(
|
|
3034
|
+
response.digilocker_redirect_url,
|
|
3035
|
+
"digilocker_verification",
|
|
3036
|
+
"width=600,height=700,scrollbars=yes,resizable=yes"
|
|
3037
|
+
);
|
|
3038
|
+
if (popup) {
|
|
3039
|
+
verificationPopupRef.current = popup;
|
|
3040
|
+
startPopupMonitoring(popup);
|
|
3041
|
+
startStatusPolling(response.session_token);
|
|
3042
|
+
} else {
|
|
3043
|
+
setIsInitiatingVerification(false);
|
|
3044
|
+
setVerificationError(
|
|
3045
|
+
"Popup blocked. Please allow popups for this site or use redirect mode."
|
|
3046
|
+
);
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
2242
3049
|
} catch (error) {
|
|
2243
3050
|
const err = error;
|
|
3051
|
+
setIsInitiatingVerification(false);
|
|
2244
3052
|
if (err.status === 422) {
|
|
2245
3053
|
if (err.message.includes("guardian_contact")) {
|
|
2246
3054
|
setGuardianFormErrors({ guardianContact: err.message });
|
|
@@ -2251,23 +3059,265 @@ var RedactoNoticeConsent = ({
|
|
|
2251
3059
|
} else {
|
|
2252
3060
|
setGuardianFormErrors({ general: err.message });
|
|
2253
3061
|
}
|
|
3062
|
+
setShowVerificationScreen(false);
|
|
3063
|
+
setShowGuardianForm(true);
|
|
2254
3064
|
} else {
|
|
2255
3065
|
setGuardianFormErrors({
|
|
2256
|
-
general: err.message || "Failed to
|
|
3066
|
+
general: err.message || "Failed to initiate verification. Please try again."
|
|
2257
3067
|
});
|
|
3068
|
+
setShowVerificationScreen(false);
|
|
3069
|
+
setShowGuardianForm(true);
|
|
2258
3070
|
onError == null ? void 0 : onError(err);
|
|
2259
3071
|
}
|
|
2260
3072
|
} finally {
|
|
2261
3073
|
setIsSubmittingGuardian(false);
|
|
2262
3074
|
}
|
|
2263
|
-
}, [accessToken, baseUrl, guardianFormData, onError]);
|
|
3075
|
+
}, [accessToken, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
|
|
2264
3076
|
const handleAgeVerificationYes = (0, import_react2.useCallback)(() => {
|
|
2265
3077
|
setShowAgeVerification(false);
|
|
3078
|
+
setIsMinorFlow(false);
|
|
3079
|
+
setSelfDeclaredAdult(true);
|
|
2266
3080
|
}, []);
|
|
2267
3081
|
const handleAgeVerificationNo = (0, import_react2.useCallback)(() => {
|
|
2268
3082
|
setShowAgeVerification(false);
|
|
2269
3083
|
setShowGuardianForm(true);
|
|
2270
3084
|
}, []);
|
|
3085
|
+
const handleVerificationContinue = (0, import_react2.useCallback)(() => {
|
|
3086
|
+
setShowVerificationScreen(false);
|
|
3087
|
+
setIsVerificationComplete(false);
|
|
3088
|
+
}, []);
|
|
3089
|
+
const handlePopupClosed = (0, import_react2.useCallback)(async () => {
|
|
3090
|
+
var _a2, _b2;
|
|
3091
|
+
if (popupCheckIntervalRef.current) {
|
|
3092
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3093
|
+
popupCheckIntervalRef.current = null;
|
|
3094
|
+
}
|
|
3095
|
+
if (statusPollIntervalRef.current) {
|
|
3096
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3097
|
+
statusPollIntervalRef.current = null;
|
|
3098
|
+
}
|
|
3099
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3100
|
+
pollingCleanupRef.current = null;
|
|
3101
|
+
verificationPopupRef.current = null;
|
|
3102
|
+
if (!isPollingStatusRef.current) return;
|
|
3103
|
+
const sessionToken = verificationSessionTokenRef.current;
|
|
3104
|
+
if (sessionToken) {
|
|
3105
|
+
try {
|
|
3106
|
+
const response = await verifyGuardianStatus({
|
|
3107
|
+
accessToken,
|
|
3108
|
+
baseUrl,
|
|
3109
|
+
sessionToken
|
|
3110
|
+
});
|
|
3111
|
+
if (response.status === "verified") {
|
|
3112
|
+
const ref = response.verification_reference || ((_b2 = response.guardian_details) == null ? void 0 : _b2.verification_reference);
|
|
3113
|
+
if (ref) {
|
|
3114
|
+
setVerificationReference(ref);
|
|
3115
|
+
setIsVerificationComplete(true);
|
|
3116
|
+
setIsPollingStatus(false);
|
|
3117
|
+
isPollingStatusRef.current = false;
|
|
3118
|
+
setIsInitiatingVerification(false);
|
|
3119
|
+
clearConsentState();
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
} catch {
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
setVerificationError(
|
|
3127
|
+
"Verification window was closed. Please try again."
|
|
3128
|
+
);
|
|
3129
|
+
setIsPollingStatus(false);
|
|
3130
|
+
isPollingStatusRef.current = false;
|
|
3131
|
+
setIsInitiatingVerification(false);
|
|
3132
|
+
}, [accessToken, baseUrl]);
|
|
3133
|
+
const startPopupMonitoring = (0, import_react2.useCallback)((popup) => {
|
|
3134
|
+
popupCheckIntervalRef.current = window.setInterval(() => {
|
|
3135
|
+
if (popup.closed) {
|
|
3136
|
+
handlePopupClosed();
|
|
3137
|
+
}
|
|
3138
|
+
}, 500);
|
|
3139
|
+
}, [handlePopupClosed]);
|
|
3140
|
+
const getVerificationErrorMessage = (0, import_react2.useCallback)(
|
|
3141
|
+
(errorCode, fallbackError) => {
|
|
3142
|
+
switch (errorCode) {
|
|
3143
|
+
case "GUARDIAN_UNDER_18":
|
|
3144
|
+
return "The guardian must be 18 years or older. Please provide details of a different guardian.";
|
|
3145
|
+
case "TOKEN_FAILED":
|
|
3146
|
+
return "DigiLocker verification could not be completed. Please try again.";
|
|
3147
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
3148
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
3149
|
+
case "NO_AUTH_CODE":
|
|
3150
|
+
return "DigiLocker did not return an authorization code. Please try again.";
|
|
3151
|
+
case "SESSION_EXPIRED":
|
|
3152
|
+
return "Verification session has expired. Please try again.";
|
|
3153
|
+
default:
|
|
3154
|
+
return fallbackError || "Verification failed. Please try again.";
|
|
3155
|
+
}
|
|
3156
|
+
},
|
|
3157
|
+
[]
|
|
3158
|
+
);
|
|
3159
|
+
const startStatusPolling = (0, import_react2.useCallback)(
|
|
3160
|
+
(token) => {
|
|
3161
|
+
verificationSessionTokenRef.current = token;
|
|
3162
|
+
setIsPollingStatus(true);
|
|
3163
|
+
isPollingStatusRef.current = true;
|
|
3164
|
+
setVerificationError(null);
|
|
3165
|
+
setVerificationErrorCode(null);
|
|
3166
|
+
setCanRetryVerification(false);
|
|
3167
|
+
let attempts = 0;
|
|
3168
|
+
let consecutiveErrors = 0;
|
|
3169
|
+
let paused = false;
|
|
3170
|
+
const MAX_ATTEMPTS = 40;
|
|
3171
|
+
const MAX_CONSECUTIVE_ERRORS = 3;
|
|
3172
|
+
const POLL_INTERVAL = 3e3;
|
|
3173
|
+
const stopPolling = () => {
|
|
3174
|
+
var _a2;
|
|
3175
|
+
if (statusPollIntervalRef.current) {
|
|
3176
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3177
|
+
statusPollIntervalRef.current = null;
|
|
3178
|
+
}
|
|
3179
|
+
if (popupCheckIntervalRef.current) {
|
|
3180
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3181
|
+
popupCheckIntervalRef.current = null;
|
|
3182
|
+
}
|
|
3183
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3184
|
+
verificationPopupRef.current = null;
|
|
3185
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3186
|
+
pollingCleanupRef.current = null;
|
|
3187
|
+
setIsPollingStatus(false);
|
|
3188
|
+
isPollingStatusRef.current = false;
|
|
3189
|
+
setIsInitiatingVerification(false);
|
|
3190
|
+
};
|
|
3191
|
+
const setError = (message, errorCode, canRetry) => {
|
|
3192
|
+
stopPolling();
|
|
3193
|
+
setVerificationError(message);
|
|
3194
|
+
setVerificationErrorCode(errorCode);
|
|
3195
|
+
setCanRetryVerification(canRetry);
|
|
3196
|
+
};
|
|
3197
|
+
const poll = async () => {
|
|
3198
|
+
var _a2;
|
|
3199
|
+
if (paused) return;
|
|
3200
|
+
attempts++;
|
|
3201
|
+
if (attempts > MAX_ATTEMPTS) {
|
|
3202
|
+
setError(
|
|
3203
|
+
"Verification is taking longer than expected. Please try again.",
|
|
3204
|
+
"SESSION_EXPIRED",
|
|
3205
|
+
true
|
|
3206
|
+
);
|
|
3207
|
+
return;
|
|
3208
|
+
}
|
|
3209
|
+
try {
|
|
3210
|
+
const response = await verifyGuardianStatus({
|
|
3211
|
+
accessToken,
|
|
3212
|
+
baseUrl,
|
|
3213
|
+
sessionToken: token
|
|
3214
|
+
});
|
|
3215
|
+
consecutiveErrors = 0;
|
|
3216
|
+
if (response.status === "verified") {
|
|
3217
|
+
stopPolling();
|
|
3218
|
+
const ref = response.verification_reference || ((_a2 = response.guardian_details) == null ? void 0 : _a2.verification_reference);
|
|
3219
|
+
if (!ref) {
|
|
3220
|
+
setError(
|
|
3221
|
+
"Verification completed but no reference received. Please try again.",
|
|
3222
|
+
null,
|
|
3223
|
+
true
|
|
3224
|
+
);
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3227
|
+
setVerificationReference(ref);
|
|
3228
|
+
setIsVerificationComplete(true);
|
|
3229
|
+
clearConsentState();
|
|
3230
|
+
return;
|
|
3231
|
+
}
|
|
3232
|
+
if (response.status === "failed" || response.status === "expired") {
|
|
3233
|
+
setError(
|
|
3234
|
+
getVerificationErrorMessage(response.error_code, response.error),
|
|
3235
|
+
response.error_code,
|
|
3236
|
+
response.can_retry
|
|
3237
|
+
);
|
|
3238
|
+
return;
|
|
3239
|
+
}
|
|
3240
|
+
if (!paused) {
|
|
3241
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3242
|
+
}
|
|
3243
|
+
} catch (error) {
|
|
3244
|
+
const err = error;
|
|
3245
|
+
if (err.status === 404 || err.status === 410) {
|
|
3246
|
+
setError(
|
|
3247
|
+
"Verification session not found or expired. Please try again.",
|
|
3248
|
+
"SESSION_EXPIRED",
|
|
3249
|
+
true
|
|
3250
|
+
);
|
|
3251
|
+
return;
|
|
3252
|
+
}
|
|
3253
|
+
consecutiveErrors++;
|
|
3254
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
3255
|
+
setError(
|
|
3256
|
+
err.message || "Unable to check verification status. Please try again.",
|
|
3257
|
+
null,
|
|
3258
|
+
true
|
|
3259
|
+
);
|
|
3260
|
+
return;
|
|
3261
|
+
}
|
|
3262
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3263
|
+
}
|
|
3264
|
+
};
|
|
3265
|
+
const onVisibilityChange = () => {
|
|
3266
|
+
if (document.hidden) {
|
|
3267
|
+
paused = true;
|
|
3268
|
+
if (statusPollIntervalRef.current) {
|
|
3269
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3270
|
+
statusPollIntervalRef.current = null;
|
|
3271
|
+
}
|
|
3272
|
+
} else {
|
|
3273
|
+
paused = false;
|
|
3274
|
+
poll();
|
|
3275
|
+
}
|
|
3276
|
+
};
|
|
3277
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
3278
|
+
pollingCleanupRef.current = () => {
|
|
3279
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3280
|
+
};
|
|
3281
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3282
|
+
},
|
|
3283
|
+
[accessToken, baseUrl, getVerificationErrorMessage]
|
|
3284
|
+
);
|
|
3285
|
+
const handleBackToGuardianForm = (0, import_react2.useCallback)((clearName = false) => {
|
|
3286
|
+
var _a2, _b2;
|
|
3287
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3288
|
+
verificationPopupRef.current = null;
|
|
3289
|
+
if (popupCheckIntervalRef.current) {
|
|
3290
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3291
|
+
popupCheckIntervalRef.current = null;
|
|
3292
|
+
}
|
|
3293
|
+
if (statusPollIntervalRef.current) {
|
|
3294
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3295
|
+
statusPollIntervalRef.current = null;
|
|
3296
|
+
}
|
|
3297
|
+
if (autoTransitionTimerRef.current) {
|
|
3298
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3299
|
+
autoTransitionTimerRef.current = null;
|
|
3300
|
+
}
|
|
3301
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3302
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3303
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3304
|
+
}
|
|
3305
|
+
(_b2 = pollingCleanupRef.current) == null ? void 0 : _b2.call(pollingCleanupRef);
|
|
3306
|
+
pollingCleanupRef.current = null;
|
|
3307
|
+
setShowVerificationScreen(false);
|
|
3308
|
+
setShowGuardianForm(true);
|
|
3309
|
+
setVerificationError(null);
|
|
3310
|
+
setVerificationErrorCode(null);
|
|
3311
|
+
setCanRetryVerification(false);
|
|
3312
|
+
setIsInitiatingVerification(false);
|
|
3313
|
+
setIsPollingStatus(false);
|
|
3314
|
+
isPollingStatusRef.current = false;
|
|
3315
|
+
setIsVerificationComplete(false);
|
|
3316
|
+
if (clearName) {
|
|
3317
|
+
setGuardianFormData((prev) => ({ ...prev, guardianName: "" }));
|
|
3318
|
+
}
|
|
3319
|
+
clearConsentState();
|
|
3320
|
+
}, []);
|
|
2271
3321
|
const availableLanguages = (0, import_react2.useMemo)(() => {
|
|
2272
3322
|
if (!content) return [language];
|
|
2273
3323
|
const languages = ["English"];
|
|
@@ -2677,12 +3727,67 @@ var RedactoNoticeConsent = ({
|
|
|
2677
3727
|
}, [content, stopAudio]);
|
|
2678
3728
|
(0, import_react2.useEffect)(() => {
|
|
2679
3729
|
return () => {
|
|
3730
|
+
var _a2, _b2;
|
|
2680
3731
|
if (abortControllerRef.current) {
|
|
2681
3732
|
abortControllerRef.current.abort();
|
|
2682
3733
|
}
|
|
2683
3734
|
stopAudio();
|
|
3735
|
+
if (popupCheckIntervalRef.current) {
|
|
3736
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3737
|
+
}
|
|
3738
|
+
if (statusPollIntervalRef.current) {
|
|
3739
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3740
|
+
}
|
|
3741
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3742
|
+
pollingCleanupRef.current = null;
|
|
3743
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
3744
|
+
if (autoTransitionTimerRef.current) {
|
|
3745
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3746
|
+
autoTransitionTimerRef.current = null;
|
|
3747
|
+
}
|
|
3748
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3749
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3750
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3751
|
+
}
|
|
2684
3752
|
};
|
|
2685
3753
|
}, [stopAudio]);
|
|
3754
|
+
(0, import_react2.useEffect)(() => {
|
|
3755
|
+
const persistedState = getConsentState();
|
|
3756
|
+
if (!persistedState) return;
|
|
3757
|
+
if (persistedState.noticeId && persistedState.noticeId !== noticeId) {
|
|
3758
|
+
clearConsentState();
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
const REDIRECT_STATE_MAX_AGE_MS = 15 * 60 * 1e3;
|
|
3762
|
+
if (persistedState.timestamp) {
|
|
3763
|
+
const stateAge = Date.now() - new Date(persistedState.timestamp).getTime();
|
|
3764
|
+
if (stateAge > REDIRECT_STATE_MAX_AGE_MS) {
|
|
3765
|
+
clearConsentState();
|
|
3766
|
+
return;
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
if (persistedState.flowState === "digilocker-pending" && persistedState.sessionToken) {
|
|
3770
|
+
setShowVerificationScreen(true);
|
|
3771
|
+
setShowGuardianForm(false);
|
|
3772
|
+
setShowAgeVerification(false);
|
|
3773
|
+
startStatusPolling(persistedState.sessionToken);
|
|
3774
|
+
} else if (persistedState.verificationResult === "verified" && persistedState.verificationReference) {
|
|
3775
|
+
setVerificationReference(persistedState.verificationReference);
|
|
3776
|
+
setShowVerificationScreen(true);
|
|
3777
|
+
setIsVerificationComplete(true);
|
|
3778
|
+
setShowGuardianForm(false);
|
|
3779
|
+
setShowAgeVerification(false);
|
|
3780
|
+
clearConsentState();
|
|
3781
|
+
} else if (persistedState.verificationResult === "failed" || persistedState.verificationResult === "expired") {
|
|
3782
|
+
setShowVerificationScreen(true);
|
|
3783
|
+
setShowGuardianForm(false);
|
|
3784
|
+
setShowAgeVerification(false);
|
|
3785
|
+
setVerificationError(
|
|
3786
|
+
persistedState.verificationResult === "expired" ? "Verification session has expired. Please try again." : "Verification failed. Please try again."
|
|
3787
|
+
);
|
|
3788
|
+
clearConsentState();
|
|
3789
|
+
}
|
|
3790
|
+
}, [startStatusPolling, noticeId]);
|
|
2686
3791
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
2687
3792
|
blockUI && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2688
3793
|
"div",
|
|
@@ -2868,6 +3973,27 @@ var RedactoNoticeConsent = ({
|
|
|
2868
3973
|
declineButtonStyle,
|
|
2869
3974
|
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
2870
3975
|
}
|
|
3976
|
+
) }) : showVerificationScreen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.content, ...responsiveStyles.content }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
3977
|
+
VerificationScreen,
|
|
3978
|
+
{
|
|
3979
|
+
onBack: handleBackToGuardianForm,
|
|
3980
|
+
onContinue: handleVerificationContinue,
|
|
3981
|
+
isInitiating: isInitiatingVerification,
|
|
3982
|
+
isPolling: isPollingStatus,
|
|
3983
|
+
isVerificationComplete,
|
|
3984
|
+
isAutoTransitioning,
|
|
3985
|
+
error: verificationError,
|
|
3986
|
+
errorCode: verificationErrorCode,
|
|
3987
|
+
canRetry: canRetryVerification,
|
|
3988
|
+
styles,
|
|
3989
|
+
responsiveStyles,
|
|
3990
|
+
settings,
|
|
3991
|
+
componentHeadingStyle,
|
|
3992
|
+
componentTextStyle,
|
|
3993
|
+
acceptButtonStyle,
|
|
3994
|
+
declineButtonStyle,
|
|
3995
|
+
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
3996
|
+
}
|
|
2871
3997
|
) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { ...styles.content, ...responsiveStyles.content }, children: [
|
|
2872
3998
|
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
2873
3999
|
"div",
|
|
@@ -3501,60 +4627,27 @@ var submitConsentEvent2 = async ({
|
|
|
3501
4627
|
var _a, _b;
|
|
3502
4628
|
try {
|
|
3503
4629
|
const apiBaseUrl = baseUrl || BASE_URL2;
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
name: element.name,
|
|
3526
|
-
enabled: Boolean(element.enabled),
|
|
3527
|
-
required: Boolean(element.required),
|
|
3528
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
3529
|
-
}))
|
|
3530
|
-
};
|
|
3531
|
-
})
|
|
3532
|
-
},
|
|
3533
|
-
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
|
|
3534
|
-
};
|
|
3535
|
-
} else {
|
|
3536
|
-
payload = {
|
|
3537
|
-
notice_uuid: noticeUuid,
|
|
3538
|
-
purposes: purposes.map((purpose) => {
|
|
3539
|
-
if (!purpose.uuid) {
|
|
3540
|
-
throw new Error(`Invalid purpose data: missing uuid`);
|
|
3541
|
-
}
|
|
3542
|
-
const dataElements = purpose.data_elements.filter((element) => element.enabled).map((element) => ({
|
|
3543
|
-
uuid: element.uuid,
|
|
3544
|
-
selected: element.required ? true : Boolean(element.selected)
|
|
3545
|
-
}));
|
|
3546
|
-
return {
|
|
3547
|
-
purpose_uuid: purpose.uuid,
|
|
3548
|
-
selected: Boolean(purpose.selected),
|
|
3549
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
3550
|
-
};
|
|
3551
|
-
}),
|
|
3552
|
-
select_all_mandatory: false,
|
|
3553
|
-
source: "WEB",
|
|
3554
|
-
declined,
|
|
3555
|
-
meta_data
|
|
3556
|
-
};
|
|
3557
|
-
}
|
|
4630
|
+
const payload = {
|
|
4631
|
+
notice_uuid: noticeUuid,
|
|
4632
|
+
purposes: purposes.map((purpose) => {
|
|
4633
|
+
if (!purpose.uuid) {
|
|
4634
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
4635
|
+
}
|
|
4636
|
+
const dataElements = purpose.data_elements.filter((element) => element.enabled).map((element) => ({
|
|
4637
|
+
uuid: element.uuid,
|
|
4638
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
4639
|
+
}));
|
|
4640
|
+
return {
|
|
4641
|
+
purpose_uuid: purpose.uuid,
|
|
4642
|
+
selected: Boolean(purpose.selected),
|
|
4643
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
4644
|
+
};
|
|
4645
|
+
}),
|
|
4646
|
+
select_all_mandatory: false,
|
|
4647
|
+
source: "WEB",
|
|
4648
|
+
declined,
|
|
4649
|
+
meta_data
|
|
4650
|
+
};
|
|
3558
4651
|
const response = await fetch(
|
|
3559
4652
|
`${apiBaseUrl}/public/organisations/${org_uuid}/workspaces/${workspace_uuid}/submit-consent`,
|
|
3560
4653
|
{
|
|
@@ -4504,8 +5597,482 @@ var RedactoConsentInlineComponent = ({
|
|
|
4504
5597
|
};
|
|
4505
5598
|
RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
|
|
4506
5599
|
var RedactoConsentInline = (0, import_react4.memo)(RedactoConsentInlineComponent);
|
|
5600
|
+
|
|
5601
|
+
// src/RedactoNoticeConsent/components/DigiLockerCallback.tsx
|
|
5602
|
+
var import_react5 = require("react");
|
|
5603
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
5604
|
+
var DigiLockerCallback = ({
|
|
5605
|
+
accessToken: propAccessToken,
|
|
5606
|
+
baseUrl,
|
|
5607
|
+
onSuccess,
|
|
5608
|
+
onError
|
|
5609
|
+
}) => {
|
|
5610
|
+
const [status, setStatus] = (0, import_react5.useState)("processing");
|
|
5611
|
+
const [message, setMessage] = (0, import_react5.useState)("Verifying your guardian...");
|
|
5612
|
+
const [errorDetail, setErrorDetail] = (0, import_react5.useState)(null);
|
|
5613
|
+
const retryTimeoutRef = (0, import_react5.useRef)(null);
|
|
5614
|
+
const redirectTimeoutRef = (0, import_react5.useRef)(null);
|
|
5615
|
+
const isMountedRef = (0, import_react5.useRef)(true);
|
|
5616
|
+
const getErrorMessage = (errorCode) => {
|
|
5617
|
+
switch (errorCode) {
|
|
5618
|
+
case "GUARDIAN_UNDER_18":
|
|
5619
|
+
return "Guardian verification failed: The guardian must be 18 years or older.";
|
|
5620
|
+
case "SESSION_EXPIRED":
|
|
5621
|
+
return "Verification session has expired. Please restart the verification process.";
|
|
5622
|
+
case "TOKEN_FAILED":
|
|
5623
|
+
return "DigiLocker authentication failed. Please try again.";
|
|
5624
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
5625
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
5626
|
+
case "NO_AUTH_CODE":
|
|
5627
|
+
return "Missing authorization code from DigiLocker. Please try again.";
|
|
5628
|
+
default:
|
|
5629
|
+
return "Verification failed. Please try again.";
|
|
5630
|
+
}
|
|
5631
|
+
};
|
|
5632
|
+
const redirectToOriginalPage = (0, import_react5.useCallback)(
|
|
5633
|
+
(originalUrl, verificationResult, verificationReference) => {
|
|
5634
|
+
updateConsentState({
|
|
5635
|
+
verificationResult,
|
|
5636
|
+
verificationReference,
|
|
5637
|
+
flowState: verificationResult === "verified" ? "consent-form" : "error"
|
|
5638
|
+
});
|
|
5639
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5640
|
+
window.location.href = originalUrl;
|
|
5641
|
+
}, 1500);
|
|
5642
|
+
},
|
|
5643
|
+
[]
|
|
5644
|
+
);
|
|
5645
|
+
const handleCallback = (0, import_react5.useCallback)(async () => {
|
|
5646
|
+
var _a, _b;
|
|
5647
|
+
try {
|
|
5648
|
+
const params = new URLSearchParams(window.location.search);
|
|
5649
|
+
const sessionToken = params.get("session_token");
|
|
5650
|
+
const urlStatus = params.get("status");
|
|
5651
|
+
const verificationReference = params.get("verification_reference");
|
|
5652
|
+
const errorCode = params.get("error_code");
|
|
5653
|
+
const persistedState = getConsentState();
|
|
5654
|
+
const originalUrl = (persistedState == null ? void 0 : persistedState.originalUrl) || "/";
|
|
5655
|
+
const storedBaseUrl = persistedState == null ? void 0 : persistedState.baseUrl;
|
|
5656
|
+
const storedSessionToken = persistedState == null ? void 0 : persistedState.sessionToken;
|
|
5657
|
+
const accessToken = propAccessToken;
|
|
5658
|
+
if (!accessToken) {
|
|
5659
|
+
throw new Error("Access token not provided. Please pass accessToken as a prop.");
|
|
5660
|
+
}
|
|
5661
|
+
const activeSessionToken = sessionToken || storedSessionToken;
|
|
5662
|
+
if (!activeSessionToken) {
|
|
5663
|
+
throw new Error("Session token not found. Please restart the verification process.");
|
|
5664
|
+
}
|
|
5665
|
+
let isInIframe = false;
|
|
5666
|
+
try {
|
|
5667
|
+
isInIframe = window.self !== window.top;
|
|
5668
|
+
} catch {
|
|
5669
|
+
isInIframe = true;
|
|
5670
|
+
}
|
|
5671
|
+
if (urlStatus === "verified" && verificationReference) {
|
|
5672
|
+
setStatus("success");
|
|
5673
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5674
|
+
onSuccess == null ? void 0 : onSuccess(verificationReference);
|
|
5675
|
+
if (isInIframe && window.parent) {
|
|
5676
|
+
window.parent.postMessage(
|
|
5677
|
+
{
|
|
5678
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5679
|
+
status: "verified",
|
|
5680
|
+
verificationReference
|
|
5681
|
+
},
|
|
5682
|
+
window.location.origin
|
|
5683
|
+
);
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
redirectToOriginalPage(originalUrl, "verified", verificationReference);
|
|
5687
|
+
return;
|
|
5688
|
+
}
|
|
5689
|
+
if (urlStatus === "failed" || urlStatus === "expired") {
|
|
5690
|
+
const urlErrorCode = errorCode != null ? errorCode : void 0;
|
|
5691
|
+
const errorMessage = getErrorMessage(urlErrorCode);
|
|
5692
|
+
setStatus("error");
|
|
5693
|
+
setMessage("Verification failed");
|
|
5694
|
+
setErrorDetail(errorMessage);
|
|
5695
|
+
onError == null ? void 0 : onError(new Error(errorMessage), urlErrorCode);
|
|
5696
|
+
if (isInIframe && window.parent) {
|
|
5697
|
+
window.parent.postMessage(
|
|
5698
|
+
{
|
|
5699
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5700
|
+
status: urlStatus,
|
|
5701
|
+
errorCode: urlErrorCode,
|
|
5702
|
+
error: errorMessage
|
|
5703
|
+
},
|
|
5704
|
+
window.location.origin
|
|
5705
|
+
);
|
|
5706
|
+
return;
|
|
5707
|
+
}
|
|
5708
|
+
redirectToOriginalPage(originalUrl, urlStatus);
|
|
5709
|
+
return;
|
|
5710
|
+
}
|
|
5711
|
+
setMessage("Processing verification...");
|
|
5712
|
+
const apiBaseUrl = baseUrl || storedBaseUrl;
|
|
5713
|
+
const response = await verifyGuardianStatus({
|
|
5714
|
+
accessToken,
|
|
5715
|
+
baseUrl: apiBaseUrl,
|
|
5716
|
+
sessionToken: activeSessionToken
|
|
5717
|
+
});
|
|
5718
|
+
if (!isMountedRef.current) return;
|
|
5719
|
+
if (response.status === "verified") {
|
|
5720
|
+
const verificationRef = response.verification_reference || ((_a = response.guardian_details) == null ? void 0 : _a.verification_reference) || void 0;
|
|
5721
|
+
if (!verificationRef) {
|
|
5722
|
+
setStatus("error");
|
|
5723
|
+
setMessage("Verification failed");
|
|
5724
|
+
setErrorDetail("Verification completed but no reference received. Please try again.");
|
|
5725
|
+
onError == null ? void 0 : onError(new Error("Verification completed but no reference received."));
|
|
5726
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5727
|
+
return;
|
|
5728
|
+
}
|
|
5729
|
+
setStatus("success");
|
|
5730
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5731
|
+
onSuccess == null ? void 0 : onSuccess(verificationRef);
|
|
5732
|
+
if (isInIframe && window.parent) {
|
|
5733
|
+
window.parent.postMessage(
|
|
5734
|
+
{
|
|
5735
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5736
|
+
status: "verified",
|
|
5737
|
+
verificationReference: verificationRef
|
|
5738
|
+
},
|
|
5739
|
+
window.location.origin
|
|
5740
|
+
);
|
|
5741
|
+
return;
|
|
5742
|
+
}
|
|
5743
|
+
redirectToOriginalPage(originalUrl, "verified", verificationRef);
|
|
5744
|
+
} else if (response.status === "failed" || response.status === "expired") {
|
|
5745
|
+
const responseErrorCode = (_b = response.error_code) != null ? _b : void 0;
|
|
5746
|
+
const errorMessage = response.error || getErrorMessage(responseErrorCode);
|
|
5747
|
+
setStatus("error");
|
|
5748
|
+
setMessage("Verification failed");
|
|
5749
|
+
setErrorDetail(errorMessage);
|
|
5750
|
+
onError == null ? void 0 : onError(new Error(errorMessage), responseErrorCode);
|
|
5751
|
+
if (isInIframe && window.parent) {
|
|
5752
|
+
window.parent.postMessage(
|
|
5753
|
+
{
|
|
5754
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5755
|
+
status: response.status,
|
|
5756
|
+
errorCode: responseErrorCode,
|
|
5757
|
+
error: errorMessage
|
|
5758
|
+
},
|
|
5759
|
+
window.location.origin
|
|
5760
|
+
);
|
|
5761
|
+
return;
|
|
5762
|
+
}
|
|
5763
|
+
redirectToOriginalPage(originalUrl, response.status);
|
|
5764
|
+
} else {
|
|
5765
|
+
setMessage("Verification is still in progress. Please wait...");
|
|
5766
|
+
const MAX_RETRIES = 3;
|
|
5767
|
+
let retryCount = 0;
|
|
5768
|
+
const attemptRetry = () => {
|
|
5769
|
+
retryCount++;
|
|
5770
|
+
const delay = 3e3 * Math.pow(2, retryCount - 1);
|
|
5771
|
+
retryTimeoutRef.current = setTimeout(async () => {
|
|
5772
|
+
var _a2, _b2;
|
|
5773
|
+
if (!isMountedRef.current) return;
|
|
5774
|
+
try {
|
|
5775
|
+
const retryResponse = await verifyGuardianStatus({
|
|
5776
|
+
accessToken,
|
|
5777
|
+
baseUrl: apiBaseUrl,
|
|
5778
|
+
sessionToken: activeSessionToken
|
|
5779
|
+
});
|
|
5780
|
+
if (!isMountedRef.current) return;
|
|
5781
|
+
const retryRef = retryResponse.verification_reference || ((_a2 = retryResponse.guardian_details) == null ? void 0 : _a2.verification_reference) || void 0;
|
|
5782
|
+
if (retryResponse.status === "verified" && retryRef) {
|
|
5783
|
+
setStatus("success");
|
|
5784
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5785
|
+
onSuccess == null ? void 0 : onSuccess(retryRef);
|
|
5786
|
+
if (isInIframe && window.parent) {
|
|
5787
|
+
window.parent.postMessage(
|
|
5788
|
+
{
|
|
5789
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5790
|
+
status: "verified",
|
|
5791
|
+
verificationReference: retryRef
|
|
5792
|
+
},
|
|
5793
|
+
window.location.origin
|
|
5794
|
+
);
|
|
5795
|
+
return;
|
|
5796
|
+
}
|
|
5797
|
+
redirectToOriginalPage(originalUrl, "verified", retryRef);
|
|
5798
|
+
} else if (retryResponse.status === "failed" || retryResponse.status === "expired") {
|
|
5799
|
+
const retryErrorCode = (_b2 = retryResponse.error_code) != null ? _b2 : void 0;
|
|
5800
|
+
const retryErrorMessage = retryResponse.error || getErrorMessage(retryErrorCode) || "Verification could not be completed. Please try again.";
|
|
5801
|
+
setStatus("error");
|
|
5802
|
+
setMessage("Verification failed");
|
|
5803
|
+
setErrorDetail(retryErrorMessage);
|
|
5804
|
+
onError == null ? void 0 : onError(new Error(retryErrorMessage), retryErrorCode);
|
|
5805
|
+
if (isInIframe && window.parent) {
|
|
5806
|
+
window.parent.postMessage(
|
|
5807
|
+
{
|
|
5808
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5809
|
+
status: retryResponse.status,
|
|
5810
|
+
errorCode: retryErrorCode,
|
|
5811
|
+
error: retryErrorMessage
|
|
5812
|
+
},
|
|
5813
|
+
window.location.origin
|
|
5814
|
+
);
|
|
5815
|
+
return;
|
|
5816
|
+
}
|
|
5817
|
+
redirectToOriginalPage(originalUrl, retryResponse.status);
|
|
5818
|
+
} else if (retryCount < MAX_RETRIES) {
|
|
5819
|
+
setMessage("Verification taking longer than expected. Please wait...");
|
|
5820
|
+
attemptRetry();
|
|
5821
|
+
} else {
|
|
5822
|
+
const timeoutMessage = "Verification could not be completed in time. Please try again.";
|
|
5823
|
+
setStatus("error");
|
|
5824
|
+
setMessage("Verification failed");
|
|
5825
|
+
setErrorDetail(timeoutMessage);
|
|
5826
|
+
onError == null ? void 0 : onError(new Error(timeoutMessage));
|
|
5827
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5828
|
+
}
|
|
5829
|
+
} catch (retryErr) {
|
|
5830
|
+
if (!isMountedRef.current) return;
|
|
5831
|
+
if (retryCount < MAX_RETRIES) {
|
|
5832
|
+
attemptRetry();
|
|
5833
|
+
} else {
|
|
5834
|
+
setStatus("error");
|
|
5835
|
+
setMessage("Verification failed");
|
|
5836
|
+
setErrorDetail(retryErr.message);
|
|
5837
|
+
onError == null ? void 0 : onError(retryErr);
|
|
5838
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
}, delay);
|
|
5842
|
+
};
|
|
5843
|
+
attemptRetry();
|
|
5844
|
+
}
|
|
5845
|
+
} catch (error) {
|
|
5846
|
+
console.error("DigiLocker callback error:", error);
|
|
5847
|
+
setStatus("error");
|
|
5848
|
+
const err = error;
|
|
5849
|
+
setMessage("Verification failed");
|
|
5850
|
+
setErrorDetail(err.message || "An error occurred during verification");
|
|
5851
|
+
onError == null ? void 0 : onError(err);
|
|
5852
|
+
const persistedState = getConsentState();
|
|
5853
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5854
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5855
|
+
redirectToOriginalPage(persistedState.originalUrl, "failed");
|
|
5856
|
+
}, 3e3);
|
|
5857
|
+
}
|
|
5858
|
+
}
|
|
5859
|
+
}, [propAccessToken, baseUrl, onSuccess, onError, redirectToOriginalPage]);
|
|
5860
|
+
(0, import_react5.useEffect)(() => {
|
|
5861
|
+
injectCheckboxStyles();
|
|
5862
|
+
handleCallback();
|
|
5863
|
+
return () => {
|
|
5864
|
+
isMountedRef.current = false;
|
|
5865
|
+
if (retryTimeoutRef.current) clearTimeout(retryTimeoutRef.current);
|
|
5866
|
+
if (redirectTimeoutRef.current) clearTimeout(redirectTimeoutRef.current);
|
|
5867
|
+
};
|
|
5868
|
+
}, [handleCallback]);
|
|
5869
|
+
const handleRetry = (0, import_react5.useCallback)(() => {
|
|
5870
|
+
const persistedState = getConsentState();
|
|
5871
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5872
|
+
clearConsentState();
|
|
5873
|
+
window.location.href = persistedState.originalUrl;
|
|
5874
|
+
} else {
|
|
5875
|
+
window.location.href = "/";
|
|
5876
|
+
}
|
|
5877
|
+
}, []);
|
|
5878
|
+
const containerStyle = {
|
|
5879
|
+
display: "flex",
|
|
5880
|
+
alignItems: "center",
|
|
5881
|
+
justifyContent: "center",
|
|
5882
|
+
minHeight: "100vh",
|
|
5883
|
+
backgroundColor: "#f8fafc",
|
|
5884
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
5885
|
+
padding: "24px",
|
|
5886
|
+
boxSizing: "border-box"
|
|
5887
|
+
};
|
|
5888
|
+
const cardStyle = {
|
|
5889
|
+
backgroundColor: "#ffffff",
|
|
5890
|
+
borderRadius: "16px",
|
|
5891
|
+
boxShadow: "0 1px 3px rgba(0, 0, 0, 0.08), 0 8px 30px rgba(0, 0, 0, 0.06)",
|
|
5892
|
+
padding: "48px 40px 40px",
|
|
5893
|
+
textAlign: "center",
|
|
5894
|
+
maxWidth: "420px",
|
|
5895
|
+
width: "100%"
|
|
5896
|
+
};
|
|
5897
|
+
const spinnerContainerStyle = {
|
|
5898
|
+
width: "72px",
|
|
5899
|
+
height: "72px",
|
|
5900
|
+
margin: "0 auto 28px",
|
|
5901
|
+
position: "relative"
|
|
5902
|
+
};
|
|
5903
|
+
const spinnerStyle = {
|
|
5904
|
+
width: "72px",
|
|
5905
|
+
height: "72px",
|
|
5906
|
+
border: "3px solid #e5e7eb",
|
|
5907
|
+
borderTopColor: "#4f87ff",
|
|
5908
|
+
borderRadius: "50%",
|
|
5909
|
+
animation: "redacto-dl-spin 0.8s linear infinite",
|
|
5910
|
+
boxSizing: "border-box"
|
|
5911
|
+
};
|
|
5912
|
+
const iconContainerStyle = {
|
|
5913
|
+
width: "72px",
|
|
5914
|
+
height: "72px",
|
|
5915
|
+
borderRadius: "50%",
|
|
5916
|
+
display: "flex",
|
|
5917
|
+
alignItems: "center",
|
|
5918
|
+
justifyContent: "center",
|
|
5919
|
+
margin: "0 auto 28px",
|
|
5920
|
+
animation: "redacto-dl-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) forwards",
|
|
5921
|
+
position: "relative"
|
|
5922
|
+
};
|
|
5923
|
+
const successIconStyle = {
|
|
5924
|
+
...iconContainerStyle,
|
|
5925
|
+
backgroundColor: "#d1fae5",
|
|
5926
|
+
color: "#059669"
|
|
5927
|
+
};
|
|
5928
|
+
const errorIconStyle = {
|
|
5929
|
+
...iconContainerStyle,
|
|
5930
|
+
backgroundColor: "#fee2e2",
|
|
5931
|
+
color: "#dc2626"
|
|
5932
|
+
};
|
|
5933
|
+
const titleStyle = {
|
|
5934
|
+
fontSize: "22px",
|
|
5935
|
+
fontWeight: 700,
|
|
5936
|
+
color: "#111827",
|
|
5937
|
+
margin: "0 0 8px 0",
|
|
5938
|
+
letterSpacing: "-0.01em"
|
|
5939
|
+
};
|
|
5940
|
+
const messageStyle = {
|
|
5941
|
+
fontSize: "14px",
|
|
5942
|
+
color: "#6b7280",
|
|
5943
|
+
marginBottom: "0",
|
|
5944
|
+
lineHeight: 1.6
|
|
5945
|
+
};
|
|
5946
|
+
const subtextStyle = {
|
|
5947
|
+
fontSize: "13px",
|
|
5948
|
+
color: "#9ca3af",
|
|
5949
|
+
marginTop: "16px",
|
|
5950
|
+
lineHeight: 1.5
|
|
5951
|
+
};
|
|
5952
|
+
const errorDetailStyle = {
|
|
5953
|
+
fontSize: "13px",
|
|
5954
|
+
color: "#dc2626",
|
|
5955
|
+
marginTop: "16px",
|
|
5956
|
+
padding: "12px 16px",
|
|
5957
|
+
backgroundColor: "#fef2f2",
|
|
5958
|
+
borderRadius: "10px",
|
|
5959
|
+
border: "1px solid #fecaca",
|
|
5960
|
+
lineHeight: 1.5,
|
|
5961
|
+
textAlign: "left"
|
|
5962
|
+
};
|
|
5963
|
+
const buttonStyle = {
|
|
5964
|
+
marginTop: "24px",
|
|
5965
|
+
padding: "12px 28px",
|
|
5966
|
+
backgroundColor: "#4f87ff",
|
|
5967
|
+
color: "#ffffff",
|
|
5968
|
+
border: "none",
|
|
5969
|
+
borderRadius: "10px",
|
|
5970
|
+
fontSize: "15px",
|
|
5971
|
+
fontWeight: 600,
|
|
5972
|
+
cursor: "pointer",
|
|
5973
|
+
transition: "background-color 0.2s, transform 0.15s",
|
|
5974
|
+
width: "100%"
|
|
5975
|
+
};
|
|
5976
|
+
const keyframesStyle = `
|
|
5977
|
+
@keyframes redacto-dl-spin {
|
|
5978
|
+
to { transform: rotate(360deg); }
|
|
5979
|
+
}
|
|
5980
|
+
@keyframes redacto-dl-pop {
|
|
5981
|
+
0% { transform: scale(0.3); opacity: 0; }
|
|
5982
|
+
60% { transform: scale(1.08); opacity: 1; }
|
|
5983
|
+
100% { transform: scale(1); opacity: 1; }
|
|
5984
|
+
}
|
|
5985
|
+
@keyframes redacto-dl-check {
|
|
5986
|
+
0% { stroke-dashoffset: 24; }
|
|
5987
|
+
100% { stroke-dashoffset: 0; }
|
|
5988
|
+
}
|
|
5989
|
+
@keyframes redacto-dl-pulse {
|
|
5990
|
+
0%, 100% { transform: scale(1); opacity: 0.6; }
|
|
5991
|
+
50% { transform: scale(1.15); opacity: 0; }
|
|
5992
|
+
}
|
|
5993
|
+
.redacto-dl-retry-btn:hover {
|
|
5994
|
+
background-color: #3d6fdb !important;
|
|
5995
|
+
transform: translateY(-1px);
|
|
5996
|
+
}
|
|
5997
|
+
.redacto-dl-retry-btn:active {
|
|
5998
|
+
transform: translateY(0);
|
|
5999
|
+
}
|
|
6000
|
+
`;
|
|
6001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6002
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { dangerouslySetInnerHTML: { __html: keyframesStyle } }),
|
|
6003
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: cardStyle, children: [
|
|
6004
|
+
status === "processing" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6005
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: spinnerContainerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: spinnerStyle }) }),
|
|
6006
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: titleStyle, children: "Processing Verification" }),
|
|
6007
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: messageStyle, children: message }),
|
|
6008
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: subtextStyle, children: "Please wait while we verify your guardian's identity..." })
|
|
6009
|
+
] }),
|
|
6010
|
+
status === "success" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6011
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { position: "relative", width: "72px", height: "72px", margin: "0 auto 28px" }, children: [
|
|
6012
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
|
|
6013
|
+
position: "absolute",
|
|
6014
|
+
inset: "-8px",
|
|
6015
|
+
borderRadius: "50%",
|
|
6016
|
+
border: "2px solid #d1fae5",
|
|
6017
|
+
animation: "redacto-dl-pulse 1.5s ease-out infinite"
|
|
6018
|
+
} }),
|
|
6019
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: successIconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6020
|
+
"svg",
|
|
6021
|
+
{
|
|
6022
|
+
width: "30",
|
|
6023
|
+
height: "30",
|
|
6024
|
+
viewBox: "0 0 24 24",
|
|
6025
|
+
fill: "none",
|
|
6026
|
+
stroke: "currentColor",
|
|
6027
|
+
strokeWidth: "2.5",
|
|
6028
|
+
strokeLinecap: "round",
|
|
6029
|
+
strokeLinejoin: "round",
|
|
6030
|
+
style: { strokeDasharray: 24, animation: "redacto-dl-check 0.4s ease-out 0.3s forwards", strokeDashoffset: 24 },
|
|
6031
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
6032
|
+
}
|
|
6033
|
+
) })
|
|
6034
|
+
] }),
|
|
6035
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: titleStyle, children: "Verification Successful" }),
|
|
6036
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: messageStyle, children: message }),
|
|
6037
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: subtextStyle, children: "You will be redirected automatically." })
|
|
6038
|
+
] }),
|
|
6039
|
+
status === "error" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
6040
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: errorIconStyle, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
6041
|
+
"svg",
|
|
6042
|
+
{
|
|
6043
|
+
width: "30",
|
|
6044
|
+
height: "30",
|
|
6045
|
+
viewBox: "0 0 24 24",
|
|
6046
|
+
fill: "none",
|
|
6047
|
+
stroke: "currentColor",
|
|
6048
|
+
strokeWidth: "2.5",
|
|
6049
|
+
strokeLinecap: "round",
|
|
6050
|
+
strokeLinejoin: "round",
|
|
6051
|
+
children: [
|
|
6052
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
6053
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
6054
|
+
]
|
|
6055
|
+
}
|
|
6056
|
+
) }),
|
|
6057
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { style: titleStyle, children: "Verification Failed" }),
|
|
6058
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: messageStyle, children: message }),
|
|
6059
|
+
errorDetail && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: errorDetailStyle, children: errorDetail }),
|
|
6060
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
6061
|
+
"button",
|
|
6062
|
+
{
|
|
6063
|
+
className: "redacto-dl-retry-btn",
|
|
6064
|
+
style: buttonStyle,
|
|
6065
|
+
onClick: handleRetry,
|
|
6066
|
+
children: "Try Again"
|
|
6067
|
+
}
|
|
6068
|
+
)
|
|
6069
|
+
] })
|
|
6070
|
+
] }) })
|
|
6071
|
+
] });
|
|
6072
|
+
};
|
|
4507
6073
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4508
6074
|
0 && (module.exports = {
|
|
6075
|
+
DigiLockerCallback,
|
|
4509
6076
|
RedactoNoticeConsent,
|
|
4510
6077
|
RedactoNoticeConsentInline
|
|
4511
6078
|
});
|