@trustchex/react-native-sdk 1.360.0 → 1.362.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/TrustchexSDK.podspec +3 -1
- package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKPackage.kt +0 -13
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraManager.kt +0 -8
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +59 -39
- package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +94 -13
- package/ios/Camera/TrustchexCameraManager.m +0 -2
- package/ios/Camera/TrustchexCameraManager.swift +0 -7
- package/ios/Camera/TrustchexCameraView.swift +16 -47
- package/ios/OpenCV/OpenCVHelper.h +17 -0
- package/ios/OpenCV/OpenCVHelper.mm +128 -0
- package/ios/OpenCV/OpenCVModule.h +6 -0
- package/ios/OpenCV/OpenCVModule.mm +141 -0
- package/ios/TrustchexSDK-Bridging-Header.h +8 -0
- package/lib/module/Screens/Debug/MRZTestScreen.js +175 -0
- package/lib/module/Shared/Components/DebugNavigationPanel.js +4 -0
- package/lib/module/Shared/Components/EIDScanner.js +0 -78
- package/lib/module/Shared/Components/FaceCamera.js +6 -3
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +199 -153
- package/lib/module/Shared/Components/QrCodeScannerCamera.js +0 -3
- package/lib/module/Shared/Config/camera-enhancement.config.js +11 -12
- package/lib/module/Shared/Libs/mrz.utils.js +265 -0
- package/lib/module/Trustchex.js +4 -0
- package/lib/module/index.js +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts +3 -0
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -0
- 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/FaceCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -1
- package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts +0 -19
- package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Config/camera-enhancement.config.d.ts +10 -10
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts +18 -1
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
- package/lib/typescript/src/Trustchex.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +2 -1
- package/src/Screens/Debug/MRZTestScreen.tsx +209 -0
- package/src/Shared/Components/DebugNavigationPanel.tsx +5 -0
- package/src/Shared/Components/EIDScanner.tsx +0 -53
- package/src/Shared/Components/FaceCamera.tsx +6 -3
- package/src/Shared/Components/IdentityDocumentCamera.tsx +246 -149
- package/src/Shared/Components/QrCodeScannerCamera.tsx +0 -9
- package/src/Shared/Components/TrustchexCamera.tsx +0 -20
- package/src/Shared/Config/camera-enhancement.config.ts +6 -6
- package/src/Shared/Libs/mrz.utils.ts +289 -1
- package/src/Trustchex.tsx +5 -0
- package/src/index.tsx +3 -0
- package/src/version.ts +1 -1
- package/android/src/main/java/com/trustchex/reactnativesdk/mrz/MRZValidationModule.kt +0 -785
- package/android/src/main/java/com/trustchex/reactnativesdk/mrz/MRZValidator.kt +0 -419
- package/ios/MRZValidation.m +0 -39
- package/ios/MRZValidation.swift +0 -802
- package/ios/MRZValidator.swift +0 -466
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { useState, useRef, useCallback } from 'react';
|
|
4
|
+
import { View, StyleSheet, Text, ScrollView, StatusBar, TouchableOpacity } from 'react-native';
|
|
5
|
+
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
6
|
+
import { TrustchexCamera } from "../../Shared/Components/TrustchexCamera.js";
|
|
7
|
+
import mrzUtils from "../../Shared/Libs/mrz.utils.js";
|
|
8
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
const MRZTestScreen = () => {
|
|
10
|
+
const cameraRef = useRef(null);
|
|
11
|
+
const [mrzText, setMrzText] = useState('Waiting for MRZ...');
|
|
12
|
+
const [mrzRawText, setMrzRawText] = useState('');
|
|
13
|
+
const [mrzValid, setMrzValid] = useState(false);
|
|
14
|
+
const [rawHistory, setRawHistory] = useState([]);
|
|
15
|
+
const [isPaused, setIsPaused] = useState(false);
|
|
16
|
+
const handleFrame = useCallback(event => {
|
|
17
|
+
if (isPaused) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const frame = event.nativeEvent.frame;
|
|
21
|
+
if (frame.resultText) {
|
|
22
|
+
setRawHistory(prev => {
|
|
23
|
+
if (prev[0] === frame.resultText) {
|
|
24
|
+
return prev;
|
|
25
|
+
}
|
|
26
|
+
const next = [frame.resultText, ...prev];
|
|
27
|
+
return next.slice(0, 20);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (frame.resultText && frame.resultText.includes('<')) {
|
|
31
|
+
// Extract MRZ-only text from detected blocks
|
|
32
|
+
let mrzOnlyText = '';
|
|
33
|
+
if (frame.textBlocks && frame.textBlocks.length > 0) {
|
|
34
|
+
// Filter blocks that look like MRZ (contain < and are in bottom half of frame)
|
|
35
|
+
const frameHeight = frame.height;
|
|
36
|
+
const bottomThreshold = frameHeight * 0.5;
|
|
37
|
+
const mrzBlocks = frame.textBlocks.filter(block => {
|
|
38
|
+
const blockText = block.text || '';
|
|
39
|
+
const hasFillers = blockText.includes('<');
|
|
40
|
+
const isInBottomArea = block.blockFrame ? block.blockFrame.y > bottomThreshold : false;
|
|
41
|
+
const isLongEnough = blockText.length >= 12;
|
|
42
|
+
return hasFillers && isInBottomArea && isLongEnough;
|
|
43
|
+
});
|
|
44
|
+
if (mrzBlocks.length > 0) {
|
|
45
|
+
mrzOnlyText = mrzBlocks.map(b => b.text).join('\n');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Fallback to full text if no MRZ blocks detected
|
|
50
|
+
if (!mrzOnlyText) {
|
|
51
|
+
mrzOnlyText = frame.resultText;
|
|
52
|
+
}
|
|
53
|
+
const fixedMrz = mrzUtils.fixMRZ(mrzOnlyText);
|
|
54
|
+
setMrzRawText(mrzOnlyText);
|
|
55
|
+
setMrzText(fixedMrz);
|
|
56
|
+
setMrzValid(mrzUtils.validateMRZWithCorrections(fixedMrz).valid);
|
|
57
|
+
}
|
|
58
|
+
}, [isPaused]);
|
|
59
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
60
|
+
style: styles.container,
|
|
61
|
+
children: [/*#__PURE__*/_jsx(StatusBar, {
|
|
62
|
+
barStyle: "light-content",
|
|
63
|
+
backgroundColor: "transparent",
|
|
64
|
+
translucent: true
|
|
65
|
+
}), /*#__PURE__*/_jsx(TrustchexCamera, {
|
|
66
|
+
ref: cameraRef,
|
|
67
|
+
style: styles.camera,
|
|
68
|
+
cameraType: "back",
|
|
69
|
+
enableFrameProcessing: true,
|
|
70
|
+
enableFaceDetection: false,
|
|
71
|
+
enableTextRecognition: true,
|
|
72
|
+
enableBarcodeScanning: false,
|
|
73
|
+
includeBase64: false,
|
|
74
|
+
targetFps: 10,
|
|
75
|
+
onFrameAvailable: handleFrame
|
|
76
|
+
}), /*#__PURE__*/_jsx(SafeAreaView, {
|
|
77
|
+
style: styles.mrzPanel,
|
|
78
|
+
edges: ['bottom'],
|
|
79
|
+
children: /*#__PURE__*/_jsx(ScrollView, {
|
|
80
|
+
style: styles.scrollView,
|
|
81
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
82
|
+
style: styles.panelContent,
|
|
83
|
+
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
84
|
+
style: styles.pauseButton,
|
|
85
|
+
onPress: () => setIsPaused(!isPaused),
|
|
86
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
87
|
+
style: styles.pauseButtonText,
|
|
88
|
+
children: isPaused ? 'Resume Processing' : 'Pause Processing'
|
|
89
|
+
})
|
|
90
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
91
|
+
style: styles.title,
|
|
92
|
+
children: "MRZ Text Read"
|
|
93
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
94
|
+
style: styles.sectionTitle,
|
|
95
|
+
children: "MRZ Raw Text"
|
|
96
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
97
|
+
style: styles.mrzText,
|
|
98
|
+
children: mrzRawText ? mrzRawText.split('\n').map((line, i) => `Line ${i + 1}: ${line} (${line.length} chars)`).join('\n') : 'No MRZ raw text'
|
|
99
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
100
|
+
style: styles.sectionTitle,
|
|
101
|
+
children: "MRZ Corrected Text"
|
|
102
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
103
|
+
style: [styles.mrzText, mrzValid ? styles.mrzValid : null],
|
|
104
|
+
children: mrzText.split('\n').map((line, i) => `Line ${i + 1}: ${line} (${line.length} chars)`).join('\n')
|
|
105
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
106
|
+
style: styles.sectionTitle,
|
|
107
|
+
children: "Raw Text History"
|
|
108
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
109
|
+
style: styles.mrzText,
|
|
110
|
+
children: rawHistory.length > 0 ? rawHistory.map((text, i) => `#${i + 1}: ${text.replace(/\n/g, ' ')}`).join('\n') : 'No history'
|
|
111
|
+
})]
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
})]
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
const styles = StyleSheet.create({
|
|
118
|
+
container: {
|
|
119
|
+
flex: 1,
|
|
120
|
+
backgroundColor: '#000000'
|
|
121
|
+
},
|
|
122
|
+
camera: {
|
|
123
|
+
flex: 2
|
|
124
|
+
},
|
|
125
|
+
mrzPanel: {
|
|
126
|
+
flex: 1,
|
|
127
|
+
backgroundColor: 'rgba(0, 0, 0, 0.95)',
|
|
128
|
+
borderTopWidth: 2,
|
|
129
|
+
borderTopColor: '#FFA500'
|
|
130
|
+
},
|
|
131
|
+
scrollView: {
|
|
132
|
+
flex: 1
|
|
133
|
+
},
|
|
134
|
+
panelContent: {
|
|
135
|
+
padding: 10
|
|
136
|
+
},
|
|
137
|
+
pauseButton: {
|
|
138
|
+
alignSelf: 'center',
|
|
139
|
+
borderWidth: 1,
|
|
140
|
+
borderColor: '#FFA500',
|
|
141
|
+
borderRadius: 4,
|
|
142
|
+
paddingVertical: 6,
|
|
143
|
+
paddingHorizontal: 12,
|
|
144
|
+
marginBottom: 8
|
|
145
|
+
},
|
|
146
|
+
pauseButtonText: {
|
|
147
|
+
color: '#FFA500',
|
|
148
|
+
fontSize: 10,
|
|
149
|
+
fontWeight: 'bold'
|
|
150
|
+
},
|
|
151
|
+
title: {
|
|
152
|
+
color: '#FFA500',
|
|
153
|
+
fontSize: 12,
|
|
154
|
+
fontWeight: 'bold',
|
|
155
|
+
marginBottom: 8,
|
|
156
|
+
textAlign: 'center'
|
|
157
|
+
},
|
|
158
|
+
sectionTitle: {
|
|
159
|
+
color: '#FFA500',
|
|
160
|
+
fontSize: 10,
|
|
161
|
+
fontWeight: 'bold',
|
|
162
|
+
marginTop: 6,
|
|
163
|
+
marginBottom: 4
|
|
164
|
+
},
|
|
165
|
+
mrzText: {
|
|
166
|
+
color: '#FFFFFF',
|
|
167
|
+
fontSize: 9,
|
|
168
|
+
fontFamily: 'monospace',
|
|
169
|
+
lineHeight: 16
|
|
170
|
+
},
|
|
171
|
+
mrzValid: {
|
|
172
|
+
color: '#00C853'
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
export default MRZTestScreen;
|
|
@@ -148,6 +148,10 @@ const DebugNavigationPanel = () => {
|
|
|
148
148
|
setupDemo: () => {
|
|
149
149
|
setupDemoSession();
|
|
150
150
|
}
|
|
151
|
+
}, {
|
|
152
|
+
screen: 'MRZTestScreen',
|
|
153
|
+
label: 'MRZ Test',
|
|
154
|
+
icon: ICONS.BUG_REPORT
|
|
151
155
|
}];
|
|
152
156
|
const selectScreen = useCallback(screen => {
|
|
153
157
|
if (!screen.hasOptions) {
|
|
@@ -13,7 +13,6 @@ import StyledButton from "./StyledButton.js";
|
|
|
13
13
|
import LottieView from 'lottie-react-native';
|
|
14
14
|
import { useKeepAwake } from "../Libs/native-keep-awake.utils.js";
|
|
15
15
|
import { speak, resetLastMessage } from "../Libs/tts.utils.js";
|
|
16
|
-
import { isDebugEnabled } from "../Libs/debug.utils.js";
|
|
17
16
|
import { trackEIDScanStart, trackEIDScanComplete, trackEIDScanFailed } from "../Libs/analytics.utils.js";
|
|
18
17
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
19
18
|
const EIDScanner = ({
|
|
@@ -439,83 +438,6 @@ const EIDScanner = ({
|
|
|
439
438
|
},
|
|
440
439
|
children: t('eidScannerScreen.approveAndContinue')
|
|
441
440
|
})
|
|
442
|
-
}), isDebugEnabled() && /*#__PURE__*/_jsxs(View, {
|
|
443
|
-
style: {
|
|
444
|
-
position: 'absolute',
|
|
445
|
-
top: insets.top + 10,
|
|
446
|
-
right: 10,
|
|
447
|
-
backgroundColor: 'rgba(0, 0, 0, 0.85)',
|
|
448
|
-
padding: 10,
|
|
449
|
-
borderRadius: 8,
|
|
450
|
-
borderWidth: 1,
|
|
451
|
-
borderColor: '#FF6B6B',
|
|
452
|
-
maxWidth: 200,
|
|
453
|
-
zIndex: 1001
|
|
454
|
-
},
|
|
455
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
456
|
-
style: {
|
|
457
|
-
color: '#FF6B6B',
|
|
458
|
-
fontSize: 11,
|
|
459
|
-
fontWeight: 'bold',
|
|
460
|
-
marginBottom: 6
|
|
461
|
-
},
|
|
462
|
-
children: "\uD83D\uDC1B DEBUG MODE"
|
|
463
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
464
|
-
style: {
|
|
465
|
-
color: '#88D8B0',
|
|
466
|
-
fontSize: 9,
|
|
467
|
-
marginBottom: 2
|
|
468
|
-
},
|
|
469
|
-
children: `NFC: ${hasNfc ? '✓' : '✗'}`
|
|
470
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
471
|
-
style: {
|
|
472
|
-
color: '#88D8B0',
|
|
473
|
-
fontSize: 9,
|
|
474
|
-
marginBottom: 2
|
|
475
|
-
},
|
|
476
|
-
children: `Enabled: ${isEnabled ? '✓' : '✗'}`
|
|
477
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
478
|
-
style: {
|
|
479
|
-
color: '#88D8B0',
|
|
480
|
-
fontSize: 9,
|
|
481
|
-
marginBottom: 2
|
|
482
|
-
},
|
|
483
|
-
children: `Scanning: ${isScanning ? '✓' : '○'}`
|
|
484
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
485
|
-
style: {
|
|
486
|
-
color: '#88D8B0',
|
|
487
|
-
fontSize: 9,
|
|
488
|
-
marginBottom: 2
|
|
489
|
-
},
|
|
490
|
-
children: `Scanned: ${isScanned ? '✓' : '○'}`
|
|
491
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
492
|
-
style: {
|
|
493
|
-
color: '#88D8B0',
|
|
494
|
-
fontSize: 9,
|
|
495
|
-
marginBottom: 2
|
|
496
|
-
},
|
|
497
|
-
children: `Progress: ${Math.round(progress)}%`
|
|
498
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
499
|
-
style: {
|
|
500
|
-
color: '#88D8B0',
|
|
501
|
-
fontSize: 9,
|
|
502
|
-
marginBottom: 2
|
|
503
|
-
},
|
|
504
|
-
children: `Face Image: ${documentFaceImage ? '✓' : '✗'}`
|
|
505
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
506
|
-
style: {
|
|
507
|
-
color: '#88D8B0',
|
|
508
|
-
fontSize: 9,
|
|
509
|
-
marginBottom: 2
|
|
510
|
-
},
|
|
511
|
-
children: `MRZ Info: ${documentMRZInfo ? '✓' : '✗'}`
|
|
512
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
513
|
-
style: {
|
|
514
|
-
color: '#88D8B0',
|
|
515
|
-
fontSize: 9
|
|
516
|
-
},
|
|
517
|
-
children: `Doc Type: ${documentType}`
|
|
518
|
-
})]
|
|
519
441
|
})]
|
|
520
442
|
})]
|
|
521
443
|
});
|
|
@@ -19,9 +19,9 @@ const {
|
|
|
19
19
|
const {
|
|
20
20
|
OpenCVModule
|
|
21
21
|
} = NativeModules;
|
|
22
|
-
const MIN_BRIGHTNESS_THRESHOLD =
|
|
22
|
+
const MIN_BRIGHTNESS_THRESHOLD = 60;
|
|
23
23
|
const BLUR_VARIANCE_THRESHOLD = 60;
|
|
24
|
-
const REGION_BRIGHTNESS_THRESHOLD =
|
|
24
|
+
const REGION_BRIGHTNESS_THRESHOLD = 50;
|
|
25
25
|
const FaceCamera = ({
|
|
26
26
|
onFacesDetected,
|
|
27
27
|
onCameraInitialized,
|
|
@@ -156,7 +156,7 @@ const FaceCamera = ({
|
|
|
156
156
|
const isBright = avgBrightness >= MIN_BRIGHTNESS_THRESHOLD;
|
|
157
157
|
|
|
158
158
|
// Check brightness in the region of interest (circular preview area)
|
|
159
|
-
let isRegionBright =
|
|
159
|
+
let isRegionBright = false;
|
|
160
160
|
if (previewRect && base64Image && OpenCVModule) {
|
|
161
161
|
try {
|
|
162
162
|
// Scale preview rect from screen coordinates to frame coordinates
|
|
@@ -169,7 +169,10 @@ const FaceCamera = ({
|
|
|
169
169
|
isRegionBright = await OpenCVModule.isCircularRegionBright(base64Image, regionMinX, regionMinY, regionWidth, regionHeight, REGION_BRIGHTNESS_THRESHOLD);
|
|
170
170
|
} catch (error) {
|
|
171
171
|
debugWarn('FaceCamera', 'Region brightness check failed:', error);
|
|
172
|
+
isRegionBright = isBright;
|
|
172
173
|
}
|
|
174
|
+
} else {
|
|
175
|
+
isRegionBright = isBright;
|
|
173
176
|
}
|
|
174
177
|
|
|
175
178
|
// Check for blur using OpenCV Laplacian variance
|