@qore-id/react-native-qoreid-sdk 0.1.0-snapshot

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 (56) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +127 -0
  3. package/android/Untitled +0 -0
  4. package/android/build.gradle +109 -0
  5. package/android/gradle.properties +9 -0
  6. package/android/src/main/AndroidManifest.xml +4 -0
  7. package/android/src/main/java/com/qoreidsdk/QoreIdJSData.kt +49 -0
  8. package/android/src/main/java/com/qoreidsdk/QoreIdReactButtonFragment.kt +116 -0
  9. package/android/src/main/java/com/qoreidsdk/QoreIdReactButtonManager.kt +168 -0
  10. package/android/src/main/java/com/qoreidsdk/QoreidSdkModule.kt +88 -0
  11. package/android/src/main/java/com/qoreidsdk/QoreidSdkPackage.kt +20 -0
  12. package/android/src/main/java/com/qoreidsdk/StyleOption.kt +7 -0
  13. package/ios/QoreidSdk.h +12 -0
  14. package/ios/QoreidSdk.mm +27 -0
  15. package/ios/QoreidSdk.xcodeproj/project.pbxproj +274 -0
  16. package/ios/QoreidSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  17. package/lib/commonjs/index.js +25 -0
  18. package/lib/commonjs/index.js.map +1 -0
  19. package/lib/commonjs/qoreIdButton.android.js +97 -0
  20. package/lib/commonjs/qoreIdButton.android.js.map +1 -0
  21. package/lib/commonjs/qoreIdButton.ios.js +129 -0
  22. package/lib/commonjs/qoreIdButton.ios.js.map +1 -0
  23. package/lib/commonjs/react-native-qoreid-sdk.d.js +6 -0
  24. package/lib/commonjs/react-native-qoreid-sdk.d.js.map +1 -0
  25. package/lib/commonjs/types.d.js +6 -0
  26. package/lib/commonjs/types.d.js.map +1 -0
  27. package/lib/commonjs/utils.js +20 -0
  28. package/lib/commonjs/utils.js.map +1 -0
  29. package/lib/module/index.js +4 -0
  30. package/lib/module/index.js.map +1 -0
  31. package/lib/module/qoreIdButton.android.js +88 -0
  32. package/lib/module/qoreIdButton.android.js.map +1 -0
  33. package/lib/module/qoreIdButton.ios.js +121 -0
  34. package/lib/module/qoreIdButton.ios.js.map +1 -0
  35. package/lib/module/react-native-qoreid-sdk.d.js +2 -0
  36. package/lib/module/react-native-qoreid-sdk.d.js.map +1 -0
  37. package/lib/module/types.d.js +2 -0
  38. package/lib/module/types.d.js.map +1 -0
  39. package/lib/module/utils.js +13 -0
  40. package/lib/module/utils.js.map +1 -0
  41. package/lib/typescript/index.d.ts +5 -0
  42. package/lib/typescript/index.d.ts.map +1 -0
  43. package/lib/typescript/qoreIdButton.android.d.ts +4 -0
  44. package/lib/typescript/qoreIdButton.android.d.ts.map +1 -0
  45. package/lib/typescript/qoreIdButton.ios.d.ts +4 -0
  46. package/lib/typescript/qoreIdButton.ios.d.ts.map +1 -0
  47. package/lib/typescript/utils.d.ts +9 -0
  48. package/lib/typescript/utils.d.ts.map +1 -0
  49. package/package.json +165 -0
  50. package/react-native-qoreid-sdk.podspec +35 -0
  51. package/src/index.tsx +10 -0
  52. package/src/qoreIdButton.android.tsx +136 -0
  53. package/src/qoreIdButton.ios.tsx +150 -0
  54. package/src/react-native-qoreid-sdk.d.ts +3 -0
  55. package/src/types.d.ts +99 -0
  56. package/src/utils.ts +73 -0
