From 6ae0f37b9c6ccb6376981e944eea1a7054eb270d Mon Sep 17 00:00:00 2001 From: Adegoke David <64401859+Blazebrain@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:37:52 +0100 Subject: [PATCH] CW-597-AuthService-Bug (#1346) * fix: AuthService keychain bug fix * fix: Fetch read implementation * fix: Simplify logic for retries * Minor enhancement --------- Co-authored-by: Omar Hatem --- lib/core/auth_service.dart | 7 +++++-- lib/core/key_service.dart | 3 ++- lib/core/secure_storage.dart | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 lib/core/secure_storage.dart diff --git a/lib/core/auth_service.dart b/lib/core/auth_service.dart index a99aef31d..48610784c 100644 --- a/lib/core/auth_service.dart +++ b/lib/core/auth_service.dart @@ -1,5 +1,7 @@ +import 'dart:async'; import 'dart:io'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/core/totp_request_details.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart'; @@ -64,7 +66,7 @@ class AuthService with Store { Future authenticate(String pin) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); - final encodedPin = await secureStorage.read(key: key); + final encodedPin = await readSecureStorage(secureStorage, key); final decodedPin = decodedPinCode(pin: encodedPin!); return decodedPin == pin; @@ -76,7 +78,8 @@ class AuthService with Store { } Future requireAuth() async { - final timestamp = int.tryParse(await secureStorage.read(key: SecureKey.lastAuthTimeMilliseconds) ?? '0'); + final timestamp = + int.tryParse(await secureStorage.read(key: SecureKey.lastAuthTimeMilliseconds) ?? '0'); final duration = _durationToRequireAuth(timestamp ?? 0); final requiredPinInterval = settingsStore.pinTimeOutDuration; diff --git a/lib/core/key_service.dart b/lib/core/key_service.dart index fce254ea2..f829c22b5 100644 --- a/lib/core/key_service.dart +++ b/lib/core/key_service.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cake_wallet/entities/encrypt.dart'; @@ -10,7 +11,7 @@ class KeyService { Future getWalletPassword({required String walletName}) async { final key = generateStoreKeyFor( key: SecretStoreKey.moneroWalletPassword, walletName: walletName); - final encodedPassword = await _secureStorage.read(key: key); + final encodedPassword = await readSecureStorage(_secureStorage, key); return decodeWalletPassword(password: encodedPassword!); } diff --git a/lib/core/secure_storage.dart b/lib/core/secure_storage.dart new file mode 100644 index 000000000..4d9334a10 --- /dev/null +++ b/lib/core/secure_storage.dart @@ -0,0 +1,27 @@ +import 'dart:async'; +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +// For now, we can create a utility function to handle this. +// +// However, we could look into abstracting the entire FlutterSecureStorage package +// so the app doesn't depend on the package directly but an absraction. +// It'll make these kind of modifications to read/write come from a single point. + +Future readSecureStorage(FlutterSecureStorage secureStorage, String key) async { + String? result; + const maxWait = Duration(seconds: 3); + const checkInterval = Duration(milliseconds: 200); + + DateTime start = DateTime.now(); + + while (result == null && DateTime.now().difference(start) < maxWait) { + result = await secureStorage.read(key: key); + + if (result != null) { + break; + } + + await Future.delayed(checkInterval); + } + + return result; +}