@explorins/pers-sdk-react-native 1.5.25 → 1.5.27
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/README.md +84 -73
- package/dist/hooks/useAnalytics.d.ts +1 -65
- package/dist/hooks/useAnalytics.d.ts.map +1 -1
- package/dist/hooks/useTransactions.d.ts +2 -3
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +735 -161
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +11 -0
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
- package/dist/providers/react-native-auth-provider.js +2 -2
- package/dist/providers/rn-dpop-provider.d.ts +19 -0
- package/dist/providers/rn-dpop-provider.d.ts.map +1 -0
- package/dist/providers/rn-dpop-provider.js +76 -0
- package/dist/storage/rn-secure-storage.d.ts +18 -0
- package/dist/storage/rn-secure-storage.d.ts.map +1 -0
- package/dist/storage/rn-secure-storage.js +102 -0
- package/package.json +6 -5
- package/src/hooks/useAnalytics.ts +4 -76
- package/src/hooks/useTransactions.ts +3 -3
- package/src/index.ts +24 -0
- package/src/providers/PersSDKProvider.tsx +13 -1
- package/src/providers/react-native-auth-provider.ts +2 -1
- package/src/providers/rn-dpop-provider.ts +88 -0
- package/src/storage/rn-secure-storage.ts +110 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import * as Keychain from 'react-native-keychain';
|
|
2
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
3
|
+
import {
|
|
4
|
+
TokenStorage,
|
|
5
|
+
DPOP_STORAGE_KEYS,
|
|
6
|
+
AUTH_STORAGE_KEYS
|
|
7
|
+
} from '@explorins/pers-sdk/core';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Secure Storage implementation for React Native
|
|
11
|
+
* Uses Keychain/Keystore for sensitive data and AsyncStorage for non-sensitive data.
|
|
12
|
+
*/
|
|
13
|
+
export class ReactNativeSecureStorage implements TokenStorage {
|
|
14
|
+
// Set to false because Keychain stores strings, so we need extractable (serializable) keys
|
|
15
|
+
readonly supportsObjects = false;
|
|
16
|
+
|
|
17
|
+
// Define which keys MUST go to secure hardware storage
|
|
18
|
+
private readonly SECURE_KEYS = new Set([
|
|
19
|
+
DPOP_STORAGE_KEYS.PRIVATE,
|
|
20
|
+
AUTH_STORAGE_KEYS.ACCESS_TOKEN,
|
|
21
|
+
AUTH_STORAGE_KEYS.REFRESH_TOKEN,
|
|
22
|
+
AUTH_STORAGE_KEYS.PROVIDER_TOKEN
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
constructor(private keyPrefix: string = 'pers_tokens_') {}
|
|
26
|
+
|
|
27
|
+
async set(key: string, value: unknown): Promise<void> {
|
|
28
|
+
const prefixedKey = this.getKeyName(key);
|
|
29
|
+
const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
|
|
30
|
+
|
|
31
|
+
// Cast key to any to bypass strict literal type checking of the Set.has method
|
|
32
|
+
// In runtime, 'key' is just a string, so this is safe.
|
|
33
|
+
if (this.SECURE_KEYS.has(key as any)) {
|
|
34
|
+
// Store in Keychain/Keystore
|
|
35
|
+
// Service name acts as the key identifier in simple usage
|
|
36
|
+
await Keychain.setGenericPassword(prefixedKey, stringValue, { service: prefixedKey });
|
|
37
|
+
} else {
|
|
38
|
+
// Store standard config/metadata in AsyncStorage
|
|
39
|
+
await AsyncStorage.setItem(prefixedKey, stringValue);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async get(key: string): Promise<unknown | null> {
|
|
44
|
+
const prefixedKey = this.getKeyName(key);
|
|
45
|
+
|
|
46
|
+
if (this.SECURE_KEYS.has(key as any)) {
|
|
47
|
+
try {
|
|
48
|
+
const credentials = await Keychain.getGenericPassword({ service: prefixedKey });
|
|
49
|
+
if (credentials) {
|
|
50
|
+
return this.tryParse(credentials.password);
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.warn(`[ReactNativeSecureStorage] Failed to access keychain for ${key}`, e);
|
|
55
|
+
return null; // Key not found or access denied
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
try {
|
|
59
|
+
const val = await AsyncStorage.getItem(prefixedKey);
|
|
60
|
+
return val ? this.tryParse(val) : null;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
console.warn(`[ReactNativeSecureStorage] Failed to access AsyncStorage for ${key}`, e);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async remove(key: string): Promise<void> {
|
|
69
|
+
const prefixedKey = this.getKeyName(key);
|
|
70
|
+
|
|
71
|
+
if (this.SECURE_KEYS.has(key as any)) {
|
|
72
|
+
await Keychain.resetGenericPassword({ service: prefixedKey });
|
|
73
|
+
} else {
|
|
74
|
+
await AsyncStorage.removeItem(prefixedKey);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async clear(): Promise<void> {
|
|
79
|
+
// Clear all known secure keys
|
|
80
|
+
for (const key of this.SECURE_KEYS) {
|
|
81
|
+
await Keychain.resetGenericPassword({ service: this.getKeyName(key) });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Clear AsyncStorage keys related to PERS
|
|
85
|
+
try {
|
|
86
|
+
const allKeys = await AsyncStorage.getAllKeys();
|
|
87
|
+
const ourKeys = allKeys.filter(k => k.startsWith(this.keyPrefix));
|
|
88
|
+
if (ourKeys.length > 0) {
|
|
89
|
+
await AsyncStorage.multiRemove(ourKeys);
|
|
90
|
+
}
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.warn('[ReactNativeSecureStorage] Failed to clear AsyncStorage', e);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private getKeyName(key: string): string {
|
|
97
|
+
// For Keychain, we might want to avoid prefixes if we want to share across apps,
|
|
98
|
+
// but for simple isolation, prefix is fine to avoid collisions if multiple instances exist.
|
|
99
|
+
// However, Keychain services are global to the app bundle ID usually.
|
|
100
|
+
return `${this.keyPrefix}${key}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private tryParse(val: string): unknown {
|
|
104
|
+
try {
|
|
105
|
+
return JSON.parse(val);
|
|
106
|
+
} catch {
|
|
107
|
+
return val;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|