react-native-security-suite 0.1.2 → 0.3.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 (38) hide show
  1. package/LICENSE +1 -2
  2. package/README.md +40 -3
  3. package/android/build.gradle +85 -43
  4. package/android/gradle.properties +5 -0
  5. package/android/src/main/AndroidManifest.xml +1 -3
  6. package/android/src/main/AndroidManifestDeprecated.xml +3 -0
  7. package/android/src/main/java/com/securitysuite/SecuritySuiteModule.java +202 -0
  8. package/android/src/main/java/com/securitysuite/SecuritySuitePackage.java +28 -0
  9. package/android/src/main/java/com/securitysuite/StorageEncryption.java +52 -0
  10. package/ios/DataHashingMethods.swift +196 -0
  11. package/ios/SecuritySuite-Bridging-Header.h +1 -0
  12. package/ios/SecuritySuite.mm +26 -0
  13. package/ios/SecuritySuite.swift +129 -0
  14. package/ios/SecuritySuite.xcodeproj/project.pbxproj +13 -17
  15. package/ios/SecuritySuite.xcodeproj/project.xcworkspace/contents.xcworkspacedata +4 -0
  16. package/ios/SecuritySuite.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  17. package/ios/SecuritySuite.xcodeproj/project.xcworkspace/xcuserdata/mohammadnavabi.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  18. package/ios/SecuritySuite.xcodeproj/xcuserdata/mohammadnavabi.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  19. package/ios/StorageEncryption.swift +81 -0
  20. package/lib/commonjs/helpers.js +16 -0
  21. package/lib/commonjs/helpers.js.map +1 -0
  22. package/lib/commonjs/index.js +158 -6
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/module/helpers.js +9 -0
  25. package/lib/module/helpers.js.map +1 -0
  26. package/lib/module/index.js +147 -1
  27. package/lib/module/index.js.map +1 -1
  28. package/lib/typescript/helpers.d.ts +2 -0
  29. package/lib/typescript/helpers.d.ts.map +1 -0
  30. package/lib/typescript/index.d.ts +20 -0
  31. package/lib/typescript/index.d.ts.map +1 -0
  32. package/package.json +54 -33
  33. package/react-native-security-suite.podspec +18 -2
  34. package/src/helpers.ts +8 -0
  35. package/src/index.tsx +203 -3
  36. package/android/src/main/java/com/reactnativesecuritysuite/SecuritySuiteModule.java +0 -38
  37. package/android/src/main/java/com/reactnativesecuritysuite/SecuritySuitePackage.java +0 -28
  38. package/ios/SecuritySuite.m +0 -12
package/src/index.tsx CHANGED
@@ -1,4 +1,7 @@
1
1
  import { NativeModules, Platform } from 'react-native';
2
+ import AsyncStorage from '@react-native-async-storage/async-storage';
3
+ import _ from 'lodash';
4
+ import { isJsonString } from './helpers';
2
5
 
3
6
  const LINKING_ERROR =
4
7
  `The package 'react-native-security-suite' doesn't seem to be linked. Make sure: \n\n` +
@@ -15,10 +18,207 @@ const SecuritySuite = NativeModules.SecuritySuite
15
18
  throw new Error(LINKING_ERROR);
16
19
  },
17
20
  }