@@ -0,0 +1,136 @@
1
+ import React, {
2
+ RefObject,
3
+ forwardRef,
4
+ useCallback,
5
+ useEffect,
6
+ useRef,
7
+ } from 'react';
8
+ import {
9
+ UIManager,
10
+ findNodeHandle,
11
+ requireNativeComponent,
12
+ View,
13
+ NativeEventEmitter,
14
+ NativeModules,
15
+ } from 'react-native';
16
+ import type { DataType, OnResultType, Options, IQoreIdButton } from './types';
17
+
18
+
19
+ const QoreIdReactButtonManager = requireNativeComponent<{
20
+ style?: { width?: number; height?: number };
21
+ }>('QoreIdReactButtonManager');
22
+
23
+ const Button = forwardRef<
24
+ {
25
+ style?: { width?: number; height?: number };
26
+ },
27
+ any
28
+ >((_props, ref) => {
29
+ return (
30
+ <>
31
+ <View
32
+ style={{
33
+ position: 'relative',
34
+ margin: 'auto',
35
+ height: 55,
36
+ borderWidth: 1,
37
+ }}
38
+ >
39
+ <QoreIdReactButtonManager
40
+ //@ts-ignore
41
+ ref={ref}
42
+ />
43
+ </View>
44
+ </>
45
+ );
46
+ });
47
+
48
+ function useQoreId(ref: RefObject<any>, options: Options) {
49
+ const onSubmitted = useCallback(
50
+ (data) => options.onSubmitted && options.onSubmitted(data),
51
+ [options]
52
+ );
53
+ const onError = useCallback(
54
+ (data) => options.onError && options.onError(data),
55
+ [options]
56
+ );
57
+
58
+ useEffect(() => {
59
+ const buttonStyles = JSON.stringify(options.buttonProps);
60
+ UIManager.dispatchViewManagerCommand(
61
+ findNodeHandle(ref.current),
62
+ // we are calling the 'create' command
63
+ //@ts-ignore
64
+ UIManager?.QoreIdReactButtonManager?.Commands?.create.toString(),
65
+ [findNodeHandle(ref.current), options.clientId, buttonStyles]
66
+ );
67
+ }, []);
68
+
69
+ useEffect(() => {
70
+ const eventEmitter = new NativeEventEmitter(NativeModules.QoreidSdk);
71
+ let eventListener = eventEmitter.addListener(
72
+ 'onResult',
73
+ (event: OnResultType) => {
74
+ if (event?.code) {
75
+ onError && onError(event);
76
+ return;
77
+ }
78
+ onSubmitted && onSubmitted(event);
79
+ }
80
+ );
81
+
82
+ return () => {
83
+ eventListener.remove();
84
+ };
85
+ }, []);
86
+ }
87
+
88
+ const onChangeData = (ref: any, data: DataType) => {
89
+ const stringified = JSON.stringify(data);
90
+
91
+ return useEffect(() => {
92
+ UIManager.dispatchViewManagerCommand(
93
+ findNodeHandle(ref.current),
94
+ // we are calling the 'create' command
95
+ //@ts-ignore
96
+ UIManager?.QoreIdReactButtonManager?.Commands?.update.toString(),
97
+ [stringified]
98
+ );
99
+ }, [stringified]);
100
+ };
101
+
102
+ export const QoreIdButton: React.FC<IQoreIdButton> = (initialData) => {
103
+ const ref = useRef(null);
104
+
105
+ useQoreId(ref, {
106
+ clientId: initialData.clientId,
107
+ onError(data) {
108
+ initialData.onQoreIDSdkError && initialData.onQoreIDSdkError(data);
109
+ },
110
+ onSubmitted(data) {
111
+ initialData.onQoreIDSdkSubmitted &&
112
+ initialData.onQoreIDSdkSubmitted(data);
113
+ },
114
+ buttonProps: {
115
+ title: initialData.title,
116
+ },
117
+ });
118
+
119
+ onChangeData(ref, {
120
+ config: {
121
+ flowId: initialData.flowId || 0,
122
+ customerRef: initialData.customerReference,
123
+ productCode: initialData.productCode!,
124
+ clientId: initialData.clientId,
125
+ },
126
+ applicantData: {
127
+ ...initialData.applicantData,
128
+ },
129
+ addressData: {
130
+ ...initialData.addressData,
131
+ },
132
+ acceptedDocuments: initialData.ocrAcceptedDocuments?.split(','),
133
+ identityData: { ...initialData.identityData },
134
+ });
135
+ return <Button ref={ref} />;
136
+ };
@@ -0,0 +1,150 @@
1
+ import React, { useState } from 'react';
2
+ import { Text, Platform, Alert, SafeAreaView } from 'react-native';
3
+ import WebView, { WebViewMessageEvent } from 'react-native-webview';
4
+ import type { IQoreIdButton } from './types';
5
+ import { Dimensions } from 'react-native';
6
+ import { TouchableOpacity } from 'react-native';
7
+
8
+ export const QoreIdButton: React.FC<IQoreIdButton> = (initialData) => {
9
+ const [canShowWebView, setCanShowWebView] = useState(false);
10
+
11
+ const toggleWebView = () => setCanShowWebView((prev) => !prev);
12
+
13
+ const onMessage = ({ nativeEvent }: WebViewMessageEvent) => {
14
+ let browserEventData = null as any;
15
+
16
+ try {
17
+ browserEventData = JSON.parse(nativeEvent?.data || '');
18
+ } catch (error: any) {
19
+ console.error(error.message);
20
+ }
21
+
22
+ switch (browserEventData?.type) {
23
+ case 'qoreid:verificationSubmitted':
24
+ if (initialData.onQoreIDSdkSubmitted)
25
+ initialData.onQoreIDSdkSubmitted(browserEventData);
26
+ break;
27
+ case 'qoreid:verificationError':
28
+ if (initialData.onQoreIDSdkError)
29
+ initialData.onQoreIDSdkError(browserEventData);
30
+ break;
31
+ case 'qoreid:verificationClosed':
32
+ setCanShowWebView(false);
33
+ if (initialData.onQoreIDSdkClosed)
34
+ initialData.onQoreIDSdkClosed(browserEventData);
35
+ break;
36
+ }
37
+ };
38
+
39
+ const html = `
40
+ <!DOCTYPE html>
41
+ <html>
42
+ <head>
43
+ <meta charset="UTF-8" />
44
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
45
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
46
+ <meta name="description" content="QoreID Web SDK" />
47
+ <title>QoreID | Web SDK</title>
48
+ </head>
49
+ <body>
50
+ <qoreid-button
51
+ id="QoreIDButton"
52
+ title="Verify"
53
+ sdkSource="${Platform.OS === 'ios' ? 'ios_sdk' : 'android_sdk'}"
54
+ flowId="${initialData.flowId || 0}"
55
+ clientId="${initialData.clientId}"
56
+ productCode="${initialData.productCode}"
57
+ customerReference="${initialData.customerReference}"
58
+ applicantData='{"firstname": "${
59
+ initialData?.applicantData?.firstName
60
+ }", "middlename": "${
61
+ initialData?.applicantData?.middleName
62
+ }", "lastname": "${initialData?.applicantData?.lastName}", "gender": "${
63
+ initialData?.applicantData?.gender
64
+ }", "phone": "${initialData?.applicantData?.phoneNumber}", "email": "${
65
+ initialData?.applicantData?.email
66
+ }"}'
67
+ identityData='{"idType": "${
68
+ initialData?.identityData?.idType
69
+ }", "idNumber": "${initialData?.identityData?.idNumber}"}'
70
+ addressData='{"address": "${
71
+ initialData?.addressData?.address
72
+ }", "city": "${initialData?.addressData?.city}", "lgaName": "${
73
+ initialData?.addressData?.lga
74
+ }"}'
75
+ ocrAcceptedDocuments="${initialData?.ocrAcceptedDocuments}"
76
+ onQoreIDSdkSubmitted="({type, detail})=>window.ReactNativeWebView.postMessage(JSON.stringify({ type, ...detail }))"
77
+ onQoreIDSdkError="({type, detail})=>window.ReactNativeWebView.postMessage(JSON.stringify({ type, ...detail }))"
78
+ onQoreIDSdkClosed="({type, detail})=>window.ReactNativeWebView.postMessage(JSON.stringify({ type, ...detail }))"
79
+ />
80
+ <script
81
+ type="text/javascript"
82
+ src="https://dev-qoreid.verifynow.ng/qoreid-sdk/qoreid.js"
83
+ ></script>
84
+ </body>
85
+ </html>
86
+ `;
87
+
88
+
89
+ if (!(initialData.productCode && initialData.clientId) && canShowWebView) {
90
+ Alert.alert(
91
+ 'Initialization Error',
92
+ 'Missing required fiels. e.g product code, customer ref, client Id'
93
+ );
94
+ setCanShowWebView(false);
95
+ return null;
96
+ }
97
+
98
+ if (canShowWebView) {
99
+ return (
100
+ <SafeAreaView
101
+ style={{
102
+ flex: 1,
103
+ alignSelf: 'stretch',
104
+ position: 'absolute',
105
+ top: 0,
106
+ left: 0,
107
+ right: 0,
108
+ }}
109
+ >
110
+ <WebView
111
+ mixedContentMode="compatibility"
112
+ style={{
113
+ flex: 1,
114
+ marginTop: 40,
115
+ height: Dimensions.get('window').height,
116
+ width: Dimensions.get('screen').width,
117
+ }}
118
+ bounces={false}
119
+ scalesPageToFit={true}
120
+ javaScriptEnabled={true}
121
+ originWhitelist={['*']}
122
+ useWebView2={true}
123
+ useWebKit={true}
124
+ onMessage={onMessage}
125
+ source={{
126
+ html,
127
+ }}
128
+ onError={console.error}
129
+ />
130
+ </SafeAreaView>
131
+ );
132
+ }
133
+
134
+ return (
135
+ (initialData.render && initialData.render({ onPress: toggleWebView })) || (
136
+ <TouchableOpacity
137
+ style={{
138
+ flex: 1,
139
+ justifyContent: 'center',
140
+ alignItems: 'center',
141
+ paddingHorizontal: 10,
142
+ paddingVertical: 5,
143
+ }}
144
+ onPress={toggleWebView}
145
+ >
146
+ <Text style={{ color: 'blue' }}>Start QoreID</Text>
147
+ </TouchableOpacity>
148
+ )
149
+ );
150
+ };
@@ -0,0 +1,3 @@
1
+ import type { ReactNode } from 'react';
2
+ import { UIManager, findNodeHandle, requireNativeComponent, View, NativeEventEmitter, NativeModules, Platform } from 'react-native';
3
+
package/src/types.d.ts ADDED
@@ -0,0 +1,99 @@
1
+ import type { GestureResponderEvent } from 'react-native';
2
+
3
+ export interface DataType {
4
+ config: IConfig;
5
+ applicantData?: ApplicantData;
6
+ addressData?: AddressData;
7
+ acceptedDocuments?: string | string[];
8
+ identityData?: IdentityData
9
+ }
10
+
11
+ interface IConfig {
12
+ flowId?: number;
13
+ customerRef: string;
14
+ productCode: string;
15
+ clientId: string;
16
+ }
17
+
18
+ interface ApplicantData {
19
+ firstName?: string;
20
+ lastName?: string;
21
+ phoneNumber?: string;
22
+ email?: string;
23
+ dob?: string;
24
+ gender?: string;
25
+ middleName?: string;
26
+ }
27
+
28
+ interface IdentityData {
29
+ idType?: string;
30
+ idNumber?: string;
31
+ }
32
+
33
+ interface AddressData {
34
+ address?: string;
35
+ town?: string;
36
+ lga?: string;
37
+ city?: string;
38
+ state?: string;
39
+ region?: string;
40
+ district?: string;
41
+ virAddress?: string;
42
+ }
43
+
44
+ export interface OnResultType {
45
+ code: string;
46
+ data: string;
47
+ message: string;
48
+ }
49
+
50
+ export interface Options {
51
+ clientId: string;
52
+ onSubmitted?: (data: Omit<OnResultType, 'code'>) => void;
53
+ onError?: (data: OnResultType) => void;
54
+ buttonProps?: {
55
+ title?: string;
56
+ color?: string;
57
+ backgroundColor?: string;
58
+ };
59
+ }
60
+
61
+
62
+
63
+ export interface BrowserEventData {
64
+ type: string;
65
+ detail: any;
66
+ }
67
+
68
+ declare interface IQoreIdButton <T = JSX.Element>{
69
+ title?: string
70
+ sdkSource?: string
71
+ flowId?: number
72
+ clientId: string
73
+ productCode?: string
74
+ customerReference: string
75
+ applicantData?: {
76
+ firstName: string,
77
+ middleName?: string,
78
+ lastName: string,
79
+ gender: 'male'|'female'|'others' | string,
80
+ phoneNumber?: string,
81
+ email?: string,
82
+ },
83
+ identityData?: {
84
+ idType: string,
85
+ idNumber: string,
86
+ },
87
+ addressData?: {
88
+ address: string,
89
+ city: string,
90
+ lga: string,
91
+ },
92
+ ocrAcceptedDocuments?: string,
93
+ onQoreIDSdkSubmitted: (data: BrowserEventData | Omit<OnResultType, 'code'>) => void;
94
+ onQoreIDSdkError: (data: BrowserEventData | OnResultType) => void;
95
+ onQoreIDSdkClosed: (data: BrowserEventData) => void;
96
+ /** Render custom button or a Pressable Component */
97
+ render?: ({onPress}:{onPress:(event: GestureResponderEvent) => void}) => T.onPress extends {onPress: (event: GestureResponderEvent) => void} ? T : never;
98
+ }
99
+
package/src/utils.ts ADDED
@@ -0,0 +1,73 @@
1
+ const acceptedDocuments = {
2
+ Nigeria: [
3
+ 'DRIVERS_LICENSE_NGA',
4
+ 'VOTERS_CARD_NGA',
5
+ 'NIN_SLIP_NGA',
6
+ 'PASSPORT_NGA',
7
+ ],
8
+ Ghana: [
9
+ 'DRIVERS_LICENSE_GHA',
10
+ 'NHIS_CARD_GHA',
11
+ 'ECOWAS_CARD_GHA',
12
+ 'SOCIAL_SECURITY_GHA',
13
+ 'VOTERS_CARD_GHA',
14
+ 'PASSPORT_GHA',
15
+ 'GHANA_CARD_GHA',
16
+ ],
17
+ Kenya: [
18
+ 'DRIVERS_LICENSE_KEN',
19
+ 'NATIONAL_ID_KEN',
20
+ 'REFUGEE_ID_KEN',
21
+ 'PASSPORT_KEN',
22
+ ],
23
+ };
24
+
25
+ const productCodes = [
26
+ 'alien_card',
27
+ 'brs',
28
+ 'business_address',
29
+ 'bvn_basic',
30
+ 'bvn_boolean',
31
+ 'bvn_nuban',
32
+ 'bvn_premium',
33
+ 'cac_basic',
34
+ 'cac_premium',
35
+ 'drivers_license',
36
+ 'employment',
37
+ 'guarantor',
38
+ 'face_verification_bvn',
39
+ 'face_verification_drivers_license',
40
+ 'face_verification_nin',
41
+ 'face_verification_passport_ng',
42
+ 'face_verification_passport_ke',
43
+ 'face_verification_vnin',
44
+ 'individual_address',
45
+ 'kenya_id',
46
+ 'license_plate_basic',
47
+ 'license_plate_premium',
48
+ 'liveness',
49
+ 'liveness_bvn',
50
+ 'liveness_drivers_license',
51
+ 'liveness_nin',
52
+ 'liveness_ocr',
53
+ 'liveness_passport_ng',
54
+ 'liveness_vnin',
55
+ 'nin',
56
+ 'nin_phone',
57
+ 'nuban',
58
+ 'ocr',
59
+ 'passport_ng',
60
+ 'passport_ke',
61
+ 'property',
62
+ 'tin',
63
+ // "vehicle",
64
+ 'verifind',
65
+ 'verifind_4d',
66
+ 'vin',
67
+ 'virtual_nin',
68
+ ];
69
+
70
+ export const utils = {
71
+ productCodes,
72
+ acceptedDocuments,
73
+ };