banking_dcb_sdk_react_native 0.1.9

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 (100) hide show
  1. package/LICENSE +20 -0
  2. package/PartnerReactNativeSdk.podspec +31 -0
  3. package/README.md +14 -0
  4. package/android/build.gradle +100 -0
  5. package/android/gradle.properties +5 -0
  6. package/android/src/main/AndroidManifest.xml +3 -0
  7. package/android/src/main/AndroidManifestNew.xml +2 -0
  8. package/android/src/main/java/com/partnerreactnativesdk/PartnerReactNativeSdkModule.kt +23 -0
  9. package/android/src/main/java/com/partnerreactnativesdk/PartnerReactNativeSdkPackage.kt +33 -0
  10. package/ios/PartnerReactNativeSdk.h +6 -0
  11. package/ios/PartnerReactNativeSdk.mm +29 -0
  12. package/lib/module/helpers/ServiceNames.js +135 -0
  13. package/lib/module/helpers/ServiceNames.js.map +1 -0
  14. package/lib/module/helpers/analytics/analytics_event_model.js +37 -0
  15. package/lib/module/helpers/analytics/analytics_event_model.js.map +1 -0
  16. package/lib/module/helpers/analytics/analytics_logger.js +73 -0
  17. package/lib/module/helpers/analytics/analytics_logger.js.map +1 -0
  18. package/lib/module/helpers/analytics/event_storage.js +35 -0
  19. package/lib/module/helpers/analytics/event_storage.js.map +1 -0
  20. package/lib/module/helpers/banking_dcb_react_native.js +297 -0
  21. package/lib/module/helpers/banking_dcb_react_native.js.map +1 -0
  22. package/lib/module/helpers/helper.js +4 -0
  23. package/lib/module/helpers/helper.js.map +1 -0
  24. package/lib/module/helpers/network/APICall.js +111 -0
  25. package/lib/module/helpers/network/APICall.js.map +1 -0
  26. package/lib/module/helpers/network/Encryption.js +148 -0
  27. package/lib/module/helpers/network/Encryption.js.map +1 -0
  28. package/lib/module/helpers/network/network_manager.js +112 -0
  29. package/lib/module/helpers/network/network_manager.js.map +1 -0
  30. package/lib/module/helpers/utils/Constants.js +12 -0
  31. package/lib/module/helpers/utils/Constants.js.map +1 -0
  32. package/lib/module/helpers/utils/LibraryConstants.js +115 -0
  33. package/lib/module/helpers/utils/LibraryConstants.js.map +1 -0
  34. package/lib/module/helpers/utils/deviceInfoManager.js +39 -0
  35. package/lib/module/helpers/utils/deviceInfoManager.js.map +1 -0
  36. package/lib/module/helpers/utils/headerManager.js +21 -0
  37. package/lib/module/helpers/utils/headerManager.js.map +1 -0
  38. package/lib/module/helpers/utils/themeManager.js +40 -0
  39. package/lib/module/helpers/utils/themeManager.js.map +1 -0
  40. package/lib/module/helpers/utils/webviewCallback.js +20 -0
  41. package/lib/module/helpers/utils/webviewCallback.js.map +1 -0
  42. package/lib/module/helpers/webview.js +314 -0
  43. package/lib/module/helpers/webview.js.map +1 -0
  44. package/lib/module/index.js +5 -0
  45. package/lib/module/index.js.map +1 -0
  46. package/lib/module/package.json +1 -0
  47. package/lib/typescript/package.json +1 -0
  48. package/lib/typescript/src/helpers/ServiceNames.d.ts +51 -0
  49. package/lib/typescript/src/helpers/ServiceNames.d.ts.map +1 -0
  50. package/lib/typescript/src/helpers/analytics/analytics_event_model.d.ts +16 -0
  51. package/lib/typescript/src/helpers/analytics/analytics_event_model.d.ts.map +1 -0
  52. package/lib/typescript/src/helpers/analytics/analytics_logger.d.ts +17 -0
  53. package/lib/typescript/src/helpers/analytics/analytics_logger.d.ts.map +1 -0
  54. package/lib/typescript/src/helpers/analytics/event_storage.d.ts +8 -0
  55. package/lib/typescript/src/helpers/analytics/event_storage.d.ts.map +1 -0
  56. package/lib/typescript/src/helpers/banking_dcb_react_native.d.ts +33 -0
  57. package/lib/typescript/src/helpers/banking_dcb_react_native.d.ts.map +1 -0
  58. package/lib/typescript/src/helpers/helper.d.ts +1 -0
  59. package/lib/typescript/src/helpers/helper.d.ts.map +1 -0
  60. package/lib/typescript/src/helpers/network/APICall.d.ts +13 -0
  61. package/lib/typescript/src/helpers/network/APICall.d.ts.map +1 -0
  62. package/lib/typescript/src/helpers/network/Encryption.d.ts +24 -0
  63. package/lib/typescript/src/helpers/network/Encryption.d.ts.map +1 -0
  64. package/lib/typescript/src/helpers/network/network_manager.d.ts +21 -0
  65. package/lib/typescript/src/helpers/network/network_manager.d.ts.map +1 -0
  66. package/lib/typescript/src/helpers/utils/Constants.d.ts +10 -0
  67. package/lib/typescript/src/helpers/utils/Constants.d.ts.map +1 -0
  68. package/lib/typescript/src/helpers/utils/LibraryConstants.d.ts +24 -0
  69. package/lib/typescript/src/helpers/utils/LibraryConstants.d.ts.map +1 -0
  70. package/lib/typescript/src/helpers/utils/deviceInfoManager.d.ts +4 -0
  71. package/lib/typescript/src/helpers/utils/deviceInfoManager.d.ts.map +1 -0
  72. package/lib/typescript/src/helpers/utils/headerManager.d.ts +5 -0
  73. package/lib/typescript/src/helpers/utils/headerManager.d.ts.map +1 -0
  74. package/lib/typescript/src/helpers/utils/themeManager.d.ts +12 -0
  75. package/lib/typescript/src/helpers/utils/themeManager.d.ts.map +1 -0
  76. package/lib/typescript/src/helpers/utils/webviewCallback.d.ts +13 -0
  77. package/lib/typescript/src/helpers/utils/webviewCallback.d.ts.map +1 -0
  78. package/lib/typescript/src/helpers/webview.d.ts +21 -0
  79. package/lib/typescript/src/helpers/webview.d.ts.map +1 -0
  80. package/lib/typescript/src/index.d.ts +5 -0
  81. package/lib/typescript/src/index.d.ts.map +1 -0
  82. package/package.json +170 -0
  83. package/react-native.config.js +12 -0
  84. package/src/helpers/ServiceNames.tsx +170 -0
  85. package/src/helpers/analytics/analytics_event_model.tsx +47 -0
  86. package/src/helpers/analytics/analytics_logger.tsx +91 -0
  87. package/src/helpers/analytics/event_storage.tsx +44 -0
  88. package/src/helpers/banking_dcb_react_native.tsx +413 -0
  89. package/src/helpers/helper.tsx +1 -0
  90. package/src/helpers/network/APICall.tsx +154 -0
  91. package/src/helpers/network/Encryption.tsx +179 -0
  92. package/src/helpers/network/network_manager.tsx +122 -0
  93. package/src/helpers/utils/Constants.tsx +10 -0
  94. package/src/helpers/utils/LibraryConstants.tsx +133 -0
  95. package/src/helpers/utils/deviceInfoManager.tsx +37 -0
  96. package/src/helpers/utils/headerManager.tsx +22 -0
  97. package/src/helpers/utils/themeManager.tsx +51 -0
  98. package/src/helpers/utils/webviewCallback.tsx +25 -0
  99. package/src/helpers/webview.tsx +410 -0
  100. package/src/index.tsx +5 -0
