@sanctum-key/react-native-sdk 1.0.24 → 1.0.25
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/build/package.json +3 -1
- package/build/src/components/EnhancedCameraView.d.ts +7 -1
- package/build/src/components/EnhancedCameraView.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.js +88 -30
- package/build/src/components/EnhancedCameraView.js.map +1 -1
- package/build/src/components/EnhancedCameraView.web.d.ts +5 -1
- package/build/src/components/EnhancedCameraView.web.d.ts.map +1 -1
- package/build/src/components/EnhancedCameraView.web.js +80 -295
- package/build/src/components/EnhancedCameraView.web.js.map +1 -1
- package/build/src/components/KYCElements/CameraCapture.js +1 -1
- package/build/src/components/KYCElements/CameraCapture.js.map +1 -1
- package/build/src/components/KYCElements/CountrySelection.d.ts.map +1 -1
- package/build/src/components/KYCElements/CountrySelection.js +38 -218
- package/build/src/components/KYCElements/CountrySelection.js.map +1 -1
- package/build/src/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
- package/build/src/components/KYCElements/CountrySelectionTemplate.js +5 -17
- package/build/src/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +509 -95
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/components/KYCElements/VerificationProgressTemplate.d.ts.map +1 -1
- package/build/src/components/KYCElements/VerificationProgressTemplate.js +93 -51
- package/build/src/components/KYCElements/VerificationProgressTemplate.js.map +1 -1
- package/build/src/components/OverLay/type.d.ts +1 -0
- package/build/src/components/OverLay/type.d.ts.map +1 -1
- package/build/src/components/OverLay/type.js.map +1 -1
- package/build/src/components/WebBarcodeScanner.d.ts +9 -0
- package/build/src/components/WebBarcodeScanner.d.ts.map +1 -0
- package/build/src/components/WebBarcodeScanner.js +152 -0
- package/build/src/components/WebBarcodeScanner.js.map +1 -0
- package/build/src/config/KYCConfigs.js +2 -2
- package/build/src/config/KYCConfigs.js.map +1 -1
- package/build/src/config/region_mapping.json +0 -14
- package/build/src/modules/api/CardAuthentification.d.ts +2 -0
- package/build/src/modules/api/CardAuthentification.d.ts.map +1 -1
- package/build/src/modules/api/CardAuthentification.js +22 -39
- package/build/src/modules/api/CardAuthentification.js.map +1 -1
- package/build/src/modules/api/KYCService.d.ts +7 -2
- package/build/src/modules/api/KYCService.d.ts.map +1 -1
- package/build/src/modules/api/KYCService.js +163 -57
- package/build/src/modules/api/KYCService.js.map +1 -1
- package/build/src/types/KYC.types.d.ts +1 -0
- package/build/src/types/KYC.types.d.ts.map +1 -1
- package/build/src/types/KYC.types.js.map +1 -1
- package/build/src/utils/aamvaParser.d.ts +62 -0
- package/build/src/utils/aamvaParser.d.ts.map +1 -0
- package/build/src/utils/aamvaParser.js +91 -0
- package/build/src/utils/aamvaParser.js.map +1 -0
- package/build/src/utils/cropByObb.d.ts.map +1 -1
- package/build/src/utils/cropByObb.js +4 -3
- package/build/src/utils/cropByObb.js.map +1 -1
- package/build/src/web/WebKYCEntry.d.ts +1 -1
- package/build/src/web/WebKYCEntry.d.ts.map +1 -1
- package/build/src/web/WebKYCEntry.js +105 -239
- package/build/src/web/WebKYCEntry.js.map +1 -1
- package/package.json +3 -1
- package/src/components/EnhancedCameraView.tsx +116 -42
- package/src/components/EnhancedCameraView.web.tsx +98 -338
- package/src/components/KYCElements/CameraCapture.tsx +1 -1
- package/src/components/KYCElements/CountrySelection.tsx +60 -240
- package/src/components/KYCElements/CountrySelectionTemplate.tsx +7 -20
- package/src/components/KYCElements/IDCardCapture.tsx +672 -151
- package/src/components/KYCElements/VerificationProgressTemplate.tsx +112 -65
- package/src/components/OverLay/type.ts +1 -1
- package/src/components/WebBarcodeScanner.tsx +273 -0
- package/src/config/KYCConfigs.ts +2 -2
- package/src/config/region_mapping.json +0 -14
- package/src/modules/api/CardAuthentification.ts +41 -56
- package/src/modules/api/KYCService.ts +236 -82
- package/src/types/KYC.types.ts +1 -0
- package/src/utils/aamvaParser.ts +102 -0
- package/src/utils/cropByObb.ts +5 -3
- package/src/web/WebKYCEntry.tsx +125 -301
|
@@ -13,6 +13,19 @@ const appendFileToFormData = async (formData, key, uri, name = 'file.jpg', type
|
|
|
13
13
|
formData.append(key, { uri, type, name });
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
|
+
const documentTypeMap = {
|
|
17
|
+
passport: "passport",
|
|
18
|
+
driversLicense: "driving_licence",
|
|
19
|
+
healthInsuranceCard: "health_insurance_card",
|
|
20
|
+
residencePermit: "permanent_residence_card",
|
|
21
|
+
identityCard: "identity_card",
|
|
22
|
+
nationalId: "identity_card", // We saw this in your earlier logs!
|
|
23
|
+
national_id: "identity_card",
|
|
24
|
+
drivers_licence: "driving_licence", // Plural 'drivers' to singular 'driving'
|
|
25
|
+
drivers_license: "driving_licence", // American spelling 'license'
|
|
26
|
+
driving_license: "driving_licence", // American spelling 'license'
|
|
27
|
+
permanent_residence: "permanent_residence_card", // Missing the word 'card'
|
|
28
|
+
};
|
|
16
29
|
let cachedToken = null;
|
|
17
30
|
let tokenExpiryTime = null;
|
|
18
31
|
let activeAuthRequest = null;
|
|
@@ -23,13 +36,8 @@ export class KYCService {
|
|
|
23
36
|
faceServiceURL = 'https://face-infera.sanctumkey.com';
|
|
24
37
|
textExtractionServiceURL = 'https://text-infera.sanctumkey.com';
|
|
25
38
|
mrzServiceURL = 'https://mrz-infera.sanctumkey.com';
|
|
26
|
-
barcodeServiceURL = 'https://
|
|
39
|
+
barcodeServiceURL = 'https://face-infera.sanctumkey.com';
|
|
27
40
|
orientationServiceURL = 'http://18.188.180.154:8080';
|
|
28
|
-
// private faceServiceURL = 'https://kyc-engine.transfergratis.net:8000';
|
|
29
|
-
// private textExtractionServiceURL = 'https://kyc-engine.transfergratis.net:8006';
|
|
30
|
-
// private mrzServiceURL = 'https://kyc-engine.transfergratis.net:8002';
|
|
31
|
-
// private barcodeServiceURL = 'https://kyc-engine.transfergratis.net:8000';
|
|
32
|
-
// private orientationServiceURL = 'http://18.188.180.154:8080';
|
|
33
41
|
constructor(baseURL, apiKey) {
|
|
34
42
|
this.baseURL = baseURL;
|
|
35
43
|
this.apiKey = apiKey;
|
|
@@ -199,14 +207,12 @@ export class KYCService {
|
|
|
199
207
|
card_obb: { x: 50, y: 50, width: 200, height: 200 }
|
|
200
208
|
};
|
|
201
209
|
}
|
|
202
|
-
// 🚨 Destructure issuingSubdivision
|
|
203
210
|
const { fileUri, docType, docRegion, token, postfix, issuingSubdivision } = params;
|
|
204
211
|
const formData = new FormData();
|
|
205
212
|
await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');
|
|
206
213
|
const docTypeShorted = GovernmentDocumentTypeShorted[docType];
|
|
207
214
|
// Build the base URL
|
|
208
215
|
let url = `${this.mrzServiceURL}/get_template_version/?doc_type=${encodeURIComponent(docTypeShorted)}&doc_region=${encodeURIComponent(docRegion)}&postfix=${postfix}`;
|
|
209
|
-
// 🚨 Append the subdivision strictly for Canada/regional docs
|
|
210
216
|
if (issuingSubdivision) {
|
|
211
217
|
url += `&issuing_subdivision=${encodeURIComponent(issuingSubdivision)}`;
|
|
212
218
|
}
|
|
@@ -228,16 +234,14 @@ export class KYCService {
|
|
|
228
234
|
const { fileUri, docType, docRegion, templatePath, issuingSubdivision, token, postfix = 'front' } = params;
|
|
229
235
|
// 1. Prepare Form Data
|
|
230
236
|
const formData = new FormData();
|
|
231
|
-
// Prefixing with 'front' or 'back' as strictly required by the docs
|
|
232
237
|
await appendFileToFormData(formData, 'file', fileUri, `id_card_${postfix}.jpg`, 'image/jpeg');
|
|
233
|
-
|
|
234
|
-
let queryParams = `doc_type=${encodeURIComponent(docType)}&doc_region=${encodeURIComponent(docRegion)}&template_path=${encodeURIComponent(templatePath)}`;
|
|
238
|
+
let queryParams = `doc_type=${encodeURIComponent(docType)}&doc_region=${encodeURIComponent(docRegion)}&template_path=${encodeURIComponent(templatePath)}&postfix=${postfix}&cleaned=true`;
|
|
235
239
|
if (issuingSubdivision) {
|
|
236
240
|
queryParams += `&issuing_subdivision=${encodeURIComponent(issuingSubdivision)}`;
|
|
237
241
|
}
|
|
242
|
+
logger.log(`URL PARAMS: ${queryParams}`);
|
|
238
243
|
const url = `${this.textExtractionServiceURL}/extract_doc_information/?${queryParams}`;
|
|
239
244
|
try {
|
|
240
|
-
// 3. Start the Job
|
|
241
245
|
const startRes = await axios.post(url, formData, {
|
|
242
246
|
headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}` },
|
|
243
247
|
timeout: 60000,
|
|
@@ -259,12 +263,11 @@ export class KYCService {
|
|
|
259
263
|
const statusData = statusRes.data;
|
|
260
264
|
if (statusData.status === 'completed') {
|
|
261
265
|
logger.log('Extraction completed successfully', JSON.stringify(truncateFields(statusData.result)));
|
|
262
|
-
return statusData.result;
|
|
266
|
+
return statusData.result;
|
|
263
267
|
}
|
|
264
268
|
if (statusData.status === 'failed') {
|
|
265
269
|
throw new Error(statusData.error || "Document extraction failed during processing.");
|
|
266
270
|
}
|
|
267
|
-
// If 'processing', loop continues...
|
|
268
271
|
}
|
|
269
272
|
throw new Error("Document extraction timed out waiting for results.");
|
|
270
273
|
}
|
|
@@ -274,7 +277,6 @@ export class KYCService {
|
|
|
274
277
|
throw new Error(errorMsg);
|
|
275
278
|
}
|
|
276
279
|
}
|
|
277
|
-
// STEP 2 - barcode extraction
|
|
278
280
|
async extractBarcode(params, env = 'PRODUCTION') {
|
|
279
281
|
// SANDBOX mode
|
|
280
282
|
if (env === 'SANDBOX') {
|
|
@@ -285,35 +287,72 @@ export class KYCService {
|
|
|
285
287
|
card_obb: { x: 50, y: 50, width: 200, height: 200 }
|
|
286
288
|
};
|
|
287
289
|
}
|
|
288
|
-
const { fileUri, token, postfix = 'back' } = params;
|
|
290
|
+
const { fileUri, token, docType, postfix = 'back' } = params;
|
|
291
|
+
logger.log(docType);
|
|
289
292
|
const formData = new FormData();
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const url = `${this.barcodeServiceURL}/decode_barcode/`;
|
|
293
|
+
await appendFileToFormData(formData, 'file', fileUri, `id_${postfix}_photo.jpg`, 'image/jpeg');
|
|
294
|
+
const url = `${this.barcodeServiceURL}/decode_barcode/?doc_type=${encodeURIComponent(docType)}`;
|
|
293
295
|
const attempt = async () => {
|
|
294
296
|
try {
|
|
295
297
|
const res = await axios.post(url, formData, {
|
|
296
|
-
headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}
|
|
298
|
+
headers: { 'Content-Type': 'multipart/form-data', 'Authorization': `Bearer ${token}` },
|
|
297
299
|
timeout: 60000,
|
|
298
300
|
});
|
|
299
|
-
logger.log('extractBarcode
|
|
300
|
-
if (Object.keys(res.data).length === 0)
|
|
301
|
-
throw new Error('No data found');
|
|
301
|
+
logger.log('📦 Raw extractBarcode response:', JSON.stringify(res.data, null, 2));
|
|
302
302
|
return res.data;
|
|
303
303
|
}
|
|
304
304
|
catch (e) {
|
|
305
|
-
throw new Error(e?.message || 'Erreur de détection du
|
|
305
|
+
throw new Error(e?.message || 'Erreur de détection du code-barres');
|
|
306
306
|
}
|
|
307
307
|
};
|
|
308
308
|
try {
|
|
309
309
|
return await attempt();
|
|
310
310
|
}
|
|
311
311
|
catch (e) {
|
|
312
|
-
logger.error('Error extracting Barcode text:', JSON.stringify(e));
|
|
312
|
+
logger.error('❌ Error extracting Barcode text:', JSON.stringify(e));
|
|
313
|
+
throw e;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
async formatBarcodeData(params, env = 'PRODUCTION') {
|
|
317
|
+
// SANDBOX mode
|
|
318
|
+
if (env === 'SANDBOX') {
|
|
319
|
+
console.log("SANDBOX mode: Skipping AI barcode formatting");
|
|
320
|
+
logger.log("SANDBOX mode: Returning mock formatted barcode response");
|
|
321
|
+
return {
|
|
322
|
+
barcode_type: "SANDBOX_MOCK",
|
|
323
|
+
first_name: "JOHN",
|
|
324
|
+
last_name: "DOE",
|
|
325
|
+
card_number: "000000000000"
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
const { textInput, token } = params;
|
|
329
|
+
const formData = new URLSearchParams();
|
|
330
|
+
formData.append('text_input', textInput);
|
|
331
|
+
const url = `${this.barcodeServiceURL}/format_barcode_data/`;
|
|
332
|
+
const attempt = async () => {
|
|
333
|
+
try {
|
|
334
|
+
const res = await axios.post(url, formData.toString(), {
|
|
335
|
+
headers: {
|
|
336
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
337
|
+
'Authorization': `Bearer ${token}`
|
|
338
|
+
},
|
|
339
|
+
timeout: 60000,
|
|
340
|
+
});
|
|
341
|
+
logger.log('📦 Raw formatBarcodeData response:', JSON.stringify(res.data, null, 2));
|
|
342
|
+
return res.data;
|
|
343
|
+
}
|
|
344
|
+
catch (e) {
|
|
345
|
+
throw new Error(e?.message || 'Erreur de formatage du code-barres');
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
try {
|
|
349
|
+
return await attempt();
|
|
350
|
+
}
|
|
351
|
+
catch (e) {
|
|
352
|
+
logger.error('❌ Error formatting Barcode text:', JSON.stringify(e));
|
|
313
353
|
throw e;
|
|
314
354
|
}
|
|
315
355
|
}
|
|
316
|
-
// STEP 3 - MRZ TEXT EXTRACTION
|
|
317
356
|
async extractMrzText(params, env = 'PRODUCTION') {
|
|
318
357
|
// SANDBOX mode
|
|
319
358
|
if (env === 'SANDBOX') {
|
|
@@ -349,8 +388,6 @@ export class KYCService {
|
|
|
349
388
|
try {
|
|
350
389
|
let response;
|
|
351
390
|
if (Platform.OS === 'web') {
|
|
352
|
-
// 🚨 THE FIX: Completely bypass React Native Web's networking polyfills.
|
|
353
|
-
// We explicitly grab the browser's native APIs so the bundler cannot interfere.
|
|
354
391
|
const nativeFetch = window.fetch;
|
|
355
392
|
const NativeFormData = window.FormData;
|
|
356
393
|
const formData = new NativeFormData();
|
|
@@ -474,44 +511,91 @@ export class KYCService {
|
|
|
474
511
|
async verificationSession(payload) {
|
|
475
512
|
try {
|
|
476
513
|
const { session_id, step, data, templateId, action, apiKey } = payload;
|
|
477
|
-
// 1. Safe Auth Resolution
|
|
478
514
|
const token = apiKey ? undefined : await authentification();
|
|
479
515
|
if (!apiKey && !token) {
|
|
480
516
|
throw new Error("Authentication failed: No API key or Token available.");
|
|
481
517
|
}
|
|
518
|
+
// 1. Original Shallow Clone (Preserves file paths perfectly)
|
|
519
|
+
const normalizedData = { ...data };
|
|
520
|
+
logger.log("🔍 [DocType Check] Raw incoming data.metadata.document_type:", normalizedData?.metadata?.document_type);
|
|
521
|
+
logger.log("🔍 [DocType Check] Raw incoming data.documentType:", normalizedData?.documentType);
|
|
522
|
+
// Enhanced fallback to guarantee we find the document type
|
|
523
|
+
const rawDocType = normalizedData?.metadata?.document_type ||
|
|
524
|
+
normalizedData?.documentType ||
|
|
525
|
+
normalizedData?.documents?.documentType;
|
|
526
|
+
if (rawDocType) {
|
|
527
|
+
const originalDocType = rawDocType;
|
|
528
|
+
const mappedDocType = documentTypeMap[originalDocType] ?? originalDocType;
|
|
529
|
+
normalizedData.metadata = {
|
|
530
|
+
...normalizedData.metadata,
|
|
531
|
+
document_type: mappedDocType,
|
|
532
|
+
};
|
|
533
|
+
normalizedData.documentType = mappedDocType;
|
|
534
|
+
if (normalizedData.documents) {
|
|
535
|
+
normalizedData.documents = {
|
|
536
|
+
...normalizedData.documents,
|
|
537
|
+
documentType: mappedDocType
|
|
538
|
+
};
|
|
539
|
+
const isSingleSided = ['passport', 'visa'].includes(mappedDocType.toLowerCase());
|
|
540
|
+
if (isSingleSided && !normalizedData.documents.back) {
|
|
541
|
+
normalizedData.documents.back = {};
|
|
542
|
+
}
|
|
543
|
+
if (normalizedData.documents.front?.mrz && typeof normalizedData.documents.front.mrz === 'string') {
|
|
544
|
+
try {
|
|
545
|
+
normalizedData.documents.front = {
|
|
546
|
+
...normalizedData.documents.front,
|
|
547
|
+
mrz: JSON.parse(normalizedData.documents.front.mrz)
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
catch (e) {
|
|
551
|
+
logger.log("Warning: Could not parse front MRZ JSON");
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (normalizedData.documents.back?.mrz && typeof normalizedData.documents.back.mrz === 'string') {
|
|
555
|
+
try {
|
|
556
|
+
normalizedData.documents.back = {
|
|
557
|
+
...normalizedData.documents.back,
|
|
558
|
+
mrz: JSON.parse(normalizedData.documents.back.mrz)
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
catch (e) {
|
|
562
|
+
logger.log("Warning: Could not parse back MRZ JSON");
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
482
567
|
const payloadData = {
|
|
483
|
-
action
|
|
568
|
+
action,
|
|
484
569
|
data: {
|
|
485
|
-
...
|
|
486
|
-
step
|
|
487
|
-
templateId
|
|
488
|
-
...(action === "location_permission" ? { permissionGranted: true } : {}),
|
|
570
|
+
...normalizedData,
|
|
571
|
+
step,
|
|
572
|
+
templateId,
|
|
489
573
|
},
|
|
490
|
-
session_id
|
|
574
|
+
session_id,
|
|
491
575
|
timestamp: new Date().toISOString(),
|
|
492
576
|
};
|
|
493
577
|
const url = `${KYCConfig.getBackendUrl()}/verification/api/kyc/sessions/${session_id}/steps/${step}/`;
|
|
494
|
-
// 3. Clean Logging
|
|
495
578
|
const logPayload = truncateFields({ payloadData, session_id, step });
|
|
496
|
-
logger.log(
|
|
579
|
+
logger.log("verificationSession payload", JSON.stringify({
|
|
497
580
|
url,
|
|
498
|
-
apiKey: apiKey ?
|
|
499
|
-
token: token ?
|
|
500
|
-
payload: logPayload
|
|
581
|
+
apiKey: apiKey ? "***HIDDEN***" : "None",
|
|
582
|
+
token: token ? "***HIDDEN***" : "None",
|
|
583
|
+
payload: logPayload,
|
|
501
584
|
}, null, 2));
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
logger.log('verificationSession res', JSON.stringify(truncateFields(res.data), null, 2));
|
|
585
|
+
const headers = {
|
|
586
|
+
"Content-Type": "application/json",
|
|
587
|
+
...(apiKey ? { Authorization: `ApiKey ${apiKey}` } : {}),
|
|
588
|
+
...(token && !apiKey ? { Authorization: `Bearer ${token}` } : {})
|
|
589
|
+
};
|
|
590
|
+
const res = await axios.post(url, payloadData, { headers });
|
|
591
|
+
logger.log("verificationSession res", JSON.stringify(truncateFields(res.data), null, 2));
|
|
510
592
|
return res.data;
|
|
511
593
|
}
|
|
512
594
|
catch (error) {
|
|
513
|
-
|
|
514
|
-
|
|
595
|
+
const parsedError = errorMessage(error);
|
|
596
|
+
const finalErrorMessage = parsedError || error?.message || "Unknown validation error";
|
|
597
|
+
logger.error("Error validating component:", JSON.stringify(finalErrorMessage, null, 2));
|
|
598
|
+
throw new Error(typeof finalErrorMessage === 'string' ? finalErrorMessage : JSON.stringify(finalErrorMessage));
|
|
515
599
|
}
|
|
516
600
|
}
|
|
517
601
|
/** Send email verification code. POST /api/v1/accounts/email/send/ */
|
|
@@ -538,16 +622,40 @@ export class KYCService {
|
|
|
538
622
|
});
|
|
539
623
|
return res.data;
|
|
540
624
|
}
|
|
541
|
-
async getVerificationResult(session_id) {
|
|
625
|
+
async getVerificationResult(session_id, apiKey) {
|
|
542
626
|
try {
|
|
543
|
-
const token = await authentification();
|
|
627
|
+
const token = apiKey ? undefined : await authentification();
|
|
544
628
|
const url = `${KYCConfig.getBackendUrl()}/verification/api/kyc/result/?session_id=${session_id}`;
|
|
545
|
-
const
|
|
546
|
-
|
|
629
|
+
const controller = new AbortController();
|
|
630
|
+
const timeoutId = setTimeout(() => {
|
|
631
|
+
logger.log("⏳ 8 seconds passed. Force-killing hanging Axios request...");
|
|
632
|
+
controller.abort();
|
|
633
|
+
}, 8000);
|
|
634
|
+
const headers = {
|
|
635
|
+
'Content-Type': 'application/json',
|
|
636
|
+
};
|
|
637
|
+
if (apiKey) {
|
|
638
|
+
headers["Authorization"] = `ApiKey ${apiKey}`;
|
|
639
|
+
}
|
|
640
|
+
else if (token) {
|
|
641
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
642
|
+
}
|
|
643
|
+
logger.log("3. Firing Axios GET to:", url);
|
|
644
|
+
const res = await axios.get(url, {
|
|
645
|
+
headers,
|
|
646
|
+
signal: controller.signal
|
|
647
|
+
});
|
|
648
|
+
// Clear the timeout if the request succeeds!
|
|
649
|
+
clearTimeout(timeoutId);
|
|
547
650
|
return res.data;
|
|
548
651
|
}
|
|
549
652
|
catch (error) {
|
|
550
|
-
|
|
653
|
+
// Catch the AbortController kill signal and format it as a timeout
|
|
654
|
+
if (axios.isCancel(error) || error.name === 'AbortError' || error.name === 'CanceledError') {
|
|
655
|
+
logger.error('Axios request was forcefully aborted due to timeout');
|
|
656
|
+
throw new Error('Timeout exceeded');
|
|
657
|
+
}
|
|
658
|
+
logger.error('Error getting verification result:', JSON.stringify(errorMessage(error) || error.message, null, 2));
|
|
551
659
|
throw error;
|
|
552
660
|
}
|
|
553
661
|
}
|
|
@@ -617,7 +725,6 @@ export class KYCService {
|
|
|
617
725
|
return { is_match: true, status_message: "SANDBOX: Valid Match" };
|
|
618
726
|
}
|
|
619
727
|
const { region, docType, frontTemplateName, backTemplateName, subRegion, token } = params;
|
|
620
|
-
// 🚨 THE FIX: Format the payload as URL Query Parameters
|
|
621
728
|
const queryParams = new URLSearchParams({
|
|
622
729
|
region: region,
|
|
623
730
|
doc_type: docType,
|
|
@@ -705,7 +812,6 @@ export const authentification = async () => {
|
|
|
705
812
|
}
|
|
706
813
|
catch (error) {
|
|
707
814
|
cachedToken = null; // Clear bad cache
|
|
708
|
-
// 🚨 FIX: Extract Keycloak's exact error message so it doesn't log as {}
|
|
709
815
|
const safeErrorMessage = error?.response?.data?.error_description ||
|
|
710
816
|
error?.response?.data?.error ||
|
|
711
817
|
error?.message ||
|