@transfergratis/react-native-sdk 0.1.24 → 0.1.26
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 +22 -7
- package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
- package/build/components/EnhancedCameraView.web.js +76 -21
- 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/EmailVerificationTemplate.d.ts +12 -0
- package/build/components/KYCElements/EmailVerificationTemplate.d.ts.map +1 -0
- package/build/components/KYCElements/EmailVerificationTemplate.js +212 -0
- package/build/components/KYCElements/EmailVerificationTemplate.js.map +1 -0
- package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
- package/build/components/KYCElements/IDCardCapture.js +216 -14
- package/build/components/KYCElements/IDCardCapture.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 +2 -2
- 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 +2 -2
- 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 +2 -2
- 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/SelfieCaptureTemplate.d.ts.map +1 -1
- package/build/components/KYCElements/SelfieCaptureTemplate.js +7 -3
- package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
- package/build/components/KYCElements/WelcomeTemplate.js +2 -1
- package/build/components/KYCElements/WelcomeTemplate.js.map +1 -1
- package/build/components/OverLay/type.d.ts +2 -0
- package/build/components/OverLay/type.d.ts.map +1 -1
- package/build/components/OverLay/type.js.map +1 -1
- package/build/components/TemplateKYCExample.d.ts +10 -0
- package/build/components/TemplateKYCExample.d.ts.map +1 -1
- package/build/components/TemplateKYCExample.js +7 -30
- package/build/components/TemplateKYCExample.js.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.d.ts +12 -0
- package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
- package/build/components/TemplateKYCFlowRefactored.js +25 -3
- package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
- 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.map +1 -1
- package/build/config/allowedDomains.js +4 -19
- package/build/config/allowedDomains.js.map +1 -1
- 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 +18 -1
- package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
- package/build/hooks/useTemplateKYCFlow.js +410 -56
- package/build/hooks/useTemplateKYCFlow.js.map +1 -1
- package/build/i18n/en/index.d.ts +42 -0
- package/build/i18n/en/index.d.ts.map +1 -1
- package/build/i18n/en/index.js +44 -2
- package/build/i18n/en/index.js.map +1 -1
- package/build/i18n/fr/index.d.ts +28 -0
- package/build/i18n/fr/index.d.ts.map +1 -1
- package/build/i18n/fr/index.js +30 -2
- package/build/i18n/fr/index.js.map +1 -1
- package/build/i18n/types.d.ts +2 -0
- package/build/i18n/types.d.ts.map +1 -1
- package/build/i18n/types.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +2 -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 +90 -12
- package/build/modules/api/CardAuthentification.js.map +1 -1
- package/build/modules/api/KYCService.d.ts +17 -7
- package/build/modules/api/KYCService.d.ts.map +1 -1
- package/build/modules/api/KYCService.js +125 -37
- 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 +0 -1
- package/build/modules/api/TemplateService.d.ts.map +1 -1
- package/build/modules/api/TemplateService.js +3 -3
- package/build/modules/api/TemplateService.js.map +1 -1
- package/build/modules/camera/VisionCameraModule.web.d.ts.map +1 -1
- package/build/modules/camera/VisionCameraModule.web.js +27 -8
- package/build/modules/camera/VisionCameraModule.web.js.map +1 -1
- package/build/types/KYC.types.d.ts +130 -5
- package/build/types/KYC.types.d.ts.map +1 -1
- 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 +7 -0
- package/build/utils/cropByObb.d.ts.map +1 -1
- package/build/utils/cropByObb.js +20 -1
- 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.map +1 -1
- package/build/utils/platformAlert.js.map +1 -1
- package/build/utils/template-transformer.d.ts.map +1 -1
- package/build/utils/template-transformer.js +12 -0
- package/build/utils/template-transformer.js.map +1 -1
- package/build/web/WebKYCEntry.d.ts.map +1 -1
- package/build/web/WebKYCEntry.js +88 -38
- package/build/web/WebKYCEntry.js.map +1 -1
- package/package.json +1 -1
- package/plugin/build/index.d.ts +1 -0
- package/plugin/build/index.js +3 -1
- package/plugin/build/withRemovePermissions.d.ts +3 -0
- package/plugin/build/withRemovePermissions.js +67 -0
- package/plugin/build/withVisionCamera.js +3 -4
- package/plugin/src/index.ts +2 -1
- package/plugin/src/withRemovePermissions.js +85 -0
- package/plugin/src/withRemovePermissions.ts +83 -0
- package/plugin/src/withVisionCamera.js +3 -4
- package/plugin/src/withVisionCamera.ts +3 -4
- package/plugin/tsconfig.tsbuildinfo +1 -1
- package/plugin.js +6 -1
- package/src/components/EnhancedCameraView.web.tsx +76 -21
- package/src/components/KYCElements/AdditionalDocumentsTemplate.tsx +346 -0
- package/src/components/KYCElements/EmailVerificationTemplate.tsx +278 -0
- package/src/components/KYCElements/IDCardCapture.tsx +253 -21
- package/src/components/KYCElements/OrientationVideoCapture.tsx +4 -1
- package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +4 -1
- package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +4 -1
- package/src/components/KYCElements/PersonalInformationTemplate.tsx +158 -0
- package/src/components/KYCElements/PhoneVerificationTemplate.tsx +253 -0
- package/src/components/KYCElements/SelfieCaptureTemplate.tsx +6 -3
- package/src/components/KYCElements/WelcomeTemplate.tsx +2 -1
- package/src/components/OverLay/type.ts +2 -0
- package/src/components/TemplateKYCExample.tsx +35 -46
- package/src/components/TemplateKYCFlowRefactored.tsx +46 -2
- package/src/config/KYCConfig.ts +34 -0
- package/src/config/allowedDomains.ts +7 -26
- package/src/hooks/useOrientationVideo.ts +5 -4
- package/src/hooks/useTemplateKYCFlow.tsx +443 -56
- package/src/i18n/en/index.ts +46 -3
- package/src/i18n/fr/index.ts +31 -2
- package/src/i18n/types.ts +2 -0
- package/src/index.ts +3 -0
- package/src/modules/api/CardAuthentification.ts +98 -12
- package/src/modules/api/KYCService.ts +158 -37
- package/src/modules/api/SelfieVerification.ts +25 -3
- package/src/modules/api/TemplateService.ts +4 -4
- package/src/modules/camera/VisionCameraModule.web.ts +30 -12
- package/src/types/KYC.types.ts +153 -6
- package/src/types/env.types.ts +13 -0
- package/src/utils/cropByObb.ts +20 -1
- package/src/utils/deviceDetection.ts +11 -0
- package/src/utils/platformAlert.ts +1 -0
- package/src/utils/template-transformer.ts +20 -8
- package/src/web/WebKYCEntry.tsx +123 -61
package/build/web/WebKYCEntry.js
CHANGED
|
@@ -4,7 +4,8 @@ import { View, Text, StyleSheet, SafeAreaView, ActivityIndicator } from 'react-n
|
|
|
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
|
|
7
|
+
import { isCallbackUrlAllowed } from '../config/allowedDomains';
|
|
8
|
+
import KYCConfig from '../config/KYCConfig';
|
|
8
9
|
const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
9
10
|
const { setLocale } = useI18n();
|
|
10
11
|
const [urlParams, setUrlParams] = useState({});
|
|
@@ -16,18 +17,33 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
16
17
|
if (typeof window === 'undefined')
|
|
17
18
|
return {};
|
|
18
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';
|
|
19
26
|
return {
|
|
20
27
|
token: urlParams.get('token') || undefined,
|
|
21
28
|
return_url: urlParams.get('return_url') || undefined,
|
|
29
|
+
push_url: urlParams.get('push_url') || undefined,
|
|
22
30
|
lang: urlParams.get('lang') || 'en',
|
|
23
31
|
theme: urlParams.get('theme') || 'light',
|
|
24
32
|
kyc_id: urlParams.get('kyc_id') || undefined,
|
|
25
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,
|
|
38
|
+
component_index: urlParams.get('component_index') || undefined,
|
|
39
|
+
country: urlParams.get('country') || undefined,
|
|
40
|
+
document_type: urlParams.get('document_type') || undefined,
|
|
41
|
+
region: urlParams.get('region') || undefined,
|
|
26
42
|
};
|
|
27
43
|
}, []);
|
|
28
44
|
// Safe redirect function with enhanced validation
|
|
29
45
|
const redirectToReturnUrl = useCallback(async (params) => {
|
|
30
|
-
const { return_url
|
|
46
|
+
const { return_url } = urlParams;
|
|
31
47
|
if (!return_url) {
|
|
32
48
|
console.warn('No return_url provided');
|
|
33
49
|
return;
|
|
@@ -46,37 +62,9 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
46
62
|
});
|
|
47
63
|
return;
|
|
48
64
|
}
|
|
49
|
-
const returnUrl = new URL(return_url);
|
|
50
|
-
// Build redirect URL with parameters
|
|
51
|
-
const redirectUrl = new URL(returnUrl);
|
|
52
|
-
const redirectParams = {
|
|
53
|
-
status: params.status,
|
|
54
|
-
};
|
|
55
|
-
if (params.kyc_id) {
|
|
56
|
-
redirectParams.kyc_id = params.kyc_id;
|
|
57
|
-
}
|
|
58
|
-
if (params.message) {
|
|
59
|
-
redirectParams.message = params.message;
|
|
60
|
-
}
|
|
61
|
-
if (params.processing_state) {
|
|
62
|
-
redirectParams.processing_state = params.processing_state;
|
|
63
|
-
}
|
|
64
|
-
if (params.verification_steps) {
|
|
65
|
-
redirectParams.verification_steps = JSON.stringify(params.verification_steps);
|
|
66
|
-
}
|
|
67
|
-
// Generate signature for integrity verification
|
|
68
|
-
if (secret) {
|
|
69
|
-
const signature = await generateCallbackSignature(redirectParams, secret);
|
|
70
|
-
if (signature) {
|
|
71
|
-
redirectParams.sig = signature;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// Add all params to URL
|
|
75
|
-
Object.entries(redirectParams).forEach(([key, value]) => {
|
|
76
|
-
redirectUrl.searchParams.set(key, value);
|
|
77
|
-
});
|
|
78
65
|
// Send postMessage to parent if in iframe
|
|
79
66
|
if (window.parent !== window) {
|
|
67
|
+
const targetOrigin = new URL(return_url).origin;
|
|
80
68
|
window.parent.postMessage({
|
|
81
69
|
type: 'kyc_result',
|
|
82
70
|
status: params.status,
|
|
@@ -84,10 +72,11 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
84
72
|
message: params.message,
|
|
85
73
|
processing_state: params.processing_state,
|
|
86
74
|
verification_steps: params.verification_steps,
|
|
87
|
-
},
|
|
75
|
+
}, targetOrigin);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
window.location.href = return_url;
|
|
88
79
|
}
|
|
89
|
-
// Redirect to return URL
|
|
90
|
-
window.location.href = redirectUrl.toString();
|
|
91
80
|
}
|
|
92
81
|
catch (error) {
|
|
93
82
|
console.error('Error during redirect:', error);
|
|
@@ -95,10 +84,36 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
95
84
|
}
|
|
96
85
|
}, [urlParams]);
|
|
97
86
|
// Handle KYC completion
|
|
98
|
-
const handleComplete = useCallback((data) => {
|
|
87
|
+
const handleComplete = useCallback(async (data) => {
|
|
99
88
|
console.log('KYC completed:', data);
|
|
100
89
|
// Check if still processing/analyzing
|
|
101
90
|
const isStillProcessing = data.isProcessing || data.session?.isProcessing;
|
|
91
|
+
// Handle Push URL webhook if provided
|
|
92
|
+
if (urlParams.push_url) {
|
|
93
|
+
try {
|
|
94
|
+
const verificationState = {
|
|
95
|
+
status: 'success', // verification completed successfully
|
|
96
|
+
result: data, // pass complete data object as result
|
|
97
|
+
};
|
|
98
|
+
// Send data to provided push_url with a timeout
|
|
99
|
+
const controller = new AbortController();
|
|
100
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
|
|
101
|
+
await fetch(urlParams.push_url, {
|
|
102
|
+
method: 'POST',
|
|
103
|
+
headers: {
|
|
104
|
+
'Content-Type': 'application/json',
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify(verificationState),
|
|
107
|
+
signal: controller.signal,
|
|
108
|
+
});
|
|
109
|
+
clearTimeout(timeoutId);
|
|
110
|
+
console.log('Successfully pushed KYC data to webhook');
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
// Fail open - redirect anyway even if webhook fails
|
|
114
|
+
console.warn('Failed to push data to webhook URL:', err);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
102
117
|
redirectToReturnUrl({
|
|
103
118
|
status: 'completed',
|
|
104
119
|
kyc_id: data.session_id || urlParams.kyc_id,
|
|
@@ -111,7 +126,7 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
111
126
|
},
|
|
112
127
|
});
|
|
113
128
|
onComplete?.(data);
|
|
114
|
-
}, [redirectToReturnUrl, urlParams
|
|
129
|
+
}, [redirectToReturnUrl, urlParams, onComplete]);
|
|
115
130
|
// Handle KYC error
|
|
116
131
|
const handleError = useCallback((error) => {
|
|
117
132
|
console.error('KYC error:', error);
|
|
@@ -126,8 +141,33 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
126
141
|
}, [redirectToReturnUrl, urlParams.kyc_id, onError]);
|
|
127
142
|
// Handle KYC cancellation
|
|
128
143
|
const handleCancel = useCallback(() => {
|
|
129
|
-
console.log('KYC cancelled');
|
|
144
|
+
console.log('KYC cancelled', urlParams.push_url, urlParams);
|
|
130
145
|
setIsAnalyzing(false);
|
|
146
|
+
if (urlParams.push_url) {
|
|
147
|
+
try {
|
|
148
|
+
const verificationState = {
|
|
149
|
+
status: 'cancelled', // verification cancelled
|
|
150
|
+
result: null, // pass null as result
|
|
151
|
+
};
|
|
152
|
+
// Send data to provided push_url with a timeout
|
|
153
|
+
const controller = new AbortController();
|
|
154
|
+
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
|
|
155
|
+
fetch(urlParams.push_url, {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: {
|
|
158
|
+
'Content-Type': 'application/json',
|
|
159
|
+
},
|
|
160
|
+
body: JSON.stringify(verificationState),
|
|
161
|
+
signal: controller.signal,
|
|
162
|
+
});
|
|
163
|
+
clearTimeout(timeoutId);
|
|
164
|
+
console.log('Successfully pushed KYC cancellation data to webhook');
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
// Fail open - redirect anyway even if webhook fails
|
|
168
|
+
console.warn('Failed to push data to webhook URL:', err);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
131
171
|
redirectToReturnUrl({
|
|
132
172
|
status: 'cancelled',
|
|
133
173
|
kyc_id: urlParams.kyc_id,
|
|
@@ -145,6 +185,10 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
145
185
|
if (params.lang) {
|
|
146
186
|
setLocale(params.lang);
|
|
147
187
|
}
|
|
188
|
+
// Configure backend environment
|
|
189
|
+
if (params.server_env) {
|
|
190
|
+
KYCConfig.setBackendEnvironment(params.server_env);
|
|
191
|
+
}
|
|
148
192
|
setIsLoading(false);
|
|
149
193
|
}
|
|
150
194
|
catch (error) {
|
|
@@ -176,7 +220,13 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
|
|
|
176
220
|
<Text style={styles.analyzingSubtext}>This may take a few moments</Text>
|
|
177
221
|
</View>
|
|
178
222
|
</View>)}
|
|
179
|
-
|
|
223
|
+
<TemplateKYCExample onComplete={handleComplete} onCancel={handleCancel} onError={handleError} language={urlParams.lang || 'en'} API_KEY={urlParams.token} templateId={urlParams.template_id} env={urlParams.env || 'PRODUCTION'} serverEnv={urlParams.server_env} existingSessionId={urlParams.kyc_id} initialComponentIndex={(() => {
|
|
224
|
+
const raw = urlParams.component_index ?? urlParams.step;
|
|
225
|
+
if (raw == null || raw === '')
|
|
226
|
+
return undefined;
|
|
227
|
+
const index = parseInt(raw, 10);
|
|
228
|
+
return Number.isNaN(index) ? undefined : index;
|
|
229
|
+
})()} initialCountryResume={urlParams.country && urlParams.document_type ? { code: urlParams.country, documentType: urlParams.document_type, region: urlParams.region || undefined } : undefined}/>
|
|
180
230
|
</SafeAreaView>);
|
|
181
231
|
};
|
|
182
232
|
const styles = StyleSheet.create({
|
|
@@ -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, 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, generateCallbackSignature } from '../config/allowedDomains';\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 secret?: string; // Optional secret for signature generation\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 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 secret: urlParams.get('secret') || 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, secret } = 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\n const returnUrl = new URL(return_url);\n\n // Build redirect URL with parameters\n const redirectUrl = new URL(returnUrl);\n const redirectParams: Record<string, string> = {\n status: params.status,\n };\n\n if (params.kyc_id) {\n redirectParams.kyc_id = params.kyc_id;\n }\n \n if (params.message) {\n redirectParams.message = params.message;\n }\n\n if (params.processing_state) {\n redirectParams.processing_state = params.processing_state;\n }\n\n if (params.verification_steps) {\n redirectParams.verification_steps = JSON.stringify(params.verification_steps);\n }\n\n // Generate signature for integrity verification\n if (secret) {\n const signature = await generateCallbackSignature(redirectParams, secret);\n if (signature) {\n redirectParams.sig = signature;\n }\n }\n\n // Add all params to URL\n Object.entries(redirectParams).forEach(([key, value]) => {\n redirectUrl.searchParams.set(key, value);\n });\n\n // 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 processing_state: params.processing_state,\n verification_steps: params.verification_steps,\n }, returnUrl.origin); // Use specific origin instead of '*'\n }\n\n // Redirect to return URL\n window.location.href = redirectUrl.toString();\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((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 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.kyc_id, 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');\n setIsAnalyzing(false);\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 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 />\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"]}
|
|
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; // Deprecated: use component_index.\n component_index?: string; // Index in template.components (0-based) to resume at\n country?: string; // Code pays pour restaurer la sélection (reprise multi-appareil)\n document_type?: string; // Type de document (national_id, passport, etc.)\n region?: string; // Région si applicable\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 component_index: urlParams.get('component_index') || undefined,\n country: urlParams.get('country') || undefined,\n document_type: urlParams.get('document_type') || undefined,\n region: urlParams.get('region') || 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 serverEnv={urlParams.server_env}\n existingSessionId={urlParams.kyc_id}\n initialComponentIndex={(() => {\n const raw = urlParams.component_index ?? urlParams.step;\n if (raw == null || raw === '') return undefined;\n const index = parseInt(raw, 10);\n return Number.isNaN(index) ? undefined : index;\n })()}\n initialCountryResume={urlParams.country && urlParams.document_type ? { code: urlParams.country, documentType: urlParams.document_type, region: urlParams.region || undefined } : 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
package/plugin/build/index.d.ts
CHANGED
|
@@ -2,3 +2,4 @@ export { default as withVisionCamera } from './withVisionCamera';
|
|
|
2
2
|
export type { VisionCameraPluginProps } from './withVisionCamera';
|
|
3
3
|
export { default as withLocation } from './withLocation';
|
|
4
4
|
export type { LocationPluginProps } from './withLocation';
|
|
5
|
+
export { default as withRemovePermissions } from './withRemovePermissions';
|
package/plugin/build/index.js
CHANGED
|
@@ -3,8 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.withLocation = exports.withVisionCamera = void 0;
|
|
6
|
+
exports.withRemovePermissions = exports.withLocation = exports.withVisionCamera = void 0;
|
|
7
7
|
var withVisionCamera_1 = require("./withVisionCamera");
|
|
8
8
|
Object.defineProperty(exports, "withVisionCamera", { enumerable: true, get: function () { return __importDefault(withVisionCamera_1).default; } });
|
|
9
9
|
var withLocation_1 = require("./withLocation");
|
|
10
10
|
Object.defineProperty(exports, "withLocation", { enumerable: true, get: function () { return __importDefault(withLocation_1).default; } });
|
|
11
|
+
var withRemovePermissions_1 = require("./withRemovePermissions");
|
|
12
|
+
Object.defineProperty(exports, "withRemovePermissions", { enumerable: true, get: function () { return __importDefault(withRemovePermissions_1).default; } });
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
4
|
+
/**
|
|
5
|
+
* Plugin to remove unnecessary permissions that cause Google Play Store rejection.
|
|
6
|
+
*
|
|
7
|
+
* For KYC apps, we don't need persistent access to media files because:
|
|
8
|
+
* - Photos are taken directly with the camera
|
|
9
|
+
* - Photos are saved to app's internal storage (documentDirectory)
|
|
10
|
+
* - File selection uses Android Photo Picker API (no permissions needed)
|
|
11
|
+
*/
|
|
12
|
+
// Permissions to remove - these cause Play Store rejection for KYC apps
|
|
13
|
+
const PERMISSIONS_TO_REMOVE = [
|
|
14
|
+
// Media permissions - not needed, causes Play Store rejection
|
|
15
|
+
'android.permission.READ_MEDIA_IMAGES',
|
|
16
|
+
'android.permission.READ_MEDIA_VIDEO',
|
|
17
|
+
'android.permission.READ_MEDIA_AUDIO',
|
|
18
|
+
// Storage permissions - not needed for KYC
|
|
19
|
+
'android.permission.READ_EXTERNAL_STORAGE',
|
|
20
|
+
'android.permission.WRITE_EXTERNAL_STORAGE',
|
|
21
|
+
// Contacts - not needed for KYC
|
|
22
|
+
'android.permission.READ_CONTACTS',
|
|
23
|
+
'android.permission.WRITE_CONTACTS',
|
|
24
|
+
];
|
|
25
|
+
const withRemovePermissions = (config) => {
|
|
26
|
+
return (0, config_plugins_1.withAndroidManifest)(config, (config) => {
|
|
27
|
+
var _a;
|
|
28
|
+
const androidManifest = config.modResults;
|
|
29
|
+
if (!androidManifest.manifest['uses-permission']) {
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
// Filter out unwanted permissions
|
|
33
|
+
const originalCount = androidManifest.manifest['uses-permission'].length;
|
|
34
|
+
androidManifest.manifest['uses-permission'] = androidManifest.manifest['uses-permission'].filter((permission) => {
|
|
35
|
+
var _a;
|
|
36
|
+
const permissionName = (_a = permission.$) === null || _a === void 0 ? void 0 : _a['android:name'];
|
|
37
|
+
const shouldRemove = PERMISSIONS_TO_REMOVE.includes(permissionName);
|
|
38
|
+
if (shouldRemove) {
|
|
39
|
+
console.log(`[withRemovePermissions] Removing: ${permissionName}`);
|
|
40
|
+
}
|
|
41
|
+
return !shouldRemove;
|
|
42
|
+
});
|
|
43
|
+
const removedCount = originalCount - androidManifest.manifest['uses-permission'].length;
|
|
44
|
+
console.log(`[withRemovePermissions] Removed ${removedCount} permissions`);
|
|
45
|
+
// Also add tools:remove to explicitly block these permissions from being merged
|
|
46
|
+
// This prevents dependencies from re-adding them
|
|
47
|
+
// Ensure xmlns:tools is defined (xmlns:android always exists in valid manifests)
|
|
48
|
+
if (androidManifest.manifest.$) {
|
|
49
|
+
androidManifest.manifest.$['xmlns:tools'] = 'http://schemas.android.com/tools';
|
|
50
|
+
}
|
|
51
|
+
// Add uses-permission with tools:node="remove" for each permission to block
|
|
52
|
+
for (const permissionName of PERMISSIONS_TO_REMOVE) {
|
|
53
|
+
// Check if a remove directive already exists
|
|
54
|
+
const existingRemove = (_a = androidManifest.manifest['uses-permission']) === null || _a === void 0 ? void 0 : _a.find((p) => { var _a, _b; return ((_a = p.$) === null || _a === void 0 ? void 0 : _a['android:name']) === permissionName && ((_b = p.$) === null || _b === void 0 ? void 0 : _b['tools:node']) === 'remove'; });
|
|
55
|
+
if (!existingRemove) {
|
|
56
|
+
androidManifest.manifest['uses-permission'].push({
|
|
57
|
+
$: {
|
|
58
|
+
'android:name': permissionName,
|
|
59
|
+
'tools:node': 'remove',
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return config;
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
exports.default = withRemovePermissions;
|
|
@@ -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({
|
package/plugin/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as withVisionCamera } from './withVisionCamera';
|
|
2
2
|
export type { VisionCameraPluginProps } from './withVisionCamera';
|
|
3
3
|
export { default as withLocation } from './withLocation';
|
|
4
|
-
export type { LocationPluginProps } from './withLocation';
|
|
4
|
+
export type { LocationPluginProps } from './withLocation';
|
|
5
|
+
export { default as withRemovePermissions } from './withRemovePermissions';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const { withAndroidManifest } = require('@expo/config-plugins');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plugin to remove unnecessary permissions that cause Google Play Store rejection.
|
|
5
|
+
*
|
|
6
|
+
* For KYC apps, we don't need persistent access to media files because:
|
|
7
|
+
* - Photos are taken directly with the camera
|
|
8
|
+
* - Photos are saved to app's internal storage (documentDirectory)
|
|
9
|
+
* - File selection uses Android Photo Picker API (no permissions needed)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Permissions to remove - these cause Play Store rejection for KYC apps
|
|
13
|
+
const PERMISSIONS_TO_REMOVE = [
|
|
14
|
+
// Media permissions - not needed, causes Play Store rejection
|
|
15
|
+
'android.permission.READ_MEDIA_IMAGES',
|
|
16
|
+
'android.permission.READ_MEDIA_VIDEO',
|
|
17
|
+
'android.permission.READ_MEDIA_AUDIO',
|
|
18
|
+
|
|
19
|
+
// Storage permissions - not needed for KYC
|
|
20
|
+
'android.permission.READ_EXTERNAL_STORAGE',
|
|
21
|
+
'android.permission.WRITE_EXTERNAL_STORAGE',
|
|
22
|
+
|
|
23
|
+
// Contacts - not needed for KYC
|
|
24
|
+
'android.permission.READ_CONTACTS',
|
|
25
|
+
'android.permission.WRITE_CONTACTS',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const withRemovePermissions = (config) => {
|
|
29
|
+
return withAndroidManifest(config, (config) => {
|
|
30
|
+
const androidManifest = config.modResults;
|
|
31
|
+
|
|
32
|
+
if (!androidManifest.manifest['uses-permission']) {
|
|
33
|
+
return config;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Filter out unwanted permissions
|
|
37
|
+
const originalCount = androidManifest.manifest['uses-permission'].length;
|
|
38
|
+
|
|
39
|
+
androidManifest.manifest['uses-permission'] = androidManifest.manifest['uses-permission'].filter(
|
|
40
|
+
(permission) => {
|
|
41
|
+
const permissionName = permission.$?.['android:name'];
|
|
42
|
+
const shouldRemove = PERMISSIONS_TO_REMOVE.includes(permissionName);
|
|
43
|
+
|
|
44
|
+
if (shouldRemove) {
|
|
45
|
+
console.log(`[withRemovePermissions] Removing: ${permissionName}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return !shouldRemove;
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const removedCount = originalCount - androidManifest.manifest['uses-permission'].length;
|
|
53
|
+
console.log(`[withRemovePermissions] Removed ${removedCount} permissions`);
|
|
54
|
+
|
|
55
|
+
// Also add tools:remove to explicitly block these permissions from being merged
|
|
56
|
+
// This prevents dependencies from re-adding them
|
|
57
|
+
if (!androidManifest.manifest.$) {
|
|
58
|
+
androidManifest.manifest.$ = {};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Ensure xmlns:tools is defined
|
|
62
|
+
androidManifest.manifest.$['xmlns:tools'] = 'http://schemas.android.com/tools';
|
|
63
|
+
|
|
64
|
+
// Add uses-permission with tools:node="remove" for each permission to block
|
|
65
|
+
for (const permissionName of PERMISSIONS_TO_REMOVE) {
|
|
66
|
+
// Check if a remove directive already exists
|
|
67
|
+
const existingRemove = androidManifest.manifest['uses-permission']?.find(
|
|
68
|
+
(p) => p.$?.['android:name'] === permissionName && p.$?.['tools:node'] === 'remove'
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
if (!existingRemove) {
|
|
72
|
+
androidManifest.manifest['uses-permission'].push({
|
|
73
|
+
$: {
|
|
74
|
+
'android:name': permissionName,
|
|
75
|
+
'tools:node': 'remove',
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return config;
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
module.exports = withRemovePermissions;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { ConfigPlugin, withAndroidManifest, AndroidConfig } from '@expo/config-plugins';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plugin to remove unnecessary permissions that cause Google Play Store rejection.
|
|
5
|
+
*
|
|
6
|
+
* For KYC apps, we don't need persistent access to media files because:
|
|
7
|
+
* - Photos are taken directly with the camera
|
|
8
|
+
* - Photos are saved to app's internal storage (documentDirectory)
|
|
9
|
+
* - File selection uses Android Photo Picker API (no permissions needed)
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Permissions to remove - these cause Play Store rejection for KYC apps
|
|
13
|
+
const PERMISSIONS_TO_REMOVE = [
|
|
14
|
+
// Media permissions - not needed, causes Play Store rejection
|
|
15
|
+
'android.permission.READ_MEDIA_IMAGES',
|
|
16
|
+
'android.permission.READ_MEDIA_VIDEO',
|
|
17
|
+
'android.permission.READ_MEDIA_AUDIO',
|
|
18
|
+
|
|
19
|
+
// Storage permissions - not needed for KYC
|
|
20
|
+
'android.permission.READ_EXTERNAL_STORAGE',
|
|
21
|
+
'android.permission.WRITE_EXTERNAL_STORAGE',
|
|
22
|
+
|
|
23
|
+
// Contacts - not needed for KYC
|
|
24
|
+
'android.permission.READ_CONTACTS',
|
|
25
|
+
'android.permission.WRITE_CONTACTS',
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const withRemovePermissions: ConfigPlugin = (config) => {
|
|
29
|
+
return withAndroidManifest(config, (config) => {
|
|
30
|
+
const androidManifest = config.modResults;
|
|
31
|
+
|
|
32
|
+
if (!androidManifest.manifest['uses-permission']) {
|
|
33
|
+
return config;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Filter out unwanted permissions
|
|
37
|
+
const originalCount = androidManifest.manifest['uses-permission'].length;
|
|
38
|
+
|
|
39
|
+
androidManifest.manifest['uses-permission'] = androidManifest.manifest['uses-permission'].filter(
|
|
40
|
+
(permission) => {
|
|
41
|
+
const permissionName = permission.$?.['android:name'];
|
|
42
|
+
const shouldRemove = PERMISSIONS_TO_REMOVE.includes(permissionName);
|
|
43
|
+
|
|
44
|
+
if (shouldRemove) {
|
|
45
|
+
console.log(`[withRemovePermissions] Removing: ${permissionName}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return !shouldRemove;
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const removedCount = originalCount - androidManifest.manifest['uses-permission'].length;
|
|
53
|
+
console.log(`[withRemovePermissions] Removed ${removedCount} permissions`);
|
|
54
|
+
|
|
55
|
+
// Also add tools:remove to explicitly block these permissions from being merged
|
|
56
|
+
// This prevents dependencies from re-adding them
|
|
57
|
+
// Ensure xmlns:tools is defined (xmlns:android always exists in valid manifests)
|
|
58
|
+
if (androidManifest.manifest.$) {
|
|
59
|
+
androidManifest.manifest.$['xmlns:tools'] = 'http://schemas.android.com/tools';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Add uses-permission with tools:node="remove" for each permission to block
|
|
63
|
+
for (const permissionName of PERMISSIONS_TO_REMOVE) {
|
|
64
|
+
// Check if a remove directive already exists
|
|
65
|
+
const existingRemove = androidManifest.manifest['uses-permission']?.find(
|
|
66
|
+
(p) => p.$?.['android:name'] === permissionName && p.$?.['tools:node'] === 'remove'
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
if (!existingRemove) {
|
|
70
|
+
androidManifest.manifest['uses-permission'].push({
|
|
71
|
+
$: {
|
|
72
|
+
'android:name': permissionName,
|
|
73
|
+
'tools:node': 'remove',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return config;
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export default withRemovePermissions;
|
|
@@ -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 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/withlocation.ts","./src/withvisioncamera.ts"],"version":"5.9.2"}
|
|
1
|
+
{"root":["./src/index.ts","./src/withlocation.ts","./src/withremovepermissions.ts","./src/withvisioncamera.ts"],"version":"5.9.2"}
|