@@ -0,0 +1,179 @@
1
+ // Encryption.ts
2
+ import AsyncStorage from '@react-native-async-storage/async-storage';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ import * as base64js from 'base64-js';
5
+ import { ServiceNames } from '../ServiceNames';
6
+
7
+ import crypto from 'react-native-quick-crypto';
8
+ import { Buffer } from '@craftzdog/react-native-buffer';
9
+
10
+ const {
11
+ randomBytes,
12
+ createCipheriv,
13
+ createDecipheriv,
14
+ publicEncrypt,
15
+ constants,
16
+ createPublicKey,
17
+ } = crypto;
18
+
19
+ type WebsiteKey = { kid: string; public: string; expiry: string };
20
+
21
+ const KEY_WEB = 'KEY_WEB';
22
+ const KEY_WEB_EXPIRY = 'KEY_WEB_EXPIRY';
23
+ const GCM_NONCE_LEN = 12; // 12-byte IV
24
+ const GCM_TAG_LEN = 16; // 16-byte tag
25
+ const AES_KEY_LEN_BYTES = 32; // 256 bits
26
+
27
+ // --- small utils ---
28
+ const bytesToB64 = (u8: Uint8Array) => base64js.fromByteArray(u8);
29
+ const b64ToBytes = (b64: string) => base64js.toByteArray(b64);
30
+
31
+ // ---------- AES-256-GCM ----------
32
+
33
+ /** Generate random 32-byte AES key */
34
+ export function generateAESKey(): Uint8Array {
35
+ return new Uint8Array(randomBytes(AES_KEY_LEN_BYTES));
36
+ }
37
+
38
+ /** Export AES key bytes -> Base64 (for RSA input) */
39
+ export function exportAESKeyBase64(keyBytes: Uint8Array): string {
40
+ return bytesToB64(keyBytes);
41
+ }
42
+
43
+ /** Encrypt plaintext -> Base64( IV || ciphertext || tag ) */
44
+ export function encryptAES(plaintext: string, keyBytes: Uint8Array): string {
45
+ const iv = new Uint8Array(randomBytes(GCM_NONCE_LEN));
46
+ const cipher = createCipheriv(
47
+ 'aes-256-gcm',
48
+ Buffer.from(keyBytes),
49
+ Buffer.from(iv)
50
+ );
51
+
52
+ const ct1 = cipher.update(plaintext, 'utf8');
53
+ const ct2 = cipher.final();
54
+ const ciphertext = Buffer.concat([ct1, ct2]);
55
+
56
+ const tag = cipher.getAuthTag(); // 16 bytes
57
+
58
+ const out = new Uint8Array(iv.length + ciphertext.length + tag.length);
59
+ out.set(iv, 0);
60
+ out.set(ciphertext, iv.length);
61
+ out.set(tag, iv.length + ciphertext.length);
62
+
63
+ return bytesToB64(out);
64
+ }
65
+
66
+ /** Decrypt Base64( IV || ciphertext || tag ) -> plaintext */
67
+ export function decryptAES(b64Data: string, keyBytes: Uint8Array): string {
68
+ const data = b64ToBytes(b64Data);
69
+ if (data.length < GCM_NONCE_LEN + GCM_TAG_LEN + 1) {
70
+ throw new Error('Invalid GCM payload length');
71
+ }
72
+ const iv = data.slice(0, GCM_NONCE_LEN);
73
+ const tag = data.slice(data.length - GCM_TAG_LEN);
74
+ const ct = data.slice(GCM_NONCE_LEN, data.length - GCM_TAG_LEN);
75
+
76
+ const decipher = createDecipheriv(
77
+ 'aes-256-gcm',
78
+ Buffer.from(keyBytes),
79
+ Buffer.from(iv)
80
+ );
81
+ decipher.setAuthTag(Buffer.from(tag));
82
+
83
+ const pt1 = decipher.update(Buffer.from(ct));
84
+ const pt2 = decipher.final();
85
+ return Buffer.concat([pt1, pt2]).toString('utf8');
86
+ }
87
+
88
+ // ---------- RSA-OAEP (SHA-256) ----------
89
+
90
+ /** RSA-OAEP(SHA-256) encrypt UTF-8 bytes of Base64(AES key) -> Base64 ciphertext */
91
+ export function encryptAESKeyWithRSA(
92
+ aesKeyBase64: string,
93
+ publicKeyPem: string
94
+ ): string {
95
+ const buf = Buffer.from(aesKeyBase64, 'utf8');
96
+ const enc = publicEncrypt(
97
+ {
98
+ key: publicKeyPem,
99
+ padding: constants.RSA_PKCS1_OAEP_PADDING,
100
+ oaepHash: 'sha256',
101
+ },
102
+ buf
103
+ );
104
+ return enc.toString('base64');
105
+ }
106
+
107
+ // ---------- Website key fetch / cache ----------
108
+
109
+ export async function getWebsiteKey(): Promise<WebsiteKey> {
110
+ // const cachedJson = await AsyncStorage.getItem(KEY_WEB);
111
+ // const cachedExpiry = await AsyncStorage.getItem(KEY_WEB_EXPIRY);
112
+ // if (cachedJson && cachedExpiry) {
113
+ // try {
114
+ // if (new Date() < new Date(cachedExpiry)) {
115
+ // return JSON.parse(cachedJson) as WebsiteKey;
116
+ // }
117
+ // } catch {
118
+ // /* ignore */
119
+ // }
120
+ // }
121
+
122
+ // const txnId = uuidv4();
123
+ const resp = await fetch(ServiceNames.WEBSITE_KEYS, {
124
+ method: 'GET',
125
+ // headers: { 'X-Txn-ID': txnId },
126
+ });
127
+ if (!resp.ok) throw new Error(`Website keys fetch failed: ${resp.status}`);
128
+
129
+ const raw = await resp.json();
130
+ console.log('Website keys response:', raw);
131
+ let obj: any;
132
+ if (
133
+ raw &&
134
+ typeof raw === 'object' &&
135
+ !(
136
+ Object.prototype.hasOwnProperty.call(raw, 'kid') &&
137
+ (Object.prototype.hasOwnProperty.call(raw, 'public') ||
138
+ Object.prototype.hasOwnProperty.call(raw, 'public_key'))
139
+ )
140
+ ) {
141
+ const values = Object.values(raw);
142
+ if (!values.length || typeof values[0] !== 'object') {
143
+ throw new Error('Unexpected keyset response shape');
144
+ }
145
+ obj = values[0];
146
+ } else {
147
+ obj = raw;
148
+ }
149
+
150
+ const kid: string | undefined = obj.kid ?? obj.KID;
151
+ const publicKey: string | undefined = obj.public ?? obj.public_key;
152
+ const expiry: string | undefined = obj.expiry ?? obj.exp ?? obj.expiresAt;
153
+ if (!kid || !publicKey || !expiry)
154
+ throw new Error('Missing kid/public/expiry');
155
+
156
+ const normalized: WebsiteKey = { kid, public: publicKey, expiry };
157
+ await AsyncStorage.setItem(KEY_WEB, JSON.stringify(normalized));
158
+ await AsyncStorage.setItem(KEY_WEB_EXPIRY, expiry);
159
+ return normalized;
160
+ }
161
+
162
+ // ---------- Optional: one-liners ----------
163
+
164
+ export type HybridEnvelope = {
165
+ kid: string;
166
+ rsaWrappedAESKey: string; // Base64 RSA(OAEP) of Base64(AES key)
167
+ cipherData: string; // Base64( IV || ciphertext || tag )
168
+ };
169
+
170
+ export async function encryptHybrid(
171
+ plaintext: string
172
+ ): Promise<HybridEnvelope> {
173
+ const { kid, public: publicPem } = await getWebsiteKey();
174
+ const aesKey = generateAESKey();
175
+ const cipherData = encryptAES(plaintext, aesKey);
176
+ const aesKeyB64 = exportAESKeyBase64(aesKey);
177
+ const rsaWrappedAESKey = encryptAESKeyWithRSA(aesKeyB64, publicPem);
178
+ return { kid, rsaWrappedAESKey, cipherData };
179
+ }
@@ -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,10 @@
1
+ export const Constants = {
2
+
3
+ MANUFACTURER: "manufacturer",
4
+ MODEL: "model",
5
+ OS: "os",
6
+ OS_VERSION: "os_version",
7
+ APP_VERSION: "app_version",
8
+ DEVICE_UUID: "device_uuid",
9
+ PRIMARY_COLOR: "#3F51B5"
10
+ } as const;
@@ -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
+ }
@@ -0,0 +1,51 @@
1
+ import AsyncStorage from '@react-native-async-storage/async-storage';
2
+ import { Platform, StatusBar, type StatusBarStyle } from "react-native";
3
+ import { Constants } from "./Constants";
4
+ import { LibraryConstants } from './LibraryConstants';
5
+
6
+ interface Theme {
7
+ primaryColor: string;
8
+ }
9
+
10
+ export class ThemeManager {
11
+
12
+
13
+
14
+ constructor() {
15
+ }
16
+
17
+ static async savePrimaryColor(color: string): Promise<void> {
18
+ console.log("Saving primary color:", color);
19
+ try {
20
+ await AsyncStorage.setItem(LibraryConstants.primaryColor, color);
21
+ } catch (error) {
22
+ console.error("Error saving primary color:", error);
23
+ }
24
+ }
25
+
26
+ static async loadPrimaryColor(): Promise<string | null> {
27
+ try {
28
+ return await AsyncStorage.getItem(LibraryConstants.primaryColor);
29
+ }
30
+ catch (error) {
31
+ console.error("Error loading primary color:", error);
32
+ return null;
33
+ }
34
+ }
35
+ static getAppTheme(): Theme {
36
+ return {
37
+ primaryColor: Constants.PRIMARY_COLOR,
38
+ };
39
+ }
40
+
41
+ static configureStatusBar(): void {
42
+ StatusBar.setBackgroundColor(LibraryConstants.primaryColor);
43
+ StatusBar.setNetworkActivityIndicatorVisible(true);
44
+ const barStyle: StatusBarStyle = 'light-content';
45
+ StatusBar.setBarStyle(barStyle);
46
+
47
+ if (Platform.OS === 'android') {
48
+ StatusBar.setTranslucent(false);
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,25 @@
1
+ export enum WebViewCallbackType {
2
+
3
+ Logout = "logout",
4
+ Redirect = "redirect"
5
+ }
6
+
7
+ export class WebViewCallback {
8
+ type: WebViewCallbackType;
9
+ status?: string | null;
10
+
11
+ private constructor(type: WebViewCallbackType, status?: string | null) {
12
+ this.type = type;
13
+ this.status = status;
14
+ }
15
+
16
+ static logout(): WebViewCallback {
17
+ return new WebViewCallback(WebViewCallbackType.Logout);
18
+ }
19
+
20
+ static redirect(status?: string | null): WebViewCallback {
21
+ return new WebViewCallback(WebViewCallbackType.Redirect, status);
22
+ }
23
+ }
24
+
25
+ export type WebViewCallbackFunction = (callback: WebViewCallback) => void;