react-native-nitro-storage 0.4.0 → 0.4.3
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 +90 -0
- package/android/build.gradle +0 -12
- package/android/consumer-rules.pro +26 -4
- package/android/src/main/cpp/AndroidStorageAdapterCpp.cpp +7 -10
- package/android/src/main/cpp/AndroidStorageAdapterCpp.hpp +0 -4
- package/android/src/main/cpp/cpp-adapter.cpp +3 -1
- package/android/src/main/java/com/nitrostorage/AndroidStorageAdapter.kt +172 -77
- package/cpp/bindings/HybridStorage.cpp +120 -69
- package/cpp/bindings/HybridStorage.hpp +4 -0
- package/ios/IOSStorageAdapterCpp.hpp +2 -1
- package/ios/IOSStorageAdapterCpp.mm +264 -49
- package/lib/commonjs/index.js +128 -20
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +169 -41
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/indexeddb-backend.js +130 -0
- package/lib/commonjs/indexeddb-backend.js.map +1 -0
- package/lib/commonjs/internal.js +51 -23
- package/lib/commonjs/internal.js.map +1 -1
- package/lib/module/index.js +121 -20
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +162 -41
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/indexeddb-backend.js +126 -0
- package/lib/module/indexeddb-backend.js.map +1 -0
- package/lib/module/internal.js +51 -23
- package/lib/module/internal.js.map +1 -1
- package/lib/typescript/index.d.ts +6 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/index.web.d.ts +7 -1
- package/lib/typescript/index.web.d.ts.map +1 -1
- package/lib/typescript/indexeddb-backend.d.ts +29 -0
- package/lib/typescript/indexeddb-backend.d.ts.map +1 -0
- package/lib/typescript/internal.d.ts.map +1 -1
- package/nitrogen/generated/android/NitroStorageOnLoad.cpp +22 -17
- package/nitrogen/generated/android/NitroStorageOnLoad.hpp +13 -4
- package/package.json +7 -3
- package/src/index.ts +137 -27
- package/src/index.web.ts +182 -49
- package/src/indexeddb-backend.ts +143 -0
- package/src/internal.ts +51 -23
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "HybridStorage.hpp"
|
|
2
|
+
#include <cmath>
|
|
2
3
|
#include <stdexcept>
|
|
3
4
|
|
|
4
5
|
#ifndef NITRO_STORAGE_DISABLE_PLATFORM_ADAPTER
|
|
@@ -33,7 +34,7 @@ HybridStorage::HybridStorage(std::shared_ptr<::NitroStorage::NativeStorageAdapte
|
|
|
33
34
|
: HybridObject(TAG), HybridStorageSpec(), nativeAdapter_(std::move(adapter)) {}
|
|
34
35
|
|
|
35
36
|
HybridStorage::Scope HybridStorage::toScope(double scopeValue) {
|
|
36
|
-
if (scopeValue < 0.0 || scopeValue > 2.0) {
|
|
37
|
+
if (std::isnan(scopeValue) || scopeValue < 0.0 || scopeValue > 2.0) {
|
|
37
38
|
throw std::runtime_error("NitroStorage: Invalid scope value");
|
|
38
39
|
}
|
|
39
40
|
|
|
@@ -58,20 +59,20 @@ void HybridStorage::set(const std::string& key, const std::string& value, double
|
|
|
58
59
|
ensureAdapter();
|
|
59
60
|
try {
|
|
60
61
|
nativeAdapter_->setDisk(key, value);
|
|
61
|
-
} catch (const std::exception&
|
|
62
|
-
throw
|
|
62
|
+
} catch (const std::exception&) {
|
|
63
|
+
throw;
|
|
63
64
|
} catch (...) {
|
|
64
|
-
throw std::runtime_error("NitroStorage: Disk set failed");
|
|
65
|
+
throw std::runtime_error("NitroStorage: Disk set failed (unknown error)");
|
|
65
66
|
}
|
|
66
67
|
break;
|
|
67
68
|
case Scope::Secure:
|
|
68
69
|
ensureAdapter();
|
|
69
70
|
try {
|
|
70
71
|
nativeAdapter_->setSecure(key, value);
|
|
71
|
-
} catch (const std::exception&
|
|
72
|
-
throw
|
|
72
|
+
} catch (const std::exception&) {
|
|
73
|
+
throw;
|
|
73
74
|
} catch (...) {
|
|
74
|
-
throw std::runtime_error("NitroStorage: Secure set failed");
|
|
75
|
+
throw std::runtime_error("NitroStorage: Secure set failed (unknown error)");
|
|
75
76
|
}
|
|
76
77
|
break;
|
|
77
78
|
}
|
|
@@ -96,19 +97,19 @@ std::optional<std::string> HybridStorage::get(const std::string& key, double sco
|
|
|
96
97
|
ensureAdapter();
|
|
97
98
|
try {
|
|
98
99
|
return nativeAdapter_->getDisk(key);
|
|
99
|
-
} catch (const std::exception&
|
|
100
|
-
throw
|
|
100
|
+
} catch (const std::exception&) {
|
|
101
|
+
throw;
|
|
101
102
|
} catch (...) {
|
|
102
|
-
throw std::runtime_error("NitroStorage: Disk get failed");
|
|
103
|
+
throw std::runtime_error("NitroStorage: Disk get failed (unknown error)");
|
|
103
104
|
}
|
|
104
105
|
case Scope::Secure:
|
|
105
106
|
ensureAdapter();
|
|
106
107
|
try {
|
|
107
108
|
return nativeAdapter_->getSecure(key);
|
|
108
|
-
} catch (const std::exception&
|
|
109
|
-
throw
|
|
109
|
+
} catch (const std::exception&) {
|
|
110
|
+
throw;
|
|
110
111
|
} catch (...) {
|
|
111
|
-
throw std::runtime_error("NitroStorage: Secure get failed");
|
|
112
|
+
throw std::runtime_error("NitroStorage: Secure get failed (unknown error)");
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
|
|
@@ -128,20 +129,20 @@ void HybridStorage::remove(const std::string& key, double scope) {
|
|
|
128
129
|
ensureAdapter();
|
|
129
130
|
try {
|
|
130
131
|
nativeAdapter_->deleteDisk(key);
|
|
131
|
-
} catch (const std::exception&
|
|
132
|
-
throw
|
|
132
|
+
} catch (const std::exception&) {
|
|
133
|
+
throw;
|
|
133
134
|
} catch (...) {
|
|
134
|
-
throw std::runtime_error("NitroStorage: Disk delete failed");
|
|
135
|
+
throw std::runtime_error("NitroStorage: Disk delete failed (unknown error)");
|
|
135
136
|
}
|
|
136
137
|
break;
|
|
137
138
|
case Scope::Secure:
|
|
138
139
|
ensureAdapter();
|
|
139
140
|
try {
|
|
140
141
|
nativeAdapter_->deleteSecure(key);
|
|
141
|
-
} catch (const std::exception&
|
|
142
|
-
throw
|
|
142
|
+
} catch (const std::exception&) {
|
|
143
|
+
throw;
|
|
143
144
|
} catch (...) {
|
|
144
|
-
throw std::runtime_error("NitroStorage: Secure delete failed");
|
|
145
|
+
throw std::runtime_error("NitroStorage: Secure delete failed (unknown error)");
|
|
145
146
|
}
|
|
146
147
|
break;
|
|
147
148
|
}
|
|
@@ -159,11 +160,16 @@ bool HybridStorage::has(const std::string& key, double scope) {
|
|
|
159
160
|
return memoryStore_.find(key) != memoryStore_.end();
|
|
160
161
|
}
|
|
161
162
|
case Scope::Disk:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
case Scope::Secure: {
|
|
164
|
+
const int scopeValue = static_cast<int>(s);
|
|
165
|
+
ensureKeyIndexHydrated(scopeValue);
|
|
166
|
+
std::lock_guard<std::mutex> lock(keyIndexMutex_);
|
|
167
|
+
auto indexIt = keyIndex_.find(scopeValue);
|
|
168
|
+
if (indexIt == keyIndex_.end()) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
return indexIt->second.count(key) > 0;
|
|
172
|
+
}
|
|
167
173
|
}
|
|
168
174
|
return false;
|
|
169
175
|
}
|
|
@@ -263,7 +269,7 @@ std::function<void()> HybridStorage::addOnChange(
|
|
|
263
269
|
double scope,
|
|
264
270
|
const std::function<void(const std::string&, const std::optional<std::string>&)>& callback
|
|
265
271
|
) {
|
|
266
|
-
int intScope = static_cast<int>(scope);
|
|
272
|
+
int intScope = static_cast<int>(toScope(scope)); // validates scope, throws on invalid
|
|
267
273
|
size_t listenerId;
|
|
268
274
|
|
|
269
275
|
{
|
|
@@ -272,15 +278,22 @@ std::function<void()> HybridStorage::addOnChange(
|
|
|
272
278
|
listeners_[intScope].push_back({listenerId, callback});
|
|
273
279
|
}
|
|
274
280
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
auto
|
|
281
|
+
std::weak_ptr<HybridStorage> weakSelf = std::dynamic_pointer_cast<HybridStorage>(shared_from_this());
|
|
282
|
+
return [weakSelf, intScope, listenerId]() {
|
|
283
|
+
auto self = weakSelf.lock();
|
|
284
|
+
if (!self) return; // HybridStorage was destroyed — safe no-op
|
|
285
|
+
std::lock_guard<std::mutex> lock(self->listenersMutex_);
|
|
286
|
+
auto& scopeListeners = self->listeners_[intScope];
|
|
287
|
+
bool found = false;
|
|
278
288
|
for (auto it = scopeListeners.begin(); it != scopeListeners.end(); ++it) {
|
|
279
289
|
if (it->id == listenerId) {
|
|
280
290
|
scopeListeners.erase(it);
|
|
291
|
+
found = true;
|
|
281
292
|
break;
|
|
282
293
|
}
|
|
283
294
|
}
|
|
295
|
+
// Silently ignore double-unsubscribe (listener already removed)
|
|
296
|
+
(void)found;
|
|
284
297
|
};
|
|
285
298
|
}
|
|
286
299
|
|
|
@@ -297,26 +310,26 @@ void HybridStorage::clear(double scope) {
|
|
|
297
310
|
ensureAdapter();
|
|
298
311
|
try {
|
|
299
312
|
nativeAdapter_->clearDisk();
|
|
300
|
-
} catch (const std::exception&
|
|
301
|
-
throw
|
|
313
|
+
} catch (const std::exception&) {
|
|
314
|
+
throw;
|
|
302
315
|
} catch (...) {
|
|
303
|
-
throw std::runtime_error("NitroStorage: Disk clear failed");
|
|
316
|
+
throw std::runtime_error("NitroStorage: Disk clear failed (unknown error)");
|
|
304
317
|
}
|
|
305
318
|
break;
|
|
306
319
|
case Scope::Secure:
|
|
307
320
|
ensureAdapter();
|
|
308
321
|
try {
|
|
309
322
|
nativeAdapter_->clearSecure();
|
|
310
|
-
} catch (const std::exception&
|
|
311
|
-
throw
|
|
323
|
+
} catch (const std::exception&) {
|
|
324
|
+
throw;
|
|
312
325
|
} catch (...) {
|
|
313
|
-
throw std::runtime_error("NitroStorage: Secure clear failed");
|
|
326
|
+
throw std::runtime_error("NitroStorage: Secure clear failed (unknown error)");
|
|
314
327
|
}
|
|
315
328
|
break;
|
|
316
329
|
}
|
|
317
330
|
|
|
318
331
|
onScopeClear(static_cast<int>(s));
|
|
319
|
-
notifyListeners(static_cast<int>(s),
|
|
332
|
+
notifyListeners(static_cast<int>(s), kClearSentinelKey, std::nullopt);
|
|
320
333
|
}
|
|
321
334
|
|
|
322
335
|
void HybridStorage::setBatch(const std::vector<std::string>& keys, const std::vector<std::string>& values, double scope) {
|
|
@@ -338,20 +351,20 @@ void HybridStorage::setBatch(const std::vector<std::string>& keys, const std::ve
|
|
|
338
351
|
ensureAdapter();
|
|
339
352
|
try {
|
|
340
353
|
nativeAdapter_->setDiskBatch(keys, values);
|
|
341
|
-
} catch (const std::exception&
|
|
342
|
-
throw
|
|
354
|
+
} catch (const std::exception&) {
|
|
355
|
+
throw;
|
|
343
356
|
} catch (...) {
|
|
344
|
-
throw std::runtime_error("NitroStorage: Disk setBatch failed");
|
|
357
|
+
throw std::runtime_error("NitroStorage: Disk setBatch failed (unknown error)");
|
|
345
358
|
}
|
|
346
359
|
break;
|
|
347
360
|
case Scope::Secure:
|
|
348
361
|
ensureAdapter();
|
|
349
362
|
try {
|
|
350
363
|
nativeAdapter_->setSecureBatch(keys, values);
|
|
351
|
-
} catch (const std::exception&
|
|
352
|
-
throw
|
|
364
|
+
} catch (const std::exception&) {
|
|
365
|
+
throw;
|
|
353
366
|
} catch (...) {
|
|
354
|
-
throw std::runtime_error("NitroStorage: Secure setBatch failed");
|
|
367
|
+
throw std::runtime_error("NitroStorage: Secure setBatch failed (unknown error)");
|
|
355
368
|
}
|
|
356
369
|
break;
|
|
357
370
|
}
|
|
@@ -390,10 +403,10 @@ std::vector<std::string> HybridStorage::getBatch(const std::vector<std::string>&
|
|
|
390
403
|
std::vector<std::optional<std::string>> values;
|
|
391
404
|
try {
|
|
392
405
|
values = nativeAdapter_->getDiskBatch(keys);
|
|
393
|
-
} catch (const std::exception&
|
|
394
|
-
throw
|
|
406
|
+
} catch (const std::exception&) {
|
|
407
|
+
throw;
|
|
395
408
|
} catch (...) {
|
|
396
|
-
throw std::runtime_error("NitroStorage: Disk getBatch failed");
|
|
409
|
+
throw std::runtime_error("NitroStorage: Disk getBatch failed (unknown error)");
|
|
397
410
|
}
|
|
398
411
|
|
|
399
412
|
for (const auto& value : values) {
|
|
@@ -406,10 +419,10 @@ std::vector<std::string> HybridStorage::getBatch(const std::vector<std::string>&
|
|
|
406
419
|
std::vector<std::optional<std::string>> values;
|
|
407
420
|
try {
|
|
408
421
|
values = nativeAdapter_->getSecureBatch(keys);
|
|
409
|
-
} catch (const std::exception&
|
|
410
|
-
throw
|
|
422
|
+
} catch (const std::exception&) {
|
|
423
|
+
throw;
|
|
411
424
|
} catch (...) {
|
|
412
|
-
throw std::runtime_error("NitroStorage: Secure getBatch failed");
|
|
425
|
+
throw std::runtime_error("NitroStorage: Secure getBatch failed (unknown error)");
|
|
413
426
|
}
|
|
414
427
|
|
|
415
428
|
for (const auto& value : values) {
|
|
@@ -437,20 +450,20 @@ void HybridStorage::removeBatch(const std::vector<std::string>& keys, double sco
|
|
|
437
450
|
ensureAdapter();
|
|
438
451
|
try {
|
|
439
452
|
nativeAdapter_->deleteDiskBatch(keys);
|
|
440
|
-
} catch (const std::exception&
|
|
441
|
-
throw
|
|
453
|
+
} catch (const std::exception&) {
|
|
454
|
+
throw;
|
|
442
455
|
} catch (...) {
|
|
443
|
-
throw std::runtime_error("NitroStorage: Disk removeBatch failed");
|
|
456
|
+
throw std::runtime_error("NitroStorage: Disk removeBatch failed (unknown error)");
|
|
444
457
|
}
|
|
445
458
|
break;
|
|
446
459
|
case Scope::Secure:
|
|
447
460
|
ensureAdapter();
|
|
448
461
|
try {
|
|
449
462
|
nativeAdapter_->deleteSecureBatch(keys);
|
|
450
|
-
} catch (const std::exception&
|
|
451
|
-
throw
|
|
463
|
+
} catch (const std::exception&) {
|
|
464
|
+
throw;
|
|
452
465
|
} catch (...) {
|
|
453
|
-
throw std::runtime_error("NitroStorage: Secure removeBatch failed");
|
|
466
|
+
throw std::runtime_error("NitroStorage: Secure removeBatch failed (unknown error)");
|
|
454
467
|
}
|
|
455
468
|
break;
|
|
456
469
|
}
|
|
@@ -482,8 +495,17 @@ void HybridStorage::removeByPrefix(const std::string& prefix, double scope) {
|
|
|
482
495
|
// --- Configuration ---
|
|
483
496
|
|
|
484
497
|
void HybridStorage::setSecureAccessControl(double level) {
|
|
498
|
+
if (std::isnan(level) || std::isinf(level)) {
|
|
499
|
+
throw std::runtime_error("NitroStorage: Invalid access control level");
|
|
500
|
+
}
|
|
501
|
+
int intLevel = static_cast<int>(level);
|
|
502
|
+
if (intLevel < 0 || intLevel > 4) {
|
|
503
|
+
throw std::runtime_error(
|
|
504
|
+
"NitroStorage: Invalid access control level " + std::to_string(intLevel) +
|
|
505
|
+
". Expected 0-4.");
|
|
506
|
+
}
|
|
485
507
|
ensureAdapter();
|
|
486
|
-
nativeAdapter_->setSecureAccessControl(
|
|
508
|
+
nativeAdapter_->setSecureAccessControl(intLevel);
|
|
487
509
|
}
|
|
488
510
|
|
|
489
511
|
void HybridStorage::setSecureWritesAsync(bool enabled) {
|
|
@@ -503,17 +525,29 @@ void HybridStorage::setSecureBiometric(const std::string& key, const std::string
|
|
|
503
525
|
}
|
|
504
526
|
|
|
505
527
|
void HybridStorage::setSecureBiometricWithLevel(const std::string& key, const std::string& value, double level) {
|
|
528
|
+
if (std::isnan(level) || std::isinf(level)) {
|
|
529
|
+
throw std::runtime_error(
|
|
530
|
+
"NitroStorage: Invalid biometric level");
|
|
531
|
+
}
|
|
532
|
+
int intLevel = static_cast<int>(level);
|
|
533
|
+
if (intLevel < 0 || intLevel > 2) {
|
|
534
|
+
throw std::runtime_error(
|
|
535
|
+
"NitroStorage: Invalid biometric level " + std::to_string(intLevel) +
|
|
536
|
+
". Expected 0 (none), 1 (user presence), or 2 (biometric only).");
|
|
537
|
+
}
|
|
506
538
|
ensureAdapter();
|
|
507
539
|
try {
|
|
508
540
|
nativeAdapter_->setSecureBiometricWithLevel(
|
|
509
541
|
key,
|
|
510
542
|
value,
|
|
511
|
-
|
|
543
|
+
intLevel
|
|
512
544
|
);
|
|
513
545
|
onKeySet(static_cast<int>(Scope::Secure), key);
|
|
514
546
|
notifyListeners(static_cast<int>(Scope::Secure), key, value);
|
|
515
|
-
} catch (const std::exception&
|
|
516
|
-
throw
|
|
547
|
+
} catch (const std::exception&) {
|
|
548
|
+
throw;
|
|
549
|
+
} catch (...) {
|
|
550
|
+
throw std::runtime_error("NitroStorage: Biometric set failed (unknown error)");
|
|
517
551
|
}
|
|
518
552
|
}
|
|
519
553
|
|
|
@@ -521,8 +555,10 @@ std::optional<std::string> HybridStorage::getSecureBiometric(const std::string&
|
|
|
521
555
|
ensureAdapter();
|
|
522
556
|
try {
|
|
523
557
|
return nativeAdapter_->getSecureBiometric(key);
|
|
524
|
-
} catch (const std::exception&
|
|
525
|
-
throw
|
|
558
|
+
} catch (const std::exception&) {
|
|
559
|
+
throw;
|
|
560
|
+
} catch (...) {
|
|
561
|
+
throw std::runtime_error("NitroStorage: Biometric get failed (unknown error)");
|
|
526
562
|
}
|
|
527
563
|
}
|
|
528
564
|
|
|
@@ -532,8 +568,10 @@ void HybridStorage::deleteSecureBiometric(const std::string& key) {
|
|
|
532
568
|
nativeAdapter_->deleteSecureBiometric(key);
|
|
533
569
|
onKeyRemove(static_cast<int>(Scope::Secure), key);
|
|
534
570
|
notifyListeners(static_cast<int>(Scope::Secure), key, std::nullopt);
|
|
535
|
-
} catch (const std::exception&
|
|
536
|
-
throw
|
|
571
|
+
} catch (const std::exception&) {
|
|
572
|
+
throw;
|
|
573
|
+
} catch (...) {
|
|
574
|
+
throw std::runtime_error("NitroStorage: Biometric delete failed (unknown error)");
|
|
537
575
|
}
|
|
538
576
|
}
|
|
539
577
|
|
|
@@ -546,10 +584,19 @@ void HybridStorage::clearSecureBiometric() {
|
|
|
546
584
|
ensureAdapter();
|
|
547
585
|
try {
|
|
548
586
|
nativeAdapter_->clearSecureBiometric();
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
587
|
+
// Invalidate the secure key index so next access re-hydrates from native adapter
|
|
588
|
+
// (which will now correctly exclude the cleared biometric keys).
|
|
589
|
+
// We do NOT call onScopeClear() here because that would also clear the index
|
|
590
|
+
// contents for regular secure keys; marking stale is sufficient.
|
|
591
|
+
{
|
|
592
|
+
std::lock_guard<std::mutex> lock(keyIndexMutex_);
|
|
593
|
+
keyIndexHydrated_[static_cast<int>(Scope::Secure)] = false;
|
|
594
|
+
}
|
|
595
|
+
notifyListeners(static_cast<int>(Scope::Secure), kClearSentinelKey, std::nullopt);
|
|
596
|
+
} catch (const std::exception&) {
|
|
597
|
+
throw;
|
|
598
|
+
} catch (...) {
|
|
599
|
+
throw std::runtime_error("NitroStorage: Biometric clear failed (unknown error)");
|
|
553
600
|
}
|
|
554
601
|
}
|
|
555
602
|
|
|
@@ -561,7 +608,6 @@ std::vector<HybridStorage::Listener> HybridStorage::copyListenersForScope(int sc
|
|
|
561
608
|
std::lock_guard<std::mutex> lock(listenersMutex_);
|
|
562
609
|
auto it = listeners_.find(scope);
|
|
563
610
|
if (it != listeners_.end()) {
|
|
564
|
-
listenersCopy.reserve(it->second.size());
|
|
565
611
|
listenersCopy = it->second;
|
|
566
612
|
}
|
|
567
613
|
}
|
|
@@ -621,13 +667,18 @@ void HybridStorage::ensureKeyIndexHydrated(int scope) {
|
|
|
621
667
|
} else {
|
|
622
668
|
keys = nativeAdapter_->getAllKeysSecure();
|
|
623
669
|
}
|
|
624
|
-
} catch (const std::exception&
|
|
625
|
-
throw
|
|
670
|
+
} catch (const std::exception&) {
|
|
671
|
+
throw;
|
|
626
672
|
} catch (...) {
|
|
627
|
-
throw std::runtime_error("NitroStorage: Key index hydration failed");
|
|
673
|
+
throw std::runtime_error("NitroStorage: Key index hydration failed (unknown error)");
|
|
628
674
|
}
|
|
629
675
|
|
|
630
676
|
std::lock_guard<std::mutex> lock(keyIndexMutex_);
|
|
677
|
+
// Double-check: another thread may have hydrated while we fetched
|
|
678
|
+
auto hydratedIt = keyIndexHydrated_.find(scope);
|
|
679
|
+
if (hydratedIt != keyIndexHydrated_.end() && hydratedIt->second) {
|
|
680
|
+
return; // discard our results
|
|
681
|
+
}
|
|
631
682
|
auto& index = keyIndex_[scope];
|
|
632
683
|
index.clear();
|
|
633
684
|
for (const auto& key : keys) {
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
#include "HybridStorageSpec.hpp"
|
|
4
4
|
#include "../core/NativeStorageAdapter.hpp"
|
|
5
5
|
#include <unordered_map>
|
|
6
|
+
#ifdef NITRO_STORAGE_USE_ORDERED_MAP_FOR_TESTS
|
|
6
7
|
#include <map>
|
|
8
|
+
#endif
|
|
7
9
|
#include <mutex>
|
|
8
10
|
#include <functional>
|
|
9
11
|
#include <memory>
|
|
@@ -90,6 +92,8 @@ private:
|
|
|
90
92
|
void onScopeClear(int scope);
|
|
91
93
|
void ensureAdapter() const;
|
|
92
94
|
Scope toScope(double scopeValue);
|
|
95
|
+
|
|
96
|
+
static constexpr const char* kClearSentinelKey = "";
|
|
93
97
|
};
|
|
94
98
|
|
|
95
99
|
} // namespace margelo::nitro::NitroStorage
|
|
@@ -51,9 +51,10 @@ private:
|
|
|
51
51
|
int accessControlLevel_ = 0;
|
|
52
52
|
std::string keychainAccessGroup_;
|
|
53
53
|
mutable std::mutex secureKeysMutex_;
|
|
54
|
+
mutable std::mutex accessGroupMutex_;
|
|
54
55
|
std::unordered_set<std::string> secureKeysCache_;
|
|
55
56
|
std::unordered_set<std::string> biometricKeysCache_;
|
|
56
|
-
bool secureKeyCacheHydrated_
|
|
57
|
+
bool secureKeyCacheHydrated_{false};
|
|
57
58
|
|
|
58
59
|
void ensureSecureKeyCacheHydrated();
|
|
59
60
|
void markSecureKeySet(const std::string& key);
|