@transfergratis/react-native-sdk 0.1.23 → 0.1.24

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.
Files changed (137) hide show
  1. package/android/src/main/AndroidManifest.xml +9 -4
  2. package/build/components/EnhancedCameraView.d.ts.map +1 -1
  3. package/build/components/EnhancedCameraView.js +26 -3
  4. package/build/components/EnhancedCameraView.js.map +1 -1
  5. package/build/components/EnhancedCameraView.web.d.ts.map +1 -1
  6. package/build/components/EnhancedCameraView.web.js +21 -0
  7. package/build/components/EnhancedCameraView.web.js.map +1 -1
  8. package/build/components/KYCElements/CameraCapture.d.ts.map +1 -1
  9. package/build/components/KYCElements/CameraCapture.js +4 -3
  10. package/build/components/KYCElements/CameraCapture.js.map +1 -1
  11. package/build/components/KYCElements/CountrySelectionTemplate.d.ts +5 -2
  12. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  13. package/build/components/KYCElements/CountrySelectionTemplate.js +360 -101
  14. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  15. package/build/components/KYCElements/FileUpload.d.ts.map +1 -1
  16. package/build/components/KYCElements/FileUpload.js +5 -4
  17. package/build/components/KYCElements/FileUpload.js.map +1 -1
  18. package/build/components/KYCElements/FileUploadTemplate.d.ts.map +1 -1
  19. package/build/components/KYCElements/FileUploadTemplate.js +5 -4
  20. package/build/components/KYCElements/FileUploadTemplate.js.map +1 -1
  21. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  22. package/build/components/KYCElements/IDCardCapture.js +193 -237
  23. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  24. package/build/components/KYCElements/LocationCaptureTemplate.d.ts.map +1 -1
  25. package/build/components/KYCElements/LocationCaptureTemplate.js +78 -37
  26. package/build/components/KYCElements/LocationCaptureTemplate.js.map +1 -1
  27. package/build/components/KYCElements/OrientationVideoCapture.js +3 -2
  28. package/build/components/KYCElements/OrientationVideoCapture.js.map +1 -1
  29. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js +3 -2
  30. package/build/components/KYCElements/OrientationVideoCaptureEnhanced.js.map +1 -1
  31. package/build/components/KYCElements/OrientationVideoCaptureFinal.js +3 -2
  32. package/build/components/KYCElements/OrientationVideoCaptureFinal.js.map +1 -1
  33. package/build/components/KYCElements/SelfieCapture.d.ts.map +1 -1
  34. package/build/components/KYCElements/SelfieCapture.js +4 -3
  35. package/build/components/KYCElements/SelfieCapture.js.map +1 -1
  36. package/build/components/KYCElements/SelfieCaptureTemplate.d.ts.map +1 -1
  37. package/build/components/KYCElements/SelfieCaptureTemplate.js +182 -39
  38. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  39. package/build/components/KYCElements/WelcomeTemplate.d.ts +12 -0
  40. package/build/components/KYCElements/WelcomeTemplate.d.ts.map +1 -0
  41. package/build/components/KYCElements/WelcomeTemplate.js +243 -0
  42. package/build/components/KYCElements/WelcomeTemplate.js.map +1 -0
  43. package/build/components/TemplateKYCExample.d.ts +4 -2
  44. package/build/components/TemplateKYCExample.d.ts.map +1 -1
  45. package/build/components/TemplateKYCExample.js +5 -69
  46. package/build/components/TemplateKYCExample.js.map +1 -1
  47. package/build/components/TemplateKYCFlowRefactored.d.ts +2 -1
  48. package/build/components/TemplateKYCFlowRefactored.d.ts.map +1 -1
  49. package/build/components/TemplateKYCFlowRefactored.js +95 -10
  50. package/build/components/TemplateKYCFlowRefactored.js.map +1 -1
  51. package/build/components/example/DynamicTemplateExample.d.ts +10 -0
  52. package/build/components/example/DynamicTemplateExample.d.ts.map +1 -0
  53. package/build/components/example/DynamicTemplateExample.js +241 -0
  54. package/build/components/example/DynamicTemplateExample.js.map +1 -0
  55. package/build/config/allowedDomains.d.ts +30 -0
  56. package/build/config/allowedDomains.d.ts.map +1 -0
  57. package/build/config/allowedDomains.js +127 -0
  58. package/build/config/allowedDomains.js.map +1 -0
  59. package/build/hooks/useTemplateKYCFlow.d.ts.map +1 -1
  60. package/build/hooks/useTemplateKYCFlow.js +31 -11
  61. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  62. package/build/hooks/useTemplateLoader.d.ts +14 -0
  63. package/build/hooks/useTemplateLoader.d.ts.map +1 -0
  64. package/build/hooks/useTemplateLoader.js +85 -0
  65. package/build/hooks/useTemplateLoader.js.map +1 -0
  66. package/build/i18n/en/index.d.ts +9 -0
  67. package/build/i18n/en/index.d.ts.map +1 -1
  68. package/build/i18n/en/index.js +9 -0
  69. package/build/i18n/en/index.js.map +1 -1
  70. package/build/i18n/fr/index.d.ts +9 -0
  71. package/build/i18n/fr/index.d.ts.map +1 -1
  72. package/build/i18n/fr/index.js +9 -0
  73. package/build/i18n/fr/index.js.map +1 -1
  74. package/build/index.d.ts +5 -0
  75. package/build/index.d.ts.map +1 -1
  76. package/build/index.js +8 -0
  77. package/build/index.js.map +1 -1
  78. package/build/modules/api/CardAuthentification.js +1 -0
  79. package/build/modules/api/CardAuthentification.js.map +1 -1
  80. package/build/modules/api/KYCService.d.ts.map +1 -1
  81. package/build/modules/api/KYCService.js +7 -2
  82. package/build/modules/api/KYCService.js.map +1 -1
  83. package/build/modules/api/TemplateService.d.ts +45 -0
  84. package/build/modules/api/TemplateService.d.ts.map +1 -0
  85. package/build/modules/api/TemplateService.js +145 -0
  86. package/build/modules/api/TemplateService.js.map +1 -0
  87. package/build/types/KYC.types.d.ts +144 -4
  88. package/build/types/KYC.types.d.ts.map +1 -1
  89. package/build/types/KYC.types.js +15 -0
  90. package/build/types/KYC.types.js.map +1 -1
  91. package/build/utils/cropByObb.d.ts +1 -0
  92. package/build/utils/cropByObb.d.ts.map +1 -1
  93. package/build/utils/cropByObb.js +70 -0
  94. package/build/utils/cropByObb.js.map +1 -1
  95. package/build/utils/platformAlert.d.ts +20 -0
  96. package/build/utils/platformAlert.d.ts.map +1 -0
  97. package/build/utils/platformAlert.js +67 -0
  98. package/build/utils/platformAlert.js.map +1 -0
  99. package/build/utils/template-transformer.d.ts +10 -0
  100. package/build/utils/template-transformer.d.ts.map +1 -0
  101. package/build/utils/template-transformer.js +353 -0
  102. package/build/utils/template-transformer.js.map +1 -0
  103. package/build/web/WebKYCEntry.d.ts.map +1 -1
  104. package/build/web/WebKYCEntry.js +102 -20
  105. package/build/web/WebKYCEntry.js.map +1 -1
  106. package/package.json +1 -1
  107. package/src/components/EnhancedCameraView.tsx +31 -2
  108. package/src/components/EnhancedCameraView.web.tsx +24 -0
  109. package/src/components/KYCElements/CameraCapture.tsx +4 -3
  110. package/src/components/KYCElements/CountrySelectionTemplate.tsx +410 -113
  111. package/src/components/KYCElements/FileUpload.tsx +5 -4
  112. package/src/components/KYCElements/FileUploadTemplate.tsx +5 -4
  113. package/src/components/KYCElements/IDCardCapture.tsx +196 -254
  114. package/src/components/KYCElements/LocationCaptureTemplate.tsx +95 -44
  115. package/src/components/KYCElements/OrientationVideoCapture.tsx +2 -2
  116. package/src/components/KYCElements/OrientationVideoCaptureEnhanced.tsx +2 -2
  117. package/src/components/KYCElements/OrientationVideoCaptureFinal.tsx +2 -2
  118. package/src/components/KYCElements/SelfieCapture.tsx +4 -3
  119. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +195 -41
  120. package/src/components/KYCElements/WelcomeTemplate.tsx +289 -0
  121. package/src/components/TemplateKYCExample.tsx +16 -72
  122. package/src/components/TemplateKYCFlowRefactored.tsx +122 -12
  123. package/src/components/example/DynamicTemplateExample.tsx +289 -0
  124. package/src/config/allowedDomains.ts +152 -0
  125. package/src/hooks/useTemplateKYCFlow.tsx +33 -11
  126. package/src/hooks/useTemplateLoader.ts +102 -0
  127. package/src/i18n/en/index.ts +10 -0
  128. package/src/i18n/fr/index.ts +9 -0
  129. package/src/index.ts +11 -0
  130. package/src/modules/api/CardAuthentification.ts +1 -1
  131. package/src/modules/api/KYCService.ts +12 -8
  132. package/src/modules/api/TemplateService.ts +167 -0
  133. package/src/types/KYC.types.ts +188 -3
  134. package/src/utils/cropByObb.ts +83 -3
  135. package/src/utils/platformAlert.ts +85 -0
  136. package/src/utils/template-transformer.ts +433 -0
  137. package/src/web/WebKYCEntry.tsx +122 -24
