@trustchex/react-native-sdk 1.464.0 → 1.475.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/build.gradle +3 -3
- package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +190 -12
- package/ios/Camera/TrustchexCameraView.swift +244 -46
- package/ios/Permission/PermissionModule.m +22 -0
- package/ios/Permission/PermissionModule.swift +67 -0
- package/lib/module/Screens/Debug/MRZTestScreen.js +121 -147
- package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +24 -3
- package/lib/module/Screens/Dynamic/VerbalConsentScreen.js +1 -1
- package/lib/module/Screens/Dynamic/VideoCallScreen.js +7 -12
- package/lib/module/Screens/Static/ResultScreen.js +9 -1
- package/lib/module/Shared/Components/EIDScanner.js +166 -163
- package/lib/module/Shared/Components/FaceCamera.js +14 -8
- package/lib/module/Shared/Components/IdentityDocumentCamera.js +45 -10
- package/lib/module/Shared/Libs/MRZ_KNOWN_ISSUES.md +112 -0
- package/lib/module/Shared/Libs/PERMISSIONS_MANAGER.md +268 -0
- package/lib/module/Shared/Libs/index.js +20 -0
- package/lib/module/Shared/Libs/mrz.utils.js +570 -16
- package/lib/module/Shared/Libs/mrzFrameAggregator.js +301 -0
- package/lib/module/Shared/Libs/mrzOcrIntegration.js +109 -0
- package/lib/module/Shared/Libs/permissions.utils.js +199 -0
- package/lib/module/Translation/Resources/en.js +1 -0
- package/lib/module/Translation/Resources/tr.js +1 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
- package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.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/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.map +1 -1
- package/lib/typescript/src/Shared/Libs/index.d.ts +20 -0
- package/lib/typescript/src/Shared/Libs/index.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts +8 -0
- package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
- package/lib/typescript/src/Shared/Libs/mrzFrameAggregator.d.ts +76 -0
- package/lib/typescript/src/Shared/Libs/mrzFrameAggregator.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/mrzOcrIntegration.d.ts +73 -0
- package/lib/typescript/src/Shared/Libs/mrzOcrIntegration.d.ts.map +1 -0
- package/lib/typescript/src/Shared/Libs/permissions.utils.d.ts +58 -0
- package/lib/typescript/src/Shared/Libs/permissions.utils.d.ts.map +1 -0
- package/lib/typescript/src/Translation/Resources/en.d.ts +1 -0
- package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
- package/lib/typescript/src/Translation/Resources/tr.d.ts +1 -0
- package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +14 -10
- package/src/Screens/Debug/MRZTestScreen.tsx +137 -166
- package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +45 -5
- package/src/Screens/Dynamic/VerbalConsentScreen.tsx +1 -1
- package/src/Screens/Dynamic/VideoCallScreen.tsx +8 -19
- package/src/Screens/Static/ResultScreen.tsx +18 -9
- package/src/Shared/Components/EIDScanner.tsx +210 -160
- package/src/Shared/Components/FaceCamera.tsx +19 -16
- package/src/Shared/Components/IdentityDocumentCamera.tsx +53 -13
- package/src/Shared/Libs/MRZ_KNOWN_ISSUES.md +112 -0
- package/src/Shared/Libs/PERMISSIONS_MANAGER.md +268 -0
- package/src/Shared/Libs/index.ts +63 -0
- package/src/Shared/Libs/mrz.utils.ts +639 -11
- package/src/Shared/Libs/mrzFrameAggregator.ts +370 -0
- package/src/Shared/Libs/mrzOcrIntegration.ts +175 -0
- package/src/Shared/Libs/permissions.utils.ts +251 -0
- package/src/Translation/Resources/en.ts +1 -0
- package/src/Translation/Resources/tr.ts +1 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Platform,
|
|
3
|
+
NativeModules,
|
|
4
|
+
PermissionsAndroid,
|
|
5
|
+
type Permission,
|
|
6
|
+
} from 'react-native';
|
|
7
|
+
import { debugLog, debugError, debugWarn } from './debug.utils';
|
|
8
|
+
|
|
9
|
+
const { PermissionModule } = NativeModules;
|
|
10
|
+
|
|
11
|
+
export type PermissionType = 'camera' | 'microphone' | 'nfc';
|
|
12
|
+
|
|
13
|
+
class PermissionManager {
|
|
14
|
+
private static permissionCache: Map<PermissionType, boolean> = new Map();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Request a single permission
|
|
18
|
+
*/
|
|
19
|
+
static async requestPermission(permission: PermissionType): Promise<boolean> {
|
|
20
|
+
try {
|
|
21
|
+
if (Platform.OS === 'android') {
|
|
22
|
+
return await this.requestAndroidPermission(permission);
|
|
23
|
+
} else {
|
|
24
|
+
return await this.requestIOSPermission(permission);
|
|
25
|
+
}
|
|
26
|
+
} catch (error) {
|
|
27
|
+
debugError(
|
|
28
|
+
'PermissionManager',
|
|
29
|
+
`Failed to request ${permission}:`,
|
|
30
|
+
error
|
|
31
|
+
);
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Request multiple permissions at once
|
|
38
|
+
*/
|
|
39
|
+
static async requestPermissions(
|
|
40
|
+
permissions: PermissionType[]
|
|
41
|
+
): Promise<Map<PermissionType, boolean>> {
|
|
42
|
+
const results = new Map<PermissionType, boolean>();
|
|
43
|
+
|
|
44
|
+
if (Platform.OS === 'android') {
|
|
45
|
+
const androidPermissions = permissions.map((p) =>
|
|
46
|
+
this.permissionTypeToAndroid(p)
|
|
47
|
+
);
|
|
48
|
+
const granted =
|
|
49
|
+
await PermissionsAndroid.requestMultiple(androidPermissions);
|
|
50
|
+
|
|
51
|
+
permissions.forEach((p, i) => {
|
|
52
|
+
const isGranted =
|
|
53
|
+
granted[androidPermissions[i]] === PermissionsAndroid.RESULTS.GRANTED;
|
|
54
|
+
results.set(p, isGranted);
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
for (const permission of permissions) {
|
|
58
|
+
const isGranted = await this.requestIOSPermission(permission);
|
|
59
|
+
results.set(permission, isGranted);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check if a permission is granted (without requesting)
|
|
68
|
+
*/
|
|
69
|
+
static async checkPermission(permission: PermissionType): Promise<boolean> {
|
|
70
|
+
try {
|
|
71
|
+
if (Platform.OS === 'android') {
|
|
72
|
+
const androidPerm = this.permissionTypeToAndroid(permission);
|
|
73
|
+
const result = await PermissionsAndroid.check(androidPerm);
|
|
74
|
+
return result;
|
|
75
|
+
} else {
|
|
76
|
+
return await this.checkIOSPermission(permission);
|
|
77
|
+
}
|
|
78
|
+
} catch (error) {
|
|
79
|
+
debugError(
|
|
80
|
+
'PermissionManager',
|
|
81
|
+
`Failed to check ${permission} permission:`,
|
|
82
|
+
error
|
|
83
|
+
);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Request permission with user-friendly error handling
|
|
90
|
+
*/
|
|
91
|
+
static async requestWithFallback(
|
|
92
|
+
permission: PermissionType,
|
|
93
|
+
onDenied?: () => void
|
|
94
|
+
): Promise<boolean> {
|
|
95
|
+
const isGranted = await this.requestPermission(permission);
|
|
96
|
+
|
|
97
|
+
if (!isGranted) {
|
|
98
|
+
debugLog('PermissionManager', `${permission} permission denied`);
|
|
99
|
+
onDenied?.();
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Convenience method: Request camera and microphone together (for video recording)
|
|
108
|
+
*/
|
|
109
|
+
static async requestCameraAndMicrophone(): Promise<boolean> {
|
|
110
|
+
const permissions = await this.requestPermissions(['camera', 'microphone']);
|
|
111
|
+
|
|
112
|
+
const hasCamera = permissions.get('camera') ?? false;
|
|
113
|
+
const hasMicrophone = permissions.get('microphone') ?? false;
|
|
114
|
+
|
|
115
|
+
return hasCamera && hasMicrophone;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Convenience method: Request camera only
|
|
120
|
+
*/
|
|
121
|
+
static async requestCamera(): Promise<boolean> {
|
|
122
|
+
return this.requestPermission('camera');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Convenience method: Request microphone only
|
|
127
|
+
*/
|
|
128
|
+
static async requestMicrophone(): Promise<boolean> {
|
|
129
|
+
return this.requestPermission('microphone');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Convenience method: Request NFC only
|
|
134
|
+
*/
|
|
135
|
+
static async requestNFC(): Promise<boolean> {
|
|
136
|
+
return this.requestPermission('nfc');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Check if camera and microphone are both accessible
|
|
141
|
+
*/
|
|
142
|
+
static async hasCameraAndMicrophone(): Promise<boolean> {
|
|
143
|
+
const camera = await this.checkPermission('camera');
|
|
144
|
+
const microphone = await this.checkPermission('microphone');
|
|
145
|
+
return camera && microphone;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Check if camera is accessible
|
|
150
|
+
*/
|
|
151
|
+
static async hasCamera(): Promise<boolean> {
|
|
152
|
+
return this.checkPermission('camera');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check if microphone is accessible
|
|
157
|
+
*/
|
|
158
|
+
static async hasMicrophone(): Promise<boolean> {
|
|
159
|
+
return this.checkPermission('microphone');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Check if NFC is accessible
|
|
164
|
+
*/
|
|
165
|
+
static async hasNFC(): Promise<boolean> {
|
|
166
|
+
return this.checkPermission('nfc');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Private helper methods
|
|
170
|
+
|
|
171
|
+
private static permissionTypeToAndroid(permission: PermissionType): Permission {
|
|
172
|
+
const map: Record<PermissionType, Permission> = {
|
|
173
|
+
camera: PermissionsAndroid.PERMISSIONS.CAMERA,
|
|
174
|
+
microphone: PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
|
|
175
|
+
nfc: 'android.permission.NFC' as Permission,
|
|
176
|
+
};
|
|
177
|
+
return map[permission];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private static async requestAndroidPermission(
|
|
181
|
+
permission: PermissionType
|
|
182
|
+
): Promise<boolean> {
|
|
183
|
+
const androidPerm = this.permissionTypeToAndroid(permission);
|
|
184
|
+
const result = await PermissionsAndroid.request(androidPerm);
|
|
185
|
+
return result === PermissionsAndroid.RESULTS.GRANTED;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private static async requestIOSPermission(
|
|
189
|
+
permission: PermissionType
|
|
190
|
+
): Promise<boolean> {
|
|
191
|
+
if (!PermissionModule) {
|
|
192
|
+
debugLog(
|
|
193
|
+
'PermissionManager',
|
|
194
|
+
'PermissionModule not available, assuming permission granted'
|
|
195
|
+
);
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
switch (permission) {
|
|
201
|
+
case 'camera':
|
|
202
|
+
return await PermissionModule.requestCameraPermission();
|
|
203
|
+
case 'microphone':
|
|
204
|
+
return await PermissionModule.requestMicrophonePermission();
|
|
205
|
+
case 'nfc':
|
|
206
|
+
// NFC permission on iOS is automatically handled when NFCManager is initialized
|
|
207
|
+
// No explicit permission request needed
|
|
208
|
+
return true;
|
|
209
|
+
default:
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
} catch (error) {
|
|
213
|
+
debugError(
|
|
214
|
+
'PermissionManager',
|
|
215
|
+
`iOS permission request failed for ${permission}:`,
|
|
216
|
+
error
|
|
217
|
+
);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private static async checkIOSPermission(
|
|
223
|
+
permission: PermissionType
|
|
224
|
+
): Promise<boolean> {
|
|
225
|
+
if (!PermissionModule) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
switch (permission) {
|
|
231
|
+
case 'camera':
|
|
232
|
+
return await PermissionModule.checkCameraPermission?.();
|
|
233
|
+
case 'microphone':
|
|
234
|
+
return await PermissionModule.checkMicrophonePermission?.();
|
|
235
|
+
case 'nfc':
|
|
236
|
+
return true;
|
|
237
|
+
default:
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
debugWarn(
|
|
242
|
+
'PermissionManager',
|
|
243
|
+
`iOS permission check failed for ${permission}`,
|
|
244
|
+
error
|
|
245
|
+
);
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export default PermissionManager;
|
|
@@ -103,6 +103,7 @@ export default {
|
|
|
103
103
|
'eidScannerScreen.docTypeResidence': 'Residence Permit',
|
|
104
104
|
'eidScannerScreen.docTypeVisa': 'Visa',
|
|
105
105
|
'eidScannerScreen.expirationDate': 'Expiration Date',
|
|
106
|
+
'eidScannerScreen.issuingState': 'Issuing State',
|
|
106
107
|
'eidScannerScreen.mrzText': 'MRZ Text',
|
|
107
108
|
'eidScannerScreen.nfcNotSupported':
|
|
108
109
|
'This device does not support NFC functionality.',
|
|
@@ -103,6 +103,7 @@ export default {
|
|
|
103
103
|
'eidScannerScreen.docTypeResidence': 'Oturma İzni',
|
|
104
104
|
'eidScannerScreen.docTypeVisa': 'Vize',
|
|
105
105
|
'eidScannerScreen.expirationDate': 'Geçerlilik Tarihi',
|
|
106
|
+
'eidScannerScreen.issuingState': 'Veren Ülke',
|
|
106
107
|
'eidScannerScreen.mrzText': 'MRZ Metni',
|
|
107
108
|
'eidScannerScreen.nfcNotSupported':
|
|
108
109
|
'Bu cihaz NFC işlevini desteklememektedir.',
|
package/src/version.ts
CHANGED