react-native-nitro-storage 0.7.0 → 0.9.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/CHANGELOG.md +54 -0
- package/README.md +89 -22
- package/SECURITY.md +2 -2
- package/cpp/bindings/HybridStorage.cpp +5 -12
- package/cpp/bindings/HybridStorage.hpp +1 -1
- package/docs/api-reference.md +11 -1
- package/docs/batch-transactions-migrations.md +8 -2
- package/docs/benchmarks.md +19 -15
- package/docs/web-backends.md +18 -1
- package/ios/IOSStorageAdapterCpp.mm +162 -17
- package/lib/commonjs/capabilities.js +26 -0
- package/lib/commonjs/capabilities.js.map +1 -0
- package/lib/commonjs/core/durability.js +137 -0
- package/lib/commonjs/core/durability.js.map +1 -0
- package/lib/commonjs/core/metrics.js +91 -0
- package/lib/commonjs/core/metrics.js.map +1 -0
- package/lib/commonjs/index.js +47 -22
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +118 -66
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/indexeddb-backend.js +73 -23
- package/lib/commonjs/indexeddb-backend.js.map +1 -1
- package/lib/commonjs/internal.js +27 -4
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/commonjs/shared.js +2 -2
- package/lib/commonjs/shared.js.map +1 -1
- package/lib/commonjs/storage-core.js +224 -237
- package/lib/commonjs/storage-core.js.map +1 -1
- package/lib/commonjs/storage-events.js.map +1 -1
- package/lib/commonjs/storage-platform.js +6 -0
- package/lib/commonjs/storage-platform.js.map +1 -0
- package/lib/commonjs/storage-runtime.js +3 -21
- package/lib/commonjs/storage-runtime.js.map +1 -1
- package/lib/commonjs/testing.js +19 -4
- package/lib/commonjs/testing.js.map +1 -1
- package/lib/commonjs/web-backend-contract.js +27 -0
- package/lib/commonjs/web-backend-contract.js.map +1 -0
- package/lib/module/capabilities.js +21 -0
- package/lib/module/capabilities.js.map +1 -0
- package/lib/module/core/durability.js +133 -0
- package/lib/module/core/durability.js.map +1 -0
- package/lib/module/core/metrics.js +87 -0
- package/lib/module/core/metrics.js.map +1 -0
- package/lib/module/index.js +48 -23
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +103 -64
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/indexeddb-backend.js +73 -23
- package/lib/module/indexeddb-backend.js.map +1 -1
- package/lib/module/internal.js +24 -3
- package/lib/module/internal.js.map +1 -1
- package/lib/module/shared.js +2 -2
- package/lib/module/shared.js.map +1 -1
- package/lib/module/storage-core.js +225 -238
- package/lib/module/storage-core.js.map +1 -1
- package/lib/module/storage-events.js.map +1 -1
- package/lib/module/storage-platform.js +4 -0
- package/lib/module/storage-platform.js.map +1 -0
- package/lib/module/storage-runtime.js +3 -21
- package/lib/module/storage-runtime.js.map +1 -1
- package/lib/module/testing.js +5 -3
- package/lib/module/testing.js.map +1 -1
- package/lib/module/web-backend-contract.js +22 -0
- package/lib/module/web-backend-contract.js.map +1 -0
- package/lib/typescript/capabilities.d.ts +11 -0
- package/lib/typescript/capabilities.d.ts.map +1 -0
- package/lib/typescript/core/durability.d.ts +27 -0
- package/lib/typescript/core/durability.d.ts.map +1 -0
- package/lib/typescript/core/metrics.d.ts +12 -0
- package/lib/typescript/core/metrics.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +5 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.web.d.ts +8 -4
- package/lib/typescript/index.web.d.ts.map +1 -1
- package/lib/typescript/indexeddb-backend.d.ts.map +1 -1
- package/lib/typescript/internal.d.ts +3 -0
- package/lib/typescript/internal.d.ts.map +1 -1
- package/lib/typescript/shared.d.ts +2 -1
- package/lib/typescript/shared.d.ts.map +1 -1
- package/lib/typescript/storage-core.d.ts +6 -6
- package/lib/typescript/storage-core.d.ts.map +1 -1
- package/lib/typescript/storage-events.d.ts +2 -2
- package/lib/typescript/storage-events.d.ts.map +1 -1
- package/lib/typescript/storage-platform.d.ts +12 -0
- package/lib/typescript/storage-platform.d.ts.map +1 -0
- package/lib/typescript/storage-runtime.d.ts.map +1 -1
- package/lib/typescript/testing.d.ts +5 -1
- package/lib/typescript/testing.d.ts.map +1 -1
- package/lib/typescript/web-backend-contract.d.ts +10 -0
- package/lib/typescript/web-backend-contract.d.ts.map +1 -0
- package/lib/typescript/web-storage-backend.d.ts +1 -1
- package/lib/typescript/web-storage-backend.d.ts.map +1 -1
- package/nitrogen/generated/shared/c++/HybridStorageSpec.hpp +1 -1
- package/package.json +4 -3
- package/react-native-nitro-storage.podspec +3 -1
- package/src/capabilities.ts +36 -0
- package/src/core/durability.ts +170 -0
- package/src/core/metrics.ts +133 -0
- package/src/index.ts +66 -40
- package/src/index.web.ts +158 -86
- package/src/indexeddb-backend.ts +91 -20
- package/src/internal.ts +50 -4
- package/src/shared.ts +7 -6
- package/src/storage-core.ts +327 -292
- package/src/storage-events.ts +2 -1
- package/src/storage-platform.ts +16 -0
- package/src/storage-runtime.ts +13 -47
- package/src/testing.ts +14 -7
- package/src/web-backend-contract.ts +34 -0
- package/src/web-storage-backend.ts +1 -1
|
@@ -8,6 +8,8 @@ namespace NitroStorage {
|
|
|
8
8
|
static NSString* const kKeychainService = @"com.nitrostorage.keychain";
|
|
9
9
|
static NSString* const kBiometricKeychainService = @"com.nitrostorage.biometric";
|
|
10
10
|
static NSString* const kDiskSuiteName = @"com.nitrostorage.disk";
|
|
11
|
+
static NSString* const kLegacyDiskKeysRegistryKey =
|
|
12
|
+
@"__nitro_storage_legacy_disk_keys__";
|
|
11
13
|
|
|
12
14
|
static std::runtime_error taggedStorageError(const char* code, const std::string& message) {
|
|
13
15
|
return std::runtime_error(
|
|
@@ -15,11 +17,69 @@ static std::runtime_error taggedStorageError(const char* code, const std::string
|
|
|
15
17
|
);
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
// Unknown keychain statuses are surfaced untagged (matching Android's
|
|
21
|
+
// cause-based wrapping), except errSecNotAvailable which means the keychain
|
|
22
|
+
// is unavailable until the device is first unlocked — a locked condition.
|
|
23
|
+
static std::runtime_error keychainStatusError(OSStatus status, const std::string& operation) {
|
|
24
|
+
if (status == errSecNotAvailable) {
|
|
25
|
+
return taggedStorageError(
|
|
26
|
+
"keychain_locked",
|
|
27
|
+
std::string("NitroStorage: ") + operation + " failed: keychain is unavailable until the device is unlocked (errSecNotAvailable)."
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
return std::runtime_error(
|
|
31
|
+
std::string("NitroStorage: ") + operation + " failed with status " + std::to_string(status)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
18
35
|
static NSUserDefaults* NitroDiskDefaults() {
|
|
19
36
|
static NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:kDiskSuiteName];
|
|
20
37
|
return defaults ?: [NSUserDefaults standardUserDefaults];
|
|
21
38
|
}
|
|
22
39
|
|
|
40
|
+
// --- Legacy disk key registry ---
|
|
41
|
+
// Versions before the suite domain stored Disk values in standardUserDefaults.
|
|
42
|
+
// The registry records legacy keys observed through the storage API so that
|
|
43
|
+
// clearDisk can remove both stores and deleted legacy values cannot reappear.
|
|
44
|
+
// Only keys observed through the storage API are ever registered; the host
|
|
45
|
+
// app's own standard defaults keys are never enumerated or touched.
|
|
46
|
+
|
|
47
|
+
static NSSet<NSString*>* registeredLegacyDiskKeys() {
|
|
48
|
+
NSArray* stored = [NitroDiskDefaults() stringArrayForKey:kLegacyDiskKeysRegistryKey];
|
|
49
|
+
return stored ? [NSSet setWithArray:stored] : [NSSet set];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static void persistLegacyDiskKeys(NSSet<NSString*>* keys) {
|
|
53
|
+
if (keys.count == 0) {
|
|
54
|
+
[NitroDiskDefaults() removeObjectForKey:kLegacyDiskKeysRegistryKey];
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
[NitroDiskDefaults() setObject:[keys allObjects] forKey:kLegacyDiskKeysRegistryKey];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static void registerLegacyDiskKey(NSString* key) {
|
|
61
|
+
NSMutableSet* keys = [registeredLegacyDiskKeys() mutableCopy];
|
|
62
|
+
[keys addObject:key];
|
|
63
|
+
persistLegacyDiskKeys(keys);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static void unregisterLegacyDiskKeys(NSArray<NSString*>* keys) {
|
|
67
|
+
if (keys.count == 0) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
NSMutableSet* registered = [registeredLegacyDiskKeys() mutableCopy];
|
|
71
|
+
BOOL changed = NO;
|
|
72
|
+
for (NSString* key in keys) {
|
|
73
|
+
if ([registered containsObject:key]) {
|
|
74
|
+
[registered removeObject:key];
|
|
75
|
+
changed = YES;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (changed) {
|
|
79
|
+
persistLegacyDiskKeys(registered);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
23
83
|
// Prevents the Keychain from showing auth UI. On iOS 14+ kSecUseAuthenticationUIFail is
|
|
24
84
|
// deprecated; the correct replacement is an LAContext with interactionNotAllowed = YES.
|
|
25
85
|
static void disableKeychainInteraction(NSMutableDictionary* query) {
|
|
@@ -52,6 +112,7 @@ void IOSStorageAdapterCpp::setDisk(const std::string& key, const std::string& va
|
|
|
52
112
|
NSUserDefaults* standard = [NSUserDefaults standardUserDefaults];
|
|
53
113
|
if ([standard objectForKey:nsKey] != nil) {
|
|
54
114
|
[standard removeObjectForKey:nsKey];
|
|
115
|
+
unregisterLegacyDiskKeys(@[nsKey]);
|
|
55
116
|
}
|
|
56
117
|
}
|
|
57
118
|
|
|
@@ -66,6 +127,7 @@ std::optional<std::string> IOSStorageAdapterCpp::getDisk(const std::string& key)
|
|
|
66
127
|
if (legacyValue) {
|
|
67
128
|
[defaults setObject:legacyValue forKey:nsKey];
|
|
68
129
|
[legacyDefaults removeObjectForKey:nsKey];
|
|
130
|
+
unregisterLegacyDiskKeys(@[nsKey]);
|
|
69
131
|
result = legacyValue;
|
|
70
132
|
}
|
|
71
133
|
}
|
|
@@ -81,22 +143,40 @@ void IOSStorageAdapterCpp::deleteDisk(const std::string& key) {
|
|
|
81
143
|
if ([standard objectForKey:nsKey] != nil) {
|
|
82
144
|
[standard removeObjectForKey:nsKey];
|
|
83
145
|
}
|
|
146
|
+
unregisterLegacyDiskKeys(@[nsKey]);
|
|
84
147
|
}
|
|
85
148
|
|
|
86
149
|
bool IOSStorageAdapterCpp::hasDisk(const std::string& key) {
|
|
87
150
|
NSString* nsKey = [NSString stringWithUTF8String:key.c_str()];
|
|
88
151
|
if ([NitroDiskDefaults() objectForKey:nsKey] != nil) return true;
|
|
89
152
|
// Check legacy standardUserDefaults for un-migrated keys
|
|
90
|
-
|
|
153
|
+
if ([[NSUserDefaults standardUserDefaults] stringForKey:nsKey] != nil) {
|
|
154
|
+
registerLegacyDiskKey(nsKey);
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
91
158
|
}
|
|
92
159
|
|
|
93
160
|
std::vector<std::string> IOSStorageAdapterCpp::getAllKeysDisk() {
|
|
94
161
|
NSUserDefaults* defaults = NitroDiskDefaults();
|
|
95
162
|
NSDictionary<NSString*, id>* entries = [defaults persistentDomainForName:kDiskSuiteName] ?: @{};
|
|
96
|
-
std::
|
|
97
|
-
keys.reserve(entries.count);
|
|
163
|
+
std::unordered_set<std::string> combined;
|
|
98
164
|
for (NSString* key in entries) {
|
|
99
|
-
|
|
165
|
+
if (![key isEqualToString:kLegacyDiskKeysRegistryKey]) {
|
|
166
|
+
combined.insert(std::string([key UTF8String]));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Only keys observed through the storage API are registered legacy keys;
|
|
170
|
+
// arbitrary host-app standard defaults keys are never enumerated.
|
|
171
|
+
for (NSString* key in [registeredLegacyDiskKeys() allObjects]) {
|
|
172
|
+
if (entries[key] == nil && ![key isEqualToString:kLegacyDiskKeysRegistryKey]) {
|
|
173
|
+
combined.insert(std::string([key UTF8String]));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
std::vector<std::string> keys;
|
|
177
|
+
keys.reserve(combined.size());
|
|
178
|
+
for (const auto& key : combined) {
|
|
179
|
+
keys.push_back(key);
|
|
100
180
|
}
|
|
101
181
|
return keys;
|
|
102
182
|
}
|
|
@@ -114,8 +194,7 @@ std::vector<std::string> IOSStorageAdapterCpp::getKeysByPrefixDisk(const std::st
|
|
|
114
194
|
}
|
|
115
195
|
|
|
116
196
|
size_t IOSStorageAdapterCpp::sizeDisk() {
|
|
117
|
-
|
|
118
|
-
return entries.count;
|
|
197
|
+
return getAllKeysDisk().size();
|
|
119
198
|
}
|
|
120
199
|
|
|
121
200
|
void IOSStorageAdapterCpp::setDiskBatch(
|
|
@@ -136,6 +215,7 @@ void IOSStorageAdapterCpp::setDiskBatch(
|
|
|
136
215
|
for (NSString* key in legacyKeysToRemove) {
|
|
137
216
|
[standard removeObjectForKey:key];
|
|
138
217
|
}
|
|
218
|
+
unregisterLegacyDiskKeys(legacyKeysToRemove);
|
|
139
219
|
}
|
|
140
220
|
|
|
141
221
|
std::vector<std::optional<std::string>> IOSStorageAdapterCpp::getDiskBatch(
|
|
@@ -158,9 +238,26 @@ void IOSStorageAdapterCpp::deleteDiskBatch(const std::vector<std::string>& keys)
|
|
|
158
238
|
void IOSStorageAdapterCpp::clearDisk() {
|
|
159
239
|
NSUserDefaults* defaults = NitroDiskDefaults();
|
|
160
240
|
NSDictionary<NSString*, id>* entries = [defaults persistentDomainForName:kDiskSuiteName] ?: @{};
|
|
241
|
+
// Capture the registry before clearing the suite domain, which removes it.
|
|
242
|
+
NSMutableSet* legacyKeys = [registeredLegacyDiskKeys() mutableCopy];
|
|
161
243
|
for (NSString* key in entries) {
|
|
162
244
|
[defaults removeObjectForKey:key];
|
|
163
245
|
}
|
|
246
|
+
// Clear the standard-defaults copies of every storage-owned key so legacy
|
|
247
|
+
// values deleted here cannot reappear through the read-time migration path.
|
|
248
|
+
NSUserDefaults* standard = [NSUserDefaults standardUserDefaults];
|
|
249
|
+
for (NSString* key in entries) {
|
|
250
|
+
if ([standard objectForKey:key] != nil) {
|
|
251
|
+
[standard removeObjectForKey:key];
|
|
252
|
+
[legacyKeys removeObject:key];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
for (NSString* key in legacyKeys) {
|
|
256
|
+
if ([standard objectForKey:key] != nil) {
|
|
257
|
+
[standard removeObjectForKey:key];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
[defaults removeObjectForKey:kLegacyDiskKeysRegistryKey];
|
|
164
261
|
}
|
|
165
262
|
|
|
166
263
|
// --- Secure (Keychain) ---
|
|
@@ -228,9 +325,7 @@ static void setSecureValue(
|
|
|
228
325
|
"The item is not accessible until the device is unlocked."
|
|
229
326
|
);
|
|
230
327
|
}
|
|
231
|
-
throw
|
|
232
|
-
"NitroStorage: Secure set failed with status " + std::to_string(addStatus)
|
|
233
|
-
);
|
|
328
|
+
throw keychainStatusError(addStatus, "Secure set");
|
|
234
329
|
}
|
|
235
330
|
|
|
236
331
|
if (status == errSecInteractionNotAllowed) {
|
|
@@ -240,9 +335,7 @@ static void setSecureValue(
|
|
|
240
335
|
"The item is not accessible until the device is unlocked."
|
|
241
336
|
);
|
|
242
337
|
}
|
|
243
|
-
throw
|
|
244
|
-
"NitroStorage: Secure set failed with status " + std::to_string(status)
|
|
245
|
-
);
|
|
338
|
+
throw keychainStatusError(status, "Secure set");
|
|
246
339
|
}
|
|
247
340
|
|
|
248
341
|
static std::optional<std::string> getSecureValue(NSString* nsKey, NSString* group) {
|
|
@@ -290,6 +383,20 @@ static void deleteSecureValue(NSString* nsKey, NSString* group) {
|
|
|
290
383
|
}
|
|
291
384
|
}
|
|
292
385
|
|
|
386
|
+
// Deletes only the plain (non-biometric) keychain copy. Promotion to biometric
|
|
387
|
+
// storage must remove the plain copy so stale plain reads cannot resurrect it.
|
|
388
|
+
static void deletePlainSecureValue(NSString* nsKey, NSString* group) {
|
|
389
|
+
NSMutableDictionary* secureQuery = baseKeychainQuery(nsKey, kKeychainService, group);
|
|
390
|
+
OSStatus secureStatus = SecItemDelete((__bridge CFDictionaryRef)secureQuery);
|
|
391
|
+
if (secureStatus == errSecInteractionNotAllowed) {
|
|
392
|
+
throw taggedStorageError(
|
|
393
|
+
"keychain_locked",
|
|
394
|
+
"NitroStorage: Keychain is locked (errSecInteractionNotAllowed). "
|
|
395
|
+
"The item is not accessible until the device is unlocked."
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
293
400
|
static std::vector<std::string> keychainAccountsForService(NSString* service, NSString* accessGroup) {
|
|
294
401
|
NSMutableDictionary* query = allAccountsQuery(service, accessGroup);
|
|
295
402
|
disableKeychainInteraction(query);
|
|
@@ -490,8 +597,7 @@ void IOSStorageAdapterCpp::clearSecure() {
|
|
|
490
597
|
"NitroStorage: Cannot clear secure storage: keychain is locked (errSecInteractionNotAllowed)"
|
|
491
598
|
);
|
|
492
599
|
}
|
|
493
|
-
throw
|
|
494
|
-
std::string("NitroStorage: clearSecure failed with status ") + std::to_string(secStatus));
|
|
600
|
+
throw keychainStatusError(secStatus, "clearSecure");
|
|
495
601
|
}
|
|
496
602
|
|
|
497
603
|
NSMutableDictionary* biometricQuery = [@{
|
|
@@ -509,8 +615,7 @@ void IOSStorageAdapterCpp::clearSecure() {
|
|
|
509
615
|
"NitroStorage: Cannot clear biometric storage: keychain is locked (errSecInteractionNotAllowed)"
|
|
510
616
|
);
|
|
511
617
|
}
|
|
512
|
-
throw
|
|
513
|
-
std::string("NitroStorage: clearSecureBiometric failed with status ") + std::to_string(bioStatus));
|
|
618
|
+
throw keychainStatusError(bioStatus, "clearSecureBiometric");
|
|
514
619
|
}
|
|
515
620
|
clearSecureKeyCache(); // Only clears cache AFTER confirmed deletion
|
|
516
621
|
}
|
|
@@ -627,12 +732,52 @@ void IOSStorageAdapterCpp::setSecureBiometricWithLevel(const std::string& key, c
|
|
|
627
732
|
"The item is not accessible until the device is unlocked."
|
|
628
733
|
);
|
|
629
734
|
}
|
|
630
|
-
|
|
735
|
+
if (addStatus == errSecNotAvailable) {
|
|
736
|
+
throw taggedStorageError(
|
|
737
|
+
"keychain_locked",
|
|
738
|
+
"NitroStorage: Biometric set failed: keychain is unavailable until the device is unlocked (errSecNotAvailable)."
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
throw taggedStorageError(
|
|
742
|
+
"biometric_unavailable",
|
|
631
743
|
std::string("NitroStorage: Biometric set failed with status ") +
|
|
632
744
|
std::to_string(addStatus) +
|
|
633
745
|
(backup.has_value() ? " (previous value restored to non-biometric keychain)" : " (no previous value)"));
|
|
634
746
|
}
|
|
747
|
+
|
|
748
|
+
// Promotion contract: the plain secure copy must not survive a biometric
|
|
749
|
+
// write, or plain reads would return a stale value (Android removes it too).
|
|
750
|
+
// If removing the plain copy fails after the biometric write succeeded,
|
|
751
|
+
// roll the biometric write back so the promotion either fully succeeds or
|
|
752
|
+
// leaves the previous state intact, then rethrow the original error.
|
|
753
|
+
try {
|
|
754
|
+
deletePlainSecureValue(nsKey, group);
|
|
755
|
+
} catch (const std::exception& plainDeleteError) {
|
|
756
|
+
if (backup.has_value()) {
|
|
757
|
+
CFErrorRef restoreError = NULL;
|
|
758
|
+
SecAccessControlRef restoreAccess = SecAccessControlCreateWithFlags(
|
|
759
|
+
kCFAllocatorDefault,
|
|
760
|
+
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
|
|
761
|
+
flags,
|
|
762
|
+
&restoreError
|
|
763
|
+
);
|
|
764
|
+
if (restoreAccess && !restoreError) {
|
|
765
|
+
NSMutableDictionary* restoreQuery = baseKeychainQuery(nsKey, kBiometricKeychainService, group);
|
|
766
|
+
restoreQuery[(__bridge id)kSecValueData] = [nsStringFromStdString(*backup) dataUsingEncoding:NSUTF8StringEncoding];
|
|
767
|
+
restoreQuery[(__bridge id)kSecAttrAccessControl] = (__bridge_transfer id)restoreAccess;
|
|
768
|
+
SecItemAdd((__bridge CFDictionaryRef)restoreQuery, NULL);
|
|
769
|
+
} else {
|
|
770
|
+
if (restoreError) CFRelease(restoreError);
|
|
771
|
+
if (restoreAccess) CFRelease(restoreAccess);
|
|
772
|
+
}
|
|
773
|
+
} else {
|
|
774
|
+
NSMutableDictionary* rollbackQuery = baseKeychainQuery(nsKey, kBiometricKeychainService, group);
|
|
775
|
+
SecItemDelete((__bridge CFDictionaryRef)rollbackQuery);
|
|
776
|
+
}
|
|
777
|
+
throw;
|
|
778
|
+
}
|
|
635
779
|
markBiometricKeySet(key);
|
|
780
|
+
markSecureKeyRemoved(key);
|
|
636
781
|
}
|
|
637
782
|
|
|
638
783
|
std::optional<std::string> IOSStorageAdapterCpp::getSecureBiometric(const std::string& key) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.resolveNativeWriteBuffering = resolveNativeWriteBuffering;
|
|
7
|
+
exports.resolveWebWriteBuffering = resolveWebWriteBuffering;
|
|
8
|
+
function resolveWebWriteBuffering(diskBackendName, secureBackendName) {
|
|
9
|
+
return {
|
|
10
|
+
disk: isIndexedDBWebBackendByName(diskBackendName),
|
|
11
|
+
secure: isIndexedDBWebBackendByName(secureBackendName)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function isIndexedDBWebBackendByName(backendName) {
|
|
15
|
+
if (!backendName) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return backendName.startsWith("indexeddb:");
|
|
19
|
+
}
|
|
20
|
+
function resolveNativeWriteBuffering(platform, secureWritesAsync) {
|
|
21
|
+
return {
|
|
22
|
+
disk: true,
|
|
23
|
+
secure: platform === "android" ? secureWritesAsync : false
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["resolveWebWriteBuffering","diskBackendName","secureBackendName","disk","isIndexedDBWebBackendByName","secure","backendName","startsWith","resolveNativeWriteBuffering","platform","secureWritesAsync"],"sourceRoot":"../../src","sources":["capabilities.ts"],"mappings":";;;;;;;AAUO,SAASA,wBAAwBA,CACtCC,eAAmC,EACnCC,iBAAqC,EACrB;EAChB,OAAO;IACLC,IAAI,EAAEC,2BAA2B,CAACH,eAAe,CAAC;IAClDI,MAAM,EAAED,2BAA2B,CAACF,iBAAiB;EACvD,CAAC;AACH;AAEA,SAASE,2BAA2BA,CAACE,WAA+B,EAAW;EAC7E,IAAI,CAACA,WAAW,EAAE;IAChB,OAAO,KAAK;EACd;EACA,OAAOA,WAAW,CAACC,UAAU,CAAC,YAAY,CAAC;AAC7C;AAEO,SAASC,2BAA2BA,CACzCC,QAA2B,EAC3BC,iBAA0B,EACV;EAChB,OAAO;IACLP,IAAI,EAAE,IAAI;IACVE,MAAM,EAAEI,QAAQ,KAAK,SAAS,GAAGC,iBAAiB,GAAG;EACvD,CAAC;AACH","ignoreList":[]}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createDurabilityCoordinator = createDurabilityCoordinator;
|
|
7
|
+
var _shared = require("../shared");
|
|
8
|
+
var _Storage = require("../Storage.types");
|
|
9
|
+
function createDurabilityCoordinator(options) {
|
|
10
|
+
const pendingDiskWrites = new Map();
|
|
11
|
+
let diskFlushScheduled = false;
|
|
12
|
+
let diskWritesAsync = false;
|
|
13
|
+
const pendingSecureWrites = new Map();
|
|
14
|
+
let secureFlushScheduled = false;
|
|
15
|
+
function flushDiskWrites() {
|
|
16
|
+
diskFlushScheduled = false;
|
|
17
|
+
if (pendingDiskWrites.size === 0) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const writes = Array.from(pendingDiskWrites.values());
|
|
21
|
+
pendingDiskWrites.clear();
|
|
22
|
+
const keysToSet = [];
|
|
23
|
+
const valuesToSet = [];
|
|
24
|
+
const keysToRemove = [];
|
|
25
|
+
writes.forEach(({
|
|
26
|
+
key,
|
|
27
|
+
value
|
|
28
|
+
}) => {
|
|
29
|
+
if (value === undefined) {
|
|
30
|
+
keysToRemove.push(key);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
keysToSet.push(key);
|
|
34
|
+
valuesToSet.push(value);
|
|
35
|
+
});
|
|
36
|
+
if (keysToSet.length > 0) {
|
|
37
|
+
options.backend.setBatch(keysToSet, valuesToSet, _Storage.StorageScope.Disk);
|
|
38
|
+
}
|
|
39
|
+
if (keysToRemove.length > 0) {
|
|
40
|
+
options.backend.removeBatch(keysToRemove, _Storage.StorageScope.Disk);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function flushSecureWrites() {
|
|
44
|
+
secureFlushScheduled = false;
|
|
45
|
+
if (pendingSecureWrites.size === 0) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const writes = Array.from(pendingSecureWrites.values());
|
|
49
|
+
pendingSecureWrites.clear();
|
|
50
|
+
const groupedSetWrites = new Map();
|
|
51
|
+
const keysToRemove = [];
|
|
52
|
+
writes.forEach(({
|
|
53
|
+
key,
|
|
54
|
+
value,
|
|
55
|
+
accessControl
|
|
56
|
+
}) => {
|
|
57
|
+
if (value === undefined) {
|
|
58
|
+
keysToRemove.push(key);
|
|
59
|
+
} else {
|
|
60
|
+
const resolvedAccessControl = accessControl ?? options.resolveSecureDefaultAccessControl();
|
|
61
|
+
const existingGroup = groupedSetWrites.get(resolvedAccessControl);
|
|
62
|
+
const group = existingGroup ?? {
|
|
63
|
+
keys: [],
|
|
64
|
+
values: []
|
|
65
|
+
};
|
|
66
|
+
group.keys.push(key);
|
|
67
|
+
group.values.push(value);
|
|
68
|
+
if (!existingGroup) {
|
|
69
|
+
groupedSetWrites.set(resolvedAccessControl, group);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
groupedSetWrites.forEach((group, accessControl) => {
|
|
74
|
+
options.backend.setSecureAccessControl(accessControl);
|
|
75
|
+
options.backend.setBatch(group.keys, group.values, _Storage.StorageScope.Secure);
|
|
76
|
+
});
|
|
77
|
+
if (keysToRemove.length > 0) {
|
|
78
|
+
options.backend.removeBatch(keysToRemove, _Storage.StorageScope.Secure);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function scheduleDiskWrite(key, value) {
|
|
82
|
+
pendingDiskWrites.set(key, {
|
|
83
|
+
key,
|
|
84
|
+
value
|
|
85
|
+
});
|
|
86
|
+
if (diskFlushScheduled) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
diskFlushScheduled = true;
|
|
90
|
+
(0, _shared.runMicrotask)(flushDiskWrites);
|
|
91
|
+
}
|
|
92
|
+
function scheduleSecureWrite(key, value, accessControl) {
|
|
93
|
+
const pendingWrite = {
|
|
94
|
+
key,
|
|
95
|
+
value
|
|
96
|
+
};
|
|
97
|
+
if (accessControl !== undefined) {
|
|
98
|
+
pendingWrite.accessControl = accessControl;
|
|
99
|
+
}
|
|
100
|
+
pendingSecureWrites.set(key, pendingWrite);
|
|
101
|
+
if (secureFlushScheduled) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
secureFlushScheduled = true;
|
|
105
|
+
(0, _shared.runMicrotask)(flushSecureWrites);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
setDiskWritesAsync(enabled) {
|
|
109
|
+
diskWritesAsync = enabled;
|
|
110
|
+
if (!enabled) {
|
|
111
|
+
flushDiskWrites();
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
isDiskWritesAsync: () => diskWritesAsync,
|
|
115
|
+
hasPendingDiskWrite: key => pendingDiskWrites.has(key),
|
|
116
|
+
hasPendingSecureWrite: key => pendingSecureWrites.has(key),
|
|
117
|
+
readPendingDiskWrite: key => pendingDiskWrites.get(key)?.value,
|
|
118
|
+
readPendingSecureWrite: key => pendingSecureWrites.get(key)?.value,
|
|
119
|
+
clearPendingDiskWrite: key => {
|
|
120
|
+
pendingDiskWrites.delete(key);
|
|
121
|
+
},
|
|
122
|
+
clearPendingSecureWrite: key => {
|
|
123
|
+
pendingSecureWrites.delete(key);
|
|
124
|
+
},
|
|
125
|
+
clearAllPendingDiskWrites: () => {
|
|
126
|
+
pendingDiskWrites.clear();
|
|
127
|
+
},
|
|
128
|
+
clearAllPendingSecureWrites: () => {
|
|
129
|
+
pendingSecureWrites.clear();
|
|
130
|
+
},
|
|
131
|
+
scheduleDiskWrite,
|
|
132
|
+
scheduleSecureWrite,
|
|
133
|
+
flushDiskWrites,
|
|
134
|
+
flushSecureWrites
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=durability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_shared","require","_Storage","createDurabilityCoordinator","options","pendingDiskWrites","Map","diskFlushScheduled","diskWritesAsync","pendingSecureWrites","secureFlushScheduled","flushDiskWrites","size","writes","Array","from","values","clear","keysToSet","valuesToSet","keysToRemove","forEach","key","value","undefined","push","length","backend","setBatch","StorageScope","Disk","removeBatch","flushSecureWrites","groupedSetWrites","accessControl","resolvedAccessControl","resolveSecureDefaultAccessControl","existingGroup","get","group","keys","set","setSecureAccessControl","Secure","scheduleDiskWrite","runMicrotask","scheduleSecureWrite","pendingWrite","setDiskWritesAsync","enabled","isDiskWritesAsync","hasPendingDiskWrite","has","hasPendingSecureWrite","readPendingDiskWrite","readPendingSecureWrite","clearPendingDiskWrite","delete","clearPendingSecureWrite","clearAllPendingDiskWrites","clearAllPendingSecureWrites"],"sourceRoot":"../../../src","sources":["core/durability.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createMetricsRegistry = createMetricsRegistry;
|
|
7
|
+
var _shared = require("../shared");
|
|
8
|
+
function createMetricsRegistry() {
|
|
9
|
+
let observer;
|
|
10
|
+
const counters = new Map();
|
|
11
|
+
function record(operation, scope, durationMs, keysCount = 1) {
|
|
12
|
+
const counterKey = `${operation}:${scope}`;
|
|
13
|
+
const existing = counters.get(counterKey);
|
|
14
|
+
if (!existing) {
|
|
15
|
+
counters.set(counterKey, {
|
|
16
|
+
count: 1,
|
|
17
|
+
totalDurationMs: durationMs,
|
|
18
|
+
maxDurationMs: durationMs
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
existing.count += 1;
|
|
22
|
+
existing.totalDurationMs += durationMs;
|
|
23
|
+
existing.maxDurationMs = Math.max(existing.maxDurationMs, durationMs);
|
|
24
|
+
}
|
|
25
|
+
observer?.({
|
|
26
|
+
operation,
|
|
27
|
+
scope,
|
|
28
|
+
durationMs,
|
|
29
|
+
keysCount
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function measure(operation, scope, fn, keysCount = 1) {
|
|
33
|
+
if (!observer) {
|
|
34
|
+
return fn();
|
|
35
|
+
}
|
|
36
|
+
const start = (0, _shared.now)();
|
|
37
|
+
try {
|
|
38
|
+
return fn();
|
|
39
|
+
} finally {
|
|
40
|
+
record(operation, scope, (0, _shared.now)() - start, keysCount);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function toSummary(value) {
|
|
44
|
+
return {
|
|
45
|
+
count: value.count,
|
|
46
|
+
totalDurationMs: value.totalDurationMs,
|
|
47
|
+
avgDurationMs: value.count === 0 ? 0 : value.totalDurationMs / value.count,
|
|
48
|
+
maxDurationMs: value.maxDurationMs
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
setObserver(next) {
|
|
53
|
+
observer = next;
|
|
54
|
+
},
|
|
55
|
+
record,
|
|
56
|
+
measure,
|
|
57
|
+
getSnapshot() {
|
|
58
|
+
const aggregated = new Map();
|
|
59
|
+
counters.forEach((value, key) => {
|
|
60
|
+
const separator = key.lastIndexOf(":");
|
|
61
|
+
const operation = separator === -1 ? key : key.slice(0, separator);
|
|
62
|
+
const existing = aggregated.get(operation);
|
|
63
|
+
if (!existing) {
|
|
64
|
+
aggregated.set(operation, {
|
|
65
|
+
...value
|
|
66
|
+
});
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
existing.count += value.count;
|
|
70
|
+
existing.totalDurationMs += value.totalDurationMs;
|
|
71
|
+
existing.maxDurationMs = Math.max(existing.maxDurationMs, value.maxDurationMs);
|
|
72
|
+
});
|
|
73
|
+
const snapshot = {};
|
|
74
|
+
aggregated.forEach((value, operation) => {
|
|
75
|
+
snapshot[operation] = toSummary(value);
|
|
76
|
+
});
|
|
77
|
+
return snapshot;
|
|
78
|
+
},
|
|
79
|
+
getScopedSnapshot() {
|
|
80
|
+
const snapshot = {};
|
|
81
|
+
counters.forEach((value, key) => {
|
|
82
|
+
snapshot[key] = toSummary(value);
|
|
83
|
+
});
|
|
84
|
+
return snapshot;
|
|
85
|
+
},
|
|
86
|
+
reset() {
|
|
87
|
+
counters.clear();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_shared","require","createMetricsRegistry","observer","counters","Map","record","operation","scope","durationMs","keysCount","counterKey","existing","get","set","count","totalDurationMs","maxDurationMs","Math","max","measure","fn","start","now","toSummary","value","avgDurationMs","setObserver","next","getSnapshot","aggregated","forEach","key","separator","lastIndexOf","slice","snapshot","getScopedSnapshot","reset","clear"],"sourceRoot":"../../../src","sources":["core/metrics.ts"],"mappings":"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","ignoreList":[]}
|