@@ -1,14 +1,16 @@
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, generateCallbackSignature } from '../config/allowedDomains';
7
8
  const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
8
9
  const { setLocale } = useI18n();
9
10
  const [urlParams, setUrlParams] = useState({});
10
11
  const [isLoading, setIsLoading] = useState(true);
11
12
  const [error, setError] = useState(null);
13
+ const [isAnalyzing, setIsAnalyzing] = useState(false);
12
14
  // Parse URL parameters
13
15
  const parseUrlParams = useCallback(() => {
14
16
  if (typeof window === 'undefined')
@@ -20,80 +22,117 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
20
22
  lang: urlParams.get('lang') || 'en',
21
23
  theme: urlParams.get('theme') || 'light',
22
24
  kyc_id: urlParams.get('kyc_id') || undefined,
25
+ secret: urlParams.get('secret') || undefined,
23
26
  };
24
27
  }, []);
25
- // Safe redirect function with validation
26
- const redirectToReturnUrl = useCallback((params) => {
27
- const { return_url } = urlParams;
28
+ // Safe redirect function with enhanced validation
29
+ const redirectToReturnUrl = useCallback(async (params) => {
30
+ const { return_url, secret } = urlParams;
28
31
  if (!return_url) {
29
32
  console.warn('No return_url provided');
30
33
  return;
31
34
  }
32
- // Basic URL validation - ensure it's a valid URL
33
35
  try {
36
+ // Enhanced URL validation with domain whitelist
37
+ const validation = isCallbackUrlAllowed(return_url);
38
+ if (!validation.allowed) {
39
+ console.error('Callback URL validation failed:', validation.reason);
40
+ setError(`Security Error: ${validation.reason}`);
41
+ // Log suspicious redirect attempt
42
+ console.warn('Suspicious redirect attempt blocked:', {
43
+ url: return_url,
44
+ reason: validation.reason,
45
+ timestamp: new Date().toISOString(),
46
+ });
47
+ return;
48
+ }
34
49
  const returnUrl = new URL(return_url);
35
- // Optional: Add domain allowlist validation here
36
- // const allowedDomains = ['example.com', 'trusted-site.com'];
37
- // if (!allowedDomains.some(domain => returnUrl.hostname.endsWith(domain))) {
38
- // console.error('Return URL not in allowlist');
39
- // return;
40
- // }
41
50
  // Build redirect URL with parameters
42
51
  const redirectUrl = new URL(returnUrl);
43
- redirectUrl.searchParams.set('status', params.status);
52
+ const redirectParams = {
53
+ status: params.status,
54
+ };
44
55
  if (params.kyc_id) {
45
- redirectUrl.searchParams.set('kyc_id', params.kyc_id);
56
+ redirectParams.kyc_id = params.kyc_id;
46
57
  }
47
58
  if (params.message) {
48
- redirectUrl.searchParams.set('message', 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);
49
66
  }
50
- if (params.sig) {
51
- redirectUrl.searchParams.set('sig', params.sig);
67
+ // Generate signature for integrity verification
68
+ if (secret) {
69
+ const signature = await generateCallbackSignature(redirectParams, secret);
70
+ if (signature) {
71
+ redirectParams.sig = signature;
72
+ }
52
73
  }
53
- // Optional: Send postMessage to parent if in iframe
74
+ // Add all params to URL
75
+ Object.entries(redirectParams).forEach(([key, value]) => {
76
+ redirectUrl.searchParams.set(key, value);
77
+ });
78
+ // Send postMessage to parent if in iframe
54
79
  if (window.parent !== window) {
55
80
  window.parent.postMessage({
56
81
  type: 'kyc_result',
57
82
  status: params.status,
58
83
  kyc_id: params.kyc_id,
59
84
  message: params.message,
60
- }, '*');
85
+ processing_state: params.processing_state,
86
+ verification_steps: params.verification_steps,
87
+ }, returnUrl.origin); // Use specific origin instead of '*'
61
88
  }
62
89
  // Redirect to return URL
63
90
  window.location.href = redirectUrl.toString();
64
91
  }
65
92
  catch (error) {
66
- console.error('Invalid return URL:', error);
67
- setError('Invalid return URL provided');
93
+ console.error('Error during redirect:', error);
94
+ setError('Failed to redirect to callback URL');
68
95
  }
69
96
  }, [urlParams]);
70
97
  // Handle KYC completion
71
98
  const handleComplete = useCallback((data) => {
72
99
  console.log('KYC completed:', data);
100
+ // Check if still processing/analyzing
101
+ const isStillProcessing = data.isProcessing || data.session?.isProcessing;
73
102
  redirectToReturnUrl({
74
103
  status: 'completed',
75
104
  kyc_id: data.session_id || urlParams.kyc_id,
76
105
  message: 'KYC process completed successfully',
106
+ processing_state: isStillProcessing ? 'analyzing' : 'completed',
107
+ verification_steps: {
108
+ document_analyzed: data.documentAnalysisComplete || false,
109
+ selfie_analyzed: data.selfieAnalysisComplete || false,
110
+ liveness_checked: data.livenessCheckComplete || false,
111
+ },
77
112
  });
78
113
  onComplete?.(data);
79
114
  }, [redirectToReturnUrl, urlParams.kyc_id, onComplete]);
80
115
  // Handle KYC error
81
116
  const handleError = useCallback((error) => {
82
117
  console.error('KYC error:', error);
118
+ setIsAnalyzing(false);
83
119
  redirectToReturnUrl({
84
120
  status: 'error',
85
121
  kyc_id: urlParams.kyc_id,
86
122
  message: error,
123
+ processing_state: 'pending',
87
124
  });
88
125
  onError?.(error);
89
126
  }, [redirectToReturnUrl, urlParams.kyc_id, onError]);
90
127
  // Handle KYC cancellation
91
128
  const handleCancel = useCallback(() => {
92
129
  console.log('KYC cancelled');
130
+ setIsAnalyzing(false);
93
131
  redirectToReturnUrl({
94
132
  status: 'cancelled',
95
133
  kyc_id: urlParams.kyc_id,
96
134
  message: 'KYC process was cancelled',
135
+ processing_state: 'pending',
97
136
  });
98
137
  onCancel?.();
99
138
  }, [redirectToReturnUrl, urlParams.kyc_id, onCancel]);
@@ -130,6 +169,13 @@ const WebKYCEntry = ({ onComplete, onError, onCancel, }) => {
130
169
  </View>);
131
170
  }
