@test-web/react-native-sdk 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/android/build/.transforms/246c075ea944392e66db7aa639265547/results.bin +1 -0
  2. package/android/build/.transforms/246c075ea944392e66db7aa639265547/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/yourcompany/sdk/BuildConfig.dex +0 -0
  3. package/android/build/.transforms/246c075ea944392e66db7aa639265547/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/yourcompany/sdk/YourSDKModule.dex +0 -0
  4. package/android/build/.transforms/246c075ea944392e66db7aa639265547/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/yourcompany/sdk/YourSDKPackage.dex +0 -0
  5. package/android/build/.transforms/246c075ea944392e66db7aa639265547/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  6. package/android/build/.transforms/952af5a0e7b5b2ac3d48ad66eccefd1f/results.bin +1 -0
  7. package/android/build/.transforms/952af5a0e7b5b2ac3d48ad66eccefd1f/transformed/classes/classes_dex/classes.dex +0 -0
  8. package/android/build/generated/source/buildConfig/debug/com/yourcompany/sdk/BuildConfig.java +10 -0
  9. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +34 -0
  10. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  11. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  12. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  13. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  14. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  15. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  16. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
  17. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  18. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
  19. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  20. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  21. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/yourcompany/sdk/BuildConfig.class +0 -0
  22. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/yourcompany/sdk/YourSDKModule.class +0 -0
  23. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/yourcompany/sdk/YourSDKPackage.class +0 -0
  24. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +2 -0
  25. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +56 -0
  26. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +34 -0
  27. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  28. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  29. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/yourcompany/sdk/BuildConfig.class +0 -0
  30. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/yourcompany/sdk/YourSDKModule.class +0 -0
  31. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/yourcompany/sdk/YourSDKPackage.class +0 -0
  32. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  33. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +1 -0
  34. package/android/build/outputs/logs/manifest-merger-debug-report.txt +61 -0
  35. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  36. package/package.json +1 -1
  37. package/src/apis/captureBarcode.ts +37 -0
  38. package/src/apis/captureMRZ.ts +39 -0
  39. package/src/apis/checkLiveness.ts +48 -0
  40. package/src/apis/index.ts +26 -75
  41. package/src/components/common/Footer.tsx +9 -12
  42. package/src/components/common/Header.tsx +8 -11
  43. package/src/context/FailedCountContext.tsx +35 -0
  44. package/src/context/IDMConfigurationContext.tsx +12 -2
  45. package/src/index.tsx +40 -28
  46. package/src/screens/BackDocumentAdvice.tsx +13 -18
  47. package/src/screens/BarcodeAdvice.tsx +39 -19
  48. package/src/screens/BarcodeCapture.tsx +127 -158
  49. package/src/screens/DocumentCaptureBack.tsx +145 -102
  50. package/src/screens/DocumentCaptureFront.tsx +146 -113
  51. package/src/screens/FrontDocumentAdvice.tsx +13 -18
  52. package/src/screens/LocationPermission.tsx +124 -17
  53. package/src/screens/MrzAdvice.tsx +27 -13
  54. package/src/screens/MrzCapture.tsx +233 -206
  55. package/src/screens/SelectDocuments.tsx +57 -66
  56. package/src/screens/SelfieCapture.tsx +135 -103
  57. package/src/screens/ThankYou.tsx +25 -31
  58. package/src/screens/VerifyIdentity.tsx +1 -0
  59. package/src/styles/BarcodeAdviceStyles.ts +6 -6
  60. package/src/styles/DocumentCaptureBackStyle.ts +70 -0
  61. package/src/styles/DocumentCaptureFrontStyle.ts +70 -0
  62. package/src/styles/FooterStyles.ts +10 -1
  63. package/src/styles/ScannerStyles.ts +46 -9
  64. package/src/styles/ThankYouStyles.ts +8 -11
  65. package/src/utils/MRZ_README.md +111 -0
  66. package/src/utils/imagesHelper.ts +264 -0
  67. package/src/utils/metadata_new.json +11373 -1
  68. package/src/utils/mrzExamples.ts +127 -0
  69. package/src/utils/mrzParser.ts +303 -0
  70. package/src/utils/mrzUtils.ts +70 -0