18
- );
19
-
21
+ );
22
+
23
+ export const getPublicKey = (): Promise<string> => SecuritySuite.getPublicKey();
24
+
25
+ export const getSharedKey = (serverPublicKey: string): Promise<string> =>
26
+ SecuritySuite.getSharedKey(serverPublicKey);
27
+
28
+ export const encryptBySharedKey = (input: string): Promise<string> =>
29
+ input && typeof input === 'string' ? SecuritySuite.encrypt(input) : '';
30
+
31
+ export const decryptBySharedKey = (input: string) =>
32
+ input && typeof input === 'string' ? SecuritySuite.decrypt(input) : '';
33
+
34
+ export const getDeviceId = (): Promise<string> =>
35
+ new Promise((resolve: any, reject: any) => {
36
+ SecuritySuite.getDeviceId((result: string | null, error: string | null) => {
37
+ if (error !== null) reject(error);
38
+ else resolve(result);
39
+ });
40
+ });
41
+
42
+ export const encrypt = (
43
+ input: string,
44
+ hardEncryption = true,
45
+ secretKey = null
46
+ ): Promise<string> =>
47
+ new Promise((resolve: any, reject: any) => {
48
+ if (!input) resolve(input);
49
+
50
+ SecuritySuite.storageEncrypt(
51
+ input,
52
+ secretKey,
53
+ hardEncryption,
54
+ (result: string | null, error: string | null) => {
55
+ if (error !== null) reject(error);
56
+ else resolve(result);
57
+ }
58
+ );
59
+ });
60
+
61
+ export const decrypt = (
62
+ input: string,
63
+ hardEncryption = true,
64
+ secretKey = null
65
+ ): Promise<string> =>
66
+ new Promise((resolve: any, reject: any) => {
67
+ if (!input) resolve(input);
68
+
69
+ SecuritySuite.storageDecrypt(
70
+ input,
71
+ secretKey,
72
+ hardEncryption,
73
+ (result: string | null, error: string | null) => {
74
+ if (error !== null) reject(error);
75
+ else resolve(result);
76
+ }
77
+ );
78
+ });
79
+
80
+ export const SecureStorage = {
81
+ setItem: async (key: string, value: string) => {
82
+ try {
83
+ const encryptedKey = await encrypt(key, false);
84
+ const encryptedValue = await encrypt(value);
85
+ return AsyncStorage.setItem(encryptedKey, encryptedValue);
86
+ } catch (e) {
87
+ return e;
88
+ }
89
+ },
90
+ getItem: async (key: string) => {
91
+ try {
92
+ const encryptedKey = await encrypt(key, false);
93
+ const encryptedData = await AsyncStorage.getItem(encryptedKey);
94
+ return decrypt(encryptedData ?? '');
95
+ } catch (e) {
96
+ return e;
97
+ }
98
+ },
99
+ mergeItem: async (key: string, value: string) => {
100
+ try {
101
+ const encryptedKey = await encrypt(key, false);
102
+ const encryptedData = await AsyncStorage.getItem(encryptedKey);
103
+ const data = await decrypt(encryptedData ?? '');
104
+ if (!isJsonString(data) || !isJsonString(value)) return null;
105
+ const mergedData = await JSON.stringify(
106
+ _.merge(JSON.parse(data), JSON.parse(value))
107
+ );
108
+ const encryptedValue = await encrypt(mergedData);
109
+ return AsyncStorage.setItem(encryptedKey, encryptedValue);
110
+ } catch (e) {
111
+ return e;
112
+ }
113
+ },
114
+ removeItem: async (key: string) => {
115
+ try {
116
+ const encryptedKey = await encrypt(key, false);
117
+ return AsyncStorage.removeItem(encryptedKey);
118
+ } catch (e) {
119
+ return e;
120
+ }
121
+ },
122
+ getAllKeys: async () => {
123
+ try {
124
+ const encryptedKeys = await AsyncStorage.getAllKeys();
125
+ return await Promise.all(
126
+ encryptedKeys.map(async (item: string): Promise<string> => {
127
+ const decryptedKey = await decrypt(item, false);
128
+ return decryptedKey ? decryptedKey : item;
129
+ })
130
+ );
131
+ } catch (e) {
132
+ return e;
133
+ }
134
+ },
135
+ multiSet: async (
136
+ keyValuePairs: Array<Array<string>>
137
+ ): Promise<void | string[][]> => {
138
+ try {
139
+ const encryptedKeyValuePairs: any = await Promise.all(
140
+ keyValuePairs.map(async (item: Array<string>) => {
141
+ if (item.length === 2 && item[0] && item[1]) {
142
+ const encryptedKey = await encrypt(item[0], false);
143
+ const encryptedValue = await encrypt(item[1]);
144
+ return [encryptedKey, encryptedValue];
145
+ }
146
+
147
+ return null;
148
+ })
149
+ );
150
+ AsyncStorage.multiSet(encryptedKeyValuePairs);
151
+ } catch (e) {
152
+ console.error('multiSet error: ', e);
153
+ }
154
+ },
155
+ multiGet: async (keys: Array<string>) => {
156
+ try {
157
+ if (!Array.isArray(keys)) return null;
158
+ const encryptedKeys = await Promise.all(
159
+ keys.map(
160
+ async (item: string): Promise<string> => await encrypt(item, false)
161
+ )
162
+ );
163
+ const encryptedItems = await AsyncStorage.multiGet(encryptedKeys);
164
+ return await Promise.all(
165
+ encryptedItems && encryptedItems.length
166
+ ? encryptedItems.map(async (item: any): Promise<string[]> => {
167
+ const decryptedKey = await decrypt(item[0], false);
168
+ const decryptedalue = await decrypt(item[1]);
169
+ return [decryptedKey, decryptedalue];
170
+ })
171
+ : []
172
+ );
173
+ } catch (e) {
174
+ return e;
175
+ }
176
+ },
177
+ multiMerge: async (keyValuePairs: Array<Array<string>>) => {
178
+ try {
179
+ return keyValuePairs.map(async (item: Array<string>) => {
180
+ if (item.length === 2 && item[0] && item[1]) {
181
+ const encryptedKey = await encrypt(item[0], false);
182
+ const encryptedData = await AsyncStorage.getItem(item[0]);
183
+ const data = await decrypt(encryptedData ?? '');
184
+ if (!isJsonString(data) || !isJsonString(item[1])) return null;
185
+ const mergedData = await JSON.stringify(
186
+ _.merge(JSON.parse(data), JSON.parse(item[1]))
187
+ );
188
+ const encryptedValue = await encrypt(mergedData, false);
189
+ return AsyncStorage.setItem(encryptedKey, encryptedValue);
190
+ }
191
+
192
+ return null;
193
+ });
194
+ } catch (e) {
195
+ return e;
196
+ }
197
+ },
198
+ multiRemove: async (keys: Array<string>) => {
199
+ try {
200
+ if (!Array.isArray(keys)) return keys;
201
+ const encryptedKeys = await Promise.all(
202
+ keys.map(
203
+ async (item: string): Promise<string> => await encrypt(item, false)
204
+ )
205
+ );
206
+ return AsyncStorage.multiRemove(encryptedKeys);
207
+ } catch (e) {
208
+ return e;
209
+ }
210
+ },
211
+ clear: async () => {
212
+ try {
213
+ return AsyncStorage.clear();
214
+ } catch (e) {
215
+ return e;
216
+ }
217
+ },
218
+ };
219
+
20
220
  export function deviceHasSecurityRisk(): Promise<boolean> {
21
221
  return SecuritySuite.deviceHasSecurityRisk();
22
222
  }
