From e2f138ddf4d9d4fbf458c5dd0b4218e97a86f920 Mon Sep 17 00:00:00 2001 From: Mati Date: Mon, 13 Nov 2023 18:58:24 -0300 Subject: [PATCH 1/6] feat: WIP - arconnect --- lib/app_shell.dart | 18 ++++++-- lib/authentication/ardrive_auth.dart | 4 ++ .../login/blocs/login_bloc.dart | 43 ++++++++++++++----- .../login/blocs/login_state.dart | 4 +- .../login/views/login_page.dart | 27 +++++------- .../ardrive_utils/lib/src/html/html_util.dart | 2 +- .../src/html/implementations/html_stub.dart | 4 +- .../src/html/implementations/html_web.dart | 8 +++- .../login/blocs/login_bloc_test.dart | 9 ++-- 9 files changed, 81 insertions(+), 38 deletions(-) diff --git a/lib/app_shell.dart b/lib/app_shell.dart index c56868717c..b2a06f2046 100644 --- a/lib/app_shell.dart +++ b/lib/app_shell.dart @@ -31,10 +31,19 @@ class AppShell extends StatefulWidget { class AppShellState extends State { bool _showProfileOverlay = false; bool _showWalletSwitchDialog = true; + Function()? _unregisterWalletSwitchListener; + + @override + void dispose() { + _unregisterWalletSwitchListener?.call(); + _unregisterWalletSwitchListener = null; + super.dispose(); + } + @override Widget build(BuildContext context) => BlocBuilder( builder: (context, _) { - onArConnectWalletSwitch(() { + _unregisterWalletSwitchListener = onArConnectWalletSwitch(() { context .read() .isCurrentProfileArConnect() @@ -76,6 +85,8 @@ class AppShellState extends State { .isCurrentProfileArConnect(), builder: (BuildContext context, AsyncSnapshot snapshot) { + final isCurrentProfileArConnect = + snapshot.data == true; return Align( alignment: Alignment.center, child: Material( @@ -92,7 +103,8 @@ class AppShellState extends State { Text(appLocalizationsOf( context) .syncProgressPercentage( - (syncProgress.progress * + (syncProgress + .progress * 100) .roundToDouble() .toString()))), @@ -118,7 +130,7 @@ class AppShellState extends State { .buttonNormalBold(), ), ), - title: snapshot.data ?? false + title: isCurrentProfileArConnect ? appLocalizationsOf(context) .syncingPleaseRemainOnThisTab : appLocalizationsOf(context) diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index 22bc046615..2ee2e02c06 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -97,6 +97,7 @@ class ArDriveAuthImpl implements ArDriveAuth { return _currentUser!; } + @visibleForTesting set currentUser(User? user) { _currentUser = user; } @@ -217,6 +218,8 @@ class ArDriveAuthImpl implements ArDriveAuth { logger.i('Logging out user'); try { + logger.d('Current user: $_currentUser'); + if (_currentUser != null) { await _secureKeyValueStore.remove('password'); await _secureKeyValueStore.remove('biometricEnabled'); @@ -226,6 +229,7 @@ class ArDriveAuthImpl implements ArDriveAuth { _userStreamController.add(null); } + await _userRepository.deleteUser(); await _databaseHelpers.deleteAllTables(); (await _metadataCache).clear(); } catch (e) { diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index 87e1c78447..d87b3ff426 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -26,6 +26,7 @@ part 'login_state.dart'; class LoginBloc extends Bloc { final ArDriveAuth _arDriveAuth; final ArConnectService _arConnectService; + Function()? _unsubscribeFromWalletSwitch; bool ignoreNextWaletSwitch = false; @@ -46,6 +47,13 @@ class LoginBloc extends Bloc { _listenToWalletChange(); } + @override + Future close() { + _unsubscribeFromWalletSwitch?.call(); + _unsubscribeFromWalletSwitch = null; + return super.close(); + } + Future _onLoginEvent(LoginEvent event, Emitter emit) async { if (event is AddWalletFile) { await _handleAddWalletFileEvent(event, emit); @@ -172,6 +180,8 @@ class LoginBloc extends Bloc { logger.e('Failed to unlock user with biometrics', e); } } + + logger.d('User is logged in, prompting for password'); emit(const PromptPassword()); return; @@ -180,7 +190,9 @@ class LoginBloc extends Bloc { if (event.gettingStarted) { _handleCreateNewWalletEvent(const CreateNewWallet(), emit); } else { - emit(LoginInitial(_arConnectService.isExtensionPresent())); + emit(LoginInitial( + isArConnectAvailable: _arConnectService.isExtensionPresent(), + )); } } @@ -257,6 +269,7 @@ class LoginBloc extends Bloc { final wallet = ArConnectWallet(_arConnectService); profileType = ProfileType.arConnect; + logger.i('ArConnect wallet detected - profile type: $profileType'); lastKnownWalletAddress = await wallet.getAddress(); @@ -267,6 +280,10 @@ class LoginBloc extends Bloc { } } catch (e) { emit(LoginFailure(e)); + logger.d( + 'Failed to add wallet from ArConnect' + ' - Emmiting previous state', + ); emit(previousState); } } @@ -279,7 +296,9 @@ class LoginBloc extends Bloc { await _arDriveAuth.logout(); } - emit(LoginInitial(_arConnectService.isExtensionPresent())); + emit(LoginInitial( + isArConnectAvailable: _arConnectService.isExtensionPresent(), + )); } Future _handleFinishOnboardingEvent( @@ -327,10 +346,14 @@ class LoginBloc extends Bloc { return; } - onArConnectWalletSwitch(() async { + // This method is not prepared to take a future. + _unsubscribeFromWalletSwitch = onArConnectWalletSwitch(() async { final isUserLoggedIng = await _arDriveAuth.isUserLoggedIn(); if (isUserLoggedIng && !_isArConnectWallet()) { - logger.d('Wallet switch detected. Is current profile ArConnect: false'); + logger.d( + 'Wallet switch detected for non-arconnect wallet' + ' ($profileType) - ignoring', + ); return; } @@ -339,14 +362,14 @@ class LoginBloc extends Bloc { return; } - logger.i('ArConnect wallet switched'); - // ignore: invalid_use_of_visible_for_testing_member - emit(const LoginFailure(WalletMismatchException())); - await _arDriveAuth.logout(); - // ignore: invalid_use_of_visible_for_testing_member - emit(const LoginInitial(true)); + logger.i('ArConnect wallet switched'); + // // ignore: invalid_use_of_visible_for_testing_member + // emit(const LoginFailure(WalletMismatchException())); + + // // ignore: invalid_use_of_visible_for_testing_member + // emit(const LoginInitial(isArConnectAvailable: true)); }); } diff --git a/lib/authentication/login/blocs/login_state.dart b/lib/authentication/login/blocs/login_state.dart index c1fbb0e497..17a9bf5321 100644 --- a/lib/authentication/login/blocs/login_state.dart +++ b/lib/authentication/login/blocs/login_state.dart @@ -8,9 +8,9 @@ abstract class LoginState extends Equatable { } class LoginInitial extends LoginState { - const LoginInitial(this.isArConnectAvailable); - final bool isArConnectAvailable; + + const LoginInitial({required this.isArConnectAvailable}); } class LoginLoading extends LoginState {} diff --git a/lib/authentication/login/views/login_page.dart b/lib/authentication/login/views/login_page.dart index f9b74975b9..a6646a3bce 100644 --- a/lib/authentication/login/views/login_page.dart +++ b/lib/authentication/login/views/login_page.dart @@ -86,7 +86,8 @@ class _LoginPageState extends State { if (loginState is LoginOnBoarding) { preCacheOnBoardingAssets(context); } else if (loginState is LoginFailure) { - // TODO: Verify if the error is `NoConnectionException` and show an appropriate message after validating with UI/UX + // TODO: Verify if the error is `NoConnectionException` and show an + /// appropriate message after validating with UI/UX logger.e('Login Failure', loginState.error); @@ -129,7 +130,9 @@ class _LoginPageState extends State { logger.d('Login Success, unlocking default profile'); context.read().unlockDefaultProfile( - loginState.user.password, loginState.user.profileType); + loginState.user.password, + loginState.user.profileType, + ); } }, builder: (context, loginState) { @@ -340,20 +343,13 @@ class _LoginPageScaffoldState extends State { final isOnBoarding = current is LoginOnBoarding; final isCreateNewWallet = current is LoginCreateNewWallet; - logger.d( - 'LoginBloc buildWhen' - ' - isFailure: $isFailure' - ' - isSuccess: $isSuccess' - ' - isOnBoarding: $isOnBoarding' - ' - isCreateNewWallet: $isCreateNewWallet', - ); - return !(isFailure || isSuccess || isOnBoarding || isCreateNewWallet); }, builder: (context, loginState) { late Widget content; if (loginState is PromptPassword) { + // HERE, Mati. content = PromptPasswordView( wallet: loginState.walletFile, ); @@ -405,13 +401,13 @@ class _LoginPageScaffoldState extends State { } class PromptWalletView extends StatefulWidget { + final bool isArConnectAvailable; + const PromptWalletView({ super.key, required this.isArConnectAvailable, }); - final bool isArConnectAvailable; - @override State createState() => _PromptWalletViewState(); } @@ -732,6 +728,9 @@ class PromptPasswordView extends StatefulWidget { } class _PromptPasswordViewState extends State { + final _passwordController = TextEditingController(); + bool _isPasswordValid = false; + @override void initState() { super.initState(); @@ -739,10 +738,6 @@ class _PromptPasswordViewState extends State { PlausibleEventTracker.track(event: PlausibleEvent.welcomeBackPage); } - final _passwordController = TextEditingController(); - - bool _isPasswordValid = false; - @override Widget build(BuildContext context) { return MaxDeviceSizesConstrainedBox( diff --git a/packages/ardrive_utils/lib/src/html/html_util.dart b/packages/ardrive_utils/lib/src/html/html_util.dart index da6736ad47..8d38bc7dc8 100644 --- a/packages/ardrive_utils/lib/src/html/html_util.dart +++ b/packages/ardrive_utils/lib/src/html/html_util.dart @@ -23,7 +23,7 @@ class TabVisibilitySingleton { } // TODO: Move this code to the arconnect package. -void onArConnectWalletSwitch(Function onWalletSwitch) => +Function() onArConnectWalletSwitch(Function onWalletSwitch) => implementation.onWalletSwitch(onWalletSwitch); void triggerHTMLPageReload() => implementation.reload(); diff --git a/packages/ardrive_utils/lib/src/html/implementations/html_stub.dart b/packages/ardrive_utils/lib/src/html/implementations/html_stub.dart index 57bc83962b..f869566100 100644 --- a/packages/ardrive_utils/lib/src/html/implementations/html_stub.dart +++ b/packages/ardrive_utils/lib/src/html/implementations/html_stub.dart @@ -25,8 +25,8 @@ StreamSubscription onTabGetsFocused(Function onFocus) { return emptyStream.listen((event) {}); } -void onWalletSwitch(Function onSwitch) { - return; +Function() onWalletSwitch(Function onSwitch) { + return () => null; } void reload() { diff --git a/packages/ardrive_utils/lib/src/html/implementations/html_web.dart b/packages/ardrive_utils/lib/src/html/implementations/html_web.dart index 18efe6bccf..da646624a8 100644 --- a/packages/ardrive_utils/lib/src/html/implementations/html_web.dart +++ b/packages/ardrive_utils/lib/src/html/implementations/html_web.dart @@ -26,10 +26,16 @@ StreamSubscription onTabGetsFocused(Function onFocus) { return subscription; } -void onWalletSwitch(Function onWalletSwitch) { +Function() onWalletSwitch(Function onWalletSwitch) { window.addEventListener('walletSwitch', (event) { onWalletSwitch(); }); + + return () { + window.removeEventListener('walletSwitch', (event) { + onWalletSwitch(); + }); + }; } void reload() { diff --git a/test/authentication/login/blocs/login_bloc_test.dart b/test/authentication/login/blocs/login_bloc_test.dart index 6e65a45347..c90c9f7da8 100644 --- a/test/authentication/login/blocs/login_bloc_test.dart +++ b/test/authentication/login/blocs/login_bloc_test.dart @@ -341,7 +341,10 @@ void main() { act: (bloc) async { bloc.add(const CheckIfUserIsLoggedIn()); }, - expect: () => [LoginLoading(), const LoginInitial(false)], + expect: () => [ + LoginLoading(), + const LoginInitial(isArConnectAvailable: false), + ], ); }); @@ -680,7 +683,7 @@ void main() { act: (bloc) async { bloc.add(const ForgetWallet()); }, - expect: () => [const LoginInitial(false)], + expect: () => [const LoginInitial(isArConnectAvailable: false)], ); blocTest( 'should emit the initial login state and not call logout when user is not logged in', @@ -706,7 +709,7 @@ void main() { bloc.add(const ForgetWallet()); }, verify: (bloc) => verifyNever(() => mockArDriveAuth.logout()), - expect: () => [const LoginInitial(false)], + expect: () => [const LoginInitial(isArConnectAvailable: false)], ); }); From c937429a4159ca6dc5a4c6f27e5365039e027f96 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 14 Nov 2023 12:10:33 -0300 Subject: [PATCH 2/6] feat(misc): cleanup PE-5015 --- lib/authentication/ardrive_auth.dart | 2 -- lib/authentication/login/blocs/login_bloc.dart | 14 -------------- lib/authentication/login/views/login_page.dart | 1 - 3 files changed, 17 deletions(-) diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index 2ee2e02c06..844e1ad59e 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -218,8 +218,6 @@ class ArDriveAuthImpl implements ArDriveAuth { logger.i('Logging out user'); try { - logger.d('Current user: $_currentUser'); - if (_currentUser != null) { await _secureKeyValueStore.remove('password'); await _secureKeyValueStore.remove('biometricEnabled'); diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index d87b3ff426..379789814e 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -180,10 +180,7 @@ class LoginBloc extends Bloc { logger.e('Failed to unlock user with biometrics', e); } } - - logger.d('User is logged in, prompting for password'); emit(const PromptPassword()); - return; } @@ -269,7 +266,6 @@ class LoginBloc extends Bloc { final wallet = ArConnectWallet(_arConnectService); profileType = ProfileType.arConnect; - logger.i('ArConnect wallet detected - profile type: $profileType'); lastKnownWalletAddress = await wallet.getAddress(); @@ -280,10 +276,6 @@ class LoginBloc extends Bloc { } } catch (e) { emit(LoginFailure(e)); - logger.d( - 'Failed to add wallet from ArConnect' - ' - Emmiting previous state', - ); emit(previousState); } } @@ -346,7 +338,6 @@ class LoginBloc extends Bloc { return; } - // This method is not prepared to take a future. _unsubscribeFromWalletSwitch = onArConnectWalletSwitch(() async { final isUserLoggedIng = await _arDriveAuth.isUserLoggedIn(); if (isUserLoggedIng && !_isArConnectWallet()) { @@ -365,11 +356,6 @@ class LoginBloc extends Bloc { await _arDriveAuth.logout(); logger.i('ArConnect wallet switched'); - // // ignore: invalid_use_of_visible_for_testing_member - // emit(const LoginFailure(WalletMismatchException())); - - // // ignore: invalid_use_of_visible_for_testing_member - // emit(const LoginInitial(isArConnectAvailable: true)); }); } diff --git a/lib/authentication/login/views/login_page.dart b/lib/authentication/login/views/login_page.dart index a6646a3bce..1d3e9f1e74 100644 --- a/lib/authentication/login/views/login_page.dart +++ b/lib/authentication/login/views/login_page.dart @@ -349,7 +349,6 @@ class _LoginPageScaffoldState extends State { late Widget content; if (loginState is PromptPassword) { - // HERE, Mati. content = PromptPasswordView( wallet: loginState.walletFile, ); From 7027f1b3f3f1e0c7ff40d3c511e8ddf987d6c6c0 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 14 Nov 2023 12:16:03 -0300 Subject: [PATCH 3/6] feat(arconnect): onWalletSwitch smol refactor PE-5015 --- .../lib/src/html/implementations/html_web.dart | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/ardrive_utils/lib/src/html/implementations/html_web.dart b/packages/ardrive_utils/lib/src/html/implementations/html_web.dart index da646624a8..eb6073f10a 100644 --- a/packages/ardrive_utils/lib/src/html/implementations/html_web.dart +++ b/packages/ardrive_utils/lib/src/html/implementations/html_web.dart @@ -27,15 +27,12 @@ StreamSubscription onTabGetsFocused(Function onFocus) { } Function() onWalletSwitch(Function onWalletSwitch) { - window.addEventListener('walletSwitch', (event) { + void listener(event) { onWalletSwitch(); - }); + } - return () { - window.removeEventListener('walletSwitch', (event) { - onWalletSwitch(); - }); - }; + window.addEventListener('walletSwitch', listener); + return () => window.removeEventListener('walletSwitch', listener); } void reload() { From dc5bcad1d4b359a4f93016cf557a177bd9438647 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 14 Nov 2023 15:33:13 -0300 Subject: [PATCH 4/6] feat(wallet switch event listener): makes the3 components not to close the event listeners PE-5015 --- lib/app_shell.dart | 48 +++++++++---------- .../login/blocs/login_bloc.dart | 10 +--- .../src/html/implementations/html_web.dart | 6 +-- 3 files changed, 25 insertions(+), 39 deletions(-) diff --git a/lib/app_shell.dart b/lib/app_shell.dart index b2a06f2046..6791185633 100644 --- a/lib/app_shell.dart +++ b/lib/app_shell.dart @@ -31,39 +31,35 @@ class AppShell extends StatefulWidget { class AppShellState extends State { bool _showProfileOverlay = false; bool _showWalletSwitchDialog = true; - Function()? _unregisterWalletSwitchListener; @override - void dispose() { - _unregisterWalletSwitchListener?.call(); - _unregisterWalletSwitchListener = null; - super.dispose(); + void initState() { + onArConnectWalletSwitch(() { + context.read().isCurrentProfileArConnect().then( + (isCurrentProfileArConnect) { + if (_showWalletSwitchDialog) { + if (isCurrentProfileArConnect) { + showDialog( + context: context, + builder: (context) => const WalletSwitchDialog(), + ); + } else { + logger.d('Wallet switch detected while not logged in' + ' to ArConnect. Ignoring.'); + } + } + // Used to prevent the dialog being shown multiple times. + _showWalletSwitchDialog = false; + }, + ); + }); + + super.initState(); } @override Widget build(BuildContext context) => BlocBuilder( builder: (context, _) { - _unregisterWalletSwitchListener = onArConnectWalletSwitch(() { - context - .read() - .isCurrentProfileArConnect() - .then((isCurrentProfileArConnect) { - if (_showWalletSwitchDialog) { - if (isCurrentProfileArConnect) { - showDialog( - context: context, - builder: (context) => const WalletSwitchDialog(), - ); - } else { - logger.d('Wallet switch detected while not logged in' - ' to ArConnect. Ignoring.'); - } - } - //Used to prevent the dialog being shown multiple times. - _showWalletSwitchDialog = false; - }); - }); - Widget buildPage(scaffold) => Material( child: BlocBuilder( builder: (context, syncState) => syncState is SyncInProgress diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index 379789814e..fe35ec9cfb 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -26,7 +26,6 @@ part 'login_state.dart'; class LoginBloc extends Bloc { final ArDriveAuth _arDriveAuth; final ArConnectService _arConnectService; - Function()? _unsubscribeFromWalletSwitch; bool ignoreNextWaletSwitch = false; @@ -47,13 +46,6 @@ class LoginBloc extends Bloc { _listenToWalletChange(); } - @override - Future close() { - _unsubscribeFromWalletSwitch?.call(); - _unsubscribeFromWalletSwitch = null; - return super.close(); - } - Future _onLoginEvent(LoginEvent event, Emitter emit) async { if (event is AddWalletFile) { await _handleAddWalletFileEvent(event, emit); @@ -338,7 +330,7 @@ class LoginBloc extends Bloc { return; } - _unsubscribeFromWalletSwitch = onArConnectWalletSwitch(() async { + onArConnectWalletSwitch(() async { final isUserLoggedIng = await _arDriveAuth.isUserLoggedIn(); if (isUserLoggedIng && !_isArConnectWallet()) { logger.d( diff --git a/packages/ardrive_utils/lib/src/html/implementations/html_web.dart b/packages/ardrive_utils/lib/src/html/implementations/html_web.dart index eb6073f10a..41ffa0051e 100644 --- a/packages/ardrive_utils/lib/src/html/implementations/html_web.dart +++ b/packages/ardrive_utils/lib/src/html/implementations/html_web.dart @@ -26,10 +26,8 @@ StreamSubscription onTabGetsFocused(Function onFocus) { return subscription; } -Function() onWalletSwitch(Function onWalletSwitch) { - void listener(event) { - onWalletSwitch(); - } +Function() onWalletSwitch(Function callback) { + listener(event) => callback(); window.addEventListener('walletSwitch', listener); return () => window.removeEventListener('walletSwitch', listener); From 421c7f8dbc25c9f8e2e02c5f3efec17ea14d1c95 Mon Sep 17 00:00:00 2001 From: Mati Date: Tue, 14 Nov 2023 15:36:24 -0300 Subject: [PATCH 5/6] test(ardrive auth): updates tests PE-5015 --- lib/authentication/ardrive_auth.dart | 2 +- lib/user/repositories/user_repository.dart | 2 +- test/authentication/ardrive_auth_test.dart | 14 +++++--------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/authentication/ardrive_auth.dart b/lib/authentication/ardrive_auth.dart index 844e1ad59e..bcea3421ad 100644 --- a/lib/authentication/ardrive_auth.dart +++ b/lib/authentication/ardrive_auth.dart @@ -229,7 +229,7 @@ class ArDriveAuthImpl implements ArDriveAuth { await _userRepository.deleteUser(); await _databaseHelpers.deleteAllTables(); - (await _metadataCache).clear(); + await (await _metadataCache).clear(); } catch (e) { logger.e('Failed to logout user', e); throw AuthenticationFailedException('Failed to logout user'); diff --git a/lib/user/repositories/user_repository.dart b/lib/user/repositories/user_repository.dart index 573b1cab88..ecc7ccc25c 100644 --- a/lib/user/repositories/user_repository.dart +++ b/lib/user/repositories/user_repository.dart @@ -90,7 +90,7 @@ class _UserRepository implements UserRepository { return profile != null; } - // Will return null if no user is not logged in - i.e. not present in the DB + // Will return null if no user is logged in - i.e. not present in the DB @override Future getOwnerOfDefaultProfile() async { final profile = await _profileDao.getDefaultProfile(); diff --git a/test/authentication/ardrive_auth_test.dart b/test/authentication/ardrive_auth_test.dart index dc9d87b019..89b542dfec 100644 --- a/test/authentication/ardrive_auth_test.dart +++ b/test/authentication/ardrive_auth_test.dart @@ -531,15 +531,17 @@ void main() { () async { when(() => mockUserRepository.hasUser()) .thenAnswer((invocation) => Future.value(false)); - when(() => mockDatabaseHelpers.deleteAllTables()) .thenAnswer((invocation) async {}); + when(() => mockUserRepository.deleteUser()) + .thenAnswer((invocation) async {}); await arDriveAuth.logout(); verifyNever(() => mockSecureKeyValueStore.remove('password')); verifyNever(() => mockSecureKeyValueStore.remove('biometricEnabled')); verify(() => mockDatabaseHelpers.deleteAllTables()).called(1); + verify(() => mockUserRepository.deleteUser()).called(1); expect(() => arDriveAuth.currentUser, throwsA(isA())); }); @@ -556,10 +558,8 @@ void main() { when(() => mockArweaveService.getFirstPrivateDriveTxId(wallet, maxRetries: any(named: 'maxRetries'))) .thenAnswer((_) async => 'some_id'); - when(() => mockBiometricAuthentication.isEnabled()) .thenAnswer((_) async => false); - when( () => mockArDriveCrypto.deriveDriveKey( wallet, @@ -567,27 +567,21 @@ void main() { any(), ), ).thenAnswer((invocation) => Future.value(SecretKey([]))); - when(() => mockUserRepository.hasUser()) .thenAnswer((invocation) => Future.value(true)); - when(() => mockArweaveService.getLatestDriveEntityWithId( any(), any(), any())) .thenAnswer((invocation) => Future.value(DriveEntity( id: 'some_id', rootFolderId: 'some_id', ))); - when(() => mockUserRepository.deleteUser()) .thenAnswer((invocation) async {}); - when(() => mockUserRepository.saveUser( 'password', ProfileType.json, wallet)) .thenAnswer((invocation) => Future.value(null)); - when(() => mockUserRepository.getUser('password')) .thenAnswer((invocation) async => loggedUser); - when(() => mockUserRepository.deleteUser()) .thenAnswer((invocation) async {}); when(() => mockSecureKeyValueStore.remove('password')) @@ -599,6 +593,8 @@ void main() { await arDriveAuth.login(wallet, 'password', ProfileType.json); + verify(() => mockUserRepository.deleteUser()).called(1); + await arDriveAuth.logout(); expect(arDriveAuth.firstPrivateDriveTxId, isNull); From 5f99d1a78c504ae7f0b82d9a10c7f3c4aa8945da Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Mon, 27 Nov 2023 10:27:05 -0300 Subject: [PATCH 6/6] fix(logout) waits for the deleting the user before sending the user for the login page --- lib/authentication/login/blocs/login_bloc.dart | 6 ++++++ lib/components/wallet_switch_dialog.dart | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/authentication/login/blocs/login_bloc.dart b/lib/authentication/login/blocs/login_bloc.dart index fe35ec9cfb..35a5e69385 100644 --- a/lib/authentication/login/blocs/login_bloc.dart +++ b/lib/authentication/login/blocs/login_bloc.dart @@ -161,10 +161,16 @@ class LoginBloc extends Bloc { CheckIfUserIsLoggedIn event, Emitter emit, ) async { + logger.d('Checking if user is logged in'); + emit(LoginLoading()); if (await _arDriveAuth.isUserLoggedIn()) { + logger.d('User is logged in'); + if (await _arDriveAuth.isBiometricsEnabled()) { + logger.d('Biometrics is enabled'); + try { await _loginWithBiometrics(emit: emit); return; diff --git a/lib/components/wallet_switch_dialog.dart b/lib/components/wallet_switch_dialog.dart index 849db22a16..e3c19b4e84 100644 --- a/lib/components/wallet_switch_dialog.dart +++ b/lib/components/wallet_switch_dialog.dart @@ -1,3 +1,6 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:ardrive/authentication/ardrive_auth.dart'; import 'package:ardrive/blocs/blocs.dart'; import 'package:ardrive/components/app_dialog.dart'; import 'package:ardrive/utils/app_localizations_wrapper.dart'; @@ -22,9 +25,12 @@ class WalletSwitchDialog extends StatelessWidget { ), actions: [ TextButton( - onPressed: () { + onPressed: () async { + await context.read().logout(); + await context.read().logoutProfile(); + Navigator.pop(context); - context.read().logoutProfile(); + if (fromAuthPage) { triggerHTMLPageReload(); context.read().promptForWallet();