@trustchex/react-native-sdk 1.478.7 → 1.483.4
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/camera/TrustchexCameraView.kt +57 -3
- package/ios/Camera/TrustchexCameraView.swift +20 -15
- package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +0 -3
- package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +21 -0
- package/lib/module/Screens/Dynamic/VideoCallScreen.js +1 -1
- package/lib/module/Screens/Static/ResultScreen.js +75 -16
- package/lib/module/Shared/Components/DiagnosticReportButton.js +64 -0
- package/lib/module/Shared/Components/EIDScanner.js +52 -19
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +132 -8
- package/lib/module/Shared/Components/NavigationManager.js +7 -9
- package/lib/module/Shared/Contexts/AppContext.js +3 -0
- package/lib/module/Shared/EIDReader/eidReader.js +167 -30
- package/lib/module/Shared/EIDReader/lds/icao/dg11File.js +77 -0
- package/lib/module/Shared/Libs/MRZ_KNOWN_ISSUES.md +7 -0
- package/lib/module/Shared/Libs/diagnosticReport.js +133 -0
- package/lib/module/Shared/Libs/diagnostics.js +171 -0
- package/lib/module/Shared/Libs/documentDataNormalizer.js +104 -0
- package/lib/module/Shared/Libs/mrz.utils.js +0 -5
- package/lib/module/Shared/Libs/mrzFrameAggregator.js +32 -5
- package/lib/module/Shared/Libs/mrzTransliteration.js +80 -0
- package/lib/module/Shared/Libs/native-device-info.utils.js +67 -0
- package/lib/module/Shared/Libs/sendDiagnosticReport.js +130 -0
- package/lib/module/Shared/Services/DataUploadService.js +6 -3
- package/lib/module/Shared/Types/documentData.js +1 -0
- package/lib/module/Shared/Types/documentReadResult.js +3 -0
- package/lib/module/Translation/Resources/en.js +5 -0
- package/lib/module/Translation/Resources/tr.js +5 -0
- package/lib/module/Trustchex.js +31 -4
- package/lib/module/version.js +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/VideoCallScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/DiagnosticReportButton.d.ts +20 -0
- package/lib/typescript/src/Shared/Components/DiagnosticReportButton.d.ts.map +1 -0
- 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.types.d.ts +10 -0
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts +10 -0
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +5 -0
- package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts +2 -0
- package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
- package/lib/typescript/src/Shared/EIDReader/lds/icao/dg11File.d.ts +35 -0
- package/lib/typescript/src/Shared/EIDReader/lds/icao/dg11File.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/diagnosticReport.d.ts +48 -0
- package/lib/typescript/src/Shared/Libs/diagnosticReport.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/diagnostics.d.ts +145 -0
- package/lib/typescript/src/Shared/Libs/diagnostics.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/documentDataNormalizer.d.ts +12 -0
- package/lib/typescript/src/Shared/Libs/documentDataNormalizer.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/mrzFrameAggregator.d.ts +33 -0
- package/lib/typescript/src/Shared/Libs/mrzFrameAggregator.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/mrzTransliteration.d.ts +3 -0
- package/lib/typescript/src/Shared/Libs/mrzTransliteration.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/native-device-info.utils.d.ts +33 -0
- package/lib/typescript/src/Shared/Libs/native-device-info.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/sendDiagnosticReport.d.ts +30 -0
- package/lib/typescript/src/Shared/Libs/sendDiagnosticReport.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +3 -2
- package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Types/documentData.d.ts +44 -0
- package/lib/typescript/src/Shared/Types/documentData.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Types/documentReadResult.d.ts +44 -0
- package/lib/typescript/src/Shared/Types/documentReadResult.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Types/mrzFields.d.ts +1 -1
- package/lib/typescript/src/Shared/Types/mrzFields.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/en.d.ts +5 -0
- package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts +5 -0
- package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
- package/lib/typescript/src/Trustchex.d.ts +9 -0
- package/lib/typescript/src/Trustchex.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +5 -1
- package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +0 -4
- package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +23 -0
- package/src/Screens/Dynamic/VideoCallScreen.tsx +5 -1
- package/src/Screens/Static/ResultScreen.tsx +85 -16
- package/src/Shared/Components/DiagnosticReportButton.tsx +77 -0
- package/src/Shared/Components/EIDScanner.tsx +67 -18
- package/src/Shared/Components/IdentityDocumentCamera.tsx +145 -7
- package/src/Shared/Components/IdentityDocumentCamera.types.ts +6 -0
- package/src/Shared/Components/NavigationManager.tsx +7 -7
- package/src/Shared/Components/TrustchexCamera.tsx +6 -0
- package/src/Shared/Contexts/AppContext.ts +8 -0
- package/src/Shared/EIDReader/eidReader.ts +193 -47
- package/src/Shared/EIDReader/lds/icao/dg11File.ts +94 -0
- package/src/Shared/Libs/MRZ_KNOWN_ISSUES.md +7 -0
- package/src/Shared/Libs/diagnosticReport.ts +206 -0
- package/src/Shared/Libs/diagnostics.ts +251 -0
- package/src/Shared/Libs/documentDataNormalizer.ts +108 -0
- package/src/Shared/Libs/mrz.utils.ts +0 -5
- package/src/Shared/Libs/mrzFrameAggregator.ts +61 -3
- package/src/Shared/Libs/mrzTransliteration.ts +131 -0
- package/src/Shared/Libs/native-device-info.utils.ts +116 -0
- package/src/Shared/Libs/sendDiagnosticReport.ts +165 -0
- package/src/Shared/Services/DataUploadService.ts +9 -3
- package/src/Shared/Types/documentData.ts +52 -0
- package/src/Shared/Types/documentReadResult.ts +47 -0
- package/src/Shared/Types/mrzFields.ts +0 -5
- package/src/Translation/Resources/en.ts +6 -0
- package/src/Translation/Resources/tr.ts +6 -0
- package/src/Trustchex.tsx +48 -3
- package/src/index.tsx +7 -0
- package/src/version.ts +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { useContext, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import type { MRZFields } from '../../Shared/Types/mrzFields';
|
|
4
|
+
import { buildDocumentName } from '../../Shared/Libs/mrzTransliteration';
|
|
5
|
+
import { normalizeFromMRZFields } from '../../Shared/Libs/documentDataNormalizer';
|
|
4
6
|
import { Alert, SafeAreaView, StyleSheet, View } from 'react-native';
|
|
5
7
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
6
8
|
import IdentityDocumentCamera, {
|
|
@@ -122,6 +124,27 @@ const IdentityDocumentScanningScreen = () => {
|
|
|
122
124
|
true
|
|
123
125
|
);
|
|
124
126
|
|
|
127
|
+
{
|
|
128
|
+
const documentData = normalizeFromMRZFields(mrzFields);
|
|
129
|
+
const faceImg = idFrontSideData?.faceImage || passportData?.faceImage;
|
|
130
|
+
const builtName = buildDocumentName(
|
|
131
|
+
documentData.firstName,
|
|
132
|
+
documentData.lastName,
|
|
133
|
+
documentData.issuingCountry
|
|
134
|
+
);
|
|
135
|
+
const documentReadResult = {
|
|
136
|
+
document: {
|
|
137
|
+
...documentData,
|
|
138
|
+
firstName: builtName.displayFirst,
|
|
139
|
+
lastName: builtName.displayLast,
|
|
140
|
+
},
|
|
141
|
+
name: builtName,
|
|
142
|
+
face: faceImg ? { data: faceImg, mimeType: 'image/jpeg' } : undefined,
|
|
143
|
+
};
|
|
144
|
+
appContext.setLastDocumentRead?.(documentReadResult);
|
|
145
|
+
appContext.onDocumentRead?.(documentReadResult);
|
|
146
|
+
}
|
|
147
|
+
|
|
125
148
|
setTimeout(
|
|
126
149
|
() => navigationManagerRef.current?.navigateToNextStep(),
|
|
127
150
|
1000
|
|
@@ -147,7 +147,11 @@ const VideoCallScreen = ({ navigation }: any) => {
|
|
|
147
147
|
const uploadService = new DataUploadService(baseUrl);
|
|
148
148
|
dataUploadServiceRef.current = uploadService;
|
|
149
149
|
const uploaded =
|
|
150
|
-
await uploadService.uploadCollectedData(
|
|
150
|
+
await uploadService.uploadCollectedData(
|
|
151
|
+
identificationInfo,
|
|
152
|
+
undefined,
|
|
153
|
+
appContext.lastDocumentRead?.name
|
|
154
|
+
);
|
|
151
155
|
if (!uploaded) {
|
|
152
156
|
console.warn('[VideoCallScreen] Upload service returned false');
|
|
153
157
|
if (mounted) {
|
|
@@ -39,7 +39,32 @@ import { Video as VideoCompressor } from 'react-native-compressor';
|
|
|
39
39
|
import { encryptWithAes, getSessionKey } from '../../Shared/Libs/crypto.utils';
|
|
40
40
|
import Video from 'react-native-video';
|
|
41
41
|
import StyledButton from '../../Shared/Components/StyledButton';
|
|
42
|
+
import DiagnosticReportButton from '../../Shared/Components/DiagnosticReportButton';
|
|
43
|
+
import type { DiagnosticImage } from '../../Shared/Libs/sendDiagnosticReport';
|
|
42
44
|
import NativeDeviceInfo from '../../Shared/Libs/native-device-info.utils';
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Collect the captured document/face images (base64) as attachments for a
|
|
48
|
+
* diagnostic report. On an ID card the BACK image is the MRZ side; on a passport
|
|
49
|
+
* the front carries the MRZ. The NFC chip face arrives as `faceImage` with its
|
|
50
|
+
* own mime type, which may be png.
|
|
51
|
+
*/
|
|
52
|
+
const collectDiagnosticImages = (
|
|
53
|
+
doc?: ScannedIdentityDocument
|
|
54
|
+
): DiagnosticImage[] => {
|
|
55
|
+
if (!doc) return [];
|
|
56
|
+
const out: DiagnosticImage[] = [];
|
|
57
|
+
const push = (name: string, b64?: string, mime: 'jpg' | 'png' = 'jpg') => {
|
|
58
|
+
if (b64 && b64 !== '') out.push({ name, base64: b64, mime });
|
|
59
|
+
};
|
|
60
|
+
push('mrz-side', doc.backImage);
|
|
61
|
+
push('front', doc.frontImage);
|
|
62
|
+
const faceMime = doc.faceImageMimeType === 'image/png' ? 'png' : 'jpg';
|
|
63
|
+
push('face', doc.faceImage, faceMime);
|
|
64
|
+
push('secondary-face', doc.secondaryFaceImage);
|
|
65
|
+
push('hologram', doc.hologramImage);
|
|
66
|
+
return out;
|
|
67
|
+
};
|
|
43
68
|
import {
|
|
44
69
|
trackError,
|
|
45
70
|
trackFunnelStep,
|
|
@@ -234,14 +259,16 @@ const ResultScreen = () => {
|
|
|
234
259
|
throw new Error('MRZ fields not found');
|
|
235
260
|
}
|
|
236
261
|
|
|
237
|
-
// Backend payload must contain raw MRZ data only.
|
|
238
|
-
// Human-friendly formatting is strictly for UI rendering paths.
|
|
239
262
|
const rawMrzFields = scannedDocument.mrzFields;
|
|
263
|
+
const docName = appContext.lastDocumentRead?.name;
|
|
240
264
|
|
|
241
265
|
const identificationDocument = {
|
|
242
266
|
type: rawMrzFields.documentCode,
|
|
243
267
|
name: rawMrzFields.firstName,
|
|
244
268
|
surname: rawMrzFields.lastName,
|
|
269
|
+
displayName: docName?.source === 'dg11' ? docName.displayFirst : undefined,
|
|
270
|
+
displaySurname: docName?.source === 'dg11' ? docName.displayLast : undefined,
|
|
271
|
+
nameSource: docName?.source === 'dg11' ? docName.source : undefined,
|
|
245
272
|
gender: getGenderEnumType(rawMrzFields.sex),
|
|
246
273
|
number: rawMrzFields.documentNumber,
|
|
247
274
|
country: rawMrzFields.issuingState,
|
|
@@ -267,7 +294,7 @@ const ResultScreen = () => {
|
|
|
267
294
|
}
|
|
268
295
|
);
|
|
269
296
|
},
|
|
270
|
-
[apiUrl, getGenderEnumType]
|
|
297
|
+
[apiUrl, appContext.lastDocumentRead, getGenderEnumType]
|
|
271
298
|
);
|
|
272
299
|
|
|
273
300
|
const uploadIdentificationMedia = useCallback(
|
|
@@ -765,23 +792,35 @@ const ResultScreen = () => {
|
|
|
765
792
|
<Text style={styles.mrzInfoLabel}>
|
|
766
793
|
{t('eidScannerScreen.name')}:
|
|
767
794
|
</Text>
|
|
768
|
-
<
|
|
769
|
-
{
|
|
770
|
-
appContext.
|
|
771
|
-
.
|
|
772
|
-
|
|
773
|
-
|
|
795
|
+
<View style={styles.mrzInfoValueGroup}>
|
|
796
|
+
<Text style={styles.mrzInfoText}>
|
|
797
|
+
{appContext.lastDocumentRead?.name.source === 'dg11'
|
|
798
|
+
? appContext.lastDocumentRead.name.displayFirst
|
|
799
|
+
: appContext.identificationInfo.scannedDocument.mrzFields?.firstName}
|
|
800
|
+
</Text>
|
|
801
|
+
{appContext.lastDocumentRead?.name.source === 'dg11' && (
|
|
802
|
+
<Text style={styles.mrzInfoSubText}>
|
|
803
|
+
{appContext.identificationInfo.scannedDocument.mrzFields?.firstName}
|
|
804
|
+
</Text>
|
|
805
|
+
)}
|
|
806
|
+
</View>
|
|
774
807
|
</View>
|
|
775
808
|
<View style={styles.mrzInfoItem}>
|
|
776
809
|
<Text style={styles.mrzInfoLabel}>
|
|
777
810
|
{t('eidScannerScreen.surname')}:
|
|
778
811
|
</Text>
|
|
779
|
-
<
|
|
780
|
-
{
|
|
781
|
-
appContext.
|
|
782
|
-
.
|
|
783
|
-
|
|
784
|
-
|
|
812
|
+
<View style={styles.mrzInfoValueGroup}>
|
|
813
|
+
<Text style={styles.mrzInfoText}>
|
|
814
|
+
{appContext.lastDocumentRead?.name.source === 'dg11'
|
|
815
|
+
? appContext.lastDocumentRead.name.displayLast
|
|
816
|
+
: appContext.identificationInfo.scannedDocument.mrzFields?.lastName}
|
|
817
|
+
</Text>
|
|
818
|
+
{appContext.lastDocumentRead?.name.source === 'dg11' && (
|
|
819
|
+
<Text style={styles.mrzInfoSubText}>
|
|
820
|
+
{appContext.identificationInfo.scannedDocument.mrzFields?.lastName}
|
|
821
|
+
</Text>
|
|
822
|
+
)}
|
|
823
|
+
</View>
|
|
785
824
|
</View>
|
|
786
825
|
<View style={styles.mrzInfoItem}>
|
|
787
826
|
<Text style={styles.mrzInfoLabel}>
|
|
@@ -1045,7 +1084,7 @@ const ResultScreen = () => {
|
|
|
1045
1084
|
)}
|
|
1046
1085
|
</View>
|
|
1047
1086
|
</ScrollView>
|
|
1048
|
-
<View style={{ paddingBottom: insets.bottom }}>
|
|
1087
|
+
<View style={[styles.footer, { paddingBottom: insets.bottom + 20 }]}>
|
|
1049
1088
|
<StyledButton
|
|
1050
1089
|
mode="contained"
|
|
1051
1090
|
onPress={() => {
|
|
@@ -1055,6 +1094,26 @@ const ResultScreen = () => {
|
|
|
1055
1094
|
>
|
|
1056
1095
|
{t('resultScreen.demoStartOver')}
|
|
1057
1096
|
</StyledButton>
|
|
1097
|
+
<DiagnosticReportButton
|
|
1098
|
+
sessionId={appContext.identificationInfo?.sessionId}
|
|
1099
|
+
scan={{
|
|
1100
|
+
documentType:
|
|
1101
|
+
appContext.identificationInfo?.scannedDocument
|
|
1102
|
+
?.documentType,
|
|
1103
|
+
dataSource:
|
|
1104
|
+
appContext.identificationInfo?.scannedDocument?.dataSource,
|
|
1105
|
+
mrzText:
|
|
1106
|
+
appContext.identificationInfo?.scannedDocument?.mrzText,
|
|
1107
|
+
mrzFields:
|
|
1108
|
+
appContext.identificationInfo?.scannedDocument?.mrzFields,
|
|
1109
|
+
barcodeValue:
|
|
1110
|
+
appContext.identificationInfo?.scannedDocument
|
|
1111
|
+
?.barcodeValue,
|
|
1112
|
+
}}
|
|
1113
|
+
images={collectDiagnosticImages(
|
|
1114
|
+
appContext.identificationInfo?.scannedDocument
|
|
1115
|
+
)}
|
|
1116
|
+
/>
|
|
1058
1117
|
</View>
|
|
1059
1118
|
</>
|
|
1060
1119
|
) : (
|
|
@@ -1182,6 +1241,16 @@ const styles = StyleSheet.create({
|
|
|
1182
1241
|
fontSize: 10,
|
|
1183
1242
|
fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
|
|
1184
1243
|
},
|
|
1244
|
+
mrzInfoValueGroup: {
|
|
1245
|
+
flexDirection: 'column',
|
|
1246
|
+
alignItems: 'flex-end',
|
|
1247
|
+
},
|
|
1248
|
+
mrzInfoSubText: {
|
|
1249
|
+
color: '#aaa',
|
|
1250
|
+
fontSize: 9,
|
|
1251
|
+
fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
|
|
1252
|
+
marginTop: 1,
|
|
1253
|
+
},
|
|
1185
1254
|
mrzTextContainer: {
|
|
1186
1255
|
padding: 12,
|
|
1187
1256
|
backgroundColor: '#F3F4F6',
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Alert } from 'react-native';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import StyledButton from './StyledButton';
|
|
5
|
+
import {
|
|
6
|
+
sendDiagnosticReport,
|
|
7
|
+
isDiagnosticSharingAvailable,
|
|
8
|
+
type DiagnosticImage,
|
|
9
|
+
} from '../Libs/sendDiagnosticReport';
|
|
10
|
+
import type { ScanDataForReport } from '../Libs/diagnosticReport';
|
|
11
|
+
import { SDK_VERSION } from '../../version';
|
|
12
|
+
|
|
13
|
+
export interface DiagnosticReportButtonProps {
|
|
14
|
+
scan: ScanDataForReport;
|
|
15
|
+
sessionId?: string;
|
|
16
|
+
images?: DiagnosticImage[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* "Report a scanning issue" button for the result screen.
|
|
21
|
+
*
|
|
22
|
+
* Shows a brief notice describing what will be shared (the draft itself is the
|
|
23
|
+
* user's review/consent step), then opens the OS share sheet — the user picks
|
|
24
|
+
* email / WhatsApp / Drive / etc. and sends the diagnostic bundle to support.
|
|
25
|
+
* Self-contained so the result screen only needs to render it with the scan
|
|
26
|
+
* data + captured images.
|
|
27
|
+
*/
|
|
28
|
+
const DiagnosticReportButton: React.FC<DiagnosticReportButtonProps> = ({
|
|
29
|
+
scan,
|
|
30
|
+
sessionId,
|
|
31
|
+
images,
|
|
32
|
+
}) => {
|
|
33
|
+
const { t } = useTranslation();
|
|
34
|
+
const [sending, setSending] = useState(false);
|
|
35
|
+
|
|
36
|
+
// `react-native-share` is optional — hide the button entirely when the host
|
|
37
|
+
// app hasn't installed it, so apps that don't want diagnostics see no UI.
|
|
38
|
+
if (!isDiagnosticSharingAvailable()) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const onPress = () => {
|
|
43
|
+
if (sending) return;
|
|
44
|
+
// Brief notice — the share draft is the actual review/consent step.
|
|
45
|
+
Alert.alert(
|
|
46
|
+
t('diagnosticReport.noticeTitle'),
|
|
47
|
+
t('diagnosticReport.noticeBody'),
|
|
48
|
+
[
|
|
49
|
+
{ text: t('diagnosticReport.cancel'), style: 'cancel' },
|
|
50
|
+
{
|
|
51
|
+
text: t('diagnosticReport.continue'),
|
|
52
|
+
onPress: async () => {
|
|
53
|
+
setSending(true);
|
|
54
|
+
try {
|
|
55
|
+
await sendDiagnosticReport({
|
|
56
|
+
scan,
|
|
57
|
+
sdkVersion: SDK_VERSION,
|
|
58
|
+
sessionId,
|
|
59
|
+
images,
|
|
60
|
+
});
|
|
61
|
+
} finally {
|
|
62
|
+
setSending(false);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
]
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<StyledButton mode="outlined" onPress={onPress} disabled={sending}>
|
|
72
|
+
{t('diagnosticReport.button')}
|
|
73
|
+
</StyledButton>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export default DiagnosticReportButton;
|
|
@@ -9,6 +9,8 @@ import { MRZInfo } from '../EIDReader/lds/icao/mrzInfo';
|
|
|
9
9
|
import { eidReader } from '../EIDReader/eidReader';
|
|
10
10
|
import NativeProgressBar from './NativeProgressBar';
|
|
11
11
|
import type { MRZFields } from '../Types/mrzFields';
|
|
12
|
+
import { buildDocumentName } from '../Libs/mrzTransliteration';
|
|
13
|
+
import { normalizeFromMRZInfo } from '../Libs/documentDataNormalizer';
|
|
12
14
|
import { useTranslation } from 'react-i18next';
|
|
13
15
|
import AppContext from '../Contexts/AppContext';
|
|
14
16
|
import StyledButton from './StyledButton';
|
|
@@ -52,6 +54,7 @@ const EIDScanner = ({
|
|
|
52
54
|
const [documentMRZInfo, setDocumentMRZInfo] = React.useState<MRZInfo>();
|
|
53
55
|
const [documentFaceImageMimeType, setDocumentFaceImageMimeType] =
|
|
54
56
|
React.useState<string>();
|
|
57
|
+
const [documentName, setDocumentName] = React.useState<import('../Types/documentReadResult').DocumentName>();
|
|
55
58
|
const [progress, setProgress] = React.useState(0);
|
|
56
59
|
const [progressStage, setProgressStage] = React.useState<string>('');
|
|
57
60
|
|
|
@@ -133,6 +136,21 @@ const EIDScanner = ({
|
|
|
133
136
|
const [voiceGuidanceMessage, setVoiceGuidanceMessage] = useState<string>();
|
|
134
137
|
const [attemptNumber, setAttemptNumber] = useState<number>(0);
|
|
135
138
|
|
|
139
|
+
const getFieldsFromMRZ = useCallback((mrz: MRZInfo) => {
|
|
140
|
+
return {
|
|
141
|
+
documentCode: mrz.getDocumentCode(),
|
|
142
|
+
personalNumber: mrz.getPersonalNumber() || mrz.getOptionalData1(),
|
|
143
|
+
documentNumber: mrz.getDocumentNumber(),
|
|
144
|
+
firstName: mrz.getSecondaryIdentifier(),
|
|
145
|
+
lastName: mrz.getPrimaryIdentifier(),
|
|
146
|
+
birthDate: mrz.getDateOfBirth(),
|
|
147
|
+
expirationDate: mrz.getDateOfExpiry(),
|
|
148
|
+
issuingState: mrz.getIssuingState(),
|
|
149
|
+
sex: mrz.getGender().getStrCode(),
|
|
150
|
+
nationality: mrz.getNationality(),
|
|
151
|
+
} satisfies MRZFields;
|
|
152
|
+
}, []);
|
|
153
|
+
|
|
136
154
|
const readNFC = useCallback(async () => {
|
|
137
155
|
const startTime = Date.now();
|
|
138
156
|
const currentAttempt = attemptNumber + 1;
|
|
@@ -228,6 +246,32 @@ const EIDScanner = ({
|
|
|
228
246
|
setDocumentMRZInfo(passportData.mrz);
|
|
229
247
|
setDocumentFaceImageMimeType(passportData.mimeType);
|
|
230
248
|
setIsScanned(true);
|
|
249
|
+
|
|
250
|
+
{
|
|
251
|
+
const documentData = normalizeFromMRZInfo(passportData.mrz);
|
|
252
|
+
const builtName = buildDocumentName(
|
|
253
|
+
documentData.firstName,
|
|
254
|
+
documentData.lastName,
|
|
255
|
+
documentData.issuingCountry,
|
|
256
|
+
passportData.dg11FirstName,
|
|
257
|
+
passportData.dg11LastName
|
|
258
|
+
);
|
|
259
|
+
setDocumentName(builtName);
|
|
260
|
+
const documentReadResult = {
|
|
261
|
+
document: {
|
|
262
|
+
...documentData,
|
|
263
|
+
firstName: builtName.displayFirst,
|
|
264
|
+
lastName: builtName.displayLast,
|
|
265
|
+
},
|
|
266
|
+
name: builtName,
|
|
267
|
+
face: {
|
|
268
|
+
data: passportData.faceImage,
|
|
269
|
+
mimeType: passportData.mimeType,
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
appContext.setLastDocumentRead?.(documentReadResult);
|
|
273
|
+
appContext.onDocumentRead?.(documentReadResult);
|
|
274
|
+
}
|
|
231
275
|
await trackEIDScanComplete(
|
|
232
276
|
docType,
|
|
233
277
|
scanDuration,
|
|
@@ -314,23 +358,10 @@ const EIDScanner = ({
|
|
|
314
358
|
isEnabled,
|
|
315
359
|
attemptNumber,
|
|
316
360
|
t,
|
|
361
|
+
getFieldsFromMRZ,
|
|
362
|
+
appContext,
|
|
317
363
|
]);
|
|
318
364
|
|
|
319
|
-
const getFieldsFromMRZ = useCallback((mrz: MRZInfo) => {
|
|
320
|
-
return {
|
|
321
|
-
documentCode: mrz.getDocumentCode(),
|
|
322
|
-
personalNumber: mrz.getPersonalNumber() || mrz.getOptionalData1(),
|
|
323
|
-
documentNumber: mrz.getDocumentNumber(),
|
|
324
|
-
firstName: mrz.getSecondaryIdentifier(),
|
|
325
|
-
lastName: mrz.getPrimaryIdentifier(),
|
|
326
|
-
birthDate: mrz.getDateOfBirth(),
|
|
327
|
-
expirationDate: mrz.getDateOfExpiry(),
|
|
328
|
-
issuingState: mrz.getIssuingState(),
|
|
329
|
-
sex: mrz.getGender().getStrCode(),
|
|
330
|
-
nationality: mrz.getNationality(),
|
|
331
|
-
} satisfies MRZFields;
|
|
332
|
-
}, []);
|
|
333
|
-
|
|
334
365
|
useEffect(() => {
|
|
335
366
|
const checkIsSupported = async () => {
|
|
336
367
|
const deviceIsSupported = await NFCManager.isSupported();
|
|
@@ -533,11 +564,13 @@ const EIDScanner = ({
|
|
|
533
564
|
<View style={styles.idCardFields}>
|
|
534
565
|
<IDCardField
|
|
535
566
|
label={t('eidScannerScreen.surname')}
|
|
536
|
-
value={documentMRZInfo.getPrimaryIdentifier()}
|
|
567
|
+
value={documentName?.displayLast ?? documentMRZInfo.getPrimaryIdentifier()}
|
|
568
|
+
subValue={documentName?.source === 'dg11' ? documentMRZInfo.getPrimaryIdentifier() : undefined}
|
|
537
569
|
/>
|
|
538
570
|
<IDCardField
|
|
539
571
|
label={t('eidScannerScreen.name')}
|
|
540
|
-
value={documentMRZInfo.getSecondaryIdentifier()}
|
|
572
|
+
value={documentName?.displayFirst ?? documentMRZInfo.getSecondaryIdentifier()}
|
|
573
|
+
subValue={documentName?.source === 'dg11' ? documentMRZInfo.getSecondaryIdentifier() : undefined}
|
|
541
574
|
/>
|
|
542
575
|
<IDCardField
|
|
543
576
|
label={t('eidScannerScreen.documentNumber')}
|
|
@@ -866,6 +899,11 @@ const styles = StyleSheet.create({
|
|
|
866
899
|
flexShrink: 1,
|
|
867
900
|
flexWrap: 'wrap',
|
|
868
901
|
},
|
|
902
|
+
idCardFieldSubValue: {
|
|
903
|
+
fontSize: 9,
|
|
904
|
+
color: '#aaa',
|
|
905
|
+
marginTop: 1,
|
|
906
|
+
},
|
|
869
907
|
guide: {
|
|
870
908
|
flex: 1,
|
|
871
909
|
display: 'flex',
|
|
@@ -896,12 +934,23 @@ const styles = StyleSheet.create({
|
|
|
896
934
|
},
|
|
897
935
|
});
|
|
898
936
|
|
|
899
|
-
const IDCardField = ({
|
|
937
|
+
const IDCardField = ({
|
|
938
|
+
label,
|
|
939
|
+
value,
|
|
940
|
+
subValue,
|
|
941
|
+
}: {
|
|
942
|
+
label: string;
|
|
943
|
+
value: string;
|
|
944
|
+
subValue?: string;
|
|
945
|
+
}) => (
|
|
900
946
|
<View style={styles.idCardFieldItem}>
|
|
901
947
|
<Text style={styles.idCardFieldLabel} numberOfLines={1}>
|
|
902
948
|
{label}
|
|
903
949
|
</Text>
|
|
904
950
|
<Text style={styles.idCardFieldValue}>{value || '—'}</Text>
|
|
951
|
+
{subValue ? (
|
|
952
|
+
<Text style={styles.idCardFieldSubValue}>{subValue}</Text>
|
|
953
|
+
) : null}
|
|
905
954
|
</View>
|
|
906
955
|
);
|
|
907
956
|
|