@sanctum-key/react-native-sdk 1.0.35 → 1.0.37
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 +1 -1
- package/build/src/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/src/components/KYCElements/IDCardCapture.js +21 -54
- package/build/src/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/src/modules/camera/VisionCameraModule.d.ts +0 -34
- package/build/src/modules/camera/VisionCameraModule.d.ts.map +1 -1
- package/build/src/modules/camera/VisionCameraModule.js +20 -102
- package/build/src/modules/camera/VisionCameraModule.js.map +1 -1
- package/build/src/utils/pathToBase64.d.ts.map +1 -1
- package/build/src/utils/pathToBase64.js +3 -5
- package/build/src/utils/pathToBase64.js.map +1 -1
- package/package.json +1 -1
- package/src/components/KYCElements/IDCardCapture.tsx +51 -97
- package/src/modules/camera/VisionCameraModule.ts +18 -106
- package/src/utils/pathToBase64.ts +4 -8
package/build/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAsB5L,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsCD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"IDCardCapture.d.ts","sourceRoot":"","sources":["../../../../src/components/KYCElements/IDCardCapture.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAIpE,OAAO,EAAE,iBAAiB,EAAoI,MAAM,uBAAuB,CAAC;AAsB5L,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAsCD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA2lCtD,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
-
import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity, useWindowDimensions
|
|
2
|
+
import { View, Text, StyleSheet, Image, ScrollView, Platform, ActivityIndicator, TouchableOpacity, useWindowDimensions } from 'react-native';
|
|
3
3
|
import { showAlert } from '../../utils/platformAlert';
|
|
4
4
|
import { EnhancedCameraView } from '../EnhancedCameraView';
|
|
5
5
|
import { GovernmentDocumentTypeShorted, GovernmentDocumentTypeBackend } from '../../types/KYC.types';
|
|
@@ -484,9 +484,7 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
484
484
|
return;
|
|
485
485
|
if (result.success && result.path) {
|
|
486
486
|
setSilentCaptureResult((prev) => ({ ...prev, isAnalyzing: true, success: false, error: '' }));
|
|
487
|
-
const safeCapturePath = Platform.OS === 'ios' && !result.path.startsWith('file://')
|
|
488
|
-
? `file://${result.path}`
|
|
489
|
-
: result.path;
|
|
487
|
+
const safeCapturePath = Platform.OS === 'ios' && !result.path.startsWith('file://') ? `file://${result.path}` : result.path;
|
|
490
488
|
let templatePath = capturedImages[currentSide]?.templatePath || '';
|
|
491
489
|
let templateBbox;
|
|
492
490
|
let templateResponse;
|
|
@@ -495,18 +493,15 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
495
493
|
return;
|
|
496
494
|
}
|
|
497
495
|
const issuingSubdivision = selectedDocumentType.region !== 'root' ? selectedDocumentType.region : undefined;
|
|
498
|
-
//
|
|
496
|
+
// Subtle timeout handling without blocking pop-ups
|
|
499
497
|
const watchdog = setTimeout(() => {
|
|
500
498
|
if (isAnalyzingRef.current) {
|
|
501
499
|
setSilentCaptureResult((prev) => ({
|
|
502
500
|
...prev,
|
|
503
501
|
isAnalyzing: false,
|
|
504
502
|
success: false,
|
|
505
|
-
error: state.currentLanguage === 'en' ? '
|
|
503
|
+
error: state.currentLanguage === 'en' ? 'Taking longer than expected. Hold steady.' : 'Traitement long. Veuillez rester immobile.'
|
|
506
504
|
}));
|
|
507
|
-
Alert.alert(state.currentLanguage === 'en' ? "Timeout" : "Délai dépassé", state.currentLanguage === 'en'
|
|
508
|
-
? "The request took too long. Please verify your network and try again."
|
|
509
|
-
: "La requête a pris trop de temps. Veuillez vérifier votre connexion et réessayer.");
|
|
510
505
|
}
|
|
511
506
|
}, 20000);
|
|
512
507
|
try {
|
|
@@ -543,10 +538,7 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
543
538
|
const mrzType = getCorrespondingMrzType(templatePath, regionMappings.regionMapping, regionMappings.key || '') || 'TD1';
|
|
544
539
|
verificationRes = await frontVerification({
|
|
545
540
|
path: safeCapturePath,
|
|
546
|
-
regionMapping: {
|
|
547
|
-
authMethod: matchedAuthMethod ? [matchedAuthMethod] : [],
|
|
548
|
-
mrzTypes: mrzType ? [mrzType] : []
|
|
549
|
-
},
|
|
541
|
+
regionMapping: { authMethod: matchedAuthMethod ? [matchedAuthMethod] : [], mrzTypes: mrzType ? [mrzType] : [] },
|
|
550
542
|
selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType?.type] || '',
|
|
551
543
|
code: countryData?.code || '',
|
|
552
544
|
currentSide,
|
|
@@ -563,10 +555,7 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
563
555
|
const frontTemplatePath = capturedImages['front']?.templatePath || '';
|
|
564
556
|
verificationRes = await backVerification({
|
|
565
557
|
path: safeCapturePath,
|
|
566
|
-
regionMapping: {
|
|
567
|
-
authMethod: matchedBackAuthMethod ? [matchedBackAuthMethod] : [],
|
|
568
|
-
mrzTypes: backMrzType ? [backMrzType] : []
|
|
569
|
-
},
|
|
558
|
+
regionMapping: { authMethod: matchedBackAuthMethod ? [matchedBackAuthMethod] : [], mrzTypes: backMrzType ? [backMrzType] : [] },
|
|
570
559
|
selectedDocumentType: GovernmentDocumentTypeShorted[selectedDocumentType.type] || '',
|
|
571
560
|
code: countryData?.code || '',
|
|
572
561
|
currentSide,
|
|
@@ -629,34 +618,28 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
629
618
|
}
|
|
630
619
|
catch (error) {
|
|
631
620
|
clearTimeout(watchdog);
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
error.code === 'ECONNABORTED' ||
|
|
636
|
-
error.message?.includes('Network');
|
|
637
|
-
let userFriendlyMessage = 'Verification failed. Please try again.';
|
|
621
|
+
const isNetworkError = !error.response || error.message === 'Network Error' || error.code === 'ECONNABORTED' || error.message?.includes('Network');
|
|
622
|
+
// Keep UI errors extremely brief and actionable
|
|
623
|
+
let hintMessage = '';
|
|
638
624
|
if (isNetworkError) {
|
|
639
|
-
|
|
640
|
-
? 'Cannot connect to verification server. Please check your internet connection.'
|
|
641
|
-
: 'Impossible de se connecter au serveur de vérification. Veuillez vérifier votre connexion internet.';
|
|
642
|
-
Alert.alert(state.currentLanguage === 'en' ? "Connection Failed" : "Échec de connexion", userFriendlyMessage);
|
|
625
|
+
hintMessage = state.currentLanguage === 'en' ? 'Poor connection. Retrying...' : 'Connexion faible. Nouvelle tentative...';
|
|
643
626
|
}
|
|
644
627
|
else {
|
|
645
628
|
const rawMessage = (error?.message || '').toLowerCase();
|
|
646
629
|
if (rawMessage.includes('impossible') || rawMessage.includes('unreadable')) {
|
|
647
|
-
|
|
630
|
+
hintMessage = state.currentLanguage === 'en' ? 'Move to better lighting.' : 'Améliorez l\'éclairage.';
|
|
648
631
|
}
|
|
649
632
|
else if (rawMessage.includes('country mismatch') || rawMessage.includes('pays sélectionné')) {
|
|
650
|
-
|
|
633
|
+
hintMessage = state.currentLanguage === 'en' ? 'Wrong document type.' : 'Mauvais type de document.';
|
|
651
634
|
}
|
|
652
635
|
else if (rawMessage.includes('card_not_fully_in_frame')) {
|
|
653
|
-
|
|
636
|
+
hintMessage = state.currentLanguage === 'en' ? 'Move closer.' : 'Rapprochez-vous.';
|
|
654
637
|
}
|
|
655
638
|
else if (rawMessage.includes('ne correspond pas au recto')) {
|
|
656
|
-
|
|
639
|
+
hintMessage = state.currentLanguage === 'en' ? 'Scan the same ID.' : 'Scannez la même pièce.';
|
|
657
640
|
}
|
|
658
641
|
}
|
|
659
|
-
setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false, error:
|
|
642
|
+
setSilentCaptureResult(prev => ({ ...prev, isAnalyzing: false, success: false, error: hintMessage }));
|
|
660
643
|
}
|
|
661
644
|
}
|
|
662
645
|
};
|
|
@@ -671,34 +654,18 @@ export const IDCardCapture = ({ component, value = {}, onValueChange, error, lan
|
|
|
671
654
|
}, [scanPhase, pendingCAImage, silentCaptureResult.barcode]);
|
|
672
655
|
const handleError = (event) => {
|
|
673
656
|
logger.error("Camera Error:", event);
|
|
674
|
-
// Normalize the error to lowercase for easy checking
|
|
675
657
|
const errString = `${event.message} ${event.name} ${event.code}`.toLowerCase();
|
|
676
|
-
let friendlyMessage = state.currentLanguage === 'en'
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
// 1. Detect Hardware Lock (Camera in use by Zoom, Teams, or another app)
|
|
680
|
-
if (errString.includes('notreadableerror') ||
|
|
681
|
-
errString.includes('trackstarterror') ||
|
|
682
|
-
errString.includes('in use') ||
|
|
683
|
-
errString.includes('concurrent') ||
|
|
684
|
-
errString.includes('camera unavailable')) {
|
|
685
|
-
friendlyMessage = state.currentLanguage === 'en'
|
|
686
|
-
? 'Your camera is currently being used by another application (like Zoom or Teams). Please close the other app and try again.'
|
|
687
|
-
: 'Votre caméra est actuellement utilisée par une autre application. Veuillez fermer l\'autre application et réessayer.';
|
|
658
|
+
let friendlyMessage = state.currentLanguage === 'en' ? 'Camera error.' : 'Erreur de caméra.';
|
|
659
|
+
if (errString.includes('notreadableerror') || errString.includes('trackstarterror') || errString.includes('in use') || errString.includes('concurrent') || errString.includes('camera unavailable')) {
|
|
660
|
+
friendlyMessage = state.currentLanguage === 'en' ? 'Camera is in use by another app.' : 'Caméra utilisée par une autre application.';
|
|
688
661
|
}
|
|
689
|
-
// 2. Detect Permission Denied
|
|
690
662
|
else if (errString.includes('notallowederror') || errString.includes('permission')) {
|
|
691
|
-
friendlyMessage = state.currentLanguage === 'en'
|
|
692
|
-
? 'Camera permission denied. Please allow camera access in your settings to proceed.'
|
|
693
|
-
: 'Autorisation de la caméra refusée. Veuillez autoriser l\'accès dans vos paramètres.';
|
|
663
|
+
friendlyMessage = state.currentLanguage === 'en' ? 'Allow camera access in settings.' : 'Autorisez l\'accès à la caméra.';
|
|
694
664
|
}
|
|
695
|
-
// 3. Detect No Camera Found
|
|
696
665
|
else if (errString.includes('notfounderror') || errString.includes('no camera')) {
|
|
697
|
-
friendlyMessage = state.currentLanguage === 'en'
|
|
698
|
-
? 'No camera detected on this device.'
|
|
699
|
-
: 'Aucune caméra détectée sur cet appareil.';
|
|
666
|
+
friendlyMessage = state.currentLanguage === 'en' ? 'No camera detected.' : 'Aucune caméra détectée.';
|
|
700
667
|
}
|
|
701
|
-
showAlert(state.currentLanguage === 'en' ? 'Camera Error' : 'Erreur
|
|
668
|
+
showAlert(state.currentLanguage === 'en' ? 'Camera Error' : 'Erreur', friendlyMessage);
|
|
702
669
|
setShowCamera(false);
|
|
703
670
|
setIsProcessingCapture(false);
|
|
704
671
|
};
|