23
223
 
24
- export default SecuritySuite;
224
+ export default SecuritySuite;
@@ -1,38 +0,0 @@
1
- package com.reactnativesecuritysuite;
2
-
3
- import androidx.annotation.NonNull;
4
-
5
- import com.facebook.react.bridge.Promise;
6
- import com.facebook.react.bridge.ReactApplicationContext;
7
- import com.facebook.react.bridge.ReactContextBaseJavaModule;
8
- import com.facebook.react.bridge.ReactMethod;
9
- import com.facebook.react.module.annotations.ReactModule;
10
- import com.scottyab.rootbeer.RootBeer;
11
-
12
- @ReactModule(name = SecuritySuiteModule.NAME)
13
- public class SecuritySuiteModule extends ReactContextBaseJavaModule {
14
- public static final String NAME = "SecuritySuite";
15
- private ReactApplicationContext context;
16
-
17
- public SecuritySuiteModule(ReactApplicationContext reactContext) {
18
- super(reactContext);
19
- context = reactContext;
20
- }
21
-
22
- @Override
23
- @NonNull
24
- public String getName() {
25
- return NAME;
26
- }
27
-
28
-
29
- // Example method
30
- // See https://reactnative.dev/docs/native-modules-android
31
- @ReactMethod
32
- public void deviceHasSecurityRisk(Promise promise) {
33
- RootBeer rootBeer = new RootBeer(context);
34
- promise.resolve(rootBeer.isRooted());
35
- }
36
-
37
- public static native int nativeMultiply(int a, int b);
38
- }
@@ -1,28 +0,0 @@
1
- package com.reactnativesecuritysuite;
2
-
3
- import androidx.annotation.NonNull;
4
-
5
- import com.facebook.react.ReactPackage;
6
- import com.facebook.react.bridge.NativeModule;
7
- import com.facebook.react.bridge.ReactApplicationContext;
8
- import com.facebook.react.uimanager.ViewManager;
9
-
10
- import java.util.ArrayList;
11
- import java.util.Collections;
12
- import java.util.List;
13
-
14
- public class SecuritySuitePackage implements ReactPackage {
15
- @NonNull
16
- @Override
17
- public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
- List<NativeModule> modules = new ArrayList<>();
19
- modules.add(new SecuritySuiteModule(reactContext));
20
- return modules;
21
- }
22
-
23
- @NonNull
24
- @Override
25
- public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
26
- return Collections.emptyList();
27
- }
28
- }
@@ -1,12 +0,0 @@
1
- #import <React/RCTBridgeModule.h>
2
-
3
- @interface RCT_EXTERN_MODULE(SecuritySuite, NSObject)
4
-
5
- RCT_EXTERN_METHOD(deviceHasSecurityRisk:(RCTPromiseResolveBlock)resolve withRejecter:(RCTPromiseRejectBlock)reject)
6
-
7
- + (BOOL)requiresMainQueueSetup
8
- {
9
- return NO;
10
- }
11
-
12
- @end