getPrivateKey function
Get a Private Key using the specified storage strategy.
If storage is not specified, it uses the LocalDataStorage class.
Implementation
Future<PrivateKey?> getPrivateKey({DataStorage? storage}) async {
if (_cachedPrivateKey != null) {
return _cachedPrivateKey;
}
storage ??= LocalDataStorage.INSTANCE;
var keyPath = 'dsa_key:${window.location.pathname}';
String? keyLockPath = 'dsa_key_lock:${window.location.pathname}';
var randomToken =
'${DateTime.now().millisecondsSinceEpoch}'
' ${DSRandom.instance.nextUint16()}'
' ${DSRandom.instance.nextUint16()}';
var hasKeyPath = false;
if (storage is SynchronousDataStorage) {
hasKeyPath = (storage as SynchronousDataStorage).hasSync(keyPath);
} else {
hasKeyPath = await storage.has(keyPath);
}
if (hasKeyPath) {
if (storage is SynchronousDataStorage) {
(storage as SynchronousDataStorage).storeSync(keyLockPath, randomToken);
} else {
await storage.store(keyLockPath, randomToken);
}
await Future<void>.delayed(const Duration(milliseconds: 20));
String existingToken;
String existingKey;
if (storage is SynchronousDataStorage) {
existingToken = (storage as SynchronousDataStorage).getSync(keyLockPath);
existingKey = (storage as SynchronousDataStorage).getSync(keyPath);
} else {
existingToken = await storage.get(keyLockPath);
existingKey = await storage.get(keyPath);
}
if (existingToken == randomToken) {
if (storage is LocalDataStorage) {
_startStorageLock(keyLockPath, randomToken);
}
_cachedPrivateKey = PrivateKey.loadFromString(existingKey);
return _cachedPrivateKey;
} else {
// use temp key, don't lock it;
keyLockPath = null;
}
}
_cachedPrivateKey = await PrivateKey.generate();
if (keyLockPath != null) {
if (storage is SynchronousDataStorage) {
(storage as SynchronousDataStorage).storeSync(
keyPath,
_cachedPrivateKey!.saveToString(),
);
(storage as SynchronousDataStorage).storeSync(keyLockPath, randomToken);
} else {
await storage.store(keyPath, _cachedPrivateKey!.saveToString());
await storage.store(keyLockPath, randomToken);
}
if (storage is LocalDataStorage) {
_startStorageLock(keyLockPath, randomToken);
}
}
return _cachedPrivateKey;
}