@redacto.io/consent-sdk-react 3.5.0 → 4.0.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/.turbo/turbo-build.log +21 -0
- package/CHANGELOG.md +6 -0
- package/dist/index.d.mts +49 -2
- package/dist/index.d.ts +49 -2
- package/dist/index.js +1785 -243
- package/dist/index.mjs +1784 -243
- package/package.json +1 -1
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.test.tsx +201 -118
- package/src/RedactoNoticeConsent/RedactoNoticeConsent.tsx +1192 -93
- package/src/RedactoNoticeConsent/api/index.ts +333 -206
- package/src/RedactoNoticeConsent/api/types.ts +138 -16
- package/src/RedactoNoticeConsent/components/DigiLockerCallback.tsx +536 -0
- package/src/RedactoNoticeConsent/components/index.ts +7 -0
- package/src/RedactoNoticeConsent/injectStyles.ts +11 -0
- package/src/RedactoNoticeConsent/services/storage.ts +122 -0
- package/src/RedactoNoticeConsent/types.ts +2 -0
- package/src/index.ts +10 -0
package/dist/index.mjs
CHANGED
|
@@ -39,73 +39,66 @@ var fetchConsentContent = async ({
|
|
|
39
39
|
validate_against = "all",
|
|
40
40
|
include_fully_consented_data = false,
|
|
41
41
|
signal
|
|
42
|
-
// AbortSignal for request cancellation
|
|
43
42
|
}) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
return cachedData;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const url = new URL(
|
|
65
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
66
|
-
);
|
|
67
|
-
if (specific_uuid) {
|
|
68
|
-
url.searchParams.append("specific_uuid", specific_uuid);
|
|
69
|
-
}
|
|
70
|
-
url.searchParams.append("validate_against", validate_against);
|
|
71
|
-
if (include_fully_consented_data) {
|
|
72
|
-
url.searchParams.append("include_fully_consented_data", "true");
|
|
73
|
-
}
|
|
74
|
-
const response = await fetch(url.toString(), {
|
|
75
|
-
method: "GET",
|
|
76
|
-
headers: {
|
|
77
|
-
Authorization: `Bearer ${accessToken}`,
|
|
78
|
-
"Accept-Language": language,
|
|
79
|
-
"Content-Type": "application/json"
|
|
80
|
-
},
|
|
81
|
-
signal
|
|
82
|
-
// Add abort signal for request cancellation
|
|
83
|
-
});
|
|
84
|
-
if (!response.ok) {
|
|
85
|
-
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
86
|
-
if (response.status === 401) {
|
|
87
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
88
|
-
} else if (response.status === 403) {
|
|
89
|
-
errorMessage = "Forbidden: Access denied";
|
|
90
|
-
} else if (response.status === 404) {
|
|
91
|
-
errorMessage = "Notice not found";
|
|
92
|
-
} else if (response.status === 409) {
|
|
93
|
-
errorMessage = "User has already provided consent";
|
|
94
|
-
} else if (response.status >= 500) {
|
|
95
|
-
errorMessage = "Server error: Please try again later";
|
|
96
|
-
}
|
|
97
|
-
const error = new Error(errorMessage);
|
|
98
|
-
error.status = response.status;
|
|
99
|
-
throw error;
|
|
43
|
+
if (!noticeId || !accessToken || !validate_against) {
|
|
44
|
+
throw new Error("noticeId and accessToken are required");
|
|
45
|
+
}
|
|
46
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
47
|
+
if (!decodedToken) {
|
|
48
|
+
throw new Error("Invalid access token");
|
|
49
|
+
}
|
|
50
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
51
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
52
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
53
|
+
}
|
|
54
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
55
|
+
const cacheKey = `${accessToken}-${noticeId}-${validate_against}-${language}-${specific_uuid || ""}-${include_fully_consented_data}`;
|
|
56
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
57
|
+
const cachedData = getCachedData(cacheKey);
|
|
58
|
+
if (cachedData) {
|
|
59
|
+
return cachedData;
|
|
100
60
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
61
|
+
}
|
|
62
|
+
const url = new URL(
|
|
63
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeId}`
|
|
64
|
+
);
|
|
65
|
+
if (specific_uuid) {
|
|
66
|
+
url.searchParams.append("specific_uuid", specific_uuid);
|
|
67
|
+
}
|
|
68
|
+
url.searchParams.append("validate_against", validate_against);
|
|
69
|
+
if (include_fully_consented_data) {
|
|
70
|
+
url.searchParams.append("include_fully_consented_data", "true");
|
|
71
|
+
}
|
|
72
|
+
const response = await fetch(url.toString(), {
|
|
73
|
+
method: "GET",
|
|
74
|
+
headers: {
|
|
75
|
+
Authorization: `Bearer ${accessToken}`,
|
|
76
|
+
"Accept-Language": language
|
|
77
|
+
},
|
|
78
|
+
signal
|
|
79
|
+
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
let errorMessage = `Failed to fetch consent content: ${response.status} ${response.statusText}`;
|
|
82
|
+
if (response.status === 401) {
|
|
83
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
84
|
+
} else if (response.status === 403) {
|
|
85
|
+
errorMessage = "Forbidden: Access denied";
|
|
86
|
+
} else if (response.status === 404) {
|
|
87
|
+
errorMessage = "Notice not found";
|
|
88
|
+
} else if (response.status === 409) {
|
|
89
|
+
errorMessage = "User has already provided consent";
|
|
90
|
+
} else if (response.status >= 500) {
|
|
91
|
+
errorMessage = "Server error: Please try again later";
|
|
104
92
|
}
|
|
105
|
-
|
|
106
|
-
|
|
93
|
+
const error = new Error(errorMessage);
|
|
94
|
+
error.status = response.status;
|
|
107
95
|
throw error;
|
|
108
96
|
}
|
|
97
|
+
const data = await response.json();
|
|
98
|
+
if (validate_against === "all" && !specific_uuid) {
|
|
99
|
+
setCachedData(cacheKey, data);
|
|
100
|
+
}
|
|
101
|
+
return data;
|
|
109
102
|
};
|
|
110
103
|
var submitConsentEvent = async ({
|
|
111
104
|
accessToken,
|
|
@@ -114,100 +107,151 @@ var submitConsentEvent = async ({
|
|
|
114
107
|
purposes,
|
|
115
108
|
declined,
|
|
116
109
|
meta_data,
|
|
110
|
+
guardianVerificationReference,
|
|
111
|
+
selfDeclaredAdult,
|
|
117
112
|
signal
|
|
118
|
-
// AbortSignal for request cancellation
|
|
119
113
|
}) => {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
114
|
+
if (!noticeUuid || !accessToken || !Array.isArray(purposes)) {
|
|
115
|
+
throw new Error("noticeUuid, accessToken, and purposes array are required");
|
|
116
|
+
}
|
|
117
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
118
|
+
if (!decodedToken) {
|
|
119
|
+
throw new Error("Invalid access token");
|
|
120
|
+
}
|
|
121
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
122
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
123
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
124
|
+
}
|
|
125
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
126
|
+
const validatedPurposes = purposes.map((purpose) => {
|
|
127
|
+
if (!purpose.uuid) {
|
|
128
|
+
throw new Error(`Invalid purpose data: missing uuid`);
|
|
131
129
|
}
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}));
|
|
141
|
-
return {
|
|
142
|
-
purpose_uuid: purpose.uuid,
|
|
143
|
-
selected: Boolean(purpose.selected),
|
|
144
|
-
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
145
|
-
};
|
|
146
|
-
});
|
|
147
|
-
const payload = {
|
|
148
|
-
notice_uuid: noticeUuid,
|
|
149
|
-
purposes: validatedPurposes,
|
|
150
|
-
select_all_mandatory: false,
|
|
151
|
-
source: "WEB",
|
|
152
|
-
declined: Boolean(declined),
|
|
153
|
-
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid } : void 0
|
|
130
|
+
const dataElements = (purpose.data_elements || []).filter((element) => element.enabled).map((element) => ({
|
|
131
|
+
uuid: element.uuid,
|
|
132
|
+
selected: element.required ? true : Boolean(element.selected)
|
|
133
|
+
}));
|
|
134
|
+
return {
|
|
135
|
+
purpose_uuid: purpose.uuid,
|
|
136
|
+
selected: Boolean(purpose.selected),
|
|
137
|
+
data_elements: dataElements.length > 0 ? dataElements : void 0
|
|
154
138
|
};
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
139
|
+
});
|
|
140
|
+
const payload = {
|
|
141
|
+
notice_uuid: noticeUuid,
|
|
142
|
+
purposes: validatedPurposes,
|
|
143
|
+
select_all_mandatory: false,
|
|
144
|
+
source: "WEB",
|
|
145
|
+
declined: Boolean(declined),
|
|
146
|
+
meta_data: meta_data ? { specific_uuid: meta_data.specific_uuid, minor_age: meta_data.minor_age } : void 0,
|
|
147
|
+
guardian_verification_reference: guardianVerificationReference,
|
|
148
|
+
self_declared_adult: selfDeclaredAdult
|
|
149
|
+
};
|
|
150
|
+
const response = await fetch(
|
|
151
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/submit-consent`,
|
|
152
|
+
{
|
|
153
|
+
method: "POST",
|
|
154
|
+
headers: {
|
|
155
|
+
Authorization: `Bearer ${accessToken}`,
|
|
156
|
+
"Content-Type": "application/json"
|
|
157
|
+
},
|
|
158
|
+
body: JSON.stringify(payload),
|
|
159
|
+
signal
|
|
160
|
+
}
|
|
161
|
+
);
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
let errorMessage = `Failed to submit consent: ${response.status} ${response.statusText}`;
|
|
164
|
+
if (response.status === 400) {
|
|
165
|
+
try {
|
|
166
|
+
const errorData = await response.json();
|
|
167
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
168
|
+
} catch {
|
|
171
169
|
errorMessage = "Invalid request data";
|
|
172
|
-
} else if (response.status === 401) {
|
|
173
|
-
errorMessage = "Unauthorized: Invalid or expired token";
|
|
174
|
-
} else if (response.status === 403) {
|
|
175
|
-
errorMessage = "Forbidden: Access denied";
|
|
176
|
-
} else if (response.status === 404) {
|
|
177
|
-
errorMessage = "Notice not found";
|
|
178
|
-
} else if (response.status >= 500) {
|
|
179
|
-
errorMessage = "Server error: Please try again later";
|
|
180
170
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
171
|
+
} else if (response.status === 401) {
|
|
172
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
173
|
+
} else if (response.status === 403) {
|
|
174
|
+
errorMessage = "Forbidden: Access denied";
|
|
175
|
+
} else if (response.status === 404) {
|
|
176
|
+
errorMessage = "Notice not found";
|
|
177
|
+
} else if (response.status >= 500) {
|
|
178
|
+
errorMessage = "Server error: Please try again later";
|
|
184
179
|
}
|
|
185
|
-
|
|
186
|
-
|
|
180
|
+
const error = new Error(errorMessage);
|
|
181
|
+
error.status = response.status;
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
apiCache.clear();
|
|
185
|
+
};
|
|
186
|
+
var fetchTTSAudioUrls = async ({
|
|
187
|
+
accessToken,
|
|
188
|
+
baseUrl,
|
|
189
|
+
noticeUuid,
|
|
190
|
+
language,
|
|
191
|
+
signal
|
|
192
|
+
}) => {
|
|
193
|
+
if (!accessToken || !noticeUuid || !language) {
|
|
194
|
+
throw new Error("accessToken, noticeUuid, and language are required");
|
|
195
|
+
}
|
|
196
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
197
|
+
if (!decodedToken) {
|
|
198
|
+
throw new Error("Invalid access token");
|
|
199
|
+
}
|
|
200
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
201
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
202
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
203
|
+
}
|
|
204
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
205
|
+
const url = `${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/notices/${noticeUuid}/audio/${language}`;
|
|
206
|
+
const response = await fetch(url, {
|
|
207
|
+
method: "GET",
|
|
208
|
+
headers: {
|
|
209
|
+
Authorization: `Bearer ${accessToken}`,
|
|
210
|
+
Accept: "application/json"
|
|
211
|
+
},
|
|
212
|
+
signal
|
|
213
|
+
});
|
|
214
|
+
if (!response.ok) {
|
|
215
|
+
let errorMessage = `Failed to fetch TTS audio URLs: ${response.status} ${response.statusText}`;
|
|
216
|
+
if (response.status === 401) {
|
|
217
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
218
|
+
} else if (response.status === 403) {
|
|
219
|
+
errorMessage = "Forbidden: Access denied";
|
|
220
|
+
} else if (response.status === 404) {
|
|
221
|
+
errorMessage = "Notice or audio not found";
|
|
222
|
+
} else if (response.status >= 500) {
|
|
223
|
+
errorMessage = "Server error: Please try again later";
|
|
224
|
+
}
|
|
225
|
+
const error = new Error(errorMessage);
|
|
226
|
+
error.status = response.status;
|
|
187
227
|
throw error;
|
|
188
228
|
}
|
|
229
|
+
const data = await response.json();
|
|
230
|
+
return data;
|
|
189
231
|
};
|
|
190
|
-
var
|
|
232
|
+
var initiateGuardianVerification = async ({
|
|
191
233
|
accessToken,
|
|
192
234
|
baseUrl,
|
|
193
235
|
guardianName,
|
|
194
236
|
guardianContact,
|
|
195
237
|
guardianRelationship,
|
|
238
|
+
frontendCallbackUrl,
|
|
239
|
+
metadata,
|
|
196
240
|
signal
|
|
197
|
-
// AbortSignal for request cancellation
|
|
198
241
|
}) => {
|
|
242
|
+
var _a;
|
|
199
243
|
try {
|
|
200
244
|
if (!accessToken) {
|
|
201
245
|
throw new Error("accessToken is required");
|
|
202
246
|
}
|
|
203
247
|
if (!(guardianName == null ? void 0 : guardianName.trim())) {
|
|
204
|
-
throw new Error("
|
|
248
|
+
throw new Error("Guardian name is required");
|
|
205
249
|
}
|
|
206
250
|
if (!(guardianContact == null ? void 0 : guardianContact.trim())) {
|
|
207
|
-
throw new Error("
|
|
251
|
+
throw new Error("Guardian contact is required");
|
|
208
252
|
}
|
|
209
253
|
if (!(guardianRelationship == null ? void 0 : guardianRelationship.trim())) {
|
|
210
|
-
throw new Error("
|
|
254
|
+
throw new Error("Guardian relationship is required");
|
|
211
255
|
}
|
|
212
256
|
const decodedToken = decodeTokenSafely(accessToken);
|
|
213
257
|
if (!decodedToken) {
|
|
@@ -217,14 +261,20 @@ var submitGuardianInfo = async ({
|
|
|
217
261
|
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
218
262
|
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
219
263
|
}
|
|
264
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
220
265
|
const payload = {
|
|
221
266
|
guardian_name: guardianName.trim(),
|
|
222
267
|
guardian_contact: guardianContact.trim(),
|
|
223
268
|
guardian_relationship: guardianRelationship.trim()
|
|
224
269
|
};
|
|
225
|
-
|
|
270
|
+
if (frontendCallbackUrl) {
|
|
271
|
+
payload.frontend_callback_url = frontendCallbackUrl;
|
|
272
|
+
}
|
|
273
|
+
if (metadata) {
|
|
274
|
+
payload.metadata = metadata;
|
|
275
|
+
}
|
|
226
276
|
const response = await fetch(
|
|
227
|
-
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian-
|
|
277
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/initiate-verification`,
|
|
228
278
|
{
|
|
229
279
|
method: "POST",
|
|
230
280
|
headers: {
|
|
@@ -233,24 +283,26 @@ var submitGuardianInfo = async ({
|
|
|
233
283
|
},
|
|
234
284
|
body: JSON.stringify(payload),
|
|
235
285
|
signal
|
|
236
|
-
// Add abort signal for request cancellation
|
|
237
286
|
}
|
|
238
287
|
);
|
|
239
288
|
if (!response.ok) {
|
|
240
|
-
let errorMessage = `Failed to
|
|
289
|
+
let errorMessage = `Failed to initiate verification: ${response.status} ${response.statusText}`;
|
|
241
290
|
if (response.status === 400) {
|
|
242
|
-
|
|
291
|
+
try {
|
|
292
|
+
const errorData = await response.json();
|
|
293
|
+
errorMessage = errorData.message || "Invalid request data";
|
|
294
|
+
} catch {
|
|
295
|
+
errorMessage = "Invalid request data";
|
|
296
|
+
}
|
|
243
297
|
} else if (response.status === 401) {
|
|
244
298
|
errorMessage = "Unauthorized: Invalid or expired token";
|
|
245
|
-
} else if (response.status === 403) {
|
|
246
|
-
errorMessage = "Forbidden: Access denied";
|
|
247
299
|
} else if (response.status === 404) {
|
|
248
300
|
errorMessage = "Organization or workspace not found";
|
|
249
301
|
} else if (response.status === 422) {
|
|
250
302
|
try {
|
|
251
303
|
const errorData = await response.json();
|
|
252
|
-
errorMessage = errorData.message || "Validation error";
|
|
253
|
-
} catch
|
|
304
|
+
errorMessage = errorData.message || "Validation error: Please check your input";
|
|
305
|
+
} catch {
|
|
254
306
|
errorMessage = "Validation error: Please check your input";
|
|
255
307
|
}
|
|
256
308
|
} else if (response.status >= 500) {
|
|
@@ -260,63 +312,98 @@ var submitGuardianInfo = async ({
|
|
|
260
312
|
error.status = response.status;
|
|
261
313
|
throw error;
|
|
262
314
|
}
|
|
315
|
+
const responseData = await response.json();
|
|
316
|
+
const detail = responseData.detail || responseData;
|
|
317
|
+
if (detail.already_verified) {
|
|
318
|
+
return {
|
|
319
|
+
success: true,
|
|
320
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
321
|
+
already_verified: true,
|
|
322
|
+
verification_reference: detail.verification_reference
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
if (!detail.session_token || !detail.digilocker_redirect_url) {
|
|
326
|
+
throw new Error("Invalid response: missing session_token or digilocker_redirect_url");
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
success: (_a = detail.success) != null ? _a : true,
|
|
330
|
+
guardian_info_uuid: detail.guardian_info_uuid,
|
|
331
|
+
already_verified: false,
|
|
332
|
+
session_token: detail.session_token,
|
|
333
|
+
digilocker_redirect_url: detail.digilocker_redirect_url,
|
|
334
|
+
expires_at: detail.expires_at
|
|
335
|
+
};
|
|
263
336
|
} catch (error) {
|
|
264
|
-
console.error("Error
|
|
337
|
+
console.error("Error initiating guardian verification:", error instanceof Error ? error.message : error);
|
|
265
338
|
throw error;
|
|
266
339
|
}
|
|
267
340
|
};
|
|
268
|
-
var
|
|
341
|
+
var verifyGuardianStatus = async ({
|
|
269
342
|
accessToken,
|
|
270
343
|
baseUrl,
|
|
271
|
-
|
|
272
|
-
language,
|
|
344
|
+
sessionToken,
|
|
273
345
|
signal
|
|
274
|
-
// AbortSignal for request cancellation
|
|
275
346
|
}) => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
347
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
348
|
+
if (!accessToken || !sessionToken) {
|
|
349
|
+
throw new Error("accessToken and sessionToken are required");
|
|
350
|
+
}
|
|
351
|
+
const decodedToken = decodeTokenSafely(accessToken);
|
|
352
|
+
if (!decodedToken) {
|
|
353
|
+
throw new Error("Invalid access token");
|
|
354
|
+
}
|
|
355
|
+
const { organisation_uuid: ORGANISATION_UUID, workspace_uuid: WORKSPACE_UUID } = decodedToken;
|
|
356
|
+
if (!ORGANISATION_UUID || !WORKSPACE_UUID) {
|
|
357
|
+
throw new Error("Invalid token: missing organization or workspace UUID");
|
|
358
|
+
}
|
|
359
|
+
const apiBaseUrl = baseUrl || BASE_URL;
|
|
360
|
+
const response = await fetch(
|
|
361
|
+
`${apiBaseUrl}/public/organisations/${ORGANISATION_UUID}/workspaces/${WORKSPACE_UUID}/guardian/verify-status`,
|
|
362
|
+
{
|
|
363
|
+
method: "POST",
|
|
292
364
|
headers: {
|
|
293
365
|
Authorization: `Bearer ${accessToken}`,
|
|
294
|
-
Accept: "application/json",
|
|
295
366
|
"Content-Type": "application/json"
|
|
296
367
|
},
|
|
368
|
+
body: JSON.stringify({
|
|
369
|
+
session_token: sessionToken
|
|
370
|
+
}),
|
|
297
371
|
signal
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
errorMessage =
|
|
306
|
-
}
|
|
307
|
-
errorMessage = "
|
|
308
|
-
} else if (response.status >= 500) {
|
|
309
|
-
errorMessage = "Server error: Please try again later";
|
|
372
|
+
}
|
|
373
|
+
);
|
|
374
|
+
if (!response.ok) {
|
|
375
|
+
let errorMessage = `Failed to check verification status: ${response.status} ${response.statusText}`;
|
|
376
|
+
if (response.status === 400) {
|
|
377
|
+
try {
|
|
378
|
+
const errorData = await response.json();
|
|
379
|
+
errorMessage = errorData.message || ((_a = errorData.detail) == null ? void 0 : _a.message) || "Invalid session token";
|
|
380
|
+
} catch {
|
|
381
|
+
errorMessage = "Invalid session token";
|
|
310
382
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
383
|
+
} else if (response.status === 401) {
|
|
384
|
+
errorMessage = "Unauthorized: Invalid or expired token";
|
|
385
|
+
} else if (response.status === 404) {
|
|
386
|
+
errorMessage = "Verification session not found or expired. Please restart the verification process.";
|
|
387
|
+
} else if (response.status === 410) {
|
|
388
|
+
errorMessage = "Verification session has expired. Please restart the verification process.";
|
|
389
|
+
} else if (response.status >= 500) {
|
|
390
|
+
errorMessage = "Server error: Please try again later";
|
|
314
391
|
}
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
} catch (error) {
|
|
392
|
+
const error = new Error(errorMessage);
|
|
393
|
+
error.status = response.status;
|
|
318
394
|
throw error;
|
|
319
395
|
}
|
|
396
|
+
const responseData = await response.json();
|
|
397
|
+
const detail = responseData.detail || responseData;
|
|
398
|
+
return {
|
|
399
|
+
status: (_b = detail.status) != null ? _b : "in_progress",
|
|
400
|
+
guardian_info_uuid: (_c = detail.guardian_info_uuid) != null ? _c : null,
|
|
401
|
+
verification_reference: (_d = detail.verification_reference) != null ? _d : null,
|
|
402
|
+
guardian_details: (_e = detail.guardian_details) != null ? _e : null,
|
|
403
|
+
error: (_f = detail.error) != null ? _f : null,
|
|
404
|
+
error_code: (_g = detail.error_code) != null ? _g : null,
|
|
405
|
+
can_retry: (_h = detail.can_retry) != null ? _h : true
|
|
406
|
+
};
|
|
320
407
|
};
|
|
321
408
|
|
|
322
409
|
// src/RedactoNoticeConsent/assets/redacto-logo.png
|
|
@@ -464,6 +551,17 @@ var injectCheckboxStyles = () => {
|
|
|
464
551
|
outline: 3px solid #FFF9C4 !important;
|
|
465
552
|
outline-offset: 2px !important;
|
|
466
553
|
}
|
|
554
|
+
|
|
555
|
+
/* Spinner animation for verification screens */
|
|
556
|
+
@keyframes spin {
|
|
557
|
+
from { transform: rotate(0deg); }
|
|
558
|
+
to { transform: rotate(360deg); }
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/* DigiLocker callback retry button hover */
|
|
562
|
+
.redacto-dl-retry-btn:hover {
|
|
563
|
+
background-color: #2563eb !important;
|
|
564
|
+
}
|
|
467
565
|
`;
|
|
468
566
|
document.head.appendChild(style);
|
|
469
567
|
stylesInjected = true;
|
|
@@ -846,6 +944,69 @@ var useMediaQuery = (query) => {
|
|
|
846
944
|
return matches;
|
|
847
945
|
};
|
|
848
946
|
|
|
947
|
+
// src/RedactoNoticeConsent/services/storage.ts
|
|
948
|
+
var STORAGE_KEY = "redacto_consent_sdk_state";
|
|
949
|
+
var STATE_EXPIRY_MS = 30 * 60 * 1e3;
|
|
950
|
+
var isBrowser = () => {
|
|
951
|
+
return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
|
|
952
|
+
};
|
|
953
|
+
var saveConsentState = (state) => {
|
|
954
|
+
if (!isBrowser()) {
|
|
955
|
+
console.warn("SessionStorage not available - state not persisted");
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
try {
|
|
959
|
+
const stateWithTimestamp = {
|
|
960
|
+
...state,
|
|
961
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
962
|
+
};
|
|
963
|
+
sessionStorage.setItem(STORAGE_KEY, JSON.stringify(stateWithTimestamp));
|
|
964
|
+
} catch (error) {
|
|
965
|
+
console.error("Failed to save consent state:", error);
|
|
966
|
+
}
|
|
967
|
+
};
|
|
968
|
+
var getConsentState = () => {
|
|
969
|
+
if (!isBrowser()) {
|
|
970
|
+
return null;
|
|
971
|
+
}
|
|
972
|
+
try {
|
|
973
|
+
const savedState = sessionStorage.getItem(STORAGE_KEY);
|
|
974
|
+
if (!savedState) {
|
|
975
|
+
return null;
|
|
976
|
+
}
|
|
977
|
+
const parsed = JSON.parse(savedState);
|
|
978
|
+
const stateAge = Date.now() - new Date(parsed.timestamp).getTime();
|
|
979
|
+
if (stateAge > STATE_EXPIRY_MS) {
|
|
980
|
+
clearConsentState();
|
|
981
|
+
return null;
|
|
982
|
+
}
|
|
983
|
+
return parsed;
|
|
984
|
+
} catch (error) {
|
|
985
|
+
console.error("Failed to get consent state:", error);
|
|
986
|
+
return null;
|
|
987
|
+
}
|
|
988
|
+
};
|
|
989
|
+
var clearConsentState = () => {
|
|
990
|
+
if (!isBrowser()) {
|
|
991
|
+
return;
|
|
992
|
+
}
|
|
993
|
+
try {
|
|
994
|
+
sessionStorage.removeItem(STORAGE_KEY);
|
|
995
|
+
} catch (error) {
|
|
996
|
+
console.error("Failed to clear consent state:", error);
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
var updateConsentState = (updates) => {
|
|
1000
|
+
const currentState = getConsentState();
|
|
1001
|
+
if (currentState) {
|
|
1002
|
+
saveConsentState({
|
|
1003
|
+
...currentState,
|
|
1004
|
+
...updates,
|
|
1005
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
|
|
849
1010
|
// src/RedactoNoticeConsent/RedactoNoticeConsent.tsx
|
|
850
1011
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
851
1012
|
var PurposeItem = ({
|
|
@@ -1153,6 +1314,12 @@ var PurposeItem = ({
|
|
|
1153
1314
|
)
|
|
1154
1315
|
] }, purpose.uuid);
|
|
1155
1316
|
};
|
|
1317
|
+
var RELATIONSHIP_OPTIONS = [
|
|
1318
|
+
{ value: "Father", label: "Father" },
|
|
1319
|
+
{ value: "Mother", label: "Mother" },
|
|
1320
|
+
{ value: "Legal Guardian", label: "Legal Guardian" },
|
|
1321
|
+
{ value: "Grandparent", label: "Grandparent" }
|
|
1322
|
+
];
|
|
1156
1323
|
var GuardianForm = ({
|
|
1157
1324
|
formData,
|
|
1158
1325
|
errors,
|
|
@@ -1169,34 +1336,128 @@ var GuardianForm = ({
|
|
|
1169
1336
|
declineButtonStyle,
|
|
1170
1337
|
logoUrl
|
|
1171
1338
|
}) => {
|
|
1339
|
+
var _a, _b, _c, _d, _e;
|
|
1340
|
+
const [isDropdownOpen, setIsDropdownOpen] = useState2(false);
|
|
1341
|
+
const [focusedIndex, setFocusedIndex] = useState2(-1);
|
|
1342
|
+
const [openUpward, setOpenUpward] = useState2(false);
|
|
1343
|
+
const dropdownRef = useRef(null);
|
|
1344
|
+
const optionsRef = useRef(null);
|
|
1345
|
+
useEffect2(() => {
|
|
1346
|
+
if (!isDropdownOpen) return;
|
|
1347
|
+
const handleClickOutside = (e) => {
|
|
1348
|
+
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
|
|
1349
|
+
setIsDropdownOpen(false);
|
|
1350
|
+
setFocusedIndex(-1);
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
1354
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
1355
|
+
}, [isDropdownOpen]);
|
|
1356
|
+
useEffect2(() => {
|
|
1357
|
+
if (!isDropdownOpen || !dropdownRef.current) return;
|
|
1358
|
+
const rect = dropdownRef.current.getBoundingClientRect();
|
|
1359
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
1360
|
+
const dropdownHeight = 220;
|
|
1361
|
+
setOpenUpward(spaceBelow < dropdownHeight && rect.top > dropdownHeight);
|
|
1362
|
+
}, [isDropdownOpen]);
|
|
1363
|
+
const handleSelect = (value) => {
|
|
1364
|
+
onChange("guardianRelationship", value);
|
|
1365
|
+
setIsDropdownOpen(false);
|
|
1366
|
+
setFocusedIndex(-1);
|
|
1367
|
+
};
|
|
1368
|
+
const handleKeyDown = (e) => {
|
|
1369
|
+
if (!isDropdownOpen) {
|
|
1370
|
+
if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
|
|
1371
|
+
e.preventDefault();
|
|
1372
|
+
setIsDropdownOpen(true);
|
|
1373
|
+
setFocusedIndex(0);
|
|
1374
|
+
}
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
switch (e.key) {
|
|
1378
|
+
case "ArrowDown":
|
|
1379
|
+
e.preventDefault();
|
|
1380
|
+
setFocusedIndex((prev) => Math.min(prev + 1, RELATIONSHIP_OPTIONS.length - 1));
|
|
1381
|
+
break;
|
|
1382
|
+
case "ArrowUp":
|
|
1383
|
+
e.preventDefault();
|
|
1384
|
+
setFocusedIndex((prev) => Math.max(prev - 1, 0));
|
|
1385
|
+
break;
|
|
1386
|
+
case "Enter":
|
|
1387
|
+
case " ":
|
|
1388
|
+
e.preventDefault();
|
|
1389
|
+
if (focusedIndex >= 0) handleSelect(RELATIONSHIP_OPTIONS[focusedIndex].value);
|
|
1390
|
+
break;
|
|
1391
|
+
case "Escape":
|
|
1392
|
+
case "Tab":
|
|
1393
|
+
setIsDropdownOpen(false);
|
|
1394
|
+
setFocusedIndex(-1);
|
|
1395
|
+
break;
|
|
1396
|
+
}
|
|
1397
|
+
};
|
|
1398
|
+
useEffect2(() => {
|
|
1399
|
+
var _a2;
|
|
1400
|
+
if (focusedIndex >= 0 && optionsRef.current) {
|
|
1401
|
+
const option = optionsRef.current.children[focusedIndex];
|
|
1402
|
+
(_a2 = option == null ? void 0 : option.scrollIntoView) == null ? void 0 : _a2.call(option, { block: "nearest" });
|
|
1403
|
+
}
|
|
1404
|
+
}, [focusedIndex]);
|
|
1405
|
+
const borderColor = (settings == null ? void 0 : settings.borderColor) || "#d0d5dd";
|
|
1406
|
+
const textColor = (settings == null ? void 0 : settings.textColor) || "#344054";
|
|
1407
|
+
const bgColor = (settings == null ? void 0 : settings.backgroundColor) || "#ffffff";
|
|
1408
|
+
const radius = (settings == null ? void 0 : settings.borderRadius) || "8px";
|
|
1409
|
+
const font = (settings == null ? void 0 : settings.font) || "inherit";
|
|
1172
1410
|
const inputStyle = {
|
|
1173
1411
|
width: "100%",
|
|
1174
1412
|
padding: "10px 12px",
|
|
1175
|
-
border: `1px solid ${
|
|
1176
|
-
borderRadius:
|
|
1413
|
+
border: `1px solid ${borderColor}`,
|
|
1414
|
+
borderRadius: radius,
|
|
1177
1415
|
fontSize: "13px",
|
|
1178
|
-
fontFamily:
|
|
1179
|
-
color:
|
|
1180
|
-
backgroundColor:
|
|
1181
|
-
marginBottom: "
|
|
1182
|
-
boxSizing: "border-box"
|
|
1416
|
+
fontFamily: font,
|
|
1417
|
+
color: textColor,
|
|
1418
|
+
backgroundColor: bgColor,
|
|
1419
|
+
marginBottom: "2px",
|
|
1420
|
+
boxSizing: "border-box",
|
|
1421
|
+
outline: "none"
|
|
1183
1422
|
};
|
|
1184
1423
|
const errorStyle = {
|
|
1185
1424
|
color: "#DC2626",
|
|
1186
|
-
fontSize: "
|
|
1425
|
+
fontSize: "11px",
|
|
1187
1426
|
marginTop: "4px",
|
|
1188
|
-
marginBottom: "
|
|
1427
|
+
marginBottom: "0px"
|
|
1189
1428
|
};
|
|
1190
1429
|
const labelStyle = {
|
|
1191
1430
|
...componentTextStyle,
|
|
1192
1431
|
fontSize: "13px",
|
|
1193
1432
|
fontWeight: "500",
|
|
1194
|
-
marginBottom: "
|
|
1433
|
+
marginBottom: "4px",
|
|
1195
1434
|
display: "block"
|
|
1196
1435
|
};
|
|
1436
|
+
const hintStyle = {
|
|
1437
|
+
fontSize: "11px",
|
|
1438
|
+
color: "#667085",
|
|
1439
|
+
marginTop: "2px",
|
|
1440
|
+
marginBottom: "0px",
|
|
1441
|
+
lineHeight: "1.4"
|
|
1442
|
+
};
|
|
1443
|
+
const infoBannerStyle = {
|
|
1444
|
+
display: "flex",
|
|
1445
|
+
alignItems: "flex-start",
|
|
1446
|
+
gap: "8px",
|
|
1447
|
+
padding: "10px 12px",
|
|
1448
|
+
backgroundColor: "#EFF6FF",
|
|
1449
|
+
border: "1px solid #BFDBFE",
|
|
1450
|
+
borderRadius: radius,
|
|
1451
|
+
marginBottom: "16px",
|
|
1452
|
+
fontSize: "12px",
|
|
1453
|
+
lineHeight: "1.5",
|
|
1454
|
+
color: "#1E40AF"
|
|
1455
|
+
};
|
|
1456
|
+
const selectedLabel = (_a = RELATIONSHIP_OPTIONS.find((o) => o.value === formData.guardianRelationship)) == null ? void 0 : _a.label;
|
|
1457
|
+
const hasError = Boolean(errors.guardianRelationship);
|
|
1197
1458
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1198
1459
|
/* @__PURE__ */ jsx("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ jsxs("div", { style: styles3.topLeft, children: [
|
|
1199
|
-
/* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "
|
|
1460
|
+
/* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1200
1461
|
/* @__PURE__ */ jsx(
|
|
1201
1462
|
"h2",
|
|
1202
1463
|
{
|
|
@@ -1208,7 +1469,7 @@ var GuardianForm = ({
|
|
|
1208
1469
|
fontSize: "16px",
|
|
1209
1470
|
fontWeight: 600
|
|
1210
1471
|
},
|
|
1211
|
-
children: "Guardian
|
|
1472
|
+
children: "Guardian Verification"
|
|
1212
1473
|
}
|
|
1213
1474
|
)
|
|
1214
1475
|
] }) }),
|
|
@@ -1228,31 +1489,49 @@ var GuardianForm = ({
|
|
|
1228
1489
|
...styles3.privacyText,
|
|
1229
1490
|
...responsiveStyles.privacyText,
|
|
1230
1491
|
...componentTextStyle,
|
|
1231
|
-
fontSize: "
|
|
1232
|
-
lineHeight: "1.
|
|
1492
|
+
fontSize: "13px",
|
|
1493
|
+
lineHeight: "1.5",
|
|
1494
|
+
marginBottom: "12px"
|
|
1233
1495
|
},
|
|
1234
|
-
children: "
|
|
1496
|
+
children: "Since you are under the age of consent, a legal guardian must verify their identity via DigiLocker before you can proceed."
|
|
1235
1497
|
}
|
|
1236
1498
|
),
|
|
1499
|
+
/* @__PURE__ */ jsxs("div", { style: infoBannerStyle, children: [
|
|
1500
|
+
/* @__PURE__ */ jsxs(
|
|
1501
|
+
"svg",
|
|
1502
|
+
{
|
|
1503
|
+
width: "16",
|
|
1504
|
+
height: "16",
|
|
1505
|
+
viewBox: "0 0 24 24",
|
|
1506
|
+
fill: "none",
|
|
1507
|
+
stroke: "#2563EB",
|
|
1508
|
+
strokeWidth: "2",
|
|
1509
|
+
strokeLinecap: "round",
|
|
1510
|
+
strokeLinejoin: "round",
|
|
1511
|
+
style: { flexShrink: 0, marginTop: "1px" },
|
|
1512
|
+
children: [
|
|
1513
|
+
/* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
1514
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
|
|
1515
|
+
/* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
|
|
1516
|
+
]
|
|
1517
|
+
}
|
|
1518
|
+
),
|
|
1519
|
+
/* @__PURE__ */ jsx("span", { children: "The guardian's name will be matched against their DigiLocker identity document (e.g. Aadhaar). Please enter the name exactly as it appears on the document." })
|
|
1520
|
+
] }),
|
|
1237
1521
|
/* @__PURE__ */ jsxs(
|
|
1238
1522
|
"div",
|
|
1239
1523
|
{
|
|
1240
1524
|
style: {
|
|
1241
1525
|
display: "flex",
|
|
1242
1526
|
flexDirection: "column",
|
|
1243
|
-
gap: "
|
|
1244
|
-
marginTop: "16px"
|
|
1527
|
+
gap: "14px"
|
|
1245
1528
|
},
|
|
1246
1529
|
children: [
|
|
1247
1530
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
"
|
|
1250
|
-
{
|
|
1251
|
-
|
|
1252
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1253
|
-
children: "Name of Guardian *"
|
|
1254
|
-
}
|
|
1255
|
-
),
|
|
1531
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "guardianName", style: labelStyle, children: [
|
|
1532
|
+
"Guardian's Full Name ",
|
|
1533
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1534
|
+
] }),
|
|
1256
1535
|
/* @__PURE__ */ jsx(
|
|
1257
1536
|
"input",
|
|
1258
1537
|
{
|
|
@@ -1262,62 +1541,170 @@ var GuardianForm = ({
|
|
|
1262
1541
|
onChange: (e) => onChange("guardianName", e.target.value),
|
|
1263
1542
|
style: {
|
|
1264
1543
|
...inputStyle,
|
|
1265
|
-
borderColor: errors.guardianName ? "#DC2626" :
|
|
1544
|
+
borderColor: errors.guardianName ? "#DC2626" : borderColor
|
|
1266
1545
|
},
|
|
1267
|
-
placeholder: "
|
|
1546
|
+
placeholder: "e.g. Rajesh Kumar",
|
|
1547
|
+
autoComplete: "name",
|
|
1548
|
+
"aria-describedby": "guardianName-hint"
|
|
1268
1549
|
}
|
|
1269
1550
|
),
|
|
1270
|
-
|
|
1551
|
+
/* @__PURE__ */ jsx("p", { id: "guardianName-hint", style: hintStyle, children: "Enter the full name as per government ID (Aadhaar, PAN, etc.)" }),
|
|
1552
|
+
errors.guardianName && /* @__PURE__ */ jsx("div", { style: errorStyle, role: "alert", children: errors.guardianName })
|
|
1271
1553
|
] }),
|
|
1272
1554
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1273
|
-
/* @__PURE__ */
|
|
1274
|
-
"
|
|
1275
|
-
{
|
|
1276
|
-
|
|
1277
|
-
style: { ...labelStyle, marginBottom: "8px", display: "block" },
|
|
1278
|
-
children: "Contact of Guardian *"
|
|
1279
|
-
}
|
|
1280
|
-
),
|
|
1555
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "guardianContact", style: labelStyle, children: [
|
|
1556
|
+
"Guardian's Phone Number ",
|
|
1557
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1558
|
+
] }),
|
|
1281
1559
|
/* @__PURE__ */ jsx(
|
|
1282
1560
|
"input",
|
|
1283
1561
|
{
|
|
1284
1562
|
id: "guardianContact",
|
|
1285
|
-
type: "
|
|
1563
|
+
type: "tel",
|
|
1564
|
+
inputMode: "tel",
|
|
1286
1565
|
value: formData.guardianContact,
|
|
1287
1566
|
onChange: (e) => onChange("guardianContact", e.target.value),
|
|
1288
1567
|
style: {
|
|
1289
1568
|
...inputStyle,
|
|
1290
|
-
borderColor: errors.guardianContact ? "#DC2626" :
|
|
1569
|
+
borderColor: errors.guardianContact ? "#DC2626" : borderColor
|
|
1291
1570
|
},
|
|
1292
|
-
placeholder: "
|
|
1571
|
+
placeholder: "e.g. 9876543210",
|
|
1572
|
+
autoComplete: "tel",
|
|
1573
|
+
"aria-describedby": "guardianContact-hint"
|
|
1293
1574
|
}
|
|
1294
1575
|
),
|
|
1295
|
-
|
|
1576
|
+
/* @__PURE__ */ jsx("p", { id: "guardianContact-hint", style: hintStyle, children: "Mobile number linked to guardian's Aadhaar" }),
|
|
1577
|
+
errors.guardianContact && /* @__PURE__ */ jsx("div", { style: errorStyle, role: "alert", children: errors.guardianContact })
|
|
1296
1578
|
] }),
|
|
1297
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1298
|
-
/* @__PURE__ */
|
|
1299
|
-
"
|
|
1579
|
+
/* @__PURE__ */ jsxs("div", { ref: dropdownRef, style: { position: "relative" }, children: [
|
|
1580
|
+
/* @__PURE__ */ jsxs("label", { id: "guardianRelationship-label", style: labelStyle, children: [
|
|
1581
|
+
"Relationship ",
|
|
1582
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#DC2626" }, children: "*" })
|
|
1583
|
+
] }),
|
|
1584
|
+
/* @__PURE__ */ jsxs(
|
|
1585
|
+
"div",
|
|
1300
1586
|
{
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1587
|
+
role: "combobox",
|
|
1588
|
+
"aria-expanded": isDropdownOpen,
|
|
1589
|
+
"aria-haspopup": "listbox",
|
|
1590
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1591
|
+
"aria-controls": "guardianRelationship-listbox",
|
|
1592
|
+
"aria-activedescendant": focusedIndex >= 0 ? `guardianRelationship-option-${focusedIndex}` : void 0,
|
|
1593
|
+
tabIndex: 0,
|
|
1594
|
+
onClick: () => {
|
|
1595
|
+
setIsDropdownOpen((prev) => !prev);
|
|
1596
|
+
setFocusedIndex(-1);
|
|
1597
|
+
},
|
|
1598
|
+
onKeyDown: handleKeyDown,
|
|
1599
|
+
style: {
|
|
1600
|
+
...inputStyle,
|
|
1601
|
+
borderColor: hasError ? "#DC2626" : isDropdownOpen ? ((_c = (_b = settings == null ? void 0 : settings.button) == null ? void 0 : _b.accept) == null ? void 0 : _c.backgroundColor) || "#3b82f6" : borderColor,
|
|
1602
|
+
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",
|
|
1603
|
+
color: selectedLabel ? textColor : "#9CA3AF",
|
|
1604
|
+
cursor: "pointer",
|
|
1605
|
+
display: "flex",
|
|
1606
|
+
alignItems: "center",
|
|
1607
|
+
justifyContent: "space-between",
|
|
1608
|
+
userSelect: "none",
|
|
1609
|
+
transition: "border-color 0.15s, box-shadow 0.15s"
|
|
1610
|
+
},
|
|
1611
|
+
children: [
|
|
1612
|
+
/* @__PURE__ */ jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: selectedLabel || "Select relationship" }),
|
|
1613
|
+
/* @__PURE__ */ jsx(
|
|
1614
|
+
"svg",
|
|
1615
|
+
{
|
|
1616
|
+
width: "14",
|
|
1617
|
+
height: "14",
|
|
1618
|
+
viewBox: "0 0 24 24",
|
|
1619
|
+
fill: "none",
|
|
1620
|
+
stroke: "#667085",
|
|
1621
|
+
strokeWidth: "2",
|
|
1622
|
+
strokeLinecap: "round",
|
|
1623
|
+
strokeLinejoin: "round",
|
|
1624
|
+
style: {
|
|
1625
|
+
flexShrink: 0,
|
|
1626
|
+
marginLeft: "8px",
|
|
1627
|
+
transform: isDropdownOpen ? "rotate(180deg)" : "rotate(0deg)",
|
|
1628
|
+
transition: "transform 0.2s"
|
|
1629
|
+
},
|
|
1630
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
|
|
1631
|
+
}
|
|
1632
|
+
)
|
|
1633
|
+
]
|
|
1304
1634
|
}
|
|
1305
1635
|
),
|
|
1306
|
-
/* @__PURE__ */ jsx(
|
|
1307
|
-
"
|
|
1636
|
+
isDropdownOpen && /* @__PURE__ */ jsx(
|
|
1637
|
+
"div",
|
|
1308
1638
|
{
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1639
|
+
ref: optionsRef,
|
|
1640
|
+
id: "guardianRelationship-listbox",
|
|
1641
|
+
role: "listbox",
|
|
1642
|
+
"aria-labelledby": "guardianRelationship-label",
|
|
1313
1643
|
style: {
|
|
1314
|
-
|
|
1315
|
-
|
|
1644
|
+
position: "absolute",
|
|
1645
|
+
...openUpward ? { bottom: "calc(100% + 4px)" } : { top: "calc(100% + 4px)" },
|
|
1646
|
+
left: 0,
|
|
1647
|
+
right: 0,
|
|
1648
|
+
backgroundColor: bgColor,
|
|
1649
|
+
border: `1px solid ${borderColor}`,
|
|
1650
|
+
borderRadius: radius,
|
|
1651
|
+
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)",
|
|
1652
|
+
zIndex: 50,
|
|
1653
|
+
overflow: "hidden",
|
|
1654
|
+
padding: "4px 0",
|
|
1655
|
+
maxHeight: "220px",
|
|
1656
|
+
overflowY: "auto"
|
|
1316
1657
|
},
|
|
1317
|
-
|
|
1658
|
+
children: RELATIONSHIP_OPTIONS.map((option, index) => {
|
|
1659
|
+
var _a2, _b2;
|
|
1660
|
+
const isSelected = formData.guardianRelationship === option.value;
|
|
1661
|
+
const isFocused = focusedIndex === index;
|
|
1662
|
+
const accentColor = ((_b2 = (_a2 = settings == null ? void 0 : settings.button) == null ? void 0 : _a2.accept) == null ? void 0 : _b2.backgroundColor) || "#3b82f6";
|
|
1663
|
+
return /* @__PURE__ */ jsxs(
|
|
1664
|
+
"div",
|
|
1665
|
+
{
|
|
1666
|
+
id: `guardianRelationship-option-${index}`,
|
|
1667
|
+
role: "option",
|
|
1668
|
+
"aria-selected": isSelected,
|
|
1669
|
+
onClick: () => handleSelect(option.value),
|
|
1670
|
+
onMouseEnter: () => setFocusedIndex(index),
|
|
1671
|
+
style: {
|
|
1672
|
+
padding: "9px 12px",
|
|
1673
|
+
fontSize: "13px",
|
|
1674
|
+
fontFamily: font,
|
|
1675
|
+
color: isSelected ? accentColor : textColor,
|
|
1676
|
+
backgroundColor: isFocused ? "#F3F4F6" : "transparent",
|
|
1677
|
+
cursor: "pointer",
|
|
1678
|
+
display: "flex",
|
|
1679
|
+
alignItems: "center",
|
|
1680
|
+
justifyContent: "space-between",
|
|
1681
|
+
transition: "background-color 0.1s"
|
|
1682
|
+
},
|
|
1683
|
+
children: [
|
|
1684
|
+
/* @__PURE__ */ jsx("span", { children: option.label }),
|
|
1685
|
+
isSelected && /* @__PURE__ */ jsx(
|
|
1686
|
+
"svg",
|
|
1687
|
+
{
|
|
1688
|
+
width: "14",
|
|
1689
|
+
height: "14",
|
|
1690
|
+
viewBox: "0 0 24 24",
|
|
1691
|
+
fill: "none",
|
|
1692
|
+
stroke: accentColor,
|
|
1693
|
+
strokeWidth: "2.5",
|
|
1694
|
+
strokeLinecap: "round",
|
|
1695
|
+
strokeLinejoin: "round",
|
|
1696
|
+
style: { flexShrink: 0 },
|
|
1697
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
1698
|
+
}
|
|
1699
|
+
)
|
|
1700
|
+
]
|
|
1701
|
+
},
|
|
1702
|
+
option.value
|
|
1703
|
+
);
|
|
1704
|
+
})
|
|
1318
1705
|
}
|
|
1319
1706
|
),
|
|
1320
|
-
errors.guardianRelationship && /* @__PURE__ */ jsx("div", { style: errorStyle, children: errors.guardianRelationship })
|
|
1707
|
+
errors.guardianRelationship && /* @__PURE__ */ jsx("div", { style: errorStyle, role: "alert", children: errors.guardianRelationship })
|
|
1321
1708
|
] })
|
|
1322
1709
|
]
|
|
1323
1710
|
}
|
|
@@ -1328,7 +1715,7 @@ var GuardianForm = ({
|
|
|
1328
1715
|
role: "alert",
|
|
1329
1716
|
style: {
|
|
1330
1717
|
color: "#DC2626",
|
|
1331
|
-
fontSize: "
|
|
1718
|
+
fontSize: "13px",
|
|
1332
1719
|
marginTop: "16px",
|
|
1333
1720
|
padding: "12px",
|
|
1334
1721
|
borderRadius: "6px",
|
|
@@ -1364,8 +1751,8 @@ var GuardianForm = ({
|
|
|
1364
1751
|
onClick: onNext,
|
|
1365
1752
|
disabled: isSubmitting,
|
|
1366
1753
|
type: "button",
|
|
1367
|
-
"aria-label": isSubmitting ? "
|
|
1368
|
-
children: isSubmitting ? "
|
|
1754
|
+
"aria-label": isSubmitting ? "Verifying guardian identity" : "Proceed to guardian verification",
|
|
1755
|
+
children: isSubmitting ? "Verifying..." : "Verify via DigiLocker"
|
|
1369
1756
|
}
|
|
1370
1757
|
),
|
|
1371
1758
|
/* @__PURE__ */ jsx(
|
|
@@ -1379,7 +1766,7 @@ var GuardianForm = ({
|
|
|
1379
1766
|
},
|
|
1380
1767
|
onClick: onDecline,
|
|
1381
1768
|
type: "button",
|
|
1382
|
-
"aria-label": "Cancel
|
|
1769
|
+
"aria-label": "Cancel",
|
|
1383
1770
|
children: "Cancel"
|
|
1384
1771
|
}
|
|
1385
1772
|
)
|
|
@@ -1388,6 +1775,266 @@ var GuardianForm = ({
|
|
|
1388
1775
|
)
|
|
1389
1776
|
] });
|
|
1390
1777
|
};
|
|
1778
|
+
var VerificationScreen = ({
|
|
1779
|
+
onBack,
|
|
1780
|
+
onContinue,
|
|
1781
|
+
isInitiating,
|
|
1782
|
+
isPolling,
|
|
1783
|
+
isVerificationComplete,
|
|
1784
|
+
isAutoTransitioning,
|
|
1785
|
+
error,
|
|
1786
|
+
errorCode,
|
|
1787
|
+
canRetry,
|
|
1788
|
+
styles: styles3,
|
|
1789
|
+
responsiveStyles,
|
|
1790
|
+
settings,
|
|
1791
|
+
componentHeadingStyle,
|
|
1792
|
+
componentTextStyle,
|
|
1793
|
+
acceptButtonStyle,
|
|
1794
|
+
declineButtonStyle,
|
|
1795
|
+
logoUrl
|
|
1796
|
+
}) => {
|
|
1797
|
+
var _a, _b;
|
|
1798
|
+
const errorStyle = {
|
|
1799
|
+
color: "#DC2626",
|
|
1800
|
+
fontSize: "14px",
|
|
1801
|
+
marginTop: "16px",
|
|
1802
|
+
padding: "12px",
|
|
1803
|
+
borderRadius: "6px",
|
|
1804
|
+
border: "1px solid #FCA5A5",
|
|
1805
|
+
backgroundColor: "#FEF2F2",
|
|
1806
|
+
textAlign: "center"
|
|
1807
|
+
};
|
|
1808
|
+
const statusStyle = {
|
|
1809
|
+
color: "#059669",
|
|
1810
|
+
fontSize: "14px",
|
|
1811
|
+
marginTop: "16px",
|
|
1812
|
+
padding: "12px",
|
|
1813
|
+
borderRadius: "6px",
|
|
1814
|
+
border: "1px solid #A7F3D0",
|
|
1815
|
+
backgroundColor: "#D1FAE5",
|
|
1816
|
+
textAlign: "center"
|
|
1817
|
+
};
|
|
1818
|
+
const spinnerStyle = {
|
|
1819
|
+
width: "48px",
|
|
1820
|
+
height: "48px",
|
|
1821
|
+
border: "4px solid #e5e7eb",
|
|
1822
|
+
borderTopColor: ((_b = (_a = settings == null ? void 0 : settings.button) == null ? void 0 : _a.accept) == null ? void 0 : _b.backgroundColor) || "#3b82f6",
|
|
1823
|
+
borderRadius: "50%",
|
|
1824
|
+
animation: "spin 1s linear infinite",
|
|
1825
|
+
margin: "24px auto"
|
|
1826
|
+
};
|
|
1827
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1828
|
+
/* @__PURE__ */ jsx("div", { style: { ...styles3.topSection, ...componentTextStyle }, children: /* @__PURE__ */ jsxs("div", { style: styles3.topLeft, children: [
|
|
1829
|
+
/* @__PURE__ */ jsx("img", { style: styles3.logo, src: logoUrl, alt: "Logo" }),
|
|
1830
|
+
/* @__PURE__ */ jsx(
|
|
1831
|
+
"h2",
|
|
1832
|
+
{
|
|
1833
|
+
id: "verification-title",
|
|
1834
|
+
style: {
|
|
1835
|
+
...styles3.title,
|
|
1836
|
+
...responsiveStyles.title,
|
|
1837
|
+
...componentHeadingStyle,
|
|
1838
|
+
fontSize: "16px",
|
|
1839
|
+
fontWeight: 600
|
|
1840
|
+
},
|
|
1841
|
+
children: "Guardian Verification"
|
|
1842
|
+
}
|
|
1843
|
+
)
|
|
1844
|
+
] }) }),
|
|
1845
|
+
/* @__PURE__ */ jsxs(
|
|
1846
|
+
"div",
|
|
1847
|
+
{
|
|
1848
|
+
style: {
|
|
1849
|
+
...styles3.middleSection,
|
|
1850
|
+
...responsiveStyles.middleSection,
|
|
1851
|
+
...componentTextStyle,
|
|
1852
|
+
textAlign: "center"
|
|
1853
|
+
},
|
|
1854
|
+
children: [
|
|
1855
|
+
isVerificationComplete && !error ? /* @__PURE__ */ jsxs(
|
|
1856
|
+
"div",
|
|
1857
|
+
{
|
|
1858
|
+
style: {
|
|
1859
|
+
display: "flex",
|
|
1860
|
+
flexDirection: "column",
|
|
1861
|
+
alignItems: "center",
|
|
1862
|
+
justifyContent: "center",
|
|
1863
|
+
flex: 1
|
|
1864
|
+
},
|
|
1865
|
+
children: [
|
|
1866
|
+
/* @__PURE__ */ jsx(
|
|
1867
|
+
"div",
|
|
1868
|
+
{
|
|
1869
|
+
style: {
|
|
1870
|
+
width: "64px",
|
|
1871
|
+
height: "64px",
|
|
1872
|
+
borderRadius: "50%",
|
|
1873
|
+
backgroundColor: "#D1FAE5",
|
|
1874
|
+
display: "flex",
|
|
1875
|
+
alignItems: "center",
|
|
1876
|
+
justifyContent: "center"
|
|
1877
|
+
},
|
|
1878
|
+
children: /* @__PURE__ */ jsx(
|
|
1879
|
+
"svg",
|
|
1880
|
+
{
|
|
1881
|
+
width: "32",
|
|
1882
|
+
height: "32",
|
|
1883
|
+
viewBox: "0 0 24 24",
|
|
1884
|
+
fill: "none",
|
|
1885
|
+
stroke: "#059669",
|
|
1886
|
+
strokeWidth: "2",
|
|
1887
|
+
strokeLinecap: "round",
|
|
1888
|
+
strokeLinejoin: "round",
|
|
1889
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
|
|
1890
|
+
}
|
|
1891
|
+
)
|
|
1892
|
+
}
|
|
1893
|
+
),
|
|
1894
|
+
/* @__PURE__ */ jsx(
|
|
1895
|
+
"p",
|
|
1896
|
+
{
|
|
1897
|
+
style: {
|
|
1898
|
+
...componentHeadingStyle,
|
|
1899
|
+
fontSize: "16px",
|
|
1900
|
+
fontWeight: 600,
|
|
1901
|
+
lineHeight: "1.5",
|
|
1902
|
+
marginTop: "12px",
|
|
1903
|
+
marginBottom: "24px"
|
|
1904
|
+
},
|
|
1905
|
+
children: "Verification Completed"
|
|
1906
|
+
}
|
|
1907
|
+
)
|
|
1908
|
+
]
|
|
1909
|
+
}
|
|
1910
|
+
) : (isInitiating || isPolling) && !error ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1911
|
+
/* @__PURE__ */ jsx("div", { style: spinnerStyle }),
|
|
1912
|
+
/* @__PURE__ */ jsx("div", { style: statusStyle, children: isInitiating ? "Opening DigiLocker in a new tab..." : "Please complete the verification in the DigiLocker tab. This page will update automatically when verification is complete." })
|
|
1913
|
+
] }) : null,
|
|
1914
|
+
error && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1915
|
+
/* @__PURE__ */ jsx(
|
|
1916
|
+
"div",
|
|
1917
|
+
{
|
|
1918
|
+
style: {
|
|
1919
|
+
width: "64px",
|
|
1920
|
+
height: "64px",
|
|
1921
|
+
borderRadius: "50%",
|
|
1922
|
+
backgroundColor: "#fee2e2",
|
|
1923
|
+
display: "flex",
|
|
1924
|
+
alignItems: "center",
|
|
1925
|
+
justifyContent: "center",
|
|
1926
|
+
margin: "24px auto"
|
|
1927
|
+
},
|
|
1928
|
+
children: /* @__PURE__ */ jsxs(
|
|
1929
|
+
"svg",
|
|
1930
|
+
{
|
|
1931
|
+
width: "32",
|
|
1932
|
+
height: "32",
|
|
1933
|
+
viewBox: "0 0 24 24",
|
|
1934
|
+
fill: "none",
|
|
1935
|
+
stroke: "#dc2626",
|
|
1936
|
+
strokeWidth: "2",
|
|
1937
|
+
strokeLinecap: "round",
|
|
1938
|
+
strokeLinejoin: "round",
|
|
1939
|
+
children: [
|
|
1940
|
+
/* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
1941
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
1942
|
+
]
|
|
1943
|
+
}
|
|
1944
|
+
)
|
|
1945
|
+
}
|
|
1946
|
+
),
|
|
1947
|
+
/* @__PURE__ */ jsx(
|
|
1948
|
+
"p",
|
|
1949
|
+
{
|
|
1950
|
+
style: {
|
|
1951
|
+
...styles3.privacyText,
|
|
1952
|
+
...responsiveStyles.privacyText,
|
|
1953
|
+
...componentTextStyle,
|
|
1954
|
+
fontSize: "14px",
|
|
1955
|
+
lineHeight: "1.5",
|
|
1956
|
+
marginBottom: "12px"
|
|
1957
|
+
},
|
|
1958
|
+
children: "Verification failed"
|
|
1959
|
+
}
|
|
1960
|
+
),
|
|
1961
|
+
/* @__PURE__ */ jsx("div", { style: errorStyle, children: error })
|
|
1962
|
+
] })
|
|
1963
|
+
]
|
|
1964
|
+
}
|
|
1965
|
+
),
|
|
1966
|
+
isAutoTransitioning ? null : /* @__PURE__ */ jsx(
|
|
1967
|
+
"div",
|
|
1968
|
+
{
|
|
1969
|
+
style: {
|
|
1970
|
+
...styles3.bottomSection,
|
|
1971
|
+
...responsiveStyles.bottomSection,
|
|
1972
|
+
...componentTextStyle,
|
|
1973
|
+
paddingTop: "12px",
|
|
1974
|
+
display: "flex",
|
|
1975
|
+
gap: "12px",
|
|
1976
|
+
justifyContent: "center"
|
|
1977
|
+
},
|
|
1978
|
+
children: isVerificationComplete && !error ? /* @__PURE__ */ jsx(
|
|
1979
|
+
"button",
|
|
1980
|
+
{
|
|
1981
|
+
style: {
|
|
1982
|
+
...styles3.button,
|
|
1983
|
+
...responsiveStyles.button,
|
|
1984
|
+
...acceptButtonStyle
|
|
1985
|
+
},
|
|
1986
|
+
onClick: onContinue,
|
|
1987
|
+
type: "button",
|
|
1988
|
+
"aria-label": "Continue to consent form",
|
|
1989
|
+
children: "Continue"
|
|
1990
|
+
}
|
|
1991
|
+
) : error && canRetry ? /* @__PURE__ */ jsx(
|
|
1992
|
+
"button",
|
|
1993
|
+
{
|
|
1994
|
+
style: {
|
|
1995
|
+
...styles3.button,
|
|
1996
|
+
...responsiveStyles.button,
|
|
1997
|
+
...styles3.acceptButton,
|
|
1998
|
+
...acceptButtonStyle
|
|
1999
|
+
},
|
|
2000
|
+
onClick: () => onBack(errorCode === "GUARDIAN_UNDER_18"),
|
|
2001
|
+
type: "button",
|
|
2002
|
+
"aria-label": errorCode === "GUARDIAN_UNDER_18" ? "Change guardian details" : "Try verification again",
|
|
2003
|
+
children: errorCode === "GUARDIAN_UNDER_18" ? "Change Guardian" : "Try Again"
|
|
2004
|
+
}
|
|
2005
|
+
) : error ? /* @__PURE__ */ jsx(
|
|
2006
|
+
"button",
|
|
2007
|
+
{
|
|
2008
|
+
style: {
|
|
2009
|
+
...styles3.button,
|
|
2010
|
+
...responsiveStyles.button,
|
|
2011
|
+
...styles3.cancelButton,
|
|
2012
|
+
...declineButtonStyle
|
|
2013
|
+
},
|
|
2014
|
+
onClick: () => onBack(false),
|
|
2015
|
+
type: "button",
|
|
2016
|
+
"aria-label": "Go back",
|
|
2017
|
+
children: "Go Back"
|
|
2018
|
+
}
|
|
2019
|
+
) : /* @__PURE__ */ jsx(
|
|
2020
|
+
"button",
|
|
2021
|
+
{
|
|
2022
|
+
style: {
|
|
2023
|
+
...styles3.button,
|
|
2024
|
+
...responsiveStyles.button,
|
|
2025
|
+
...styles3.cancelButton,
|
|
2026
|
+
...declineButtonStyle
|
|
2027
|
+
},
|
|
2028
|
+
onClick: () => onBack(false),
|
|
2029
|
+
type: "button",
|
|
2030
|
+
"aria-label": "Cancel verification",
|
|
2031
|
+
children: "Cancel"
|
|
2032
|
+
}
|
|
2033
|
+
)
|
|
2034
|
+
}
|
|
2035
|
+
)
|
|
2036
|
+
] });
|
|
2037
|
+
};
|
|
1391
2038
|
var AgeVerification = ({
|
|
1392
2039
|
onYes,
|
|
1393
2040
|
onNo,
|
|
@@ -1550,6 +2197,10 @@ var RedactoNoticeConsent = ({
|
|
|
1550
2197
|
settings,
|
|
1551
2198
|
applicationId,
|
|
1552
2199
|
validateAgainst = "all",
|
|
2200
|
+
digilockerMode = "redirect",
|
|
2201
|
+
// Default to full page redirect (DigiLocker blocks iframe embedding)
|
|
2202
|
+
digilockerCallbackUrl = "/digilocker-callback",
|
|
2203
|
+
// Default callback path
|
|
1553
2204
|
includeFullyConsentedData = false,
|
|
1554
2205
|
reviewModeButtonText = "Continue"
|
|
1555
2206
|
}) => {
|
|
@@ -1605,6 +2256,8 @@ var RedactoNoticeConsent = ({
|
|
|
1605
2256
|
const [currentAudioIndex, setCurrentAudioIndex] = useState2(0);
|
|
1606
2257
|
const [highlightedElementId, setHighlightedElementId] = useState2(null);
|
|
1607
2258
|
const [showAgeVerification, setShowAgeVerification] = useState2(false);
|
|
2259
|
+
const [isMinorFlow, setIsMinorFlow] = useState2(false);
|
|
2260
|
+
const [selfDeclaredAdult, setSelfDeclaredAdult] = useState2(false);
|
|
1608
2261
|
const [showGuardianForm, setShowGuardianForm] = useState2(false);
|
|
1609
2262
|
const [isSubmittingGuardian, setIsSubmittingGuardian] = useState2(false);
|
|
1610
2263
|
const [guardianFormData, setGuardianFormData] = useState2({
|
|
@@ -1613,12 +2266,32 @@ var RedactoNoticeConsent = ({
|
|
|
1613
2266
|
guardianRelationship: ""
|
|
1614
2267
|
});
|
|
1615
2268
|
const [guardianFormErrors, setGuardianFormErrors] = useState2({});
|
|
2269
|
+
const [showVerificationScreen, setShowVerificationScreen] = useState2(false);
|
|
2270
|
+
const [verificationReference, setVerificationReference] = useState2(null);
|
|
2271
|
+
const [isInitiatingVerification, setIsInitiatingVerification] = useState2(false);
|
|
2272
|
+
const [verificationError, setVerificationError] = useState2(
|
|
2273
|
+
null
|
|
2274
|
+
);
|
|
2275
|
+
const [verificationErrorCode, setVerificationErrorCode] = useState2(null);
|
|
2276
|
+
const [canRetryVerification, setCanRetryVerification] = useState2(false);
|
|
2277
|
+
const [isPollingStatus, setIsPollingStatus] = useState2(false);
|
|
2278
|
+
const [isVerificationComplete, setIsVerificationComplete] = useState2(false);
|
|
2279
|
+
const [isAutoTransitioning, setIsAutoTransitioning] = useState2(false);
|
|
1616
2280
|
const modalRef = useRef(null);
|
|
1617
2281
|
const firstFocusableRef = useRef(null);
|
|
1618
2282
|
const lastFocusableRef = useRef(null);
|
|
1619
2283
|
const abortControllerRef = useRef(null);
|
|
1620
2284
|
const isRequestInProgressRef = useRef(false);
|
|
1621
2285
|
const currentAudioRef = useRef(null);
|
|
2286
|
+
const popupCheckIntervalRef = useRef(null);
|
|
2287
|
+
const statusPollIntervalRef = useRef(null);
|
|
2288
|
+
const verificationPopupRef = useRef(null);
|
|
2289
|
+
const pollingCleanupRef = useRef(null);
|
|
2290
|
+
const autoTransitionTimerRef = useRef(null);
|
|
2291
|
+
const digilockerRedirectTimeoutRef = useRef(null);
|
|
2292
|
+
const isInitialMountRef = useRef(true);
|
|
2293
|
+
const isPollingStatusRef = useRef(false);
|
|
2294
|
+
const verificationSessionTokenRef = useRef(null);
|
|
1622
2295
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
1623
2296
|
const responsiveStyles = useMemo(
|
|
1624
2297
|
() => ({
|
|
@@ -1726,6 +2399,7 @@ var RedactoNoticeConsent = ({
|
|
|
1726
2399
|
}, [content, selectedDataElements]);
|
|
1727
2400
|
const acceptDisabled = isSubmitting || !areAllRequiredElementsChecked;
|
|
1728
2401
|
useEffect2(() => {
|
|
2402
|
+
var _a2, _b2;
|
|
1729
2403
|
clearApiCache();
|
|
1730
2404
|
isRequestInProgressRef.current = false;
|
|
1731
2405
|
setContent(null);
|
|
@@ -1741,6 +2415,8 @@ var RedactoNoticeConsent = ({
|
|
|
1741
2415
|
setIsSubmittingAccept(false);
|
|
1742
2416
|
setIsSubmittingDecline(false);
|
|
1743
2417
|
setShowAgeVerification(false);
|
|
2418
|
+
setIsMinorFlow(false);
|
|
2419
|
+
setSelfDeclaredAdult(false);
|
|
1744
2420
|
setShowGuardianForm(false);
|
|
1745
2421
|
setIsSubmittingGuardian(false);
|
|
1746
2422
|
setGuardianFormData({
|
|
@@ -1749,6 +2425,41 @@ var RedactoNoticeConsent = ({
|
|
|
1749
2425
|
guardianRelationship: ""
|
|
1750
2426
|
});
|
|
1751
2427
|
setGuardianFormErrors({});
|
|
2428
|
+
setShowVerificationScreen(false);
|
|
2429
|
+
setVerificationReference(null);
|
|
2430
|
+
setIsInitiatingVerification(false);
|
|
2431
|
+
setVerificationError(null);
|
|
2432
|
+
setVerificationErrorCode(null);
|
|
2433
|
+
setCanRetryVerification(false);
|
|
2434
|
+
setIsVerificationComplete(false);
|
|
2435
|
+
setIsAutoTransitioning(false);
|
|
2436
|
+
setIsPollingStatus(false);
|
|
2437
|
+
isPollingStatusRef.current = false;
|
|
2438
|
+
verificationSessionTokenRef.current = null;
|
|
2439
|
+
if (popupCheckIntervalRef.current) {
|
|
2440
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
2441
|
+
popupCheckIntervalRef.current = null;
|
|
2442
|
+
}
|
|
2443
|
+
if (statusPollIntervalRef.current) {
|
|
2444
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
2445
|
+
statusPollIntervalRef.current = null;
|
|
2446
|
+
}
|
|
2447
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
2448
|
+
pollingCleanupRef.current = null;
|
|
2449
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
2450
|
+
verificationPopupRef.current = null;
|
|
2451
|
+
if (autoTransitionTimerRef.current) {
|
|
2452
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
2453
|
+
autoTransitionTimerRef.current = null;
|
|
2454
|
+
}
|
|
2455
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
2456
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
2457
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
2458
|
+
}
|
|
2459
|
+
if (!isInitialMountRef.current) {
|
|
2460
|
+
clearConsentState();
|
|
2461
|
+
}
|
|
2462
|
+
isInitialMountRef.current = false;
|
|
1752
2463
|
}, [accessToken]);
|
|
1753
2464
|
useEffect2(() => {
|
|
1754
2465
|
if (hasAlreadyConsented) {
|
|
@@ -1957,7 +2668,11 @@ var RedactoNoticeConsent = ({
|
|
|
1957
2668
|
setInitialDataElementSelections({});
|
|
1958
2669
|
}
|
|
1959
2670
|
if (consentContentData.detail.is_minor) {
|
|
1960
|
-
|
|
2671
|
+
setIsMinorFlow(true);
|
|
2672
|
+
const persistedState = getConsentState();
|
|
2673
|
+
if (!(persistedState == null ? void 0 : persistedState.sessionToken) && !(persistedState == null ? void 0 : persistedState.verificationReference)) {
|
|
2674
|
+
setShowAgeVerification(true);
|
|
2675
|
+
}
|
|
1961
2676
|
}
|
|
1962
2677
|
setIsLoading(false);
|
|
1963
2678
|
} catch (err) {
|
|
@@ -2056,6 +2771,10 @@ var RedactoNoticeConsent = ({
|
|
|
2056
2771
|
const handleAccept = async () => {
|
|
2057
2772
|
const submitController = new AbortController();
|
|
2058
2773
|
try {
|
|
2774
|
+
if (isMinorFlow && !verificationReference) {
|
|
2775
|
+
setErrorMessage("Guardian verification is required before consent can be submitted.");
|
|
2776
|
+
return;
|
|
2777
|
+
}
|
|
2059
2778
|
setIsSubmittingAccept(true);
|
|
2060
2779
|
setIsSubmitting(true);
|
|
2061
2780
|
setErrorMessage(null);
|
|
@@ -2091,6 +2810,8 @@ var RedactoNoticeConsent = ({
|
|
|
2091
2810
|
}),
|
|
2092
2811
|
declined: false,
|
|
2093
2812
|
meta_data: applicationId ? { specific_uuid: applicationId } : void 0,
|
|
2813
|
+
guardianVerificationReference: verificationReference || void 0,
|
|
2814
|
+
selfDeclaredAdult: selfDeclaredAdult || void 0,
|
|
2094
2815
|
signal: submitController.signal
|
|
2095
2816
|
});
|
|
2096
2817
|
}
|
|
@@ -2155,17 +2876,102 @@ var RedactoNoticeConsent = ({
|
|
|
2155
2876
|
try {
|
|
2156
2877
|
setIsSubmittingGuardian(true);
|
|
2157
2878
|
setGuardianFormErrors({});
|
|
2158
|
-
|
|
2879
|
+
setVerificationError(null);
|
|
2880
|
+
const callbackUrl = digilockerMode === "popup" ? new URL(digilockerCallbackUrl, window.location.origin).href : void 0;
|
|
2881
|
+
const response = await initiateGuardianVerification({
|
|
2159
2882
|
accessToken,
|
|
2160
2883
|
baseUrl,
|
|
2161
2884
|
guardianName: guardianFormData.guardianName,
|
|
2162
2885
|
guardianContact: guardianFormData.guardianContact,
|
|
2163
2886
|
guardianRelationship: guardianFormData.guardianRelationship,
|
|
2887
|
+
frontendCallbackUrl: callbackUrl,
|
|
2888
|
+
// Only for popup mode
|
|
2164
2889
|
signal: guardianController.signal
|
|
2165
2890
|
});
|
|
2891
|
+
setIsSubmittingGuardian(false);
|
|
2892
|
+
if (response.already_verified && response.verification_reference) {
|
|
2893
|
+
setVerificationReference(response.verification_reference);
|
|
2894
|
+
setShowGuardianForm(false);
|
|
2895
|
+
setShowVerificationScreen(true);
|
|
2896
|
+
setIsInitiatingVerification(false);
|
|
2897
|
+
setIsVerificationComplete(true);
|
|
2898
|
+
setIsAutoTransitioning(true);
|
|
2899
|
+
autoTransitionTimerRef.current = setTimeout(() => {
|
|
2900
|
+
setShowVerificationScreen(false);
|
|
2901
|
+
setIsVerificationComplete(false);
|
|
2902
|
+
setIsAutoTransitioning(false);
|
|
2903
|
+
autoTransitionTimerRef.current = null;
|
|
2904
|
+
}, 1e3);
|
|
2905
|
+
return;
|
|
2906
|
+
}
|
|
2907
|
+
if (!response.session_token || !response.digilocker_redirect_url) {
|
|
2908
|
+
throw new Error("Invalid response from server: missing required fields");
|
|
2909
|
+
}
|
|
2166
2910
|
setShowGuardianForm(false);
|
|
2911
|
+
setShowVerificationScreen(true);
|
|
2912
|
+
setIsInitiatingVerification(true);
|
|
2913
|
+
if (digilockerMode === "redirect") {
|
|
2914
|
+
saveConsentState({
|
|
2915
|
+
flowState: "digilocker-pending",
|
|
2916
|
+
sessionToken: response.session_token,
|
|
2917
|
+
guardianInfoUuid: response.guardian_info_uuid,
|
|
2918
|
+
selectedPurposes,
|
|
2919
|
+
selectedDataElements,
|
|
2920
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2921
|
+
originalUrl: window.location.href,
|
|
2922
|
+
noticeId,
|
|
2923
|
+
baseUrl
|
|
2924
|
+
});
|
|
2925
|
+
try {
|
|
2926
|
+
const openedWindow = window.open(
|
|
2927
|
+
response.digilocker_redirect_url,
|
|
2928
|
+
"_blank"
|
|
2929
|
+
);
|
|
2930
|
+
if (!openedWindow) {
|
|
2931
|
+
console.warn("Popup blocked \u2014 cannot open DigiLocker in new tab");
|
|
2932
|
+
setIsInitiatingVerification(false);
|
|
2933
|
+
setVerificationError(
|
|
2934
|
+
"Unable to open DigiLocker in a new tab. Please allow popups for this site and try again."
|
|
2935
|
+
);
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
try {
|
|
2939
|
+
openedWindow.opener = null;
|
|
2940
|
+
} catch {
|
|
2941
|
+
}
|
|
2942
|
+
} catch (error) {
|
|
2943
|
+
console.error("Failed to open DigiLocker in new tab:", error);
|
|
2944
|
+
setIsInitiatingVerification(false);
|
|
2945
|
+
setVerificationError(
|
|
2946
|
+
"Unable to open DigiLocker. Please allow popups for this site and try again."
|
|
2947
|
+
);
|
|
2948
|
+
return;
|
|
2949
|
+
}
|
|
2950
|
+
setIsInitiatingVerification(false);
|
|
2951
|
+
setIsPollingStatus(true);
|
|
2952
|
+
isPollingStatusRef.current = true;
|
|
2953
|
+
startStatusPolling(response.session_token);
|
|
2954
|
+
} else {
|
|
2955
|
+
setIsInitiatingVerification(true);
|
|
2956
|
+
const popup = window.open(
|
|
2957
|
+
response.digilocker_redirect_url,
|
|
2958
|
+
"digilocker_verification",
|
|
2959
|
+
"width=600,height=700,scrollbars=yes,resizable=yes"
|
|
2960
|
+
);
|
|
2961
|
+
if (popup) {
|
|
2962
|
+
verificationPopupRef.current = popup;
|
|
2963
|
+
startPopupMonitoring(popup);
|
|
2964
|
+
startStatusPolling(response.session_token);
|
|
2965
|
+
} else {
|
|
2966
|
+
setIsInitiatingVerification(false);
|
|
2967
|
+
setVerificationError(
|
|
2968
|
+
"Popup blocked. Please allow popups for this site or use redirect mode."
|
|
2969
|
+
);
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2167
2972
|
} catch (error) {
|
|
2168
2973
|
const err = error;
|
|
2974
|
+
setIsInitiatingVerification(false);
|
|
2169
2975
|
if (err.status === 422) {
|
|
2170
2976
|
if (err.message.includes("guardian_contact")) {
|
|
2171
2977
|
setGuardianFormErrors({ guardianContact: err.message });
|
|
@@ -2176,23 +2982,265 @@ var RedactoNoticeConsent = ({
|
|
|
2176
2982
|
} else {
|
|
2177
2983
|
setGuardianFormErrors({ general: err.message });
|
|
2178
2984
|
}
|
|
2985
|
+
setShowVerificationScreen(false);
|
|
2986
|
+
setShowGuardianForm(true);
|
|
2179
2987
|
} else {
|
|
2180
2988
|
setGuardianFormErrors({
|
|
2181
|
-
general: err.message || "Failed to
|
|
2989
|
+
general: err.message || "Failed to initiate verification. Please try again."
|
|
2182
2990
|
});
|
|
2991
|
+
setShowVerificationScreen(false);
|
|
2992
|
+
setShowGuardianForm(true);
|
|
2183
2993
|
onError == null ? void 0 : onError(err);
|
|
2184
2994
|
}
|
|
2185
2995
|
} finally {
|
|
2186
2996
|
setIsSubmittingGuardian(false);
|
|
2187
2997
|
}
|
|
2188
|
-
}, [accessToken, baseUrl, guardianFormData, onError]);
|
|
2998
|
+
}, [accessToken, baseUrl, guardianFormData, digilockerMode, digilockerCallbackUrl, selectedPurposes, selectedDataElements, noticeId, onError]);
|
|
2189
2999
|
const handleAgeVerificationYes = useCallback(() => {
|
|
2190
3000
|
setShowAgeVerification(false);
|
|
3001
|
+
setIsMinorFlow(false);
|
|
3002
|
+
setSelfDeclaredAdult(true);
|
|
2191
3003
|
}, []);
|
|
2192
3004
|
const handleAgeVerificationNo = useCallback(() => {
|
|
2193
3005
|
setShowAgeVerification(false);
|
|
2194
3006
|
setShowGuardianForm(true);
|
|
2195
3007
|
}, []);
|
|
3008
|
+
const handleVerificationContinue = useCallback(() => {
|
|
3009
|
+
setShowVerificationScreen(false);
|
|
3010
|
+
setIsVerificationComplete(false);
|
|
3011
|
+
}, []);
|
|
3012
|
+
const handlePopupClosed = useCallback(async () => {
|
|
3013
|
+
var _a2, _b2;
|
|
3014
|
+
if (popupCheckIntervalRef.current) {
|
|
3015
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3016
|
+
popupCheckIntervalRef.current = null;
|
|
3017
|
+
}
|
|
3018
|
+
if (statusPollIntervalRef.current) {
|
|
3019
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3020
|
+
statusPollIntervalRef.current = null;
|
|
3021
|
+
}
|
|
3022
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3023
|
+
pollingCleanupRef.current = null;
|
|
3024
|
+
verificationPopupRef.current = null;
|
|
3025
|
+
if (!isPollingStatusRef.current) return;
|
|
3026
|
+
const sessionToken = verificationSessionTokenRef.current;
|
|
3027
|
+
if (sessionToken) {
|
|
3028
|
+
try {
|
|
3029
|
+
const response = await verifyGuardianStatus({
|
|
3030
|
+
accessToken,
|
|
3031
|
+
baseUrl,
|
|
3032
|
+
sessionToken
|
|
3033
|
+
});
|
|
3034
|
+
if (response.status === "verified") {
|
|
3035
|
+
const ref = response.verification_reference || ((_b2 = response.guardian_details) == null ? void 0 : _b2.verification_reference);
|
|
3036
|
+
if (ref) {
|
|
3037
|
+
setVerificationReference(ref);
|
|
3038
|
+
setIsVerificationComplete(true);
|
|
3039
|
+
setIsPollingStatus(false);
|
|
3040
|
+
isPollingStatusRef.current = false;
|
|
3041
|
+
setIsInitiatingVerification(false);
|
|
3042
|
+
clearConsentState();
|
|
3043
|
+
return;
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
} catch {
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
setVerificationError(
|
|
3050
|
+
"Verification window was closed. Please try again."
|
|
3051
|
+
);
|
|
3052
|
+
setIsPollingStatus(false);
|
|
3053
|
+
isPollingStatusRef.current = false;
|
|
3054
|
+
setIsInitiatingVerification(false);
|
|
3055
|
+
}, [accessToken, baseUrl]);
|
|
3056
|
+
const startPopupMonitoring = useCallback((popup) => {
|
|
3057
|
+
popupCheckIntervalRef.current = window.setInterval(() => {
|
|
3058
|
+
if (popup.closed) {
|
|
3059
|
+
handlePopupClosed();
|
|
3060
|
+
}
|
|
3061
|
+
}, 500);
|
|
3062
|
+
}, [handlePopupClosed]);
|
|
3063
|
+
const getVerificationErrorMessage = useCallback(
|
|
3064
|
+
(errorCode, fallbackError) => {
|
|
3065
|
+
switch (errorCode) {
|
|
3066
|
+
case "GUARDIAN_UNDER_18":
|
|
3067
|
+
return "The guardian must be 18 years or older. Please provide details of a different guardian.";
|
|
3068
|
+
case "TOKEN_FAILED":
|
|
3069
|
+
return "DigiLocker verification could not be completed. Please try again.";
|
|
3070
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
3071
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
3072
|
+
case "NO_AUTH_CODE":
|
|
3073
|
+
return "DigiLocker did not return an authorization code. Please try again.";
|
|
3074
|
+
case "SESSION_EXPIRED":
|
|
3075
|
+
return "Verification session has expired. Please try again.";
|
|
3076
|
+
default:
|
|
3077
|
+
return fallbackError || "Verification failed. Please try again.";
|
|
3078
|
+
}
|
|
3079
|
+
},
|
|
3080
|
+
[]
|
|
3081
|
+
);
|
|
3082
|
+
const startStatusPolling = useCallback(
|
|
3083
|
+
(token) => {
|
|
3084
|
+
verificationSessionTokenRef.current = token;
|
|
3085
|
+
setIsPollingStatus(true);
|
|
3086
|
+
isPollingStatusRef.current = true;
|
|
3087
|
+
setVerificationError(null);
|
|
3088
|
+
setVerificationErrorCode(null);
|
|
3089
|
+
setCanRetryVerification(false);
|
|
3090
|
+
let attempts = 0;
|
|
3091
|
+
let consecutiveErrors = 0;
|
|
3092
|
+
let paused = false;
|
|
3093
|
+
const MAX_ATTEMPTS = 40;
|
|
3094
|
+
const MAX_CONSECUTIVE_ERRORS = 3;
|
|
3095
|
+
const POLL_INTERVAL = 3e3;
|
|
3096
|
+
const stopPolling = () => {
|
|
3097
|
+
var _a2;
|
|
3098
|
+
if (statusPollIntervalRef.current) {
|
|
3099
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3100
|
+
statusPollIntervalRef.current = null;
|
|
3101
|
+
}
|
|
3102
|
+
if (popupCheckIntervalRef.current) {
|
|
3103
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3104
|
+
popupCheckIntervalRef.current = null;
|
|
3105
|
+
}
|
|
3106
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3107
|
+
verificationPopupRef.current = null;
|
|
3108
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3109
|
+
pollingCleanupRef.current = null;
|
|
3110
|
+
setIsPollingStatus(false);
|
|
3111
|
+
isPollingStatusRef.current = false;
|
|
3112
|
+
setIsInitiatingVerification(false);
|
|
3113
|
+
};
|
|
3114
|
+
const setError = (message, errorCode, canRetry) => {
|
|
3115
|
+
stopPolling();
|
|
3116
|
+
setVerificationError(message);
|
|
3117
|
+
setVerificationErrorCode(errorCode);
|
|
3118
|
+
setCanRetryVerification(canRetry);
|
|
3119
|
+
};
|
|
3120
|
+
const poll = async () => {
|
|
3121
|
+
var _a2;
|
|
3122
|
+
if (paused) return;
|
|
3123
|
+
attempts++;
|
|
3124
|
+
if (attempts > MAX_ATTEMPTS) {
|
|
3125
|
+
setError(
|
|
3126
|
+
"Verification is taking longer than expected. Please try again.",
|
|
3127
|
+
"SESSION_EXPIRED",
|
|
3128
|
+
true
|
|
3129
|
+
);
|
|
3130
|
+
return;
|
|
3131
|
+
}
|
|
3132
|
+
try {
|
|
3133
|
+
const response = await verifyGuardianStatus({
|
|
3134
|
+
accessToken,
|
|
3135
|
+
baseUrl,
|
|
3136
|
+
sessionToken: token
|
|
3137
|
+
});
|
|
3138
|
+
consecutiveErrors = 0;
|
|
3139
|
+
if (response.status === "verified") {
|
|
3140
|
+
stopPolling();
|
|
3141
|
+
const ref = response.verification_reference || ((_a2 = response.guardian_details) == null ? void 0 : _a2.verification_reference);
|
|
3142
|
+
if (!ref) {
|
|
3143
|
+
setError(
|
|
3144
|
+
"Verification completed but no reference received. Please try again.",
|
|
3145
|
+
null,
|
|
3146
|
+
true
|
|
3147
|
+
);
|
|
3148
|
+
return;
|
|
3149
|
+
}
|
|
3150
|
+
setVerificationReference(ref);
|
|
3151
|
+
setIsVerificationComplete(true);
|
|
3152
|
+
clearConsentState();
|
|
3153
|
+
return;
|
|
3154
|
+
}
|
|
3155
|
+
if (response.status === "failed" || response.status === "expired") {
|
|
3156
|
+
setError(
|
|
3157
|
+
getVerificationErrorMessage(response.error_code, response.error),
|
|
3158
|
+
response.error_code,
|
|
3159
|
+
response.can_retry
|
|
3160
|
+
);
|
|
3161
|
+
return;
|
|
3162
|
+
}
|
|
3163
|
+
if (!paused) {
|
|
3164
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3165
|
+
}
|
|
3166
|
+
} catch (error) {
|
|
3167
|
+
const err = error;
|
|
3168
|
+
if (err.status === 404 || err.status === 410) {
|
|
3169
|
+
setError(
|
|
3170
|
+
"Verification session not found or expired. Please try again.",
|
|
3171
|
+
"SESSION_EXPIRED",
|
|
3172
|
+
true
|
|
3173
|
+
);
|
|
3174
|
+
return;
|
|
3175
|
+
}
|
|
3176
|
+
consecutiveErrors++;
|
|
3177
|
+
if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) {
|
|
3178
|
+
setError(
|
|
3179
|
+
err.message || "Unable to check verification status. Please try again.",
|
|
3180
|
+
null,
|
|
3181
|
+
true
|
|
3182
|
+
);
|
|
3183
|
+
return;
|
|
3184
|
+
}
|
|
3185
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3186
|
+
}
|
|
3187
|
+
};
|
|
3188
|
+
const onVisibilityChange = () => {
|
|
3189
|
+
if (document.hidden) {
|
|
3190
|
+
paused = true;
|
|
3191
|
+
if (statusPollIntervalRef.current) {
|
|
3192
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3193
|
+
statusPollIntervalRef.current = null;
|
|
3194
|
+
}
|
|
3195
|
+
} else {
|
|
3196
|
+
paused = false;
|
|
3197
|
+
poll();
|
|
3198
|
+
}
|
|
3199
|
+
};
|
|
3200
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
3201
|
+
pollingCleanupRef.current = () => {
|
|
3202
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
3203
|
+
};
|
|
3204
|
+
statusPollIntervalRef.current = window.setTimeout(poll, POLL_INTERVAL);
|
|
3205
|
+
},
|
|
3206
|
+
[accessToken, baseUrl, getVerificationErrorMessage]
|
|
3207
|
+
);
|
|
3208
|
+
const handleBackToGuardianForm = useCallback((clearName = false) => {
|
|
3209
|
+
var _a2, _b2;
|
|
3210
|
+
(_a2 = verificationPopupRef.current) == null ? void 0 : _a2.close();
|
|
3211
|
+
verificationPopupRef.current = null;
|
|
3212
|
+
if (popupCheckIntervalRef.current) {
|
|
3213
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3214
|
+
popupCheckIntervalRef.current = null;
|
|
3215
|
+
}
|
|
3216
|
+
if (statusPollIntervalRef.current) {
|
|
3217
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3218
|
+
statusPollIntervalRef.current = null;
|
|
3219
|
+
}
|
|
3220
|
+
if (autoTransitionTimerRef.current) {
|
|
3221
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3222
|
+
autoTransitionTimerRef.current = null;
|
|
3223
|
+
}
|
|
3224
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3225
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3226
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3227
|
+
}
|
|
3228
|
+
(_b2 = pollingCleanupRef.current) == null ? void 0 : _b2.call(pollingCleanupRef);
|
|
3229
|
+
pollingCleanupRef.current = null;
|
|
3230
|
+
setShowVerificationScreen(false);
|
|
3231
|
+
setShowGuardianForm(true);
|
|
3232
|
+
setVerificationError(null);
|
|
3233
|
+
setVerificationErrorCode(null);
|
|
3234
|
+
setCanRetryVerification(false);
|
|
3235
|
+
setIsInitiatingVerification(false);
|
|
3236
|
+
setIsPollingStatus(false);
|
|
3237
|
+
isPollingStatusRef.current = false;
|
|
3238
|
+
setIsVerificationComplete(false);
|
|
3239
|
+
if (clearName) {
|
|
3240
|
+
setGuardianFormData((prev) => ({ ...prev, guardianName: "" }));
|
|
3241
|
+
}
|
|
3242
|
+
clearConsentState();
|
|
3243
|
+
}, []);
|
|
2196
3244
|
const availableLanguages = useMemo(() => {
|
|
2197
3245
|
if (!content) return [language];
|
|
2198
3246
|
const languages = ["English"];
|
|
@@ -2602,12 +3650,67 @@ var RedactoNoticeConsent = ({
|
|
|
2602
3650
|
}, [content, stopAudio]);
|
|
2603
3651
|
useEffect2(() => {
|
|
2604
3652
|
return () => {
|
|
3653
|
+
var _a2, _b2;
|
|
2605
3654
|
if (abortControllerRef.current) {
|
|
2606
3655
|
abortControllerRef.current.abort();
|
|
2607
3656
|
}
|
|
2608
3657
|
stopAudio();
|
|
3658
|
+
if (popupCheckIntervalRef.current) {
|
|
3659
|
+
clearInterval(popupCheckIntervalRef.current);
|
|
3660
|
+
}
|
|
3661
|
+
if (statusPollIntervalRef.current) {
|
|
3662
|
+
clearTimeout(statusPollIntervalRef.current);
|
|
3663
|
+
}
|
|
3664
|
+
(_a2 = pollingCleanupRef.current) == null ? void 0 : _a2.call(pollingCleanupRef);
|
|
3665
|
+
pollingCleanupRef.current = null;
|
|
3666
|
+
(_b2 = verificationPopupRef.current) == null ? void 0 : _b2.close();
|
|
3667
|
+
if (autoTransitionTimerRef.current) {
|
|
3668
|
+
clearTimeout(autoTransitionTimerRef.current);
|
|
3669
|
+
autoTransitionTimerRef.current = null;
|
|
3670
|
+
}
|
|
3671
|
+
if (digilockerRedirectTimeoutRef.current) {
|
|
3672
|
+
clearTimeout(digilockerRedirectTimeoutRef.current);
|
|
3673
|
+
digilockerRedirectTimeoutRef.current = null;
|
|
3674
|
+
}
|
|
2609
3675
|
};
|
|
2610
3676
|
}, [stopAudio]);
|
|
3677
|
+
useEffect2(() => {
|
|
3678
|
+
const persistedState = getConsentState();
|
|
3679
|
+
if (!persistedState) return;
|
|
3680
|
+
if (persistedState.noticeId && persistedState.noticeId !== noticeId) {
|
|
3681
|
+
clearConsentState();
|
|
3682
|
+
return;
|
|
3683
|
+
}
|
|
3684
|
+
const REDIRECT_STATE_MAX_AGE_MS = 15 * 60 * 1e3;
|
|
3685
|
+
if (persistedState.timestamp) {
|
|
3686
|
+
const stateAge = Date.now() - new Date(persistedState.timestamp).getTime();
|
|
3687
|
+
if (stateAge > REDIRECT_STATE_MAX_AGE_MS) {
|
|
3688
|
+
clearConsentState();
|
|
3689
|
+
return;
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
if (persistedState.flowState === "digilocker-pending" && persistedState.sessionToken) {
|
|
3693
|
+
setShowVerificationScreen(true);
|
|
3694
|
+
setShowGuardianForm(false);
|
|
3695
|
+
setShowAgeVerification(false);
|
|
3696
|
+
startStatusPolling(persistedState.sessionToken);
|
|
3697
|
+
} else if (persistedState.verificationResult === "verified" && persistedState.verificationReference) {
|
|
3698
|
+
setVerificationReference(persistedState.verificationReference);
|
|
3699
|
+
setShowVerificationScreen(true);
|
|
3700
|
+
setIsVerificationComplete(true);
|
|
3701
|
+
setShowGuardianForm(false);
|
|
3702
|
+
setShowAgeVerification(false);
|
|
3703
|
+
clearConsentState();
|
|
3704
|
+
} else if (persistedState.verificationResult === "failed" || persistedState.verificationResult === "expired") {
|
|
3705
|
+
setShowVerificationScreen(true);
|
|
3706
|
+
setShowGuardianForm(false);
|
|
3707
|
+
setShowAgeVerification(false);
|
|
3708
|
+
setVerificationError(
|
|
3709
|
+
persistedState.verificationResult === "expired" ? "Verification session has expired. Please try again." : "Verification failed. Please try again."
|
|
3710
|
+
);
|
|
3711
|
+
clearConsentState();
|
|
3712
|
+
}
|
|
3713
|
+
}, [startStatusPolling, noticeId]);
|
|
2611
3714
|
return /* @__PURE__ */ jsx(Fragment, { children: hasAlreadyConsented ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2612
3715
|
blockUI && /* @__PURE__ */ jsx(
|
|
2613
3716
|
"div",
|
|
@@ -2793,6 +3896,27 @@ var RedactoNoticeConsent = ({
|
|
|
2793
3896
|
declineButtonStyle,
|
|
2794
3897
|
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
2795
3898
|
}
|
|
3899
|
+
) }) : showVerificationScreen ? /* @__PURE__ */ jsx("div", { style: { ...styles.content, ...responsiveStyles.content }, children: /* @__PURE__ */ jsx(
|
|
3900
|
+
VerificationScreen,
|
|
3901
|
+
{
|
|
3902
|
+
onBack: handleBackToGuardianForm,
|
|
3903
|
+
onContinue: handleVerificationContinue,
|
|
3904
|
+
isInitiating: isInitiatingVerification,
|
|
3905
|
+
isPolling: isPollingStatus,
|
|
3906
|
+
isVerificationComplete,
|
|
3907
|
+
isAutoTransitioning,
|
|
3908
|
+
error: verificationError,
|
|
3909
|
+
errorCode: verificationErrorCode,
|
|
3910
|
+
canRetry: canRetryVerification,
|
|
3911
|
+
styles,
|
|
3912
|
+
responsiveStyles,
|
|
3913
|
+
settings,
|
|
3914
|
+
componentHeadingStyle,
|
|
3915
|
+
componentTextStyle,
|
|
3916
|
+
acceptButtonStyle,
|
|
3917
|
+
declineButtonStyle,
|
|
3918
|
+
logoUrl: (content == null ? void 0 : content.logo_url) || redacto_logo_default
|
|
3919
|
+
}
|
|
2796
3920
|
) }) : /* @__PURE__ */ jsxs("div", { style: { ...styles.content, ...responsiveStyles.content }, children: [
|
|
2797
3921
|
errorMessage && /* @__PURE__ */ jsxs(
|
|
2798
3922
|
"div",
|
|
@@ -4396,7 +5520,424 @@ var RedactoConsentInlineComponent = ({
|
|
|
4396
5520
|
};
|
|
4397
5521
|
RedactoConsentInlineComponent.displayName = "RedactoConsentInline";
|
|
4398
5522
|
var RedactoConsentInline = memo(RedactoConsentInlineComponent);
|
|
5523
|
+
|
|
5524
|
+
// src/RedactoNoticeConsent/components/DigiLockerCallback.tsx
|
|
5525
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef3, useState as useState5 } from "react";
|
|
5526
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5527
|
+
var DigiLockerCallback = ({
|
|
5528
|
+
accessToken: propAccessToken,
|
|
5529
|
+
baseUrl,
|
|
5530
|
+
onSuccess,
|
|
5531
|
+
onError
|
|
5532
|
+
}) => {
|
|
5533
|
+
const [status, setStatus] = useState5("processing");
|
|
5534
|
+
const [message, setMessage] = useState5("Verifying your guardian...");
|
|
5535
|
+
const [errorDetail, setErrorDetail] = useState5(null);
|
|
5536
|
+
const retryTimeoutRef = useRef3(null);
|
|
5537
|
+
const redirectTimeoutRef = useRef3(null);
|
|
5538
|
+
const isMountedRef = useRef3(true);
|
|
5539
|
+
const getErrorMessage = (errorCode) => {
|
|
5540
|
+
switch (errorCode) {
|
|
5541
|
+
case "GUARDIAN_UNDER_18":
|
|
5542
|
+
return "Guardian verification failed: The guardian must be 18 years or older.";
|
|
5543
|
+
case "SESSION_EXPIRED":
|
|
5544
|
+
return "Verification session has expired. Please restart the verification process.";
|
|
5545
|
+
case "TOKEN_FAILED":
|
|
5546
|
+
return "DigiLocker authentication failed. Please try again.";
|
|
5547
|
+
case "DIGILOCKER_AUTH_FAILED":
|
|
5548
|
+
return "DigiLocker authorization was cancelled or failed. Please try again.";
|
|
5549
|
+
case "NO_AUTH_CODE":
|
|
5550
|
+
return "Missing authorization code from DigiLocker. Please try again.";
|
|
5551
|
+
default:
|
|
5552
|
+
return "Verification failed. Please try again.";
|
|
5553
|
+
}
|
|
5554
|
+
};
|
|
5555
|
+
const redirectToOriginalPage = useCallback3(
|
|
5556
|
+
(originalUrl, verificationResult, verificationReference) => {
|
|
5557
|
+
updateConsentState({
|
|
5558
|
+
verificationResult,
|
|
5559
|
+
verificationReference,
|
|
5560
|
+
flowState: verificationResult === "verified" ? "consent-form" : "error"
|
|
5561
|
+
});
|
|
5562
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5563
|
+
window.location.href = originalUrl;
|
|
5564
|
+
}, 1500);
|
|
5565
|
+
},
|
|
5566
|
+
[]
|
|
5567
|
+
);
|
|
5568
|
+
const handleCallback = useCallback3(async () => {
|
|
5569
|
+
var _a, _b;
|
|
5570
|
+
try {
|
|
5571
|
+
const params = new URLSearchParams(window.location.search);
|
|
5572
|
+
const sessionToken = params.get("session_token");
|
|
5573
|
+
const urlStatus = params.get("status");
|
|
5574
|
+
const verificationReference = params.get("verification_reference");
|
|
5575
|
+
const errorCode = params.get("error_code");
|
|
5576
|
+
const persistedState = getConsentState();
|
|
5577
|
+
const originalUrl = (persistedState == null ? void 0 : persistedState.originalUrl) || "/";
|
|
5578
|
+
const storedBaseUrl = persistedState == null ? void 0 : persistedState.baseUrl;
|
|
5579
|
+
const storedSessionToken = persistedState == null ? void 0 : persistedState.sessionToken;
|
|
5580
|
+
const accessToken = propAccessToken;
|
|
5581
|
+
if (!accessToken) {
|
|
5582
|
+
throw new Error("Access token not provided. Please pass accessToken as a prop.");
|
|
5583
|
+
}
|
|
5584
|
+
const activeSessionToken = sessionToken || storedSessionToken;
|
|
5585
|
+
if (!activeSessionToken) {
|
|
5586
|
+
throw new Error("Session token not found. Please restart the verification process.");
|
|
5587
|
+
}
|
|
5588
|
+
let isInIframe = false;
|
|
5589
|
+
try {
|
|
5590
|
+
isInIframe = window.self !== window.top;
|
|
5591
|
+
} catch {
|
|
5592
|
+
isInIframe = true;
|
|
5593
|
+
}
|
|
5594
|
+
if (urlStatus === "verified" && verificationReference) {
|
|
5595
|
+
setStatus("success");
|
|
5596
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5597
|
+
onSuccess == null ? void 0 : onSuccess(verificationReference);
|
|
5598
|
+
if (isInIframe && window.parent) {
|
|
5599
|
+
window.parent.postMessage(
|
|
5600
|
+
{
|
|
5601
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5602
|
+
status: "verified",
|
|
5603
|
+
verificationReference
|
|
5604
|
+
},
|
|
5605
|
+
window.location.origin
|
|
5606
|
+
);
|
|
5607
|
+
return;
|
|
5608
|
+
}
|
|
5609
|
+
redirectToOriginalPage(originalUrl, "verified", verificationReference);
|
|
5610
|
+
return;
|
|
5611
|
+
}
|
|
5612
|
+
if (urlStatus === "failed" || urlStatus === "expired") {
|
|
5613
|
+
const urlErrorCode = errorCode != null ? errorCode : void 0;
|
|
5614
|
+
const errorMessage = getErrorMessage(urlErrorCode);
|
|
5615
|
+
setStatus("error");
|
|
5616
|
+
setMessage("Verification failed");
|
|
5617
|
+
setErrorDetail(errorMessage);
|
|
5618
|
+
onError == null ? void 0 : onError(new Error(errorMessage), urlErrorCode);
|
|
5619
|
+
if (isInIframe && window.parent) {
|
|
5620
|
+
window.parent.postMessage(
|
|
5621
|
+
{
|
|
5622
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5623
|
+
status: urlStatus,
|
|
5624
|
+
errorCode: urlErrorCode,
|
|
5625
|
+
error: errorMessage
|
|
5626
|
+
},
|
|
5627
|
+
window.location.origin
|
|
5628
|
+
);
|
|
5629
|
+
return;
|
|
5630
|
+
}
|
|
5631
|
+
redirectToOriginalPage(originalUrl, urlStatus);
|
|
5632
|
+
return;
|
|
5633
|
+
}
|
|
5634
|
+
setMessage("Processing verification...");
|
|
5635
|
+
const apiBaseUrl = baseUrl || storedBaseUrl;
|
|
5636
|
+
const response = await verifyGuardianStatus({
|
|
5637
|
+
accessToken,
|
|
5638
|
+
baseUrl: apiBaseUrl,
|
|
5639
|
+
sessionToken: activeSessionToken
|
|
5640
|
+
});
|
|
5641
|
+
if (!isMountedRef.current) return;
|
|
5642
|
+
if (response.status === "verified") {
|
|
5643
|
+
const verificationRef = response.verification_reference || ((_a = response.guardian_details) == null ? void 0 : _a.verification_reference) || void 0;
|
|
5644
|
+
if (!verificationRef) {
|
|
5645
|
+
setStatus("error");
|
|
5646
|
+
setMessage("Verification failed");
|
|
5647
|
+
setErrorDetail("Verification completed but no reference received. Please try again.");
|
|
5648
|
+
onError == null ? void 0 : onError(new Error("Verification completed but no reference received."));
|
|
5649
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5650
|
+
return;
|
|
5651
|
+
}
|
|
5652
|
+
setStatus("success");
|
|
5653
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5654
|
+
onSuccess == null ? void 0 : onSuccess(verificationRef);
|
|
5655
|
+
if (isInIframe && window.parent) {
|
|
5656
|
+
window.parent.postMessage(
|
|
5657
|
+
{
|
|
5658
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5659
|
+
status: "verified",
|
|
5660
|
+
verificationReference: verificationRef
|
|
5661
|
+
},
|
|
5662
|
+
window.location.origin
|
|
5663
|
+
);
|
|
5664
|
+
return;
|
|
5665
|
+
}
|
|
5666
|
+
redirectToOriginalPage(originalUrl, "verified", verificationRef);
|
|
5667
|
+
} else if (response.status === "failed" || response.status === "expired") {
|
|
5668
|
+
const responseErrorCode = (_b = response.error_code) != null ? _b : void 0;
|
|
5669
|
+
const errorMessage = response.error || getErrorMessage(responseErrorCode);
|
|
5670
|
+
setStatus("error");
|
|
5671
|
+
setMessage("Verification failed");
|
|
5672
|
+
setErrorDetail(errorMessage);
|
|
5673
|
+
onError == null ? void 0 : onError(new Error(errorMessage), responseErrorCode);
|
|
5674
|
+
if (isInIframe && window.parent) {
|
|
5675
|
+
window.parent.postMessage(
|
|
5676
|
+
{
|
|
5677
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5678
|
+
status: response.status,
|
|
5679
|
+
errorCode: responseErrorCode,
|
|
5680
|
+
error: errorMessage
|
|
5681
|
+
},
|
|
5682
|
+
window.location.origin
|
|
5683
|
+
);
|
|
5684
|
+
return;
|
|
5685
|
+
}
|
|
5686
|
+
redirectToOriginalPage(originalUrl, response.status);
|
|
5687
|
+
} else {
|
|
5688
|
+
setMessage("Verification is still in progress. Please wait...");
|
|
5689
|
+
const MAX_RETRIES = 3;
|
|
5690
|
+
let retryCount = 0;
|
|
5691
|
+
const attemptRetry = () => {
|
|
5692
|
+
retryCount++;
|
|
5693
|
+
const delay = 3e3 * Math.pow(2, retryCount - 1);
|
|
5694
|
+
retryTimeoutRef.current = setTimeout(async () => {
|
|
5695
|
+
var _a2, _b2;
|
|
5696
|
+
if (!isMountedRef.current) return;
|
|
5697
|
+
try {
|
|
5698
|
+
const retryResponse = await verifyGuardianStatus({
|
|
5699
|
+
accessToken,
|
|
5700
|
+
baseUrl: apiBaseUrl,
|
|
5701
|
+
sessionToken: activeSessionToken
|
|
5702
|
+
});
|
|
5703
|
+
if (!isMountedRef.current) return;
|
|
5704
|
+
const retryRef = retryResponse.verification_reference || ((_a2 = retryResponse.guardian_details) == null ? void 0 : _a2.verification_reference) || void 0;
|
|
5705
|
+
if (retryResponse.status === "verified" && retryRef) {
|
|
5706
|
+
setStatus("success");
|
|
5707
|
+
setMessage("Guardian verified successfully! Redirecting...");
|
|
5708
|
+
onSuccess == null ? void 0 : onSuccess(retryRef);
|
|
5709
|
+
if (isInIframe && window.parent) {
|
|
5710
|
+
window.parent.postMessage(
|
|
5711
|
+
{
|
|
5712
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5713
|
+
status: "verified",
|
|
5714
|
+
verificationReference: retryRef
|
|
5715
|
+
},
|
|
5716
|
+
window.location.origin
|
|
5717
|
+
);
|
|
5718
|
+
return;
|
|
5719
|
+
}
|
|
5720
|
+
redirectToOriginalPage(originalUrl, "verified", retryRef);
|
|
5721
|
+
} else if (retryResponse.status === "failed" || retryResponse.status === "expired") {
|
|
5722
|
+
const retryErrorCode = (_b2 = retryResponse.error_code) != null ? _b2 : void 0;
|
|
5723
|
+
const retryErrorMessage = retryResponse.error || getErrorMessage(retryErrorCode) || "Verification could not be completed. Please try again.";
|
|
5724
|
+
setStatus("error");
|
|
5725
|
+
setMessage("Verification failed");
|
|
5726
|
+
setErrorDetail(retryErrorMessage);
|
|
5727
|
+
onError == null ? void 0 : onError(new Error(retryErrorMessage), retryErrorCode);
|
|
5728
|
+
if (isInIframe && window.parent) {
|
|
5729
|
+
window.parent.postMessage(
|
|
5730
|
+
{
|
|
5731
|
+
type: "DIGILOCKER_VERIFICATION_STATUS",
|
|
5732
|
+
status: retryResponse.status,
|
|
5733
|
+
errorCode: retryErrorCode,
|
|
5734
|
+
error: retryErrorMessage
|
|
5735
|
+
},
|
|
5736
|
+
window.location.origin
|
|
5737
|
+
);
|
|
5738
|
+
return;
|
|
5739
|
+
}
|
|
5740
|
+
redirectToOriginalPage(originalUrl, retryResponse.status);
|
|
5741
|
+
} else if (retryCount < MAX_RETRIES) {
|
|
5742
|
+
setMessage("Verification taking longer than expected. Please wait...");
|
|
5743
|
+
attemptRetry();
|
|
5744
|
+
} else {
|
|
5745
|
+
const timeoutMessage = "Verification could not be completed in time. Please try again.";
|
|
5746
|
+
setStatus("error");
|
|
5747
|
+
setMessage("Verification failed");
|
|
5748
|
+
setErrorDetail(timeoutMessage);
|
|
5749
|
+
onError == null ? void 0 : onError(new Error(timeoutMessage));
|
|
5750
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5751
|
+
}
|
|
5752
|
+
} catch (retryErr) {
|
|
5753
|
+
if (!isMountedRef.current) return;
|
|
5754
|
+
if (retryCount < MAX_RETRIES) {
|
|
5755
|
+
attemptRetry();
|
|
5756
|
+
} else {
|
|
5757
|
+
setStatus("error");
|
|
5758
|
+
setMessage("Verification failed");
|
|
5759
|
+
setErrorDetail(retryErr.message);
|
|
5760
|
+
onError == null ? void 0 : onError(retryErr);
|
|
5761
|
+
redirectToOriginalPage(originalUrl, "failed");
|
|
5762
|
+
}
|
|
5763
|
+
}
|
|
5764
|
+
}, delay);
|
|
5765
|
+
};
|
|
5766
|
+
attemptRetry();
|
|
5767
|
+
}
|
|
5768
|
+
} catch (error) {
|
|
5769
|
+
console.error("DigiLocker callback error:", error);
|
|
5770
|
+
setStatus("error");
|
|
5771
|
+
const err = error;
|
|
5772
|
+
setMessage("Verification failed");
|
|
5773
|
+
setErrorDetail(err.message || "An error occurred during verification");
|
|
5774
|
+
onError == null ? void 0 : onError(err);
|
|
5775
|
+
const persistedState = getConsentState();
|
|
5776
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5777
|
+
redirectTimeoutRef.current = setTimeout(() => {
|
|
5778
|
+
redirectToOriginalPage(persistedState.originalUrl, "failed");
|
|
5779
|
+
}, 3e3);
|
|
5780
|
+
}
|
|
5781
|
+
}
|
|
5782
|
+
}, [propAccessToken, baseUrl, onSuccess, onError, redirectToOriginalPage]);
|
|
5783
|
+
useEffect5(() => {
|
|
5784
|
+
injectCheckboxStyles();
|
|
5785
|
+
handleCallback();
|
|
5786
|
+
return () => {
|
|
5787
|
+
isMountedRef.current = false;
|
|
5788
|
+
if (retryTimeoutRef.current) clearTimeout(retryTimeoutRef.current);
|
|
5789
|
+
if (redirectTimeoutRef.current) clearTimeout(redirectTimeoutRef.current);
|
|
5790
|
+
};
|
|
5791
|
+
}, [handleCallback]);
|
|
5792
|
+
const handleRetry = useCallback3(() => {
|
|
5793
|
+
const persistedState = getConsentState();
|
|
5794
|
+
if (persistedState == null ? void 0 : persistedState.originalUrl) {
|
|
5795
|
+
clearConsentState();
|
|
5796
|
+
window.location.href = persistedState.originalUrl;
|
|
5797
|
+
} else {
|
|
5798
|
+
window.location.href = "/";
|
|
5799
|
+
}
|
|
5800
|
+
}, []);
|
|
5801
|
+
const containerStyle = {
|
|
5802
|
+
display: "flex",
|
|
5803
|
+
alignItems: "center",
|
|
5804
|
+
justifyContent: "center",
|
|
5805
|
+
minHeight: "100vh",
|
|
5806
|
+
backgroundColor: "#f9fafb",
|
|
5807
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
|
|
5808
|
+
padding: "20px",
|
|
5809
|
+
boxSizing: "border-box"
|
|
5810
|
+
};
|
|
5811
|
+
const cardStyle = {
|
|
5812
|
+
backgroundColor: "#ffffff",
|
|
5813
|
+
borderRadius: "12px",
|
|
5814
|
+
boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
|
|
5815
|
+
padding: "40px",
|
|
5816
|
+
textAlign: "center",
|
|
5817
|
+
maxWidth: "400px",
|
|
5818
|
+
width: "100%"
|
|
5819
|
+
};
|
|
5820
|
+
const spinnerStyle = {
|
|
5821
|
+
width: "48px",
|
|
5822
|
+
height: "48px",
|
|
5823
|
+
border: "4px solid #e5e7eb",
|
|
5824
|
+
borderTopColor: "#3b82f6",
|
|
5825
|
+
borderRadius: "50%",
|
|
5826
|
+
animation: "spin 1s linear infinite",
|
|
5827
|
+
margin: "0 auto 24px"
|
|
5828
|
+
};
|
|
5829
|
+
const iconStyle = {
|
|
5830
|
+
width: "64px",
|
|
5831
|
+
height: "64px",
|
|
5832
|
+
borderRadius: "50%",
|
|
5833
|
+
display: "flex",
|
|
5834
|
+
alignItems: "center",
|
|
5835
|
+
justifyContent: "center",
|
|
5836
|
+
margin: "0 auto 24px"
|
|
5837
|
+
};
|
|
5838
|
+
const successIconStyle = {
|
|
5839
|
+
...iconStyle,
|
|
5840
|
+
backgroundColor: "#d1fae5",
|
|
5841
|
+
color: "#059669"
|
|
5842
|
+
};
|
|
5843
|
+
const errorIconStyle = {
|
|
5844
|
+
...iconStyle,
|
|
5845
|
+
backgroundColor: "#fee2e2",
|
|
5846
|
+
color: "#dc2626"
|
|
5847
|
+
};
|
|
5848
|
+
const titleStyle = {
|
|
5849
|
+
fontSize: "20px",
|
|
5850
|
+
fontWeight: 600,
|
|
5851
|
+
color: "#111827",
|
|
5852
|
+
margin: "0 0 12px 0"
|
|
5853
|
+
};
|
|
5854
|
+
const messageStyle = {
|
|
5855
|
+
fontSize: "14px",
|
|
5856
|
+
color: "#6b7280",
|
|
5857
|
+
marginBottom: "8px",
|
|
5858
|
+
lineHeight: 1.5
|
|
5859
|
+
};
|
|
5860
|
+
const errorDetailStyle = {
|
|
5861
|
+
fontSize: "13px",
|
|
5862
|
+
color: "#dc2626",
|
|
5863
|
+
marginTop: "12px",
|
|
5864
|
+
padding: "12px",
|
|
5865
|
+
backgroundColor: "#fef2f2",
|
|
5866
|
+
borderRadius: "6px",
|
|
5867
|
+
border: "1px solid #fecaca"
|
|
5868
|
+
};
|
|
5869
|
+
const buttonStyle = {
|
|
5870
|
+
marginTop: "20px",
|
|
5871
|
+
padding: "10px 24px",
|
|
5872
|
+
backgroundColor: "#3b82f6",
|
|
5873
|
+
color: "#ffffff",
|
|
5874
|
+
border: "none",
|
|
5875
|
+
borderRadius: "6px",
|
|
5876
|
+
fontSize: "14px",
|
|
5877
|
+
fontWeight: 500,
|
|
5878
|
+
cursor: "pointer",
|
|
5879
|
+
transition: "background-color 0.2s"
|
|
5880
|
+
};
|
|
5881
|
+
return /* @__PURE__ */ jsx3("div", { style: containerStyle, children: /* @__PURE__ */ jsxs3("div", { style: cardStyle, children: [
|
|
5882
|
+
status === "processing" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
5883
|
+
/* @__PURE__ */ jsx3("div", { style: spinnerStyle }),
|
|
5884
|
+
/* @__PURE__ */ jsx3("h2", { style: titleStyle, children: "Processing Verification" }),
|
|
5885
|
+
/* @__PURE__ */ jsx3("p", { style: messageStyle, children: message }),
|
|
5886
|
+
/* @__PURE__ */ jsx3("p", { style: { ...messageStyle, fontSize: "12px", color: "#9ca3af" }, children: "Please wait while we verify your guardian's identity..." })
|
|
5887
|
+
] }),
|
|
5888
|
+
status === "success" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
5889
|
+
/* @__PURE__ */ jsx3("div", { style: successIconStyle, children: /* @__PURE__ */ jsx3(
|
|
5890
|
+
"svg",
|
|
5891
|
+
{
|
|
5892
|
+
width: "32",
|
|
5893
|
+
height: "32",
|
|
5894
|
+
viewBox: "0 0 24 24",
|
|
5895
|
+
fill: "none",
|
|
5896
|
+
stroke: "currentColor",
|
|
5897
|
+
strokeWidth: "2",
|
|
5898
|
+
strokeLinecap: "round",
|
|
5899
|
+
strokeLinejoin: "round",
|
|
5900
|
+
children: /* @__PURE__ */ jsx3("polyline", { points: "20 6 9 17 4 12" })
|
|
5901
|
+
}
|
|
5902
|
+
) }),
|
|
5903
|
+
/* @__PURE__ */ jsx3("h2", { style: titleStyle, children: "Verification Successful" }),
|
|
5904
|
+
/* @__PURE__ */ jsx3("p", { style: messageStyle, children: message })
|
|
5905
|
+
] }),
|
|
5906
|
+
status === "error" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
5907
|
+
/* @__PURE__ */ jsx3("div", { style: errorIconStyle, children: /* @__PURE__ */ jsxs3(
|
|
5908
|
+
"svg",
|
|
5909
|
+
{
|
|
5910
|
+
width: "32",
|
|
5911
|
+
height: "32",
|
|
5912
|
+
viewBox: "0 0 24 24",
|
|
5913
|
+
fill: "none",
|
|
5914
|
+
stroke: "currentColor",
|
|
5915
|
+
strokeWidth: "2",
|
|
5916
|
+
strokeLinecap: "round",
|
|
5917
|
+
strokeLinejoin: "round",
|
|
5918
|
+
children: [
|
|
5919
|
+
/* @__PURE__ */ jsx3("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
5920
|
+
/* @__PURE__ */ jsx3("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
5921
|
+
]
|
|
5922
|
+
}
|
|
5923
|
+
) }),
|
|
5924
|
+
/* @__PURE__ */ jsx3("h2", { style: titleStyle, children: "Verification Failed" }),
|
|
5925
|
+
/* @__PURE__ */ jsx3("p", { style: messageStyle, children: message }),
|
|
5926
|
+
errorDetail && /* @__PURE__ */ jsx3("p", { style: errorDetailStyle, children: errorDetail }),
|
|
5927
|
+
/* @__PURE__ */ jsx3(
|
|
5928
|
+
"button",
|
|
5929
|
+
{
|
|
5930
|
+
className: "redacto-dl-retry-btn",
|
|
5931
|
+
style: buttonStyle,
|
|
5932
|
+
onClick: handleRetry,
|
|
5933
|
+
children: "Try Again"
|
|
5934
|
+
}
|
|
5935
|
+
)
|
|
5936
|
+
] })
|
|
5937
|
+
] }) });
|
|
5938
|
+
};
|
|
4399
5939
|
export {
|
|
5940
|
+
DigiLockerCallback,
|
|
4400
5941
|
RedactoNoticeConsent,
|
|
4401
5942
|
RedactoConsentInline as RedactoNoticeConsentInline
|
|
4402
5943
|
};
|