partner_react_native_sdk 0.1.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.
- package/LICENSE +20 -0
- package/PartnerReactNativeSdk.podspec +26 -0
- package/README.md +14 -0
- package/android/build.gradle +100 -0
- package/android/generated/java/com/partnerreactnativesdk/NativePartnerReactNativeSdkSpec.java +37 -0
- package/android/generated/jni/CMakeLists.txt +36 -0
- package/android/generated/jni/RNPartnerReactNativeSdkSpec-generated.cpp +32 -0
- package/android/generated/jni/RNPartnerReactNativeSdkSpec.h +31 -0
- package/android/generated/jni/react/renderer/components/RNPartnerReactNativeSdkSpec/RNPartnerReactNativeSdkSpecJSI-generated.cpp +28 -0
- package/android/generated/jni/react/renderer/components/RNPartnerReactNativeSdkSpec/RNPartnerReactNativeSdkSpecJSI.h +71 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/partnerreactnativesdk/PartnerReactNativeSdkModule.kt +23 -0
- package/android/src/main/java/com/partnerreactnativesdk/PartnerReactNativeSdkPackage.kt +33 -0
- package/ios/PartnerReactNativeSdk.h +6 -0
- package/ios/PartnerReactNativeSdk.mm +18 -0
- package/ios/generated/RNPartnerReactNativeSdkSpec/RNPartnerReactNativeSdkSpec-generated.mm +39 -0
- package/ios/generated/RNPartnerReactNativeSdkSpec/RNPartnerReactNativeSdkSpec.h +63 -0
- package/ios/generated/RNPartnerReactNativeSdkSpecJSI-generated.cpp +28 -0
- package/ios/generated/RNPartnerReactNativeSdkSpecJSI.h +71 -0
- package/lib/module/NativePartnerReactNativeSdk.ts +8 -0
- package/lib/module/helpers/ServiceNames.js +132 -0
- package/lib/module/helpers/ServiceNames.js.map +1 -0
- package/lib/module/helpers/helper.js +4 -0
- package/lib/module/helpers/helper.js.map +1 -0
- package/lib/module/helpers/network/APICall.js +41 -0
- package/lib/module/helpers/network/APICall.js.map +1 -0
- package/lib/module/helpers/network/network_manager.js +112 -0
- package/lib/module/helpers/network/network_manager.js.map +1 -0
- package/lib/module/helpers/partner_library_react_native.js +197 -0
- package/lib/module/helpers/partner_library_react_native.js.map +1 -0
- package/lib/module/helpers/utils/Constants.js +12 -0
- package/lib/module/helpers/utils/Constants.js.map +1 -0
- package/lib/module/helpers/utils/LibraryConstants.js +115 -0
- package/lib/module/helpers/utils/LibraryConstants.js.map +1 -0
- package/lib/module/helpers/utils/deviceInfoManager.js +39 -0
- package/lib/module/helpers/utils/deviceInfoManager.js.map +1 -0
- package/lib/module/helpers/utils/headerManager.js +21 -0
- package/lib/module/helpers/utils/headerManager.js.map +1 -0
- package/lib/module/helpers/utils/themeManager.js +40 -0
- package/lib/module/helpers/utils/themeManager.js.map +1 -0
- package/lib/module/helpers/utils/webviewCallback.js +20 -0
- package/lib/module/helpers/utils/webviewCallback.js.map +1 -0
- package/lib/module/helpers/webview.js +273 -0
- package/lib/module/helpers/webview.js.map +1 -0
- package/lib/module/index.js +8 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativePartnerReactNativeSdk.d.ts +7 -0
- package/lib/typescript/src/NativePartnerReactNativeSdk.d.ts.map +1 -0
- package/lib/typescript/src/helpers/ServiceNames.d.ts +50 -0
- package/lib/typescript/src/helpers/ServiceNames.d.ts.map +1 -0
- package/lib/typescript/src/helpers/helper.d.ts +1 -0
- package/lib/typescript/src/helpers/helper.d.ts.map +1 -0
- package/lib/typescript/src/helpers/network/APICall.d.ts +12 -0
- package/lib/typescript/src/helpers/network/APICall.d.ts.map +1 -0
- package/lib/typescript/src/helpers/network/network_manager.d.ts +21 -0
- package/lib/typescript/src/helpers/network/network_manager.d.ts.map +1 -0
- package/lib/typescript/src/helpers/partner_library_react_native.d.ts +23 -0
- package/lib/typescript/src/helpers/partner_library_react_native.d.ts.map +1 -0
- package/lib/typescript/src/helpers/utils/Constants.d.ts +10 -0
- package/lib/typescript/src/helpers/utils/Constants.d.ts.map +1 -0
- package/lib/typescript/src/helpers/utils/LibraryConstants.d.ts +24 -0
- package/lib/typescript/src/helpers/utils/LibraryConstants.d.ts.map +1 -0
- package/lib/typescript/src/helpers/utils/deviceInfoManager.d.ts +4 -0
- package/lib/typescript/src/helpers/utils/deviceInfoManager.d.ts.map +1 -0
- package/lib/typescript/src/helpers/utils/headerManager.d.ts +5 -0
- package/lib/typescript/src/helpers/utils/headerManager.d.ts.map +1 -0
- package/lib/typescript/src/helpers/utils/themeManager.d.ts +12 -0
- package/lib/typescript/src/helpers/utils/themeManager.d.ts.map +1 -0
- package/lib/typescript/src/helpers/utils/webviewCallback.d.ts +13 -0
- package/lib/typescript/src/helpers/utils/webviewCallback.d.ts.map +1 -0
- package/lib/typescript/src/helpers/webview.d.ts +21 -0
- package/lib/typescript/src/helpers/webview.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +187 -0
- package/react-native.config.js +12 -0
- package/src/NativePartnerReactNativeSdk.ts +8 -0
- package/src/helpers/ServiceNames.tsx +166 -0
- package/src/helpers/helper.tsx +1 -0
- package/src/helpers/network/APICall.tsx +65 -0
- package/src/helpers/network/network_manager.tsx +122 -0
- package/src/helpers/partner_library_react_native.tsx +279 -0
- package/src/helpers/utils/Constants.tsx +10 -0
- package/src/helpers/utils/LibraryConstants.tsx +133 -0
- package/src/helpers/utils/deviceInfoManager.tsx +37 -0
- package/src/helpers/utils/headerManager.tsx +22 -0
- package/src/helpers/utils/themeManager.tsx +51 -0
- package/src/helpers/utils/webviewCallback.tsx +25 -0
- package/src/helpers/webview.tsx +343 -0
- package/src/index.tsx +9 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import NetworkManager from './network_manager';
|
|
2
|
+
import { HeaderManager } from '../utils/headerManager';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export class APICall {
|
|
6
|
+
|
|
7
|
+
private networkManager: NetworkManager = new NetworkManager;
|
|
8
|
+
private headerManager: HeaderManager = new HeaderManager;
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async callAPI(
|
|
12
|
+
method: string,
|
|
13
|
+
apiUrl: string,
|
|
14
|
+
options?: {
|
|
15
|
+
body?: Record<string, any>;
|
|
16
|
+
headers?: Record<string, any>;
|
|
17
|
+
encrypted?: boolean;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
): Promise<any> {
|
|
21
|
+
const { body, headers, encrypted = false } = options || {};
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const response = encrypted
|
|
25
|
+
? await this._callAPIEncrypt(method, apiUrl, body, headers)
|
|
26
|
+
: await this._callAPIRaw(method, apiUrl, body, headers);
|
|
27
|
+
|
|
28
|
+
return response;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.log("Error in callAPI:", error);
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
private async _callAPIRaw(
|
|
37
|
+
method: string,
|
|
38
|
+
apiUrl: string,
|
|
39
|
+
body?: Record<string, any>,
|
|
40
|
+
headers?: Record<string, any>
|
|
41
|
+
): Promise<any> {
|
|
42
|
+
const mergedHeaders = {
|
|
43
|
+
...(await this.headerManager.generateHeaders()),
|
|
44
|
+
...(headers || {}),
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return this.networkManager.request({
|
|
48
|
+
url: apiUrl,
|
|
49
|
+
method: method,
|
|
50
|
+
body: body,
|
|
51
|
+
headers: mergedHeaders
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// TODO: Implement encryption logic
|
|
56
|
+
private async _callAPIEncrypt(
|
|
57
|
+
method: string,
|
|
58
|
+
apiUrl: string,
|
|
59
|
+
body?: Record<string, any>,
|
|
60
|
+
headers?: Record<string, any>
|
|
61
|
+
): Promise<any> {
|
|
62
|
+
// Encryption logic not implemented, fallback to raw
|
|
63
|
+
return this._callAPIRaw(method, apiUrl, body, headers);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import axios, { type AxiosInstance, type AxiosResponse, type AxiosRequestConfig } from 'axios';
|
|
2
|
+
|
|
3
|
+
class NetworkManager {
|
|
4
|
+
private static _instance: NetworkManager = new NetworkManager();
|
|
5
|
+
private _axios: AxiosInstance;
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
this._axios = axios.create();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static getInstance(): NetworkManager {
|
|
12
|
+
return NetworkManager._instance;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async request({
|
|
16
|
+
url,
|
|
17
|
+
method,
|
|
18
|
+
body,
|
|
19
|
+
headers,
|
|
20
|
+
options,
|
|
21
|
+
}: {
|
|
22
|
+
url: string;
|
|
23
|
+
method: string;
|
|
24
|
+
body?: Record<string, any>;
|
|
25
|
+
headers?: Record<string, any>;
|
|
26
|
+
options?: AxiosRequestConfig;
|
|
27
|
+
}): Promise<AxiosResponse | null> {
|
|
28
|
+
try {
|
|
29
|
+
headers = headers || {};
|
|
30
|
+
options = options || { headers };
|
|
31
|
+
|
|
32
|
+
let response: AxiosResponse;
|
|
33
|
+
const config: AxiosRequestConfig = {
|
|
34
|
+
...options,
|
|
35
|
+
headers,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
switch (method.toUpperCase()) {
|
|
39
|
+
case 'POST':
|
|
40
|
+
response = await this._axios.post(url, body, config);
|
|
41
|
+
break;
|
|
42
|
+
case 'GET':
|
|
43
|
+
response = await this._axios.get(url, config);
|
|
44
|
+
break;
|
|
45
|
+
case 'PUT':
|
|
46
|
+
response = await this._axios.put(url, body, config);
|
|
47
|
+
break;
|
|
48
|
+
case 'PATCH':
|
|
49
|
+
response = await this._axios.patch(url, body, config);
|
|
50
|
+
break;
|
|
51
|
+
case 'DELETE':
|
|
52
|
+
response = await this._axios.delete(url, {
|
|
53
|
+
...config,
|
|
54
|
+
data: body,
|
|
55
|
+
});
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
throw new Error(`Method not supported: ${method}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return response;
|
|
62
|
+
} catch (error) {
|
|
63
|
+
if (__DEV__) {
|
|
64
|
+
if (axios.isAxiosError(error)) {
|
|
65
|
+
if (!error.response) {
|
|
66
|
+
console.log("Network error:", error.message);
|
|
67
|
+
}
|
|
68
|
+
return error.response || null;
|
|
69
|
+
} else {
|
|
70
|
+
console.log("Unexpected error during network request:", error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw error;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async get(
|
|
78
|
+
url: string,
|
|
79
|
+
headers?: Record<string, any>,
|
|
80
|
+
options?: AxiosRequestConfig
|
|
81
|
+
): Promise<AxiosResponse | null> {
|
|
82
|
+
return this.request({ url, method: 'GET', headers, options });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async post(
|
|
86
|
+
url: string,
|
|
87
|
+
body: Record<string, any>,
|
|
88
|
+
headers?: Record<string, any>,
|
|
89
|
+
options?: AxiosRequestConfig
|
|
90
|
+
): Promise<AxiosResponse | null> {
|
|
91
|
+
return this.request({ url, method: 'POST', body, headers, options });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async put(
|
|
95
|
+
url: string,
|
|
96
|
+
body: Record<string, any>,
|
|
97
|
+
headers?: Record<string, any>,
|
|
98
|
+
options?: AxiosRequestConfig
|
|
99
|
+
): Promise<AxiosResponse | null> {
|
|
100
|
+
return this.request({ url, method: 'PUT', body, headers, options });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async patch(
|
|
104
|
+
url: string,
|
|
105
|
+
body: Record<string, any>,
|
|
106
|
+
headers?: Record<string, any>,
|
|
107
|
+
options?: AxiosRequestConfig
|
|
108
|
+
): Promise<AxiosResponse | null> {
|
|
109
|
+
return this.request({ url, method: 'PATCH', body, headers, options });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async delete(
|
|
113
|
+
url: string,
|
|
114
|
+
headers?: Record<string, any>,
|
|
115
|
+
body?: Record<string, any>,
|
|
116
|
+
options?: AxiosRequestConfig
|
|
117
|
+
): Promise<AxiosResponse | null> {
|
|
118
|
+
return this.request({ url, method: 'DELETE', body, headers, options });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export default NetworkManager;
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import { APICall } from './network/APICall';
|
|
2
|
+
import { DeviceInfoManager } from './utils/deviceInfoManager';
|
|
3
|
+
import { LibraryConstants } from './utils/LibraryConstants';
|
|
4
|
+
import { type WebViewCallbackFunction } from './utils/webviewCallback';
|
|
5
|
+
import { ServiceNames } from './ServiceNames';
|
|
6
|
+
import { Constants } from './utils/Constants';
|
|
7
|
+
import { WebView } from '../helpers/webview';
|
|
8
|
+
import { SafeAreaView } from 'react-native-safe-area-context';
|
|
9
|
+
import { StatusBar } from 'react-native';
|
|
10
|
+
export type { WebViewCallbackFunction } from './utils/webviewCallback';
|
|
11
|
+
type InitOptions = {
|
|
12
|
+
whitelistedDomains: string[];
|
|
13
|
+
deviceBindingEnabled: boolean;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
export class PartnerLibrary {
|
|
18
|
+
|
|
19
|
+
private static instance: PartnerLibrary | null = null;
|
|
20
|
+
private static intialized = false;
|
|
21
|
+
|
|
22
|
+
private _apiCall = new APICall();
|
|
23
|
+
static webViewCallback: WebViewCallbackFunction;
|
|
24
|
+
|
|
25
|
+
private constructor() { }
|
|
26
|
+
|
|
27
|
+
static getInstance(): PartnerLibrary {
|
|
28
|
+
if (!PartnerLibrary.instance) {
|
|
29
|
+
PartnerLibrary.instance = new PartnerLibrary();
|
|
30
|
+
}
|
|
31
|
+
return PartnerLibrary.instance;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static async init(hostName: string, options: InitOptions = {
|
|
35
|
+
whitelistedDomains: [],
|
|
36
|
+
deviceBindingEnabled: false
|
|
37
|
+
}): Promise<void> {
|
|
38
|
+
// console.log("PartnerLibrary.init - initialized:", PartnerLibrary.intialized);
|
|
39
|
+
if (PartnerLibrary.intialized) return;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
// Ensure instance exists before setup
|
|
43
|
+
if (!PartnerLibrary.instance) {
|
|
44
|
+
// console.log("PartnerLibrary.init - creating new instance");
|
|
45
|
+
PartnerLibrary.instance = new PartnerLibrary();
|
|
46
|
+
}
|
|
47
|
+
await PartnerLibrary.instance._setup(hostName, options.whitelistedDomains, options.deviceBindingEnabled);
|
|
48
|
+
PartnerLibrary.intialized = true;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error("Initialization failed: ", error);
|
|
52
|
+
throw new Error("Initialization failed");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async _setup(
|
|
57
|
+
hostName: string,
|
|
58
|
+
whitelistedDomains: string[],
|
|
59
|
+
deviceBindingEnabled: boolean
|
|
60
|
+
): Promise<void> {
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
LibraryConstants.init({
|
|
64
|
+
host: hostName,
|
|
65
|
+
whitelistedDomains: whitelistedDomains,
|
|
66
|
+
deviceBinding: deviceBindingEnabled
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async open(
|
|
72
|
+
module: string,
|
|
73
|
+
token: string,
|
|
74
|
+
WebViewCallbackFunction: WebViewCallbackFunction,
|
|
75
|
+
|
|
76
|
+
): Promise<React.ReactElement> {
|
|
77
|
+
if (!PartnerLibrary.intialized) {
|
|
78
|
+
throw new Error('PartnerLibrary not initialized. Call init() first.');
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
let bank = "";
|
|
82
|
+
|
|
83
|
+
if (module.includes("banking/")) {
|
|
84
|
+
const startIndex = module.indexOf("banking/") + "banking/".length;
|
|
85
|
+
const temp = module.substring(startIndex);
|
|
86
|
+
const endIndex = temp.indexOf("/");
|
|
87
|
+
bank = endIndex === -1 ? temp : temp.substring(0, endIndex);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return this._loginAndNavigateToWebView(module, bank, token, WebViewCallbackFunction);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.error('Error opening webview:', e);
|
|
93
|
+
throw e;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
private async _checkDeviceBinding(
|
|
99
|
+
bank: string,
|
|
100
|
+
url: string,
|
|
101
|
+
WebViewCallbackFunction: WebViewCallbackFunction,
|
|
102
|
+
|
|
103
|
+
): Promise<React.ReactElement> {
|
|
104
|
+
|
|
105
|
+
console.log("entered in check device binding")
|
|
106
|
+
if (LibraryConstants.deviceBindingEnabled) {
|
|
107
|
+
// TODO: Build the device binding flow
|
|
108
|
+
return Promise.resolve(<></>);
|
|
109
|
+
|
|
110
|
+
} else {
|
|
111
|
+
console.log("calling setup device session")
|
|
112
|
+
|
|
113
|
+
return this._setupDeviceSession(bank, url, WebViewCallbackFunction);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private async _loginAndNavigateToWebView(
|
|
118
|
+
module: string,
|
|
119
|
+
bank: string,
|
|
120
|
+
token: string,
|
|
121
|
+
WebViewCallbackFunction: WebViewCallbackFunction,
|
|
122
|
+
|
|
123
|
+
): Promise<React.ReactElement> {
|
|
124
|
+
// console.log("PartnerLibrary._loginAndNavigateToWebView - LibraryConstants.hostName:", LibraryConstants.hostName);
|
|
125
|
+
try {
|
|
126
|
+
let tokenResponse: any;
|
|
127
|
+
const url = ServiceNames.LOGIN_URL;
|
|
128
|
+
console.log("url is : ", url)
|
|
129
|
+
tokenResponse = await this._apiCall.callAPI(
|
|
130
|
+
'POST',
|
|
131
|
+
ServiceNames.LOGIN_URL, {
|
|
132
|
+
body: {
|
|
133
|
+
'token': token
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
if (tokenResponse?.data?.code === "USER_TOKEN_EXPIRED") {
|
|
139
|
+
console.log("Token expired");
|
|
140
|
+
return Promise.resolve(<></>);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (tokenResponse?.data && 'RATE_LIMIT_USER' in tokenResponse.data) {
|
|
144
|
+
console.log("rate limit user");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// console.log("Checking login success condition:", {
|
|
148
|
+
// statusCode: tokenResponse?.statusCode,
|
|
149
|
+
// code: tokenResponse?.data?.code
|
|
150
|
+
// });
|
|
151
|
+
|
|
152
|
+
if (tokenResponse?.data?.code === "USER_LOGIN_SUCCESS") {
|
|
153
|
+
console.log("User login success");
|
|
154
|
+
this.fetchAndSetTheme();
|
|
155
|
+
return this._checkDeviceBinding(bank, module, WebViewCallbackFunction);
|
|
156
|
+
} else {
|
|
157
|
+
console.log("Login not successful. Token Response:", tokenResponse);
|
|
158
|
+
return Promise.resolve(<></>);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
} catch (e) {
|
|
162
|
+
console.error('Error during login:', e);
|
|
163
|
+
throw e;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private async _setupDeviceSession(
|
|
170
|
+
bank: string,
|
|
171
|
+
url: string,
|
|
172
|
+
WebViewCallbackFunction: WebViewCallbackFunction,
|
|
173
|
+
|
|
174
|
+
): Promise<React.ReactElement> {
|
|
175
|
+
try {
|
|
176
|
+
console.log("in setup device session")
|
|
177
|
+
|
|
178
|
+
const deviceInfo = await DeviceInfoManager.getDeviceInfo();
|
|
179
|
+
const appVersion = deviceInfo['app_version'] || 'unknown';
|
|
180
|
+
|
|
181
|
+
if (__DEV__) {
|
|
182
|
+
console.log("Device Info:", deviceInfo);
|
|
183
|
+
console.log("App Version:", appVersion);
|
|
184
|
+
}
|
|
185
|
+
console.log("device uuid is : ", deviceInfo[Constants.DEVICE_UUID]);
|
|
186
|
+
|
|
187
|
+
const response = await this._apiCall.callAPI(
|
|
188
|
+
'POST',
|
|
189
|
+
ServiceNames.DEVICE_SESSION.params({ "partner": bank }),
|
|
190
|
+
{
|
|
191
|
+
body: {
|
|
192
|
+
[Constants.MANUFACTURER]: deviceInfo[Constants.MANUFACTURER],
|
|
193
|
+
[Constants.MODEL]: deviceInfo[Constants.MODEL],
|
|
194
|
+
[Constants.DEVICE_UUID]: deviceInfo[Constants.DEVICE_UUID],
|
|
195
|
+
[Constants.OS]: deviceInfo[Constants.OS],
|
|
196
|
+
[Constants.OS_VERSION]: deviceInfo[Constants.OS_VERSION],
|
|
197
|
+
[Constants.APP_VERSION]: appVersion,
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
//console.log("response from setup device session is : ", response)
|
|
202
|
+
if (response?.data && 'RATE_LIMIT_USER' in response.data) {
|
|
203
|
+
console.log("rate limit user");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (response?.status === 200) {
|
|
207
|
+
|
|
208
|
+
return this._openWebView(url, WebViewCallbackFunction);
|
|
209
|
+
} else {
|
|
210
|
+
console.warn('Error setting up device session:', response);
|
|
211
|
+
return this._openWebView(url, WebViewCallbackFunction);
|
|
212
|
+
}
|
|
213
|
+
} catch (e) {
|
|
214
|
+
console.error('Error setting up device session:', e);
|
|
215
|
+
throw e;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
async _openWebView(
|
|
222
|
+
url: string,
|
|
223
|
+
WebViewCallbackFunction: WebViewCallbackFunction,
|
|
224
|
+
): Promise<React.ReactElement> {
|
|
225
|
+
console.log("entered in open web view");
|
|
226
|
+
console.log("url is : ", LibraryConstants.hostName + url);
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<SafeAreaView style={{ flex: 1 }}>
|
|
231
|
+
<WebView
|
|
232
|
+
url={LibraryConstants.hostName + url}
|
|
233
|
+
onCallback={WebViewCallbackFunction}
|
|
234
|
+
whitelistedUrls={LibraryConstants.whitelistedDomains}
|
|
235
|
+
hostName={LibraryConstants.hostName}
|
|
236
|
+
onPageFinished={() => console.log('WebView page finished loading')}
|
|
237
|
+
/>
|
|
238
|
+
</SafeAreaView>
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async fetchAndSetTheme(): Promise<void> {
|
|
243
|
+
try {
|
|
244
|
+
console.log("Fetching theme from API");
|
|
245
|
+
|
|
246
|
+
const themeResponse: any = await this._apiCall.callAPI(
|
|
247
|
+
'GET',
|
|
248
|
+
ServiceNames.THEME_URL
|
|
249
|
+
);
|
|
250
|
+
const theme = themeResponse?.data;
|
|
251
|
+
|
|
252
|
+
if (theme && theme["--color-primary-500"]) {
|
|
253
|
+
const rgbValues = theme["--color-primary-500"].split(" ").map(Number);
|
|
254
|
+
if (rgbValues.length === 3) {
|
|
255
|
+
const [r, g, b] = rgbValues;
|
|
256
|
+
|
|
257
|
+
// Update LibraryConstants color
|
|
258
|
+
LibraryConstants.setPrimaryColorFromRGB(r, g, b);
|
|
259
|
+
|
|
260
|
+
// Set status bar color
|
|
261
|
+
|
|
262
|
+
StatusBar.setBackgroundColor(LibraryConstants.primaryColor);
|
|
263
|
+
StatusBar.setBarStyle('light-content');
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
console.log("Theme color set successfully:", LibraryConstants.primaryColor);
|
|
267
|
+
} else {
|
|
268
|
+
console.warn("Invalid RGB values in theme response");
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
console.warn("--color-primary-500 not found in theme response");
|
|
272
|
+
}
|
|
273
|
+
} catch (e) {
|
|
274
|
+
console.error("Error Fetching theme: ", e);
|
|
275
|
+
throw e;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
|
|
3
|
+
interface Color {
|
|
4
|
+
r: number;
|
|
5
|
+
g: number;
|
|
6
|
+
b: number;
|
|
7
|
+
a: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// interface ColorWithValues extends Color {
|
|
11
|
+
// withValues(params: { red: number; green: number; blue: number; alpha: number }): string;
|
|
12
|
+
// }
|
|
13
|
+
|
|
14
|
+
// Helper function for color handling
|
|
15
|
+
const hexToRgba = (hex: string): Color => {
|
|
16
|
+
const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
17
|
+
|
|
18
|
+
if (match && match[1] && match[2] && match[3]) {
|
|
19
|
+
return {
|
|
20
|
+
r: parseInt(match[1], 16),
|
|
21
|
+
g: parseInt(match[2], 16),
|
|
22
|
+
b: parseInt(match[3], 16),
|
|
23
|
+
a: 1,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return { r: 0, g: 0, b: 0, a: 1 };
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
// const rgbaToHex = (color: Color): string => {
|
|
33
|
+
// return `#${color.r.toString(16).padStart(2, '0')}${color.g.toString(16).padStart(2, '0')}${color.b.toString(16).padStart(2, '0')}`;
|
|
34
|
+
// };
|
|
35
|
+
|
|
36
|
+
const rgbaToString = (color: Color): string => {
|
|
37
|
+
return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export class LibraryConstants {
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
static deviceBindingEnabled: boolean = true;
|
|
44
|
+
|
|
45
|
+
// Primary color definition
|
|
46
|
+
private static _primaryColorHex: string = '#037EAB';
|
|
47
|
+
private static _primaryColorObj: Color = hexToRgba('#037EAB');
|
|
48
|
+
|
|
49
|
+
// static get primaryColor(): string {
|
|
50
|
+
// return this._primaryColorHex;
|
|
51
|
+
// }
|
|
52
|
+
|
|
53
|
+
static set primaryColor(value: string) {
|
|
54
|
+
this._primaryColorHex = value;
|
|
55
|
+
this._primaryColorObj = hexToRgba(value);
|
|
56
|
+
}
|
|
57
|
+
private static rgbToHex(r: number, g: number, b: number): string {
|
|
58
|
+
return `#${[r, g, b]
|
|
59
|
+
.map(x => {
|
|
60
|
+
const hex = x.toString(16);
|
|
61
|
+
return hex.length === 1 ? '0' + hex : hex;
|
|
62
|
+
})
|
|
63
|
+
.join('')}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static setPrimaryColorFromRGB(r: number, g: number, b: number): void {
|
|
67
|
+
this._primaryColorObj = { r, g, b, a: 1 };
|
|
68
|
+
this._primaryColorHex = LibraryConstants.rgbToHex(r, g, b);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
static secondaryColor: string = '#FFFFFF';
|
|
75
|
+
|
|
76
|
+
// Calculate disabled primary color (with 50% opacity)
|
|
77
|
+
static get primaryColorDisabled(): string {
|
|
78
|
+
return rgbaToString({
|
|
79
|
+
r: this._primaryColorObj.r,
|
|
80
|
+
g: this._primaryColorObj.g,
|
|
81
|
+
b: this._primaryColorObj.b,
|
|
82
|
+
a: 0.5
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static openExternally: string[] = [""];
|
|
87
|
+
static whitelistedUrlsAndroid: string[] = [];
|
|
88
|
+
static whitelistedUrlsIos: string[] = [];
|
|
89
|
+
static hostName: string = "";
|
|
90
|
+
static whitelistedDomains: string[] = [];
|
|
91
|
+
|
|
92
|
+
static init({
|
|
93
|
+
host,
|
|
94
|
+
// whitelistedAndroid,
|
|
95
|
+
// whitelistedIos,
|
|
96
|
+
whitelistedDomains,
|
|
97
|
+
deviceBinding,
|
|
98
|
+
}: {
|
|
99
|
+
host: string;
|
|
100
|
+
whitelistedDomains: string[]
|
|
101
|
+
// whitelistedAndroid?: string[];
|
|
102
|
+
// whitelistedIos?: string[];
|
|
103
|
+
deviceBinding?: boolean;
|
|
104
|
+
}): void {
|
|
105
|
+
this.hostName = host;
|
|
106
|
+
// if (whitelistedAndroid) this.whitelistedUrlsAndroid = whitelistedAndroid;
|
|
107
|
+
// if (whitelistedIos) this.whitelistedUrlsIos = whitelistedIos;
|
|
108
|
+
this.whitelistedDomains = whitelistedDomains;
|
|
109
|
+
if (deviceBinding !== undefined) this.deviceBindingEnabled = deviceBinding;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Helper method to get whitelisted URLs based on platform
|
|
113
|
+
// static getWhitelistedUrls(): string[] {
|
|
114
|
+
// return Platform.OS === 'ios' ? this.whitelistedUrlsIos : this.whitelistedUrlsAndroid;
|
|
115
|
+
// }
|
|
116
|
+
|
|
117
|
+
static getWhitelistedDomains(): string[] {
|
|
118
|
+
return this.whitelistedDomains;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static get primaryColor(): string {
|
|
122
|
+
if (Platform.OS === 'android') {
|
|
123
|
+
return rgbaToString(this._primaryColorObj);
|
|
124
|
+
}
|
|
125
|
+
return this._primaryColorHex;
|
|
126
|
+
}
|
|
127
|
+
static getPrimaryColorWithOpacity(opacity: number): string {
|
|
128
|
+
return rgbaToString({
|
|
129
|
+
...this._primaryColorObj,
|
|
130
|
+
a: opacity
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import DeviceInfo from 'react-native-device-info';
|
|
3
|
+
import { Constants } from './Constants';
|
|
4
|
+
|
|
5
|
+
export class DeviceInfoManager {
|
|
6
|
+
static async getDeviceInfo(): Promise<Record<string, string>> {
|
|
7
|
+
if (Platform.OS === 'android') {
|
|
8
|
+
let androidId = 'unknown';
|
|
9
|
+
try {
|
|
10
|
+
androidId = await DeviceInfo.getAndroidId();
|
|
11
|
+
} catch (e) {
|
|
12
|
+
if (__DEV__) {
|
|
13
|
+
console.log('Error getting android id:', e);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
[Constants.MANUFACTURER]: (await DeviceInfo.getManufacturer()) || 'unknown',
|
|
18
|
+
[Constants.MODEL]: DeviceInfo.getModel() || 'unknown',
|
|
19
|
+
[Constants.OS]: 'android',
|
|
20
|
+
[Constants.OS_VERSION]: DeviceInfo.getSystemVersion() || 'unknown',
|
|
21
|
+
[Constants.APP_VERSION]: DeviceInfo.getVersion() || 'unknown',
|
|
22
|
+
[Constants.DEVICE_UUID]: androidId,
|
|
23
|
+
};
|
|
24
|
+
} else if (Platform.OS === 'ios') {
|
|
25
|
+
return {
|
|
26
|
+
[Constants.MANUFACTURER]: 'Apple',
|
|
27
|
+
[Constants.MODEL]: DeviceInfo.getModel() || 'unknown',
|
|
28
|
+
[Constants.OS]: 'ios',
|
|
29
|
+
[Constants.OS_VERSION]: DeviceInfo.getSystemVersion() || 'unknown',
|
|
30
|
+
[Constants.APP_VERSION]: DeviceInfo.getVersion() || 'unknown',
|
|
31
|
+
[Constants.DEVICE_UUID]: (await DeviceInfo.getUniqueId()) || 'unknown',
|
|
32
|
+
};
|
|
33
|
+
} else {
|
|
34
|
+
throw new Error('Unsupported platform');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Platform } from 'react-native';
|
|
2
|
+
import DeviceInfo from 'react-native-device-info';
|
|
3
|
+
import { DeviceInfoManager } from './deviceInfoManager';
|
|
4
|
+
|
|
5
|
+
export class HeaderManager {
|
|
6
|
+
|
|
7
|
+
private deviceInfoManager = DeviceInfoManager;
|
|
8
|
+
|
|
9
|
+
async generateHeaders(isEncrypted: boolean = true): Promise<Record<string, string>> {
|
|
10
|
+
|
|
11
|
+
const deviceInfo = await this.deviceInfoManager.getDeviceInfo();
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
...deviceInfo,
|
|
15
|
+
app_version: DeviceInfo.getVersion() || 'unknown',
|
|
16
|
+
os: Platform.OS === 'android' ? 'Android' : 'iOS',
|
|
17
|
+
os_version: DeviceInfo.getSystemVersion() || 'unknown',
|
|
18
|
+
...(isEncrypted && { 'Content-Type': 'application/json;charset=utf-8' })
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
}
|