@trustchex/react-native-sdk 1.381.0 → 1.464.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/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKModule.kt +2 -8
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +60 -13
- package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
- package/ios/Camera/TrustchexCameraView.swift +10 -13
- package/ios/MLKit/MLKitModule.swift +1 -1
- package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
- package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
- package/lib/module/Screens/Debug/NFCScanTestScreen.js +635 -0
- package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -32
- package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +22 -4
- package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
- package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +126 -27
- package/lib/module/Screens/Dynamic/VerbalConsentScreen.js +1079 -0
- package/lib/module/Screens/Dynamic/VideoCallScreen.js +678 -0
- package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
- package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
- package/lib/module/Screens/Static/ResultScreen.js +154 -34
- package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +59 -51
- package/lib/module/Shared/Animations/recording.json +1 -0
- package/lib/module/Shared/Animations/video-call.json +1 -0
- package/lib/module/Shared/Components/DebugNavigationPanel.js +231 -67
- package/lib/module/Shared/Components/EIDScanner.js +213 -112
- package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +5 -3
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +77 -39
- package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +13 -4
- package/lib/module/Shared/Components/NavigationManager.js +39 -19
- package/lib/module/Shared/Contexts/AppContext.js +1 -0
- package/lib/module/Shared/EIDReader/aesSecureMessagingWrapper.js +51 -0
- package/lib/module/Shared/EIDReader/apduLevelPACECapable.js +3 -0
- package/lib/module/Shared/EIDReader/bacKey.js +16 -2
- package/lib/module/Shared/EIDReader/eidReader.js +354 -13
- package/lib/module/Shared/EIDReader/eidService.js +25 -1
- package/lib/module/Shared/EIDReader/nfcManagerCardService.js +4 -7
- package/lib/module/Shared/EIDReader/paceInfo.js +85 -0
- package/lib/module/Shared/EIDReader/paceKeySpec.js +51 -0
- package/lib/module/Shared/EIDReader/protocol/paceAPDUSender.js +100 -0
- package/lib/module/Shared/EIDReader/protocol/paceProtocol.js +655 -0
- package/lib/module/Shared/EIDReader/protocol/paceResult.js +37 -0
- package/lib/module/Shared/EIDReader/secureMessagingWrapper.js +27 -4
- package/lib/module/Shared/EIDReader/smartcards/commandAPDU.js +2 -1
- package/lib/module/Shared/EIDReader/tlv/tlv.helpers.js +1 -1
- package/lib/module/Shared/EIDReader/tlv/tlv.utils.js +6 -3
- package/lib/module/Shared/EIDReader/utils/aesCrypto.utils.js +189 -0
- package/lib/module/Shared/Libs/SignalingClient.js +128 -0
- package/lib/module/Shared/Libs/analytics.utils.js +8 -0
- package/lib/module/Shared/Libs/contains.js +1 -40
- package/lib/module/Shared/Libs/country-display.utils.js +34 -0
- package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
- package/lib/module/Shared/Libs/demo.utils.js +8 -0
- package/lib/module/Shared/Libs/http-client.js +9 -0
- package/lib/module/Shared/Libs/mrz.utils.js +3 -2
- package/lib/module/Shared/Libs/promise.utils.js +16 -2
- package/lib/module/Shared/Libs/status-bar.utils.js +23 -0
- package/lib/module/Shared/Services/DataUploadService.js +294 -0
- package/lib/module/Shared/Services/VideoSessionService.js +156 -0
- package/lib/module/Shared/Services/WebRTCService.js +510 -0
- package/lib/module/Shared/Types/analytics.types.js +4 -0
- package/lib/module/Translation/Resources/en.js +61 -2
- package/lib/module/Translation/Resources/tr.js +61 -2
- package/lib/module/Trustchex.js +64 -20
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Debug/NFCScanTestScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Debug/NFCScanTestScreen.d.ts.map +1 -0
- package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/VerbalConsentScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Dynamic/VerbalConsentScreen.d.ts.map +1 -0
- package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
- package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +5 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
- package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/aesSecureMessagingWrapper.d.ts +18 -0
- package/lib/typescript/src/Shared/EIDReader/aesSecureMessagingWrapper.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/apduLevelPACECapable.d.ts +23 -0
- package/lib/typescript/src/Shared/EIDReader/apduLevelPACECapable.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/bacKey.d.ts +6 -0
- package/lib/typescript/src/Shared/EIDReader/bacKey.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/eidService.d.ts +9 -0
- package/lib/typescript/src/Shared/EIDReader/eidService.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/nfcManagerCardService.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/paceInfo.d.ts +50 -0
- package/lib/typescript/src/Shared/EIDReader/paceInfo.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/paceKeySpec.d.ts +30 -0
- package/lib/typescript/src/Shared/EIDReader/paceKeySpec.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/protocol/paceAPDUSender.d.ts +17 -0
- package/lib/typescript/src/Shared/EIDReader/protocol/paceAPDUSender.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts +105 -0
- package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/protocol/paceResult.d.ts +24 -0
- package/lib/typescript/src/Shared/EIDReader/protocol/paceResult.d.ts.map +1 -0
- package/lib/typescript/src/Shared/EIDReader/secureMessagingWrapper.d.ts +15 -0
- package/lib/typescript/src/Shared/EIDReader/secureMessagingWrapper.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/smartcards/commandAPDU.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/tlv/tlv.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/utils/aesCrypto.utils.d.ts +39 -0
- package/lib/typescript/src/Shared/EIDReader/utils/aesCrypto.utils.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
- package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/contains.d.ts +0 -7
- package/lib/typescript/src/Shared/Libs/contains.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts +2 -0
- package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/demo.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/http-client.d.ts +1 -1
- package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
- package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
- package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
- package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Types/analytics.types.d.ts +4 -0
- package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +13 -1
- package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/en.d.ts +60 -1
- package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts +60 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
- package/lib/typescript/src/Trustchex.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +35 -5
- package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
- package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
- package/src/Screens/Debug/NFCScanTestScreen.tsx +692 -0
- package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +58 -35
- package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +27 -4
- package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
- package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +156 -27
- package/src/Screens/Dynamic/VerbalConsentScreen.tsx +1401 -0
- package/src/Screens/Dynamic/VideoCallScreen.tsx +766 -0
- package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
- package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
- package/src/Screens/Static/ResultScreen.tsx +235 -48
- package/src/Screens/Static/VerificationSessionCheckScreen.tsx +67 -72
- package/src/Shared/Animations/recording.json +1 -0
- package/src/Shared/Animations/video-call.json +1 -0
- package/src/Shared/Components/DebugNavigationPanel.tsx +252 -51
- package/src/Shared/Components/EIDScanner.tsx +223 -116
- package/src/Shared/Components/IdentityDocumentCamera.flows.ts +7 -4
- package/src/Shared/Components/IdentityDocumentCamera.tsx +224 -188
- package/src/Shared/Components/IdentityDocumentCamera.utils.ts +13 -4
- package/src/Shared/Components/NavigationManager.tsx +41 -19
- package/src/Shared/Contexts/AppContext.ts +2 -0
- package/src/Shared/EIDReader/aesSecureMessagingWrapper.ts +69 -0
- package/src/Shared/EIDReader/apduLevelPACECapable.ts +34 -0
- package/src/Shared/EIDReader/bacKey.ts +24 -8
- package/src/Shared/EIDReader/eidReader.ts +398 -12
- package/src/Shared/EIDReader/eidService.ts +49 -1
- package/src/Shared/EIDReader/nfcManagerCardService.ts +4 -6
- package/src/Shared/EIDReader/paceInfo.ts +159 -0
- package/src/Shared/EIDReader/paceKeySpec.ts +56 -0
- package/src/Shared/EIDReader/protocol/paceAPDUSender.ts +163 -0
- package/src/Shared/EIDReader/protocol/paceProtocol.ts +946 -0
- package/src/Shared/EIDReader/protocol/paceResult.ts +62 -0
- package/src/Shared/EIDReader/secureMessagingWrapper.ts +28 -10
- package/src/Shared/EIDReader/smartcards/commandAPDU.ts +2 -1
- package/src/Shared/EIDReader/tlv/tlv.helpers.ts +1 -1
- package/src/Shared/EIDReader/tlv/tlv.utils.ts +8 -5
- package/src/Shared/EIDReader/utils/aesCrypto.utils.ts +217 -0
- package/src/Shared/Libs/SignalingClient.ts +189 -0
- package/src/Shared/Libs/analytics.utils.ts +8 -0
- package/src/Shared/Libs/contains.ts +0 -53
- package/src/Shared/Libs/country-display.utils.ts +55 -0
- package/src/Shared/Libs/crypto.utils.ts +2 -2
- package/src/Shared/Libs/deeplink.utils.ts +12 -1
- package/src/Shared/Libs/demo.utils.ts +10 -0
- package/src/Shared/Libs/http-client.ts +19 -1
- package/src/Shared/Libs/mrz.utils.ts +3 -2
- package/src/Shared/Libs/promise.utils.ts +16 -2
- package/src/Shared/Libs/status-bar.utils.ts +21 -0
- package/src/Shared/Services/DataUploadService.ts +395 -0
- package/src/Shared/Services/VideoSessionService.ts +190 -0
- package/src/Shared/Services/WebRTCService.ts +636 -0
- package/src/Shared/Types/analytics.types.ts +4 -0
- package/src/Shared/Types/identificationInfo.ts +16 -1
- package/src/Translation/Resources/en.ts +88 -3
- package/src/Translation/Resources/tr.ts +89 -3
- package/src/Trustchex.tsx +65 -19
- package/src/version.ts +1 -1
|
@@ -38,12 +38,15 @@ import {
|
|
|
38
38
|
trackError,
|
|
39
39
|
useScreenTracking,
|
|
40
40
|
} from '../../Shared/Libs/analytics.utils';
|
|
41
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
42
|
+
import { useStatusBarWhiteBackground } from '../../Shared/Libs/status-bar.utils';
|
|
41
43
|
|
|
42
44
|
type OTPVerificationScreenParams = {
|
|
43
45
|
sessionId: string;
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
const OTPVerificationScreen = () => {
|
|
49
|
+
useKeepAwake();
|
|
47
50
|
const route =
|
|
48
51
|
useRoute<RouteProp<{ params: OTPVerificationScreenParams }, 'params'>>();
|
|
49
52
|
const sessionId = route.params?.sessionId;
|
|
@@ -60,6 +63,9 @@ const OTPVerificationScreen = () => {
|
|
|
60
63
|
|
|
61
64
|
useScreenTracking('otp_verification');
|
|
62
65
|
|
|
66
|
+
// Configure status bar for white background
|
|
67
|
+
useStatusBarWhiteBackground();
|
|
68
|
+
|
|
63
69
|
// Guard: If sessionId is not provided, show error
|
|
64
70
|
if (!sessionId) {
|
|
65
71
|
return (
|
|
@@ -5,11 +5,17 @@ import AppContext from '../../Shared/Contexts/AppContext';
|
|
|
5
5
|
import QrCodeScannerCamera from '../../Shared/Components/QrCodeScannerCamera';
|
|
6
6
|
import { useNavigation } from '@react-navigation/native';
|
|
7
7
|
import { handleDeepLink } from '../../Shared/Libs/deeplink.utils';
|
|
8
|
+
import { useKeepAwake } from '../../Shared/Libs/native-keep-awake.utils';
|
|
9
|
+
import { useStatusBarWhiteBackground } from '../../Shared/Libs/status-bar.utils';
|
|
8
10
|
|
|
9
11
|
const QrCodeScanningScreen = () => {
|
|
12
|
+
useKeepAwake();
|
|
10
13
|
const appContext = React.useContext(AppContext);
|
|
11
14
|
const navigation = useNavigation();
|
|
12
15
|
|
|
16
|
+
// Configure status bar for white background
|
|
17
|
+
useStatusBarWhiteBackground();
|
|
18
|
+
|
|
13
19
|
const onQrCodeScanned = (data: string) => {
|
|
14
20
|
const [bUrl, sId] = handleDeepLink({ url: data });
|
|
15
21
|
|
|
@@ -26,7 +32,7 @@ const QrCodeScanningScreen = () => {
|
|
|
26
32
|
appContext.identificationInfo.sessionId = sId;
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
navigation.
|
|
35
|
+
navigation.goBack();
|
|
30
36
|
}
|
|
31
37
|
};
|
|
32
38
|
|
|
@@ -25,11 +25,14 @@ import type {
|
|
|
25
25
|
IdentificationInfo,
|
|
26
26
|
LivenessDetection,
|
|
27
27
|
ScannedIdentityDocument,
|
|
28
|
+
VerbalConsentVideo,
|
|
28
29
|
} from '../../Shared/Types/identificationInfo';
|
|
29
30
|
import { runWithRetry } from '../../Shared/Libs/promise.utils';
|
|
31
|
+
import { useStatusBarWhiteBackground } from '../../Shared/Libs/status-bar.utils';
|
|
30
32
|
import NavigationManager, {
|
|
31
33
|
type NavigationManagerRef,
|
|
32
34
|
} from '../../Shared/Components/NavigationManager';
|
|
35
|
+
import { getLocalizedCountryName } from '../../Shared/Libs/country-display.utils';
|
|
33
36
|
import mrzUtils from '../../Shared/Libs/mrz.utils';
|
|
34
37
|
import { useTranslation } from 'react-i18next';
|
|
35
38
|
import { Video as VideoCompressor } from 'react-native-compressor';
|
|
@@ -53,14 +56,18 @@ const ResultScreen = () => {
|
|
|
53
56
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
54
57
|
const [progress, setProgress] = useState(0);
|
|
55
58
|
const navigationManagerRef = React.useRef<NavigationManagerRef>(null);
|
|
59
|
+
const hasSubmittedRef = React.useRef(false);
|
|
56
60
|
const [shouldShowDemoData, setShouldShowDemoData] = useState(false);
|
|
57
61
|
const [deviceIdentifier, setDeviceIdentifier] = useState<string>('');
|
|
58
|
-
const { t } = useTranslation();
|
|
62
|
+
const { t, i18n } = useTranslation();
|
|
59
63
|
const insets = useSafeAreaInsets();
|
|
60
64
|
|
|
61
65
|
// Track screen view and exit
|
|
62
66
|
useScreenTracking('result_screen');
|
|
63
67
|
|
|
68
|
+
// Configure status bar for white background
|
|
69
|
+
useStatusBarWhiteBackground();
|
|
70
|
+
|
|
64
71
|
const formatDate = useCallback((dateStr?: string | null) => {
|
|
65
72
|
if (!dateStr) return '';
|
|
66
73
|
|
|
@@ -72,7 +79,7 @@ const ResultScreen = () => {
|
|
|
72
79
|
const dd = dateStr.substring(4, 6);
|
|
73
80
|
|
|
74
81
|
// Assume 19xx if YY >= 50, else 20xx
|
|
75
|
-
const year = parseInt(yy) >= 50 ? `19${yy}` : `20${yy}`;
|
|
82
|
+
const year = parseInt(yy, 10) >= 50 ? `19${yy}` : `20${yy}`;
|
|
76
83
|
return `${dd}/${mm}/${year}`;
|
|
77
84
|
}
|
|
78
85
|
|
|
@@ -91,13 +98,47 @@ const ResultScreen = () => {
|
|
|
91
98
|
}
|
|
92
99
|
}, []);
|
|
93
100
|
|
|
101
|
+
const formatGender = useCallback(
|
|
102
|
+
(code?: string | null) => {
|
|
103
|
+
switch (code?.toUpperCase()) {
|
|
104
|
+
case 'M':
|
|
105
|
+
return t('eidScannerScreen.genderMale');
|
|
106
|
+
case 'F':
|
|
107
|
+
return t('eidScannerScreen.genderFemale');
|
|
108
|
+
default:
|
|
109
|
+
return t('eidScannerScreen.genderUnspecified');
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
[t]
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
const formatDocumentType = useCallback(
|
|
116
|
+
(code?: string | null) => {
|
|
117
|
+
if (!code) return '';
|
|
118
|
+
const upper = code.toUpperCase();
|
|
119
|
+
if (upper.startsWith('P')) return t('eidScannerScreen.docTypePassport');
|
|
120
|
+
if (upper.startsWith('I')) return t('eidScannerScreen.docTypeID');
|
|
121
|
+
if (upper.startsWith('A')) return t('eidScannerScreen.docTypeResidence');
|
|
122
|
+
if (upper.startsWith('V')) return t('eidScannerScreen.docTypeVisa');
|
|
123
|
+
return code;
|
|
124
|
+
},
|
|
125
|
+
[t]
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const formatNationality = useCallback(
|
|
129
|
+
(code?: string | null) => {
|
|
130
|
+
return getLocalizedCountryName(code, i18n.language);
|
|
131
|
+
},
|
|
132
|
+
[i18n.language]
|
|
133
|
+
);
|
|
134
|
+
|
|
94
135
|
const apiUrl = useMemo(
|
|
95
136
|
() => `${appContext.baseUrl}/api/app/mobile`,
|
|
96
137
|
[appContext.baseUrl]
|
|
97
138
|
);
|
|
98
139
|
|
|
99
140
|
useEffect(() => {
|
|
100
|
-
if (appContext.isDemoSession) {
|
|
141
|
+
if (appContext.isDemoSession || appContext.isTestVideoSession) {
|
|
101
142
|
setShouldShowDemoData(true);
|
|
102
143
|
// Generate device identifier for demo
|
|
103
144
|
NativeDeviceInfo.generateHumanReadableIdentifier().then(
|
|
@@ -107,6 +148,7 @@ const ResultScreen = () => {
|
|
|
107
148
|
}, [
|
|
108
149
|
appContext.identificationInfo.identificationId,
|
|
109
150
|
appContext.isDemoSession,
|
|
151
|
+
appContext.isTestVideoSession,
|
|
110
152
|
]);
|
|
111
153
|
|
|
112
154
|
const createIdentification = useCallback(
|
|
@@ -187,22 +229,22 @@ const ResultScreen = () => {
|
|
|
187
229
|
throw new Error('MRZ fields not found');
|
|
188
230
|
}
|
|
189
231
|
|
|
232
|
+
// Backend payload must contain raw MRZ data only.
|
|
233
|
+
// Human-friendly formatting is strictly for UI rendering paths.
|
|
234
|
+
const rawMrzFields = scannedDocument.mrzFields;
|
|
235
|
+
|
|
190
236
|
const identificationDocument = {
|
|
191
|
-
type:
|
|
192
|
-
name:
|
|
193
|
-
surname:
|
|
194
|
-
gender: getGenderEnumType(
|
|
195
|
-
number:
|
|
196
|
-
country:
|
|
237
|
+
type: rawMrzFields.documentCode,
|
|
238
|
+
name: rawMrzFields.firstName,
|
|
239
|
+
surname: rawMrzFields.lastName,
|
|
240
|
+
gender: getGenderEnumType(rawMrzFields.sex),
|
|
241
|
+
number: rawMrzFields.documentNumber,
|
|
242
|
+
country: rawMrzFields.issuingState,
|
|
197
243
|
barcodeValue: scannedDocument.barcodeValue,
|
|
198
|
-
personalNumber:
|
|
199
|
-
|
|
200
|
-
scannedDocument.mrzFields.optional1,
|
|
201
|
-
birthDate: mrzUtils.convertMRZDateToISODate(
|
|
202
|
-
scannedDocument.mrzFields.birthDate
|
|
203
|
-
),
|
|
244
|
+
personalNumber: rawMrzFields.personalNumber || rawMrzFields.optional1,
|
|
245
|
+
birthDate: mrzUtils.convertMRZDateToISODate(rawMrzFields.birthDate),
|
|
204
246
|
expiryDate: mrzUtils.convertMRZDateToISODate(
|
|
205
|
-
|
|
247
|
+
rawMrzFields.expirationDate
|
|
206
248
|
),
|
|
207
249
|
dataSource: scannedDocument.dataSource,
|
|
208
250
|
mrzText: scannedDocument.mrzText,
|
|
@@ -227,8 +269,17 @@ const ResultScreen = () => {
|
|
|
227
269
|
async (
|
|
228
270
|
identificationId: string,
|
|
229
271
|
scannedIdentityDocument?: ScannedIdentityDocument,
|
|
230
|
-
livenessDetection?: LivenessDetection
|
|
272
|
+
livenessDetection?: LivenessDetection,
|
|
273
|
+
skipIfAlreadyUploaded?: boolean
|
|
231
274
|
) => {
|
|
275
|
+
// Skip media upload if already uploaded during video call
|
|
276
|
+
if (skipIfAlreadyUploaded) {
|
|
277
|
+
console.log(
|
|
278
|
+
'[ResultScreen] Media already uploaded during video call, skipping'
|
|
279
|
+
);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
232
283
|
const uploadFileOptions: RNFS.UploadFileOptions = {
|
|
233
284
|
toUrl: `${apiUrl}/identifications/${identificationId}/media`,
|
|
234
285
|
method: 'POST',
|
|
@@ -287,7 +338,9 @@ const ResultScreen = () => {
|
|
|
287
338
|
const extension =
|
|
288
339
|
scannedIdentityDocument.faceImageMimeType === 'image/jp2'
|
|
289
340
|
? 'jp2'
|
|
290
|
-
: '
|
|
341
|
+
: scannedIdentityDocument.faceImageMimeType === 'image/png'
|
|
342
|
+
? 'png'
|
|
343
|
+
: 'jpg';
|
|
291
344
|
await RNFS.writeFile(
|
|
292
345
|
decodeURIComponent(
|
|
293
346
|
`${RNFS.TemporaryDirectoryPath}/FACE_IMAGE.${extension}`
|
|
@@ -378,10 +431,9 @@ const ResultScreen = () => {
|
|
|
378
431
|
if (livenessVideoPath) {
|
|
379
432
|
let videoFilePath: string;
|
|
380
433
|
if (Platform.OS === 'ios') {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
videoFilePath = `${RNFS.TemporaryDirectoryPath}/${new Date().getTime()}/LIVENESS_VIDEO.mp4`;
|
|
434
|
+
const tmpTimestamp = new Date().getTime();
|
|
435
|
+
await RNFS.mkdir(`${RNFS.TemporaryDirectoryPath}/${tmpTimestamp}`);
|
|
436
|
+
videoFilePath = `${RNFS.TemporaryDirectoryPath}/${tmpTimestamp}/LIVENESS_VIDEO.mp4`;
|
|
385
437
|
} else {
|
|
386
438
|
videoFilePath = `${RNFS.TemporaryDirectoryPath}/LIVENESS_VIDEO.mp4`;
|
|
387
439
|
}
|
|
@@ -414,6 +466,10 @@ const ResultScreen = () => {
|
|
|
414
466
|
}
|
|
415
467
|
}
|
|
416
468
|
|
|
469
|
+
if (uploadFileOptions.files.length === 0) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
417
473
|
const response = await RNFS.uploadFiles(uploadFileOptions).promise;
|
|
418
474
|
|
|
419
475
|
if (![200, 201, 204].includes(response.statusCode)) {
|
|
@@ -423,6 +479,68 @@ const ResultScreen = () => {
|
|
|
423
479
|
[apiUrl]
|
|
424
480
|
);
|
|
425
481
|
|
|
482
|
+
const uploadVerbalConsentVideos = useCallback(
|
|
483
|
+
async (
|
|
484
|
+
identificationId: string,
|
|
485
|
+
verbalConsentVideos?: VerbalConsentVideo[]
|
|
486
|
+
) => {
|
|
487
|
+
if (!verbalConsentVideos?.length) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
for (const consentVideo of verbalConsentVideos) {
|
|
492
|
+
const normalizedPath = consentVideo.videoPath.replace('file://', '');
|
|
493
|
+
let targetPath: string;
|
|
494
|
+
if (Platform.OS === 'ios') {
|
|
495
|
+
const tmpTimestamp = new Date().getTime();
|
|
496
|
+
await RNFS.mkdir(`${RNFS.TemporaryDirectoryPath}/${tmpTimestamp}`);
|
|
497
|
+
targetPath = `${RNFS.TemporaryDirectoryPath}/${tmpTimestamp}/VERBAL_CONSENT_VIDEO.mp4`;
|
|
498
|
+
} else {
|
|
499
|
+
targetPath = `${RNFS.TemporaryDirectoryPath}/VERBAL_CONSENT_VIDEO.mp4`;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
await RNFS.copyFile(normalizedPath, targetPath);
|
|
503
|
+
|
|
504
|
+
const compressedVideoPath = await VideoCompressor.compress(targetPath, {
|
|
505
|
+
compressionMethod: 'manual',
|
|
506
|
+
bitrate: 500000, // 500 kbps
|
|
507
|
+
maxSize: 1280, // HD 720p
|
|
508
|
+
minimumFileSizeForCompress: 0, // Always compress
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
const compressedNormalizedPath = compressedVideoPath.replace(
|
|
512
|
+
'file://',
|
|
513
|
+
''
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
const response = await RNFS.uploadFiles({
|
|
517
|
+
toUrl: `${apiUrl}/identifications/${identificationId}/media`,
|
|
518
|
+
method: 'POST',
|
|
519
|
+
headers: {
|
|
520
|
+
Accept: 'application/json',
|
|
521
|
+
},
|
|
522
|
+
fields: {
|
|
523
|
+
consentTitle: consentVideo.title,
|
|
524
|
+
consentText: consentVideo.text,
|
|
525
|
+
},
|
|
526
|
+
files: [
|
|
527
|
+
{
|
|
528
|
+
name: 'files',
|
|
529
|
+
filename: 'VERBAL_CONSENT_VIDEO.mp4',
|
|
530
|
+
filepath: compressedNormalizedPath,
|
|
531
|
+
filetype: 'video/mp4',
|
|
532
|
+
},
|
|
533
|
+
],
|
|
534
|
+
}).promise;
|
|
535
|
+
|
|
536
|
+
if (![200, 201, 204].includes(response.statusCode)) {
|
|
537
|
+
throw new Error('Verbal consent video upload failed');
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
},
|
|
541
|
+
[apiUrl]
|
|
542
|
+
);
|
|
543
|
+
|
|
426
544
|
const submit = useCallback(
|
|
427
545
|
async (identificationInfo: IdentificationInfo) => {
|
|
428
546
|
try {
|
|
@@ -432,11 +550,16 @@ const ResultScreen = () => {
|
|
|
432
550
|
throw new Error('IdentificationId not found');
|
|
433
551
|
}
|
|
434
552
|
|
|
553
|
+
const alreadyUploaded =
|
|
554
|
+
!!identificationInfo.mediaUploadedDuringVideoCall;
|
|
555
|
+
|
|
435
556
|
const sessionKey = await runWithRetry(() =>
|
|
436
557
|
getSessionKey(apiUrl, appContext.identificationInfo.sessionId)
|
|
437
558
|
);
|
|
438
559
|
|
|
439
|
-
|
|
560
|
+
if (!alreadyUploaded) {
|
|
561
|
+
await runWithRetry(() => createIdentification(identificationId));
|
|
562
|
+
}
|
|
440
563
|
setProgress(20);
|
|
441
564
|
|
|
442
565
|
await runWithRetry(() =>
|
|
@@ -444,27 +567,37 @@ const ResultScreen = () => {
|
|
|
444
567
|
);
|
|
445
568
|
setProgress(30);
|
|
446
569
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
570
|
+
if (!alreadyUploaded) {
|
|
571
|
+
const scannedIdentityDocument = identificationInfo.scannedDocument;
|
|
572
|
+
if (
|
|
573
|
+
scannedIdentityDocument &&
|
|
574
|
+
scannedIdentityDocument.documentType !== 'UNKNOWN'
|
|
575
|
+
) {
|
|
576
|
+
await runWithRetry(() =>
|
|
577
|
+
submitIdentificationDocument(
|
|
578
|
+
identificationId,
|
|
579
|
+
scannedIdentityDocument,
|
|
580
|
+
sessionKey
|
|
581
|
+
)
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
setProgress(40);
|
|
585
|
+
|
|
586
|
+
const livenessDetection = identificationInfo.livenessDetection;
|
|
452
587
|
await runWithRetry(() =>
|
|
453
|
-
|
|
588
|
+
uploadIdentificationMedia(
|
|
454
589
|
identificationId,
|
|
455
590
|
scannedIdentityDocument,
|
|
456
|
-
|
|
591
|
+
livenessDetection,
|
|
592
|
+
false
|
|
457
593
|
)
|
|
458
594
|
);
|
|
459
595
|
}
|
|
460
|
-
setProgress(40);
|
|
461
596
|
|
|
462
|
-
const livenessDetection = identificationInfo.livenessDetection;
|
|
463
597
|
await runWithRetry(() =>
|
|
464
|
-
|
|
598
|
+
uploadVerbalConsentVideos(
|
|
465
599
|
identificationId,
|
|
466
|
-
|
|
467
|
-
livenessDetection
|
|
600
|
+
identificationInfo.verbalConsentVideos
|
|
468
601
|
)
|
|
469
602
|
);
|
|
470
603
|
setProgress(90);
|
|
@@ -524,6 +657,7 @@ const ResultScreen = () => {
|
|
|
524
657
|
createIdentification,
|
|
525
658
|
apiUrl,
|
|
526
659
|
uploadIdentificationMedia,
|
|
660
|
+
uploadVerbalConsentVideos,
|
|
527
661
|
finishIdentification,
|
|
528
662
|
submitIdentificationDocument,
|
|
529
663
|
submitIdentificationConsent,
|
|
@@ -533,13 +667,28 @@ const ResultScreen = () => {
|
|
|
533
667
|
);
|
|
534
668
|
|
|
535
669
|
useEffect(() => {
|
|
536
|
-
if (
|
|
670
|
+
if (
|
|
671
|
+
appContext.identificationInfo &&
|
|
672
|
+
!appContext.isDemoSession &&
|
|
673
|
+
!appContext.isTestVideoSession &&
|
|
674
|
+
!hasSubmittedRef.current
|
|
675
|
+
) {
|
|
676
|
+
hasSubmittedRef.current = true;
|
|
537
677
|
submit(appContext.identificationInfo);
|
|
538
678
|
}
|
|
539
|
-
}, [
|
|
679
|
+
}, [
|
|
680
|
+
appContext.identificationInfo,
|
|
681
|
+
appContext.isDemoSession,
|
|
682
|
+
appContext.isTestVideoSession,
|
|
683
|
+
submit,
|
|
684
|
+
]);
|
|
540
685
|
|
|
541
686
|
useEffect(() => {
|
|
542
|
-
if (
|
|
687
|
+
if (
|
|
688
|
+
progress === 100 &&
|
|
689
|
+
!appContext.isDemoSession &&
|
|
690
|
+
!appContext.isTestVideoSession
|
|
691
|
+
) {
|
|
543
692
|
setTimeout(() => {
|
|
544
693
|
appContext.onCompleted?.();
|
|
545
694
|
navigationManagerRef.current?.reset();
|
|
@@ -601,10 +750,10 @@ const ResultScreen = () => {
|
|
|
601
750
|
{t('eidScannerScreen.documentCode')}:
|
|
602
751
|
</Text>
|
|
603
752
|
<Text style={styles.mrzInfoText}>
|
|
604
|
-
{
|
|
753
|
+
{formatDocumentType(
|
|
605
754
|
appContext.identificationInfo.scannedDocument
|
|
606
755
|
.mrzFields?.documentCode
|
|
607
|
-
}
|
|
756
|
+
)}
|
|
608
757
|
</Text>
|
|
609
758
|
</View>
|
|
610
759
|
<View style={styles.mrzInfoItem}>
|
|
@@ -612,10 +761,12 @@ const ResultScreen = () => {
|
|
|
612
761
|
{t('eidScannerScreen.nationality')}:
|
|
613
762
|
</Text>
|
|
614
763
|
<Text style={styles.mrzInfoText}>
|
|
615
|
-
{
|
|
764
|
+
{formatNationality(
|
|
616
765
|
appContext.identificationInfo.scannedDocument
|
|
617
|
-
.mrzFields?.
|
|
618
|
-
|
|
766
|
+
.mrzFields?.nationality ||
|
|
767
|
+
appContext.identificationInfo.scannedDocument
|
|
768
|
+
.mrzFields?.issuingState
|
|
769
|
+
)}
|
|
619
770
|
</Text>
|
|
620
771
|
</View>
|
|
621
772
|
<View style={styles.mrzInfoItem}>
|
|
@@ -678,10 +829,10 @@ const ResultScreen = () => {
|
|
|
678
829
|
{t('eidScannerScreen.gender')}:
|
|
679
830
|
</Text>
|
|
680
831
|
<Text style={styles.mrzInfoText}>
|
|
681
|
-
{
|
|
832
|
+
{formatGender(
|
|
682
833
|
appContext.identificationInfo.scannedDocument
|
|
683
834
|
.mrzFields?.sex
|
|
684
|
-
}
|
|
835
|
+
)}
|
|
685
836
|
</Text>
|
|
686
837
|
</View>
|
|
687
838
|
<View style={styles.mrzInfoItem}>
|
|
@@ -883,6 +1034,41 @@ const ResultScreen = () => {
|
|
|
883
1034
|
</ScrollView>
|
|
884
1035
|
</>
|
|
885
1036
|
)}
|
|
1037
|
+
|
|
1038
|
+
{!!appContext.identificationInfo.verbalConsentVideos
|
|
1039
|
+
?.length && (
|
|
1040
|
+
<>
|
|
1041
|
+
<Text style={styles.sectionHeader}>
|
|
1042
|
+
{t('resultScreen.demoVerbalConsent')}
|
|
1043
|
+
</Text>
|
|
1044
|
+
{appContext.identificationInfo.verbalConsentVideos.map(
|
|
1045
|
+
(consentVideo, index) => (
|
|
1046
|
+
<View key={`${consentVideo.videoPath}-${index}`}>
|
|
1047
|
+
<Text style={styles.sectionText}>
|
|
1048
|
+
{t('resultScreen.demoVerbalConsentTitle')}:{' '}
|
|
1049
|
+
{consentVideo.title}
|
|
1050
|
+
</Text>
|
|
1051
|
+
<Text style={styles.sectionText}>
|
|
1052
|
+
{t('resultScreen.demoVerbalConsentText')}:{' '}
|
|
1053
|
+
{consentVideo.text}
|
|
1054
|
+
</Text>
|
|
1055
|
+
<Text style={styles.sectionText}>
|
|
1056
|
+
{t('resultScreen.demoVideo')}
|
|
1057
|
+
</Text>
|
|
1058
|
+
<Video
|
|
1059
|
+
source={{
|
|
1060
|
+
uri: consentVideo.videoPath,
|
|
1061
|
+
}}
|
|
1062
|
+
resizeMode="contain"
|
|
1063
|
+
style={styles.video}
|
|
1064
|
+
controls={true}
|
|
1065
|
+
muted={false}
|
|
1066
|
+
/>
|
|
1067
|
+
</View>
|
|
1068
|
+
)
|
|
1069
|
+
)}
|
|
1070
|
+
</>
|
|
1071
|
+
)}
|
|
886
1072
|
</View>
|
|
887
1073
|
</ScrollView>
|
|
888
1074
|
<View style={{ paddingBottom: insets.bottom }}>
|
|
@@ -973,9 +1159,10 @@ const styles = StyleSheet.create({
|
|
|
973
1159
|
},
|
|
974
1160
|
image: {
|
|
975
1161
|
width: 100,
|
|
976
|
-
height:
|
|
977
|
-
objectFit: '
|
|
978
|
-
borderRadius:
|
|
1162
|
+
height: 140,
|
|
1163
|
+
objectFit: 'cover',
|
|
1164
|
+
borderRadius: 12,
|
|
1165
|
+
overflow: 'hidden',
|
|
979
1166
|
},
|
|
980
1167
|
imageItem: {
|
|
981
1168
|
display: 'flex',
|