@transfergratis/react-native-sdk 0.1.23 → 0.1.25
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/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +12 -5
- package/android/build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar +0 -0
- package/android/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/incremental/debug-mergeJavaRes/merge-state +0 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +61 -59
- package/android/build/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-transfergratis-react-native-sdk.jar +0 -0
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +12 -5
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/aar/transfergratis-react-native-sdk-debug.aar +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +26 -34
- package/android/src/main/AndroidManifest.xml +13 -5
- package/build/components/EnhancedCameraView.d.ts.map +1 -1
- package/build/components/EnhancedCameraView.js +26 -3
- package/build/components/EnhancedCameraView.js.map +1 -1
- package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
- package/build/components/EnhancedCameraView.web.js +21 -0
- package/build/components/EnhancedCameraView.web.js.map +1 -1
- package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts +12 -0
- package/build/components/KYCElements/AdditionalDocumentsTemplate.d.ts.map +1 -0
- package/build/components/KYCElements/AdditionalDocumentsTemplate.js +283 -0
- package/build/components/KYCElements/AdditionalDocumentsTemplate.js.map +1 -0
- package/build/components/KYCElements/CameraCapture.d.ts.map +1 -1
- package/build/components/KYCElements/CameraCapture.js +4 -3
- package/build/components/KYCElements/CameraCapture.js.map +1 -1
- package/build/components/KYCElements/CountrySelectionTemplate.d.ts +5 -2
- package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/CountrySelectionTemplate.js +360 -101
- package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
- package/build/components/KYCElements/EmailVerificationTemplate.d.ts +12 -0
- package/build/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -0
- package/build/components/KYCElements/EmailVerificationTemplate.js +193 -0
- package/build/components/KYCElements/EmailVerificationTemplate.js.map +1 -0
- package/build/components/KYCElements/FileUpload.d.ts.map +1 -1
- package/build/components/KYCElements/FileUpload.js +5 -4
- package/build/components/KYCElements/FileUpload.js.map +1 -1
- package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/FileUploadTemplate.js +5 -4
- package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
- package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/components/KYCElements/IDCardCapture.js +356 -227
- package/build/components/KYCElements/IDCardCapture.js.map +1 -1
- package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/LocationCaptureTemplate.js +78 -37
- package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
- package/build/components/KYCElements/OrientationVideoCapture.d.ts +2 -0
- package/build/components/KYCElements/OrientationVideoCapture.d.ts.map +1 -1
- package/build/components/KYCElements/OrientationVideoCapture.js +5 -4
- package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
- package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts +2 -0
- package/build/components/KYCElements/OrientationVideoCaptureEnhanced.d.ts.map +1 -1
- package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +5 -4
- package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
- package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts +2 -0
- package/build/components/KYCElements/OrientationVideoCaptureFinal.d.ts.map +1 -1
- package/build/components/KYCElements/OrientationVideoCaptureFinal.js +5 -4
- package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
- package/build/components/KYCElements/PersonalInformationTemplate.d.ts +12 -0
- package/build/components/KYCElements/PersonalInformationTemplate.d.ts.map +1 -0
- package/build/components/KYCElements/PersonalInformationTemplate.js +120 -0
- package/build/components/KYCElements/PersonalInformationTemplate.js.map +1 -0
- package/build/components/KYCElements/PhoneVerificationTemplate.d.ts +12 -0
- package/build/components/KYCElements/PhoneVerificationTemplate.d.ts.map +1 -0
- package/build/components/KYCElements/PhoneVerificationTemplate.js +185 -0
- package/build/components/KYCElements/PhoneVerificationTemplate.js.map +1 -0
- package/build/components/KYCElements/SelfieCapture.d.ts.map +1 -1
- package/build/components/KYCElements/SelfieCapture.js +4 -3
- package/build/components/KYCElements/SelfieCapture.js.map +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.js +189 -42
- package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
- package/build/components/KYCElements/WelcomeTemplate.d.ts +12 -0
- package/build/components/KYCElements/WelcomeTemplate.d.ts.map +1 -0
- package/build/components/KYCElements/WelcomeTemplate.js +243 -0
- package/build/components/KYCElements/WelcomeTemplate.js.map +1 -0
- package/build/components/TemplateKYCExample.d.ts +8 -2
- package/build/components/TemplateKYCExample.d.ts.map +1 -1
- package/build/components/TemplateKYCExample.js +10 -97
- package/build/components/TemplateKYCExample.js.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.d.ts +6 -1
- package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.js +108 -11
- package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
- package/build/components/example/DynamicTemplateExample.d.ts +10 -0
- package/build/components/example/DynamicTemplateExample.d.ts.map +1 -0
- package/build/components/example/DynamicTemplateExample.js +241 -0
- package/build/components/example/DynamicTemplateExample.js.map +1 -0
- package/build/config/KYCConfig.d.ts +14 -0
- package/build/config/KYCConfig.d.ts.map +1 -0
- package/build/config/KYCConfig.js +26 -0
- package/build/config/KYCConfig.js.map +1 -0
- package/build/config/allowedDomains.d.ts +30 -0
- package/build/config/allowedDomains.d.ts.map +1 -0
- package/build/config/allowedDomains.js +112 -0
- package/build/config/allowedDomains.js.map +1 -0
- package/build/hooks/useOrientationVideo.d.ts +2 -1
- package/build/hooks/useOrientationVideo.d.ts.map +1 -1
- package/build/hooks/useOrientationVideo.js +3 -3
- package/build/hooks/useOrientationVideo.js.map +1 -1
- package/build/hooks/useTemplateKYCFlow.d.ts +6 -1
- package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
- package/build/hooks/useTemplateKYCFlow.js +317 -34
- package/build/hooks/useTemplateKYCFlow.js.map +1 -1
- package/build/hooks/useTemplateLoader.d.ts +14 -0
- package/build/hooks/useTemplateLoader.d.ts.map +1 -0
- package/build/hooks/useTemplateLoader.js +85 -0
- package/build/hooks/useTemplateLoader.js.map +1 -0
- package/build/i18n/en/index.d.ts +49 -0
- package/build/i18n/en/index.d.ts.map +1 -1
- package/build/i18n/en/index.js +50 -1
- package/build/i18n/en/index.js.map +1 -1
- package/build/i18n/fr/index.d.ts +35 -0
- package/build/i18n/fr/index.d.ts.map +1 -1
- package/build/i18n/fr/index.js +36 -1
- package/build/i18n/fr/index.js.map +1 -1
- package/build/index.d.ts +6 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +10 -0
- package/build/index.js.map +1 -1
- package/build/modules/api/CardAuthentification.d.ts +24 -3
- package/build/modules/api/CardAuthentification.d.ts.map +1 -1
- package/build/modules/api/CardAuthentification.js +69 -10
- package/build/modules/api/CardAuthentification.js.map +1 -1
- package/build/modules/api/KYCService.d.ts +7 -7
- package/build/modules/api/KYCService.d.ts.map +1 -1
- package/build/modules/api/KYCService.js +108 -39
- package/build/modules/api/KYCService.js.map +1 -1
- package/build/modules/api/SelfieVerification.d.ts +3 -1
- package/build/modules/api/SelfieVerification.d.ts.map +1 -1
- package/build/modules/api/SelfieVerification.js +17 -1
- package/build/modules/api/SelfieVerification.js.map +1 -1
- package/build/modules/api/TemplateService.d.ts +44 -0
- package/build/modules/api/TemplateService.d.ts.map +1 -0
- package/build/modules/api/TemplateService.js +145 -0
- package/build/modules/api/TemplateService.js.map +1 -0
- package/build/types/KYC.types.d.ts +265 -4
- package/build/types/KYC.types.d.ts.map +1 -1
- package/build/types/KYC.types.js +15 -0
- package/build/types/KYC.types.js.map +1 -1
- package/build/types/env.types.d.ts +13 -0
- package/build/types/env.types.d.ts.map +1 -0
- package/build/types/env.types.js +2 -0
- package/build/types/env.types.js.map +1 -0
- package/build/utils/cropByObb.d.ts +1 -0
- package/build/utils/cropByObb.d.ts.map +1 -1
- package/build/utils/cropByObb.js +70 -0
- package/build/utils/cropByObb.js.map +1 -1
- package/build/utils/deviceDetection.d.ts +6 -0
- package/build/utils/deviceDetection.d.ts.map +1 -0
- package/build/utils/deviceDetection.js +12 -0
- package/build/utils/deviceDetection.js.map +1 -0
- package/build/utils/platformAlert.d.ts +20 -0
- package/build/utils/platformAlert.d.ts.map +1 -0
- package/build/utils/platformAlert.js +67 -0
- package/build/utils/platformAlert.js.map +1 -0
- package/build/utils/template-transformer.d.ts +10 -0
- package/build/utils/template-transformer.d.ts.map +1 -0
- package/build/utils/template-transformer.js +365 -0
- package/build/utils/template-transformer.js.map +1 -0
- package/build/web/WebKYCEntry.d.ts.map +1 -1
- package/build/web/WebKYCEntry.js +158 -32
- package/build/web/WebKYCEntry.js.map +1 -1
- package/package.json +1 -1
- package/plugin/build/withVisionCamera.js +3 -4
- package/plugin/src/withVisionCamera.js +3 -4
- package/plugin/src/withVisionCamera.ts +3 -4
- package/src/components/EnhancedCameraView.tsx +31 -2
- package/src/components/EnhancedCameraView.web.tsx +24 -0
- package/src/components/KYCElements/AdditionalDocumentsTemplate.tsx +346 -0
- package/src/components/KYCElements/CameraCapture.tsx +4 -3
- package/src/components/KYCElements/CountrySelectionTemplate.tsx +410 -113
- package/src/components/KYCElements/EmailVerificationTemplate.tsx +264 -0
- package/src/components/KYCElements/FileUpload.tsx +5 -4
- package/src/components/KYCElements/FileUploadTemplate.tsx +5 -4
- package/src/components/KYCElements/IDCardCapture.tsx +397 -254
- package/src/components/KYCElements/LocationCaptureTemplate.tsx +95 -44
- package/src/components/KYCElements/OrientationVideoCapture.tsx +6 -3
- package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +6 -3
- package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +6 -3
- package/src/components/KYCElements/PersonalInformationTemplate.tsx +158 -0
- package/src/components/KYCElements/PhoneVerificationTemplate.tsx +253 -0
- package/src/components/KYCElements/SelfieCapture.tsx +4 -3
- package/src/components/KYCElements/SelfieCaptureTemplate.tsx +201 -44
- package/src/components/KYCElements/WelcomeTemplate.tsx +289 -0
- package/src/components/TemplateKYCExample.tsx +37 -108
- package/src/components/TemplateKYCFlowRefactored.tsx +148 -12
- package/src/components/example/DynamicTemplateExample.tsx +289 -0
- package/src/config/KYCConfig.ts +34 -0
- package/src/config/allowedDomains.ts +133 -0
- package/src/hooks/useOrientationVideo.ts +5 -4
- package/src/hooks/useTemplateKYCFlow.tsx +347 -32
- package/src/hooks/useTemplateLoader.ts +102 -0
- package/src/i18n/en/index.ts +53 -2
- package/src/i18n/fr/index.ts +37 -1
- package/src/index.ts +14 -0
- package/src/modules/api/CardAuthentification.ts +76 -11
- package/src/modules/api/KYCService.ts +129 -45
- package/src/modules/api/SelfieVerification.ts +25 -3
- package/src/modules/api/TemplateService.ts +167 -0
- package/src/types/KYC.types.ts +331 -3
- package/src/types/env.types.ts +13 -0
- package/src/utils/cropByObb.ts +83 -3
- package/src/utils/deviceDetection.ts +11 -0
- package/src/utils/platformAlert.ts +86 -0
- package/src/utils/template-transformer.ts +445 -0
- package/src/web/WebKYCEntry.tsx +199 -50
package/build/web/WebKYCEntry.js
CHANGED
|
@@ -1,99 +1,174 @@
|
|
|
1
1
|
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
|
-
import { View, Text, StyleSheet, SafeAreaView } from 'react-native';
|
|
2
|
+
import { View, Text, StyleSheet, SafeAreaView, ActivityIndicator } from 'react-native';
|
|
3
3
|
// import { TemplateKYCFlow } from '../components/TemplateKYCFlowRefactored';
|
|
4
4
|
// import { KYCTemplate } from '../types/KYC.types';
|
|
5
5
|
import { useI18n } from '../hooks/useI18n';
|
|
6
6
|
import { TemplateKYCExample } from '../components/TemplateKYCExample';
|
|
7
|
+
import { isCallbackUrlAllowed } from '../config/allowedDomains';
|
|
8
|
+
import KYCConfig from '../config/KYCConfig';
|
|
7
9
|
const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
8
10
|
const { setLocale } = useI18n();
|
|
9
11
|
const [urlParams, setUrlParams] = useState({});
|
|
10
12
|
const [isLoading, setIsLoading] = useState(true);
|
|
11
13
|
const [error, setError] = useState(null);
|
|
14
|
+
const [isAnalyzing, setIsAnalyzing] = useState(false);
|
|
12
15
|
// Parse URL parameters
|
|
13
16
|
const parseUrlParams = useCallback(() => {
|
|
14
17
|
if (typeof window === 'undefined')
|
|
15
18
|
return {};
|
|
16
19
|
const urlParams = new URLSearchParams(window.location.search);
|
|
20
|
+
const envParam = urlParams.get('env');
|
|
21
|
+
const validEnv = envParam === 'SANDBOX' || envParam === 'PRODUCTION' ? envParam : 'PRODUCTION';
|
|
22
|
+
const serverEnvParam = urlParams.get('server_env');
|
|
23
|
+
const validServerEnv = serverEnvParam === 'TEST' || serverEnvParam === 'PRODUCTION'
|
|
24
|
+
? serverEnvParam
|
|
25
|
+
: 'PRODUCTION';
|
|
17
26
|
return {
|
|
18
27
|
token: urlParams.get('token') || undefined,
|
|
19
28
|
return_url: urlParams.get('return_url') || undefined,
|
|
29
|
+
push_url: urlParams.get('push_url') || undefined,
|
|
20
30
|
lang: urlParams.get('lang') || 'en',
|
|
21
31
|
theme: urlParams.get('theme') || 'light',
|
|
22
32
|
kyc_id: urlParams.get('kyc_id') || undefined,
|
|
33
|
+
secret: urlParams.get('secret') || undefined,
|
|
34
|
+
env: validEnv,
|
|
35
|
+
template_id: urlParams.get('template_id') || undefined,
|
|
36
|
+
server_env: validServerEnv,
|
|
37
|
+
step: urlParams.get('step') || undefined,
|
|
23
38
|
};
|
|
24
39
|
}, []);
|
|
25
|
-
// Safe redirect function with validation
|
|
26
|
-
const redirectToReturnUrl = useCallback((params) => {
|
|
40
|
+
// Safe redirect function with enhanced validation
|
|
41
|
+
const redirectToReturnUrl = useCallback(async (params) => {
|
|
27
42
|
const { return_url } = urlParams;
|
|
28
43
|
if (!return_url) {
|
|
29
44
|
console.warn('No return_url provided');
|
|
30
45
|
return;
|
|
31
46
|
}
|
|
32
|
-
// Basic URL validation - ensure it's a valid URL
|
|
33
47
|
try {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
// Enhanced URL validation with domain whitelist
|
|
49
|
+
const validation = isCallbackUrlAllowed(return_url);
|
|
50
|
+
if (!validation.allowed) {
|
|
51
|
+
console.error('Callback URL validation failed:', validation.reason);
|
|
52
|
+
setError(`Security Error: ${validation.reason}`);
|
|
53
|
+
// Log suspicious redirect attempt
|
|
54
|
+
console.warn('Suspicious redirect attempt blocked:', {
|
|
55
|
+
url: return_url,
|
|
56
|
+
reason: validation.reason,
|
|
57
|
+
timestamp: new Date().toISOString(),
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
46
60
|
}
|
|
47
|
-
if
|
|
48
|
-
redirectUrl.searchParams.set('message', params.message);
|
|
49
|
-
}
|
|
50
|
-
if (params.sig) {
|
|
51
|
-
redirectUrl.searchParams.set('sig', params.sig);
|
|
52
|
-
}
|
|
53
|
-
// Optional: Send postMessage to parent if in iframe
|
|
61
|
+
// Send postMessage to parent if in iframe
|
|
54
62
|
if (window.parent !== window) {
|
|
63
|
+
const targetOrigin = new URL(return_url).origin;
|
|
55
64
|
window.parent.postMessage({
|
|
56
65
|
type: 'kyc_result',
|
|
57
66
|
status: params.status,
|
|
58
67
|
kyc_id: params.kyc_id,
|
|
59
68
|
message: params.message,
|
|
60
|
-
|
|
69
|
+
processing_state: params.processing_state,
|
|
70
|
+
verification_steps: params.verification_steps,
|
|
71
|
+
}, targetOrigin);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
window.location.href = return_url;
|
|
61
75
|
}
|
|
62
|
-
// Redirect to return URL
|
|
63
|
-
window.location.href = redirectUrl.toString();
|
|
64
76
|
}
|
|
65
77
|
catch (error) {
|
|
66
|
-
console.error('
|
|
67
|
-
setError('
|
|
78
|
+
console.error('Error during redirect:', error);
|
|
79
|
+
setError('Failed to redirect to callback URL');
|
|
68
80
|
}
|
|
69
81
|
}, [urlParams]);
|
|
70
82
|
// Handle KYC completion
|
|
71
|
-
const handleComplete = useCallback((data) => {
|
|
83
|
+
const handleComplete = useCallback(async (data) => {
|
|
72
84
|
console.log('KYC completed:', data);
|
|
85
|
+
// Check if still processing/analyzing
|
|
86
|
+
const isStillProcessing = data.isProcessing || data.session?.isProcessing;
|
|
87
|
+
// Handle Push URL webhook if provided
|
|
88
|
+
if (urlParams.push_url) {
|
|
89
|
+
try {
|
|
90
|
+
const verificationState = {
|
|
91
|
+
status: 'success', // verification completed successfully
|
|
92
|
+
result: data, // pass complete data object as result
|
|
93
|
+
};
|
|
94
|
+
// Send data to provided push_url with a timeout
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
|
|
97
|
+
await fetch(urlParams.push_url, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: {
|
|
100
|
+
'Content-Type': 'application/json',
|
|
101
|
+
},
|
|
102
|
+
body: JSON.stringify(verificationState),
|
|
103
|
+
signal: controller.signal,
|
|
104
|
+
});
|
|
105
|
+
clearTimeout(timeoutId);
|
|
106
|
+
console.log('Successfully pushed KYC data to webhook');
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
// Fail open - redirect anyway even if webhook fails
|
|
110
|
+
console.warn('Failed to push data to webhook URL:', err);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
73
113
|
redirectToReturnUrl({
|
|
74
114
|
status: 'completed',
|
|
75
115
|
kyc_id: data.session_id || urlParams.kyc_id,
|
|
76
116
|
message: 'KYC process completed successfully',
|
|
117
|
+
processing_state: isStillProcessing ? 'analyzing' : 'completed',
|
|
118
|
+
verification_steps: {
|
|
119
|
+
document_analyzed: data.documentAnalysisComplete || false,
|
|
120
|
+
selfie_analyzed: data.selfieAnalysisComplete || false,
|
|
121
|
+
liveness_checked: data.livenessCheckComplete || false,
|
|
122
|
+
},
|
|
77
123
|
});
|
|
78
124
|
onComplete?.(data);
|
|
79
|
-
}, [redirectToReturnUrl, urlParams
|
|
125
|
+
}, [redirectToReturnUrl, urlParams, onComplete]);
|
|
80
126
|
// Handle KYC error
|
|
81
127
|
const handleError = useCallback((error) => {
|
|
82
128
|
console.error('KYC error:', error);
|
|
129
|
+
setIsAnalyzing(false);
|
|
83
130
|
redirectToReturnUrl({
|
|
84
131
|
status: 'error',
|
|
85
132
|
kyc_id: urlParams.kyc_id,
|
|
86
133
|
message: error,
|
|
134
|
+
processing_state: 'pending',
|
|
87
135
|
});
|
|
88
136
|
onError?.(error);
|
|
89
137
|
}, [redirectToReturnUrl, urlParams.kyc_id, onError]);
|
|
90
138
|
// Handle KYC cancellation
|
|
91
139
|
const handleCancel = useCallback(() => {
|
|
92
|
-
console.log('KYC cancelled');
|
|
140
|
+
console.log('KYC cancelled', urlParams.push_url, urlParams);
|
|
141
|
+
setIsAnalyzing(false);
|
|
142
|
+
if (urlParams.push_url) {
|
|
143
|
+
try {
|
|
144
|
+
const verificationState = {
|
|
145
|
+
status: 'cancelled', // verification cancelled
|
|
146
|
+
result: null, // pass null as result
|
|
147
|
+
};
|
|
148
|
+
// Send data to provided push_url with a timeout
|
|
149
|
+
const controller = new AbortController();
|
|
150
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
|
|
151
|
+
fetch(urlParams.push_url, {
|
|
152
|
+
method: 'POST',
|
|
153
|
+
headers: {
|
|
154
|
+
'Content-Type': 'application/json',
|
|
155
|
+
},
|
|
156
|
+
body: JSON.stringify(verificationState),
|
|
157
|
+
signal: controller.signal,
|
|
158
|
+
});
|
|
159
|
+
clearTimeout(timeoutId);
|
|
160
|
+
console.log('Successfully pushed KYC cancellation data to webhook');
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Fail open - redirect anyway even if webhook fails
|
|
164
|
+
console.warn('Failed to push data to webhook URL:', err);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
93
167
|
redirectToReturnUrl({
|
|
94
168
|
status: 'cancelled',
|
|
95
169
|
kyc_id: urlParams.kyc_id,
|
|
96
170
|
message: 'KYC process was cancelled',
|
|
171
|
+
processing_state: 'pending',
|
|
97
172
|
});
|
|
98
173
|
onCancel?.();
|
|
99
174
|
}, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);
|
|
@@ -106,6 +181,10 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
106
181
|
if (params.lang) {
|
|
107
182
|
setLocale(params.lang);
|
|
108
183
|
}
|
|
184
|
+
// Configure backend environment
|
|
185
|
+
if (params.server_env) {
|
|
186
|
+
KYCConfig.setBackendEnvironment(params.server_env);
|
|
187
|
+
}
|
|
109
188
|
setIsLoading(false);
|
|
110
189
|
}
|
|
111
190
|
catch (error) {
|
|
@@ -130,13 +209,25 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
130
209
|
</View>);
|
|
131
210
|
}
|
|
132
211
|
return (<SafeAreaView style={styles.container}>
|
|
133
|
-
|
|
212
|
+
{isAnalyzing && (<View style={styles.analyzingOverlay}>
|
|
213
|
+
<View style={styles.analyzingContainer}>
|
|
214
|
+
<ActivityIndicator size="large" color="#2DBD60"/>
|
|
215
|
+
<Text style={styles.analyzingText}>Analyzing verification data...</Text>
|
|
216
|
+
<Text style={styles.analyzingSubtext}>This may take a few moments</Text>
|
|
217
|
+
</View>
|
|
218
|
+
</View>)}
|
|
219
|
+
<TemplateKYCExample onComplete={handleComplete} onCancel={handleCancel} onError={handleError} language={urlParams.lang || 'en'} API_KEY={urlParams.token} templateId={urlParams.template_id} env={urlParams.env || 'PRODUCTION'} existingSessionId={urlParams.kyc_id} initialStep={urlParams.step ? (() => {
|
|
220
|
+
const stepNum = parseInt(urlParams.step, 10);
|
|
221
|
+
console.log('Parsing step from URL:', { stepString: urlParams.step, stepNumber: stepNum, isNaN: isNaN(stepNum) });
|
|
222
|
+
return isNaN(stepNum) ? undefined : stepNum;
|
|
223
|
+
})() : undefined}/>
|
|
134
224
|
</SafeAreaView>);
|
|
135
225
|
};
|
|
136
226
|
const styles = StyleSheet.create({
|
|
137
227
|
container: {
|
|
138
228
|
flex: 1,
|
|
139
229
|
backgroundColor: '#f5f5f5',
|
|
230
|
+
overflow: 'visible', // Allow scrolling on web
|
|
140
231
|
},
|
|
141
232
|
loadingText: {
|
|
142
233
|
fontSize: 18,
|
|
@@ -151,6 +242,41 @@ const styles = StyleSheet.create({
|
|
|
151
242
|
color: '#dc2626',
|
|
152
243
|
paddingHorizontal: 20,
|
|
153
244
|
},
|
|
245
|
+
analyzingOverlay: {
|
|
246
|
+
position: 'absolute',
|
|
247
|
+
top: 0,
|
|
248
|
+
left: 0,
|
|
249
|
+
right: 0,
|
|
250
|
+
bottom: 0,
|
|
251
|
+
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
|
252
|
+
justifyContent: 'center',
|
|
253
|
+
alignItems: 'center',
|
|
254
|
+
zIndex: 9999,
|
|
255
|
+
},
|
|
256
|
+
analyzingContainer: {
|
|
257
|
+
backgroundColor: 'white',
|
|
258
|
+
borderRadius: 12,
|
|
259
|
+
padding: 32,
|
|
260
|
+
alignItems: 'center',
|
|
261
|
+
shadowColor: '#000',
|
|
262
|
+
shadowOffset: { width: 0, height: 4 },
|
|
263
|
+
shadowOpacity: 0.3,
|
|
264
|
+
shadowRadius: 8,
|
|
265
|
+
elevation: 8,
|
|
266
|
+
},
|
|
267
|
+
analyzingText: {
|
|
268
|
+
fontSize: 18,
|
|
269
|
+
fontWeight: '600',
|
|
270
|
+
color: '#333',
|
|
271
|
+
marginTop: 16,
|
|
272
|
+
textAlign: 'center',
|
|
273
|
+
},
|
|
274
|
+
analyzingSubtext: {
|
|
275
|
+
fontSize: 14,
|
|
276
|
+
color: '#666',
|
|
277
|
+
marginTop: 8,
|
|
278
|
+
textAlign: 'center',
|
|
279
|
+
},
|
|
154
280
|
});
|
|
155
281
|
export default WebKYCEntry;
|
|
156
282
|
//# sourceMappingURL=WebKYCEntry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebKYCEntry.js","sourceRoot":"","sources":["../../src/web/WebKYCEntry.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useState, useCallback } from 'react';\nimport { View, Text, StyleSheet, SafeAreaView } from 'react-native';\n// import { TemplateKYCFlow } from '../components/TemplateKYCFlowRefactored';\n// import { KYCTemplate } from '../types/KYC.types';\nimport { useI18n } from '../hooks/useI18n';\nimport { TemplateKYCExample } from '../components/TemplateKYCExample';\n\ninterface WebKYCEntryProps {\n onComplete?: (data: any) => void;\n onError?: (error: string) => void;\n onCancel?: () => void;\n}\n\ninterface URLParams {\n token?: string;\n return_url?: string;\n lang?: string;\n theme?: string;\n kyc_id?: string;\n}\n\nconst WebKYCEntry: React.FC<WebKYCEntryProps> = ({\n onComplete,\n onError,\n onCancel,\n}) => {\n const { setLocale } = useI18n();\n const [urlParams, setUrlParams] = useState<URLParams>({});\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Parse URL parameters\n const parseUrlParams = useCallback((): URLParams => {\n if (typeof window === 'undefined') return {};\n \n const urlParams = new URLSearchParams(window.location.search);\n return {\n token: urlParams.get('token') || undefined,\n return_url: urlParams.get('return_url') || undefined,\n lang: urlParams.get('lang') || 'en',\n theme: urlParams.get('theme') || 'light',\n kyc_id: urlParams.get('kyc_id') || undefined,\n };\n }, []);\n\n // Safe redirect function with validation\n const redirectToReturnUrl = useCallback((params: {\n status: 'completed' | 'cancelled' | 'error';\n kyc_id?: string;\n message?: string;\n sig?: string;\n }) => {\n const { return_url } = urlParams;\n \n if (!return_url) {\n console.warn('No return_url provided');\n return;\n }\n\n // Basic URL validation - ensure it's a valid URL\n try {\n const returnUrl = new URL(return_url);\n \n // Optional: Add domain allowlist validation here\n // const allowedDomains = ['example.com', 'trusted-site.com'];\n // if (!allowedDomains.some(domain => returnUrl.hostname.endsWith(domain))) {\n // console.error('Return URL not in allowlist');\n // return;\n // }\n\n // Build redirect URL with parameters\n const redirectUrl = new URL(returnUrl);\n redirectUrl.searchParams.set('status', params.status);\n \n if (params.kyc_id) {\n redirectUrl.searchParams.set('kyc_id', params.kyc_id);\n }\n \n if (params.message) {\n redirectUrl.searchParams.set('message', params.message);\n }\n \n if (params.sig) {\n redirectUrl.searchParams.set('sig', params.sig);\n }\n\n // Optional: Send postMessage to parent if in iframe\n if (window.parent !== window) {\n window.parent.postMessage({\n type: 'kyc_result',\n status: params.status,\n kyc_id: params.kyc_id,\n message: params.message,\n }, '*');\n }\n\n // Redirect to return URL\n window.location.href = redirectUrl.toString();\n } catch (error) {\n console.error('Invalid return URL:', error);\n setError('Invalid return URL provided');\n }\n }, [urlParams]);\n\n // Handle KYC completion\n const handleComplete = useCallback((data: any) => {\n console.log('KYC completed:', data);\n redirectToReturnUrl({\n status: 'completed',\n kyc_id: data.session_id || urlParams.kyc_id,\n message: 'KYC process completed successfully',\n });\n onComplete?.(data);\n }, [redirectToReturnUrl, urlParams.kyc_id, onComplete]);\n\n // Handle KYC error\n const handleError = useCallback((error: string) => {\n console.error('KYC error:', error);\n redirectToReturnUrl({\n status: 'error',\n kyc_id: urlParams.kyc_id,\n message: error,\n });\n onError?.(error);\n }, [redirectToReturnUrl, urlParams.kyc_id, onError]);\n\n // Handle KYC cancellation\n const handleCancel = useCallback(() => {\n console.log('KYC cancelled');\n redirectToReturnUrl({\n status: 'cancelled',\n kyc_id: urlParams.kyc_id,\n message: 'KYC process was cancelled',\n });\n onCancel?.();\n }, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);\n\n // Initialize component\n useEffect(() => {\n try {\n const params = parseUrlParams();\n setUrlParams(params);\n \n // Set language if provided\n if (params.lang) {\n setLocale(params.lang);\n }\n \n setIsLoading(false);\n } catch (error) {\n console.error('Error parsing URL parameters:', error);\n setError('Error parsing URL parameters');\n setIsLoading(false);\n }\n }, [parseUrlParams, setLocale]);\n\n\n if (isLoading) {\n return (\n <View style={styles.container}>\n <Text style={styles.loadingText}>Loading KYC process...</Text>\n </View>\n );\n }\n\n if (error) {\n return (\n <View style={styles.container}>\n <Text style={styles.errorText}>Error: {error}</Text>\n </View>\n );\n }\n\n if (!urlParams.token) {\n return (\n <View style={styles.container}>\n <Text style={styles.errorText}>No token provided in URL parameters</Text>\n </View>\n );\n }\n\n return (\n <SafeAreaView style={styles.container}>\n <TemplateKYCExample \n onComplete={handleComplete} \n onCancel={handleCancel} \n onError={handleError}\n language={urlParams.lang || 'en'}\n API_KEY={urlParams.token}\n />\n </SafeAreaView>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: '#f5f5f5',\n },\n loadingText: {\n fontSize: 18,\n textAlign: 'center',\n marginTop: 50,\n color: '#666',\n },\n errorText: {\n fontSize: 16,\n textAlign: 'center',\n marginTop: 50,\n color: '#dc2626',\n paddingHorizontal: 20,\n },\n});\n\nexport default WebKYCEntry;\n"]}
|
|
1
|
+
{"version":3,"file":"WebKYCEntry.js","sourceRoot":"","sources":["../../src/web/WebKYCEntry.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useEffect, useState, useCallback } from 'react';\nimport { View, Text, StyleSheet, SafeAreaView, ActivityIndicator } from 'react-native';\n// import { TemplateKYCFlow } from '../components/TemplateKYCFlowRefactored';\n// import { KYCTemplate } from '../types/KYC.types';\nimport { useI18n } from '../hooks/useI18n';\nimport { TemplateKYCExample } from '../components/TemplateKYCExample';\nimport { isCallbackUrlAllowed } from '../config/allowedDomains';\nimport KYCConfig from '../config/KYCConfig';\nimport { BackendEnvironment } from '../types/env.types';\n\ninterface WebKYCEntryProps {\n onComplete?: (data: any) => void;\n onError?: (error: string) => void;\n onCancel?: () => void;\n}\n\ninterface URLParams {\n token?: string;\n return_url?: string;\n push_url?: string;\n lang?: string;\n theme?: string;\n kyc_id?: string;\n secret?: string; // Optional secret for signature generation\n env?: 'PRODUCTION' | 'SANDBOX'; // Environment mode\n template_id?: string; // Template ID for dynamic template loading\n server_env?: BackendEnvironment; // Backend environment mode\n step?: string; // Step index to resume verification at the correct point\n}\n\ninterface VerificationSteps {\n document_analyzed?: boolean;\n selfie_analyzed?: boolean;\n liveness_checked?: boolean;\n}\n\nconst WebKYCEntry: React.FC<WebKYCEntryProps> = ({\n onComplete,\n onError,\n onCancel,\n}) => {\n const { setLocale } = useI18n();\n const [urlParams, setUrlParams] = useState<URLParams>({});\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [isAnalyzing, setIsAnalyzing] = useState(false);\n\n // Parse URL parameters\n const parseUrlParams = useCallback((): URLParams => {\n if (typeof window === 'undefined') return {};\n\n const urlParams = new URLSearchParams(window.location.search);\n const envParam = urlParams.get('env');\n const validEnv = envParam === 'SANDBOX' || envParam === 'PRODUCTION' ? envParam : 'PRODUCTION';\n\n const serverEnvParam = urlParams.get('server_env');\n const validServerEnv: BackendEnvironment = serverEnvParam === 'TEST' || serverEnvParam === 'PRODUCTION'\n ? (serverEnvParam as BackendEnvironment)\n : 'PRODUCTION';\n\n return {\n token: urlParams.get('token') || undefined,\n return_url: urlParams.get('return_url') || undefined,\n push_url: urlParams.get('push_url') || undefined,\n lang: urlParams.get('lang') || 'en',\n theme: urlParams.get('theme') || 'light',\n kyc_id: urlParams.get('kyc_id') || undefined,\n secret: urlParams.get('secret') || undefined,\n env: validEnv,\n template_id: urlParams.get('template_id') || undefined,\n server_env: validServerEnv,\n step: urlParams.get('step') || undefined,\n };\n }, []);\n\n // Safe redirect function with enhanced validation\n const redirectToReturnUrl = useCallback(async (params: {\n status: 'completed' | 'cancelled' | 'error';\n kyc_id?: string;\n message?: string;\n processing_state?: 'analyzing' | 'completed' | 'pending';\n verification_steps?: VerificationSteps;\n }) => {\n const { return_url } = urlParams;\n\n if (!return_url) {\n console.warn('No return_url provided');\n return;\n }\n\n try {\n // Enhanced URL validation with domain whitelist\n const validation = isCallbackUrlAllowed(return_url);\n if (!validation.allowed) {\n console.error('Callback URL validation failed:', validation.reason);\n setError(`Security Error: ${validation.reason}`);\n\n // Log suspicious redirect attempt\n console.warn('Suspicious redirect attempt blocked:', {\n url: return_url,\n reason: validation.reason,\n timestamp: new Date().toISOString(),\n });\n return;\n }\n // Send postMessage to parent if in iframe\n if (window.parent !== window) {\n const targetOrigin = new URL(return_url).origin;\n window.parent.postMessage({\n type: 'kyc_result',\n status: params.status,\n kyc_id: params.kyc_id,\n message: params.message,\n processing_state: params.processing_state,\n verification_steps: params.verification_steps,\n }, targetOrigin);\n } else {\n window.location.href = return_url;\n }\n } catch (error) {\n console.error('Error during redirect:', error);\n setError('Failed to redirect to callback URL');\n }\n }, [urlParams]);\n\n // Handle KYC completion\n const handleComplete = useCallback(async (data: any) => {\n console.log('KYC completed:', data);\n\n // Check if still processing/analyzing\n const isStillProcessing = data.isProcessing || data.session?.isProcessing;\n\n // Handle Push URL webhook if provided\n if (urlParams.push_url) {\n try {\n const verificationState = {\n status: 'success', // verification completed successfully\n result: data, // pass complete data object as result\n };\n\n // Send data to provided push_url with a timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout\n\n await fetch(urlParams.push_url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(verificationState),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n console.log('Successfully pushed KYC data to webhook');\n } catch (err) {\n // Fail open - redirect anyway even if webhook fails\n console.warn('Failed to push data to webhook URL:', err);\n }\n }\n\n redirectToReturnUrl({\n status: 'completed',\n kyc_id: data.session_id || urlParams.kyc_id,\n message: 'KYC process completed successfully',\n processing_state: isStillProcessing ? 'analyzing' : 'completed',\n verification_steps: {\n document_analyzed: data.documentAnalysisComplete || false,\n selfie_analyzed: data.selfieAnalysisComplete || false,\n liveness_checked: data.livenessCheckComplete || false,\n },\n });\n onComplete?.(data);\n }, [redirectToReturnUrl, urlParams, onComplete]);\n\n // Handle KYC error\n const handleError = useCallback((error: string) => {\n console.error('KYC error:', error);\n setIsAnalyzing(false);\n redirectToReturnUrl({\n status: 'error',\n kyc_id: urlParams.kyc_id,\n message: error,\n processing_state: 'pending',\n });\n onError?.(error);\n }, [redirectToReturnUrl, urlParams.kyc_id, onError]);\n\n // Handle KYC cancellation\n const handleCancel = useCallback(() => {\n console.log('KYC cancelled', urlParams.push_url, urlParams);\n setIsAnalyzing(false);\n if (urlParams.push_url) {\n try {\n const verificationState = {\n status: 'cancelled', // verification cancelled\n result: null, // pass null as result\n };\n\n // Send data to provided push_url with a timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout\n\n fetch(urlParams.push_url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(verificationState),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n console.log('Successfully pushed KYC cancellation data to webhook');\n } catch (err) {\n // Fail open - redirect anyway even if webhook fails\n console.warn('Failed to push data to webhook URL:', err);\n }\n }\n redirectToReturnUrl({\n status: 'cancelled',\n kyc_id: urlParams.kyc_id,\n message: 'KYC process was cancelled',\n processing_state: 'pending',\n });\n onCancel?.();\n }, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);\n\n // Initialize component\n useEffect(() => {\n try {\n const params = parseUrlParams();\n setUrlParams(params);\n\n // Set language if provided\n if (params.lang) {\n setLocale(params.lang);\n }\n\n // Configure backend environment\n if (params.server_env) {\n KYCConfig.setBackendEnvironment(params.server_env);\n }\n\n setIsLoading(false);\n } catch (error) {\n console.error('Error parsing URL parameters:', error);\n setError('Error parsing URL parameters');\n setIsLoading(false);\n }\n }, [parseUrlParams, setLocale]);\n\n\n if (isLoading) {\n return (\n <View style={styles.container}>\n <Text style={styles.loadingText}>Loading KYC process...</Text>\n </View>\n );\n }\n\n if (error) {\n return (\n <View style={styles.container}>\n <Text style={styles.errorText}>Error: {error}</Text>\n </View>\n );\n }\n\n if (!urlParams.token) {\n return (\n <View style={styles.container}>\n <Text style={styles.errorText}>No token provided in URL parameters</Text>\n </View>\n );\n }\n\n return (\n <SafeAreaView style={styles.container}>\n {isAnalyzing && (\n <View style={styles.analyzingOverlay}>\n <View style={styles.analyzingContainer}>\n <ActivityIndicator size=\"large\" color=\"#2DBD60\" />\n <Text style={styles.analyzingText}>Analyzing verification data...</Text>\n <Text style={styles.analyzingSubtext}>This may take a few moments</Text>\n </View>\n </View>\n )}\n <TemplateKYCExample\n onComplete={handleComplete}\n onCancel={handleCancel}\n onError={handleError}\n language={urlParams.lang || 'en'}\n API_KEY={urlParams.token}\n templateId={urlParams.template_id}\n env={urlParams.env || 'PRODUCTION'}\n existingSessionId={urlParams.kyc_id}\n initialStep={urlParams.step ? (() => {\n const stepNum = parseInt(urlParams.step, 10);\n console.log('Parsing step from URL:', { stepString: urlParams.step, stepNumber: stepNum, isNaN: isNaN(stepNum) });\n return isNaN(stepNum) ? undefined : stepNum;\n })() : undefined}\n />\n </SafeAreaView>\n );\n};\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: '#f5f5f5',\n overflow: 'visible' as any, // Allow scrolling on web\n },\n loadingText: {\n fontSize: 18,\n textAlign: 'center',\n marginTop: 50,\n color: '#666',\n },\n errorText: {\n fontSize: 16,\n textAlign: 'center',\n marginTop: 50,\n color: '#dc2626',\n paddingHorizontal: 20,\n },\n analyzingOverlay: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundColor: 'rgba(0, 0, 0, 0.7)',\n justifyContent: 'center',\n alignItems: 'center',\n zIndex: 9999,\n },\n analyzingContainer: {\n backgroundColor: 'white',\n borderRadius: 12,\n padding: 32,\n alignItems: 'center',\n shadowColor: '#000',\n shadowOffset: { width: 0, height: 4 },\n shadowOpacity: 0.3,\n shadowRadius: 8,\n elevation: 8,\n },\n analyzingText: {\n fontSize: 18,\n fontWeight: '600',\n color: '#333',\n marginTop: 16,\n textAlign: 'center',\n },\n analyzingSubtext: {\n fontSize: 14,\n color: '#666',\n marginTop: 8,\n textAlign: 'center',\n },\n});\n\nexport default WebKYCEntry;\n"]}
|
package/package.json
CHANGED
|
@@ -28,10 +28,9 @@ const withVisionCameraPermissions = (config, { cameraPermissionText = 'This app
|
|
|
28
28
|
'android.permission.CAMERA',
|
|
29
29
|
'android.permission.RECORD_AUDIO',
|
|
30
30
|
];
|
|
31
|
-
//
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
31
|
+
// Note: WRITE_EXTERNAL_STORAGE is NOT needed even with frame processors
|
|
32
|
+
// Frame processors work in memory, and photos are saved to app's internal storage
|
|
33
|
+
// Adding storage permissions causes Google Play Store rejection for KYC apps
|
|
35
34
|
for (const permission of permissions) {
|
|
36
35
|
if (!androidManifest.manifest['uses-permission'].find((perm) => perm.$['android:name'] === permission)) {
|
|
37
36
|
androidManifest.manifest['uses-permission'].push({
|
|
@@ -37,10 +37,9 @@ const withVisionCameraPermissions = (config, {
|
|
|
37
37
|
'android.permission.RECORD_AUDIO',
|
|
38
38
|
];
|
|
39
39
|
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
40
|
+
// Note: WRITE_EXTERNAL_STORAGE is NOT needed even with frame processors
|
|
41
|
+
// Frame processors work in memory, and photos are saved to app's internal storage
|
|
42
|
+
// Adding storage permissions causes Google Play Store rejection for KYC apps
|
|
44
43
|
|
|
45
44
|
for (const permission of permissions) {
|
|
46
45
|
if (!androidManifest.manifest['uses-permission'].find(
|
|
@@ -46,10 +46,9 @@ const withVisionCameraPermissions: ConfigPlugin<VisionCameraPluginProps> = (
|
|
|
46
46
|
'android.permission.RECORD_AUDIO',
|
|
47
47
|
];
|
|
48
48
|
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
49
|
+
// Note: WRITE_EXTERNAL_STORAGE is NOT needed even with frame processors
|
|
50
|
+
// Frame processors work in memory, and photos are saved to app's internal storage
|
|
51
|
+
// Adding storage permissions causes Google Play Store rejection for KYC apps
|
|
53
52
|
|
|
54
53
|
for (const permission of permissions) {
|
|
55
54
|
if (!androidManifest.manifest['uses-permission'].find(
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState, useMemo } from 'react';
|
|
2
2
|
import { View, StyleSheet, TouchableOpacity, Text } from 'react-native';
|
|
3
3
|
import { Camera, useCameraDevice } from 'react-native-vision-camera';
|
|
4
4
|
import VisionCameraModule from '../modules/camera/VisionCameraModule';
|
|
@@ -43,6 +43,34 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
43
43
|
const device = useCameraDevice(cameraType);
|
|
44
44
|
console.log({ setCameraType, setFlash });
|
|
45
45
|
|
|
46
|
+
// Sélectionner le meilleur format disponible pour une qualité maximale
|
|
47
|
+
// Prioriser les formats avec une bonne résolution vidéo (pour la prévisualisation) ET photo (pour la capture)
|
|
48
|
+
const bestFormat = useMemo(() => {
|
|
49
|
+
if (!device || !device.formats || device.formats.length === 0) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Trier les formats en combinant la résolution vidéo (pour la prévisualisation) et photo (pour la capture)
|
|
54
|
+
// On priorise les formats avec une bonne résolution vidéo car c'est ce qui est affiché en temps réel
|
|
55
|
+
const sortedFormats = [...device.formats].sort((a, b) => {
|
|
56
|
+
// Résolution vidéo (pour la prévisualisation live)
|
|
57
|
+
const videoResolutionA = (a.videoWidth || 0) * (a.videoHeight || 0);
|
|
58
|
+
const videoResolutionB = (b.videoWidth || 0) * (b.videoHeight || 0);
|
|
59
|
+
|
|
60
|
+
// Résolution photo (pour la capture)
|
|
61
|
+
const photoResolutionA = (a.photoWidth || 0) * (a.photoHeight || 0);
|
|
62
|
+
const photoResolutionB = (b.photoWidth || 0) * (b.photoHeight || 0);
|
|
63
|
+
|
|
64
|
+
// Prioriser d'abord la résolution vidéo (prévisualisation), puis la résolution photo
|
|
65
|
+
if (videoResolutionB !== videoResolutionA) {
|
|
66
|
+
return videoResolutionB - videoResolutionA;
|
|
67
|
+
}
|
|
68
|
+
return photoResolutionB - photoResolutionA;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
return sortedFormats[0];
|
|
72
|
+
}, [device]);
|
|
73
|
+
|
|
46
74
|
const checkPermissions = async () => {
|
|
47
75
|
try {
|
|
48
76
|
const hasAllPermissions = await VisionCameraModule.hasAllPermissions();
|
|
@@ -102,7 +130,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
102
130
|
} catch (error) {
|
|
103
131
|
|
|
104
132
|
}
|
|
105
|
-
}, [isInitialized, onError, onSilentCapture]);
|
|
133
|
+
}, [isInitialized, onError, onSilentCapture, enableFlash, flash, silentCaptureResult]);
|
|
106
134
|
|
|
107
135
|
// Automatically take a silent photo every 5 seconds when ready
|
|
108
136
|
useEffect(() => {
|
|
@@ -244,6 +272,7 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
244
272
|
photo={true}
|
|
245
273
|
video={enableVideo}
|
|
246
274
|
audio={enableVideo}
|
|
275
|
+
format={bestFormat}
|
|
247
276
|
onInitialized={onInitialized}
|
|
248
277
|
onError={onCameraError}
|
|
249
278
|
/>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { View, StyleSheet, TouchableOpacity, Text, Platform } from 'react-native';
|
|
3
3
|
import { EnhancedCameraViewProps } from './OverLay/type';
|
|
4
|
+
import { useI18n } from '../hooks/useI18n';
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
@@ -27,6 +28,8 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
27
28
|
onSilentCapture,
|
|
28
29
|
silentCaptureResult,
|
|
29
30
|
}) => {
|
|
31
|
+
const { t } = useI18n();
|
|
32
|
+
|
|
30
33
|
// Vérification de plateforme - ce composant est uniquement pour le web
|
|
31
34
|
if (Platform.OS !== 'web') {
|
|
32
35
|
console.warn('EnhancedCameraView.web.tsx should only be used on web platform');
|
|
@@ -350,6 +353,13 @@ export const EnhancedCameraView: React.FC<EnhancedCameraViewProps> = ({
|
|
|
350
353
|
</View>
|
|
351
354
|
)}
|
|
352
355
|
|
|
356
|
+
{/* Analyzing indicator - Same as mobile */}
|
|
357
|
+
{silentCaptureResult?.isAnalyzing && (
|
|
358
|
+
<View style={styles.analyzingContainer}>
|
|
359
|
+
<Text style={styles.analyzingText}>{t('camera.analyzing')}</Text>
|
|
360
|
+
</View>
|
|
361
|
+
)}
|
|
362
|
+
|
|
353
363
|
{/* Camera controls */}
|
|
354
364
|
<View style={styles.controlsContainer}>
|
|
355
365
|
{/* Flash button */}
|
|
@@ -515,4 +525,18 @@ const styles = StyleSheet.create({
|
|
|
515
525
|
borderStyle: 'solid',
|
|
516
526
|
backgroundColor: 'transparent',
|
|
517
527
|
},
|
|
528
|
+
analyzingContainer: {
|
|
529
|
+
position: 'absolute',
|
|
530
|
+
bottom: 100,
|
|
531
|
+
alignSelf: 'center',
|
|
532
|
+
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
|
533
|
+
padding: 10,
|
|
534
|
+
borderRadius: 10,
|
|
535
|
+
zIndex: 1000,
|
|
536
|
+
},
|
|
537
|
+
analyzingText: {
|
|
538
|
+
color: 'white',
|
|
539
|
+
fontSize: 16,
|
|
540
|
+
fontWeight: 'bold',
|
|
541
|
+
},
|
|
518
542
|
});
|