132
171
  return (<SafeAreaView style={styles.container}>
172
+ {isAnalyzing && (<View style={styles.analyzingOverlay}>
173
+ <View style={styles.analyzingContainer}>
174
+ <ActivityIndicator size="large" color="#2DBD60"/>
175
+ <Text style={styles.analyzingText}>Analyzing verification data...</Text>
176
+ <Text style={styles.analyzingSubtext}>This may take a few moments</Text>
177
+ </View>
178
+ </View>)}
133
179
  <TemplateKYCExample onComplete={handleComplete} onCancel={handleCancel} onError={handleError} language={urlParams.lang || 'en'} API_KEY={urlParams.token}/>
134
180
  </SafeAreaView>);
135
181
  };
@@ -137,6 +183,7 @@ const styles = StyleSheet.create({
137
183
  container: {
138
184
  flex: 1,
139
185
  backgroundColor: '#f5f5f5',
186
+ overflow: 'visible', // Allow scrolling on web
140
187
  },
141
188
  loadingText: {
142
189
  fontSize: 18,
@@ -151,6 +198,41 @@ const styles = StyleSheet.create({
151
198
  color: '#dc2626',
152
199
  paddingHorizontal: 20,
153
200
  },
201
+ analyzingOverlay: {
202
+ position: 'absolute',
203
+ top: 0,
204
+ left: 0,
205
+ right: 0,
206
+ bottom: 0,
207
+ backgroundColor: 'rgba(0, 0, 0, 0.7)',
208
+ justifyContent: 'center',
209
+ alignItems: 'center',
210
+ zIndex: 9999,
211
+ },
212
+ analyzingContainer: {
213
+ backgroundColor: 'white',
214
+ borderRadius: 12,
215
+ padding: 32,
216
+ alignItems: 'center',
217
+ shadowColor: '#000',
218
+ shadowOffset: { width: 0, height: 4 },
219
+ shadowOpacity: 0.3,
220
+ shadowRadius: 8,
221
+ elevation: 8,
222
+ },
223
+ analyzingText: {
224
+ fontSize: 18,
225
+ fontWeight: '600',
226
+ color: '#333',
227
+ marginTop: 16,
228
+ textAlign: 'center',
229
+ },
230
+ analyzingSubtext: {
231
+ fontSize: 14,
232
+ color: '#666',
233
+ marginTop: 8,
234
+ textAlign: 'center',
235
+ },
154
236
  });
155
237
  export default WebKYCEntry;
156
238
  //# 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, 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transfergratis/react-native-sdk",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "transfergratis react native sdk",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -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
  });
@@ -1,5 +1,6 @@
1
1
  import React, { useState } from 'react';
2
- import { View, Text, TouchableOpacity, StyleSheet, Image, Alert } from 'react-native';
2
+ import { View, Text, TouchableOpacity, StyleSheet, Image } from 'react-native';
3
+ import { showAlert } from '../../utils/platformAlert';
3
4
  import { EnhancedCameraView } from '../EnhancedCameraView';
4
5
 
5
6
  import { KYCElement } from '../../types/KYC.types';
@@ -39,12 +40,12 @@ export const CameraCapture: React.FC<CameraCaptureProps> = ({
39
40
  onValueChange(result.path);
40
41
  setShowCamera(false);
41
42
  } else {
42
- Alert.alert('Erreur', result.error || 'Impossible de prendre la photo');
43
+ showAlert('Erreur', result.error || 'Impossible de prendre la photo');
43
44
  }
44
45
  };
45
46
 
46
47
  const handleError = (event: { message: string }) => {
47
- Alert.alert('Erreur', event.message);
48
+ showAlert('Erreur', event.message);
48
49
  setShowCamera(false);
49
50
  };
50
51