@@ -1,8 +1,7 @@
1
- import { Image, StyleProp, View, ViewStyle, ImageSourcePropType } from 'react-native';
1
+ import { Image, StyleProp, View, ViewStyle } from 'react-native';
2
2
  import { useTheme } from '../../context/ThemeContext';
3
3
  import { useOrientation } from '../../hooks/useOrientation';
4
4
  import { useIDM } from '../../context/IDMConfigurationContext';
5
- import { useEffect, useState } from 'react';
6
5
  import getStyles from '../../styles/HeaderStyles';
7
6
 
8
7
  interface HeaderProps {
@@ -15,19 +14,17 @@ export default function Header({ style }: HeaderProps) {
15
14
  const { idmConf } = useIDM();
16
15
  const styles = getStyles(theme, orientation);
17
16
 
18
- const defaultLogo = require('../../../assets/images/logo.png');
19
- const [logoSource, setLogoSource] = useState<ImageSourcePropType>(defaultLogo);
17
+ // Get logo from configuration - never show default logo
18
+ const logo = idmConf?.configuration?.logo;
20
19
 
21
- useEffect(() => {
22
- const logo = idmConf?.configuration?.logo;
23
- if (logo?.startsWith('data:image')) {
24
- setLogoSource({ uri: logo });
25
- }
26
- }, [idmConf]);
20
+ // Only render if logo is available from configuration
21
+ if (!logo || !logo.startsWith('data:image')) {
22
+ return null;
23
+ }
27
24
 
28
25
  return (
29
26
  <View style={[styles.container, style]}>
30
- <Image source={logoSource} style={styles.logo} resizeMode="contain" />
27
+ <Image source={{ uri: logo }} style={styles.logo} resizeMode="contain" />
31
28
  </View>
32
29
  );
33
30
  }
@@ -0,0 +1,35 @@
1
+ import React, { createContext, useContext, useState, ReactNode } from 'react';
2
+
3
+ // Define the context shape
4
+ interface FailedCountContextType {
5
+ failedCount: number;
6
+ setFailedCount: React.Dispatch<React.SetStateAction<number>>;
7
+ }
8
+
9
+ // Create the context
10
+ const FailedCountContext = createContext<FailedCountContextType | undefined>(undefined);
11
+
12
+ // Custom hook to consume the context
13
+ export const useFailedCount = () => {
14
+ const context = useContext(FailedCountContext);
15
+ if (!context) {
16
+ throw new Error('useFailedCount must be used within a FailedCountProvider');
17
+ }
18
+ return context;
19
+ };
20
+
21
+ // Provider props interface
22
+ interface FailedCountProviderProps {
23
+ children: ReactNode;
24
+ }
25
+
26
+ // Provider component
27
+ export const FailedCountProvider: React.FC<FailedCountProviderProps> = ({ children }) => {
28
+ const [failedCount, setFailedCount] = useState<number>(0);
29
+
30
+ return (
31
+ <FailedCountContext.Provider value={{ failedCount, setFailedCount }}>
32
+ {children}
33
+ </FailedCountContext.Provider>
34
+ );
35
+ };
@@ -17,9 +17,19 @@ interface IDMProviderProps {
17
17
  export function IDMProvider({ children, initialConf }: IDMProviderProps) {
18
18
  const [idmConf, setIDMConf] = useState<IDMConf>(initialConf);
19
19
 
20
- // Optimized partial update function
20
+ // Optimized partial update function that preserves configuration
21
21
  const updateIDMConf = useCallback((updates: Partial<IDMConf>) => {
22
- setIDMConf((prev) => ({ ...prev, ...updates }));
22
+ setIDMConf((prev) => {
23
+ // Ensure configuration is preserved during updates
24
+ const newConf = { ...prev, ...updates };
25
+
26
+ // If configuration exists in prev but not in updates, preserve it
27
+ if (prev.configuration && !updates.configuration) {
28
+ newConf.configuration = prev.configuration;
29
+ }
30
+
31
+ return newConf;
32
+ });
23
33
  }, []);
24
34
 
25
35
  // Memoize context value to prevent unnecessary re-renders
package/src/index.tsx CHANGED
@@ -23,6 +23,7 @@ import { themes } from './context/themes';
23
23
  import { IDMConf } from './types/IDMConf';
24
24
  import { IDMProvider, useIDM } from './context/IDMConfigurationContext';
25
25
  import { KeyboardProvider, useKeyboard } from './context/KeyboardContext';
26
+ import { FailedCountProvider } from './context/FailedCountContext';
26
27
  import Footer from './components/common/Footer';
27
28
  import Header from './components/common/Header';
28
29
  import Loader from './components/common/Loader';
@@ -31,7 +32,7 @@ import {
31
32
  generateAccessToken,
32
33
  generateRequest,
33
34
  getConfiguration,
34
- getCountries,
35
+ countryMetaData,
35
36
  } from './apis';
36
37
 
37
38
  const Stack = createNativeStackNavigator();
@@ -54,11 +55,13 @@ interface IDMScanProps {
54
55
 
55
56
  export default function IDMScan({ idmConf }: IDMScanProps) {
56
57
  return (
57
- <IDMProvider initialConf={idmConf}>
58
- <KeyboardProvider>
59
- <IDMScanContent />
60
- </KeyboardProvider>
61
- </IDMProvider>
58
+ <FailedCountProvider>
59
+ <IDMProvider initialConf={idmConf}>
60
+ <KeyboardProvider>
61
+ <IDMScanContent />
62
+ </KeyboardProvider>
63
+ </IDMProvider>
64
+ </FailedCountProvider>
62
65
  );
63
66
  }
64
67
 
@@ -69,6 +72,7 @@ function IDMScanContent() {
69
72
  const [currentRoute, setCurrentRoute] = useState<string | undefined>();
70
73
  const [loading, setLoading] = useState(true);
71
74
  const [error, setError] = useState<string | null>(null);
75
+ const [isActivityReady, setIsActivityReady] = useState(false);
72
76
 
73
77
  // Memoize theme calculation
74
78
  const theme = useMemo(
@@ -102,35 +106,40 @@ function IDMScanContent() {
102
106
  if (!idmConf.userDetails) {
103
107
  console.log('Fetching user data...');
104
108
  const userData = await getUserDataAPI();
105
- const updatedConf = { ...idmConf, userDetails: userData };
106
- setIDMConf(updatedConf);
107
-
109
+
108
110
  // Step 2: Generate access token if not provided
109
111
  if (!idmConf.accessToken) {
110
112
  console.log('Generating access token...');
111
- const token = await generateAccessToken(updatedConf);
112
- const confWithToken = { ...updatedConf, accessToken: token };
113
- setIDMConf(confWithToken);
113
+ const token = await generateAccessToken({ ...idmConf, userDetails: userData });
114
114
 
115
115
  // Step 3: Generate verification request
116
116
  console.log('Generating verification request...');
117
- const requestResult = await generateRequest(confWithToken, idmConf.requestData);
118
- const confWithVerifyCode = {
119
- ...confWithToken,
120
- verificationCode: requestResult.verificationCode,
121
- };
122
- setIDMConf(confWithVerifyCode);
117
+ const requestResult = await generateRequest(
118
+ { ...idmConf, userDetails: userData, accessToken: token },
119
+ idmConf.requestData
120
+ );
123
121
 
124
122
  // Step 4: Get configuration
125
123
  console.log('Fetching configuration...');
126
124
  const fetchedConfig = await getConfiguration(
127
- confWithVerifyCode,
125
+ { ...idmConf, userDetails: userData, accessToken: token, verificationCode: requestResult.verificationCode },
128
126
  requestResult.verificationCode
129
127
  );
128
+
129
+ // Update all at once to prevent state loss
130
130
  setIDMConf({
131
- ...confWithVerifyCode,
131
+ ...idmConf,
132
+ userDetails: userData,
133
+ accessToken: token,
134
+ verificationCode: requestResult.verificationCode,
132
135
  configuration: fetchedConfig,
133
136
  });
137
+ } else {
138
+ // Only update user data if token already exists
139
+ setIDMConf({
140
+ ...idmConf,
141
+ userDetails: userData,
142
+ });
134
143
  }
135
144
  }
136
145
  } catch (err: any) {
@@ -138,20 +147,23 @@ function IDMScanContent() {
138
147
  setError(err.message || 'Failed to initialize SDK');
139
148
  } finally {
140
149
  setLoading(false);
150
+ // Add delay to ensure Activity is fully ready before showing permission screen
151
+ setTimeout(() => {
152
+ setIsActivityReady(true);
153
+ }, 1000);
141
154
  }
142
155
  };
143
156
 
144
157
  initializeSDK();
145
158
  }, []); // Run once on mount
146
159
 
147
- // Fetch countries when access token and verification code are available
160
+ // Load static country metadata when access token and verification code are available
148
161
  useEffect(() => {
149
- const fetchCountriesData = async () => {
162
+ const loadCountriesData = () => {
150
163
  if (idmConf.accessToken && idmConf.verificationCode && !idmConf.countryDetails) {
151
164
  try {
152
- console.log('Fetching countries...');
153
- const response = await getCountries(idmConf);
154
- const countriesArray = Array.isArray(response) ? response : response?.data || [];
165
+ console.log('Loading countries from static metadata...');
166
+ const countriesArray = countryMetaData || [];
155
167
 
156
168
  const mapped = countriesArray.map((singleCountry: any) => ({
157
169
  label: singleCountry.country,
@@ -164,12 +176,12 @@ function IDMScanContent() {
164
176
  countryDetails: mapped,
165
177
  });
166
178
  } catch (err: any) {
167
- console.error('Error fetching countries:', err);
179
+ console.error('Error loading countries:', err);
168
180
  }
169
181
  }
170
182
  };
171
183
 
172
- fetchCountriesData();
184
+ loadCountriesData();
173
185
  }, [idmConf.accessToken, idmConf.verificationCode]);
174
186
 
175
187
  // Determine initial route based on permissions
@@ -180,7 +192,7 @@ function IDMScanContent() {
180
192
  return 'LocationPermission';
181
193
  }, [idmConf.userDetails?.permissionGranted]);
182
194
 
183
- if (loading) {
195
+ if (loading || !isActivityReady) {
184
196
  return (
185
197
  <ThemeProvider theme={theme}>
186
198
  <Loader />
@@ -1,21 +1,21 @@
1
1
  import { useNavigation } from '@react-navigation/native';
2
- import { Image, ScrollView, View } from 'react-native';
2
+ import { Image, ScrollView } from 'react-native';
3
3
  import Button from '../components/ui/Button';
4
4
  import ThemedText from '../components/ui/ThemedText';
5
5
  import getStyles from '../styles/DocumentAdviceStyles';
6
6
  import { useTheme } from '../context/ThemeContext';
7
7
  import { useOrientation } from '../hooks/useOrientation';
8
+ import { useIDM } from '../context/IDMConfigurationContext';
8
9
  import { useMemo } from 'react';
10
+ import { getCardScanImageBack } from '../utils/imagesHelper';
9
11
 
10
12
  export default function BackDocumentAdvice() {
11
13
  const { theme } = useTheme();
14
+ const { idmConf } = useIDM();
12
15
  const orientation = useOrientation();
13
16
  const navigation = useNavigation();
14
17
 
15
- const styles = useMemo(
16
- () => getStyles(theme, orientation),
17
- [theme, orientation]
18
- );
18
+ const styles = useMemo(() => getStyles(theme, orientation), [theme, orientation]);
19
19
 
20
20
  const handleRedirect = () => {
21
21
  navigation.navigate('DocumentCaptureBack' as never);
@@ -27,19 +27,14 @@ export default function BackDocumentAdvice() {
27
27
  Capture Your ID Back
28
28
  </ThemedText>
29
29
 
30
- {/* Placeholder for ID card back image */}
31
- <View
32
- style={[
33
- styles.idcard,
34
- {
35
- backgroundColor: '#f0f0f0',
36
- justifyContent: 'center',
37
- alignItems: 'center',
38
- },
39
- ]}
40
- >
41
- <ThemedText>ID Back Image</ThemedText>
42
- </View>
30
+ <Image
31
+ source={getCardScanImageBack(
32
+ idmConf?.selectedCountryDetails?.selectedMetaData?.type,
33
+ idmConf?.selectedCountryDetails?.selectedMetaData?.countryCode
34
+ )}
35
+ style={styles.idcard}
36
+ resizeMode="contain"
37
+ />
43
38
 
44
39
  <Button
45
40
  title="Take a photo"
@@ -1,17 +1,22 @@
1
1
  import { useNavigation } from '@react-navigation/native';
2
- import { ScrollView, View } from 'react-native';
2
+ import { Image, ScrollView } from 'react-native';
3
3
  import Button from '../components/ui/Button';
4
4
  import ThemedText from '../components/ui/ThemedText';
5
5
  import getStyles from '../styles/BarcodeAdviceStyles';
6
6
  import { useTheme } from '../context/ThemeContext';
7
7
  import { useOrientation } from '../hooks/useOrientation';
8
- import { useMemo } from 'react';
8
+ import { useIDM } from '../context/IDMConfigurationContext';
9
+ import { useEffect, useState, useMemo } from 'react';
9
10
 
10
11
  export default function BarcodeAdvice() {
11
12
  const { theme } = useTheme();
13
+ const { idmConf } = useIDM();
12
14
  const orientation = useOrientation();
13
15
  const navigation = useNavigation();
14
16
 
17
+ const [barcodeType, setBarcodeType] = useState<string | null>('PDF417 B');
18
+
19
+ // Memoize styles to avoid recalculation on every render
15
20
  const styles = useMemo(
16
21
  () => getStyles(theme, orientation),
17
22
  [theme, orientation]
@@ -21,25 +26,40 @@ export default function BarcodeAdvice() {
21
26
  navigation.navigate('BarcodeCapture' as never);
22
27
  };
23
28
 
29
+ useEffect(() => {
30
+ const metadata = idmConf?.selectedCountryDetails?.selectedMetaData;
31
+ if (metadata?.barcode === 'PDF417F') {
32
+ setBarcodeType('PDF417F');
33
+ } else {
34
+ setBarcodeType('PDF417 B');
35
+ }
36
+ }, [idmConf]);
37
+
24
38
  return (
25
39
  <ScrollView contentContainerStyle={styles.container}>
26
- <ThemedText style={styles.maintitle} type="title">
27
- Scan the barcode on the back of your ID
28
- </ThemedText>
29
-
30
- {/* Placeholder for barcode image */}
31
- <View
32
- style={[
33
- styles.idcard,
34
- {
35
- backgroundColor: '#f0f0f0',
36
- justifyContent: 'center',
37
- alignItems: 'center',
38
- },
39
- ]}
40
- >
41
- <ThemedText>Barcode Image</ThemedText>
42
- </View>
40
+ {barcodeType === 'PDF417 B' ? (
41
+ <ThemedText style={styles.maintitle} type="title">
42
+ Scan the barcode on the back of your ID
43
+ </ThemedText>
44
+ ) : (
45
+ <ThemedText style={styles.maintitle} type="title">
46
+ Scan the barcode on the front of your ID
47
+ </ThemedText>
48
+ )}
49
+
50
+ {barcodeType === 'PDF417 B' ? (
51
+ <Image
52
+ source={require('../../assets/images/card-scan-back-icon.jpg')}
53
+ style={styles.idcard}
54
+ resizeMode="contain"
55
+ />
56
+ ) : (
57
+ <Image
58
+ source={require('../../assets/images/card-scan-front-icon.png')}
59
+ style={styles.idcard}
60
+ resizeMode="contain"
61
+ />
62
+ )}
43
63
 
44
64
  <Button
45
65
  title="Scan"