From 672f275b430c4801d1e532f2dcb399c155a335cf Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Tue, 21 May 2024 13:16:05 +0700 Subject: [PATCH 1/5] TW-1785: Improve logout for multiple homeserver --- .../settings_dashboard/settings/settings.dart | 42 +++++++++++-- .../mixins/connect_page_mixin.dart | 1 + lib/widgets/matrix.dart | 61 +++++++++++++------ 3 files changed, 82 insertions(+), 22 deletions(-) diff --git a/lib/pages/settings_dashboard/settings/settings.dart b/lib/pages/settings_dashboard/settings/settings.dart index 4a56c4edfd..30b292aa86 100644 --- a/lib/pages/settings_dashboard/settings/settings.dart +++ b/lib/pages/settings_dashboard/settings/settings.dart @@ -86,11 +86,40 @@ class SettingsController extends State with ConnectPageMixin { OkCancelResult.cancel) { return; } - final matrix = Matrix.of(context); if (PlatformInfos.isMobile) { + await _logoutActionsOnMobile(); + } else { + await _logoutActionsOnWeb(); + } + } + + Future _logoutActionsOnMobile() async { + try { await tryLogoutSso(context); + } catch (e) { + Logs().e('SettingsController()::_logoutActionsOnMobile - error: $e'); + return; + } + if (matrix.canDeleteToMDatabase == true) { + final hiveCollectionToMDatabase = getIt.get(); + await hiveCollectionToMDatabase.clear(); } - if (matrix.twakeSupported == true) { + await TwakeDialog.showFutureLoadingDialogFullScreen( + future: () async { + try { + if (matrix.backgroundPush != null) { + await matrix.backgroundPush!.removeCurrentPusher(); + } + await matrix.client.logout(); + } catch (e) { + Logs().e('SettingsController()::_logoutActionsOnMobile - error: $e'); + } + }, + ); + } + + Future _logoutActionsOnWeb() async { + if (matrix.canDeleteToMDatabase == true) { final hiveCollectionToMDatabase = getIt.get(); await hiveCollectionToMDatabase.clear(); } @@ -102,10 +131,15 @@ class SettingsController extends State with ConnectPageMixin { } await matrix.client.logout(); } catch (e) { - Logs().e('SettingsController()::logoutAction - error: $e'); + Logs().e('SettingsController()::_logoutActionsOnWeb - error: $e'); } finally { if (PlatformInfos.isWeb) { - await tryLogoutSso(context); + try { + await tryLogoutSso(context); + } catch (e) { + Logs().e('SettingsController()::_logoutActionsOnWeb - error: $e'); + return; + } } } }, diff --git a/lib/presentation/mixins/connect_page_mixin.dart b/lib/presentation/mixins/connect_page_mixin.dart index b16f423b65..67114b1849 100644 --- a/lib/presentation/mixins/connect_page_mixin.dart +++ b/lib/presentation/mixins/connect_page_mixin.dart @@ -177,6 +177,7 @@ mixin ConnectPageMixin { Logs().d('tryLogoutSso::result: $result'); } catch (e) { Logs().d('tryLogoutSso::error: $e'); + rethrow; } } diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 887bcee2cf..4e56cc0b2d 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -81,7 +81,7 @@ class MatrixState extends State String? activeBundle; Store store = Store(); HomeserverSummary? loginHomeserverSummary; - String? authUrl; + String? _authUrl; XFile? loginAvatar; String? loginUsername; LoginType? loginType; @@ -94,8 +94,16 @@ class MatrixState extends State return tomServerUrlInterceptor.baseUrl != null; } + bool get canDeleteToMDatabase { + final lastClientTwakeSupport = + widget.clients.where((client) => client.homeserver != null).length == 1; + return lastClientTwakeSupport && twakeSupported; + } + BackgroundPush? backgroundPush; + String? get authUrl => _authUrl; + Client get client { if (widget.clients.isEmpty) { widget.clients.add(getLoginClient()); @@ -125,7 +133,7 @@ class MatrixState extends State _activeClient = index; // TODO: Multi-client VoiP support createVoipPlugin(); - _setUpToMServicesWhenChangingActiveClient(newClient); + await _setUpToMServicesWhenChangingActiveClient(newClient); await _storePersistActiveAccount(newClient!); return SetActiveClientState.success; } else { @@ -392,7 +400,7 @@ class MatrixState extends State ) async { await _cancelSubs(currentClient.clientName); widget.clients.remove(currentClient); - ClientManager.removeClientNameFromStore(currentClient.clientName); + await ClientManager.removeClientNameFromStore(currentClient.clientName); TwakeSnackBar.show( TwakeApp.routerKey.currentContext!, L10n.of(context)!.oneClientLoggedOut, @@ -411,8 +419,8 @@ class MatrixState extends State } } - void _handleFirstLoggedIn(Client newActiveClient) { - setUpToMServicesInLogin(newActiveClient); + Future _handleFirstLoggedIn(Client newActiveClient) async { + await setUpToMServicesInLogin(newActiveClient); _storePersistActiveAccount(newActiveClient); TwakeApp.router.go( '/rooms', @@ -439,7 +447,7 @@ class MatrixState extends State _loginClientCandidate!.clientName, ); if (activeClient == null) return; - setUpToMServicesInLogin(activeClient); + await setUpToMServicesInLogin(activeClient); final result = await setActiveClient(activeClient); if (result.isSuccess) { TwakeApp.router.go( @@ -566,7 +574,7 @@ class MatrixState extends State toMConfigurations.tomServerInformation, toMConfigurations.identityServerInformation, ); - authUrl = toMConfigurations.authUrl; + _setupAuthUrl(url: toMConfigurations.authUrl); loginType = toMConfigurations.loginType; } catch (e) { Logs().e('MatrixState::_retrieveToMConfiguration: $e'); @@ -588,7 +596,7 @@ class MatrixState extends State } } - void setUpToMServicesInLogin(Client client) { + Future setUpToMServicesInLogin(Client client) async { final tomServer = loginHomeserverSummary?.tomServer; Logs().d('MatrixState::setUpToMServicesInLogin: $tomServer'); if (tomServer != null) { @@ -598,9 +606,7 @@ class MatrixState extends State loginHomeserverSummary?.discoveryInformation?.mIdentityServer; final homeServer = loginHomeserverSummary?.discoveryInformation?.mHomeserver; - final newAuthUrl = loginHomeserverSummary?.discoveryInformation - ?.additionalProperties["m.authentication"]?["issuer"]; - authUrl = newAuthUrl is String ? newAuthUrl : null; + _setupAuthUrl(); if (identityServer != null) { _setUpIdentityServer(identityServer); } @@ -608,7 +614,7 @@ class MatrixState extends State _setUpHomeServer(homeServer.baseUrl); } if (tomServer != null) { - _storeToMConfiguration( + await _storeToMConfiguration( client, ToMConfigurations( tomServerInformation: tomServer, @@ -657,10 +663,10 @@ class MatrixState extends State .changeBaseUrl(identityServer.baseUrl.toString()); } - void _storeToMConfiguration( + Future _storeToMConfiguration( Client client, ToMConfigurations config, - ) { + ) async { try { Logs().e( 'Matrix::_storeToMConfiguration: clientName - ${client.clientName}', @@ -671,7 +677,7 @@ class MatrixState extends State if (client.userID == null) return; final ToMConfigurationsRepository configurationRepository = getIt.get(); - configurationRepository.saveTomConfigurations( + await configurationRepository.saveTomConfigurations( client.userID!, config, ); @@ -683,7 +689,7 @@ class MatrixState extends State } } - void _setUpToMServicesWhenChangingActiveClient(Client? client) async { + Future _setUpToMServicesWhenChangingActiveClient(Client? client) async { Logs().d( 'Matrix::_checkHomeserverExists: Old twakeSupported - $twakeSupported', ); @@ -697,6 +703,7 @@ class MatrixState extends State _setUpToMServer(null); } else { _setUpToMServer(toMConfigurations.tomServerInformation); + _setupAuthUrl(url: toMConfigurations.authUrl); } } catch (e) { _setUpToMServer(null); @@ -731,10 +738,10 @@ class MatrixState extends State Future _storePersistActiveAccount(Client newClient) async { if (newClient.userID == null) return; try { - Logs().e( + Logs().d( 'Matrix::_storePersistActiveAccount: clientName - ${newClient.clientName}', ); - Logs().e( + Logs().d( 'Matrix::_storePersistActiveAccount: userId - ${newClient.userID}', ); final MultipleAccountRepository multipleAccountRepository = @@ -757,6 +764,24 @@ class MatrixState extends State didChangeAppLifecycleState(AppLifecycleState.paused); } + Future _setupAuthUrl({ + String? url, + }) async { + final newAuthUrl = loginHomeserverSummary?.discoveryInformation + ?.additionalProperties["m.authentication"]?["issuer"]; + if (url != null) { + Logs().e( + 'Matrix::_setupAuthUrl: newAuthUrl - $url', + ); + _authUrl = url; + } else { + Logs().e( + 'Matrix::_setupAuthUrl: newAuthUrl - $newAuthUrl', + ); + _authUrl = newAuthUrl is String ? newAuthUrl : url; + } + } + @override void didChangeAppLifecycleState(AppLifecycleState state) { Logs().i('didChangeAppLifecycleState: AppLifecycleState = $state'); From 97ac2d3c501563598ecb7627da2c696f92a2e8d4 Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Wed, 22 May 2024 00:18:51 +0700 Subject: [PATCH 2/5] fixup! TW-1785: Improve logout for multiple homeserver --- .../tom_configurations_datasource.dart | 2 + .../tom_configurations_datasource_impl.dart | 6 ++ .../tom_configurations_repository_impl.dart | 5 ++ .../tom_configurations_repository.dart | 2 + .../settings_dashboard/settings/settings.dart | 59 ++++++++++++------- lib/widgets/matrix.dart | 29 +++++---- 6 files changed, 70 insertions(+), 33 deletions(-) diff --git a/lib/data/datasource/tom_configurations_datasource.dart b/lib/data/datasource/tom_configurations_datasource.dart index a39ae18400..6cfac3820c 100644 --- a/lib/data/datasource/tom_configurations_datasource.dart +++ b/lib/data/datasource/tom_configurations_datasource.dart @@ -7,4 +7,6 @@ abstract class ToMConfigurationsDatasource { String userId, ToMConfigurations toMConfigurations, ); + + Future deleteTomConfigurations(String userId); } diff --git a/lib/data/datasource_impl/tom_configurations_datasource_impl.dart b/lib/data/datasource_impl/tom_configurations_datasource_impl.dart index b6914654ed..2a51dc247a 100644 --- a/lib/data/datasource_impl/tom_configurations_datasource_impl.dart +++ b/lib/data/datasource_impl/tom_configurations_datasource_impl.dart @@ -46,4 +46,10 @@ class HiveToMConfigurationDatasource implements ToMConfigurationsDatasource { .toJson(), ); } + + @override + Future deleteTomConfigurations(String userId) { + final hiveCollectionToMDatabase = getIt.get(); + return hiveCollectionToMDatabase.tomConfigurationsBox.delete(userId); + } } diff --git a/lib/data/repository/tom_configurations_repository_impl.dart b/lib/data/repository/tom_configurations_repository_impl.dart index 4a8bcdc115..9ddecd06f0 100644 --- a/lib/data/repository/tom_configurations_repository_impl.dart +++ b/lib/data/repository/tom_configurations_repository_impl.dart @@ -22,4 +22,9 @@ class ToMConfigurationsRepositoryImpl implements ToMConfigurationsRepository { toMConfigurations, ); } + + @override + Future deleteTomConfigurations(String userId) { + return tomConfigurationsDatasource.deleteTomConfigurations(userId); + } } diff --git a/lib/domain/repository/tom_configurations_repository.dart b/lib/domain/repository/tom_configurations_repository.dart index 673f1ee6ce..de71cb74bc 100644 --- a/lib/domain/repository/tom_configurations_repository.dart +++ b/lib/domain/repository/tom_configurations_repository.dart @@ -7,4 +7,6 @@ abstract class ToMConfigurationsRepository { String userId, ToMConfigurations toMConfigurations, ); + + Future deleteTomConfigurations(String userId); } diff --git a/lib/pages/settings_dashboard/settings/settings.dart b/lib/pages/settings_dashboard/settings/settings.dart index 30b292aa86..73f31a7d79 100644 --- a/lib/pages/settings_dashboard/settings/settings.dart +++ b/lib/pages/settings_dashboard/settings/settings.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/data/hive/hive_collection_tom_database.dart'; import 'package:fluffychat/di/global/get_it_initializer.dart'; +import 'package:fluffychat/domain/repository/tom_configurations_repository.dart'; import 'package:fluffychat/event/twake_inapp_event_types.dart'; import 'package:fluffychat/pages/bootstrap/bootstrap_dialog.dart'; import 'package:fluffychat/presentation/mixins/connect_page_mixin.dart'; @@ -39,6 +39,8 @@ class SettingsController extends State with ConnectPageMixin { final ValueNotifier avatarUriNotifier = ValueNotifier(Uri()); final ValueNotifier displayNameNotifier = ValueNotifier(''); + final tomConfigurationRepository = getIt.get(); + StreamSubscription? onAccountDataSubscription; final List getListSettingItem = [ @@ -89,7 +91,7 @@ class SettingsController extends State with ConnectPageMixin { if (PlatformInfos.isMobile) { await _logoutActionsOnMobile(); } else { - await _logoutActionsOnWeb(); + await _logoutActions(); } } @@ -100,17 +102,16 @@ class SettingsController extends State with ConnectPageMixin { Logs().e('SettingsController()::_logoutActionsOnMobile - error: $e'); return; } - if (matrix.canDeleteToMDatabase == true) { - final hiveCollectionToMDatabase = getIt.get(); - await hiveCollectionToMDatabase.clear(); - } await TwakeDialog.showFutureLoadingDialogFullScreen( future: () async { try { if (matrix.backgroundPush != null) { await matrix.backgroundPush!.removeCurrentPusher(); } - await matrix.client.logout(); + Future.wait([ + matrix.client.logout(), + _deleteTomConfigurations(matrix.client), + ]); } catch (e) { Logs().e('SettingsController()::_logoutActionsOnMobile - error: $e'); } @@ -118,28 +119,25 @@ class SettingsController extends State with ConnectPageMixin { ); } - Future _logoutActionsOnWeb() async { - if (matrix.canDeleteToMDatabase == true) { - final hiveCollectionToMDatabase = getIt.get(); - await hiveCollectionToMDatabase.clear(); - } + Future _logoutActions() async { await TwakeDialog.showFutureLoadingDialogFullScreen( future: () async { try { if (matrix.backgroundPush != null) { await matrix.backgroundPush!.removeCurrentPusher(); } - await matrix.client.logout(); + Future.wait([ + matrix.client.logout(), + _deleteTomConfigurations(matrix.client), + ]); } catch (e) { - Logs().e('SettingsController()::_logoutActionsOnWeb - error: $e'); + Logs().e('SettingsController()::_logoutActions - error: $e'); } finally { - if (PlatformInfos.isWeb) { - try { - await tryLogoutSso(context); - } catch (e) { - Logs().e('SettingsController()::_logoutActionsOnWeb - error: $e'); - return; - } + try { + await tryLogoutSso(context); + } catch (e) { + Logs().e('SettingsController()::_logoutActions - error: $e'); + return; } } }, @@ -278,6 +276,25 @@ class SettingsController extends State with ConnectPageMixin { }); } + Future _deleteTomConfigurations(Client currentClient) async { + try { + Logs().d( + 'SettingsController::_deleteTomConfigurations - Client ID: ${currentClient.userID}', + ); + if (matrix.twakeSupported) { + await tomConfigurationRepository + .deleteTomConfigurations(currentClient.userID!); + } + Logs().d( + 'SettingsController::_deleteTomConfigurations - Success', + ); + } catch (e) { + Logs().e( + 'SettingsController::_deleteTomConfigurations - error: $e', + ); + } + } + @override void initState() { _getCurrentProfile(client); diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 4e56cc0b2d..0110c18457 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -94,12 +94,6 @@ class MatrixState extends State return tomServerUrlInterceptor.baseUrl != null; } - bool get canDeleteToMDatabase { - final lastClientTwakeSupport = - widget.clients.where((client) => client.homeserver != null).length == 1; - return lastClientTwakeSupport && twakeSupported; - } - BackgroundPush? backgroundPush; String? get authUrl => _authUrl; @@ -385,7 +379,7 @@ class MatrixState extends State } else { Logs().v('[MATRIX]:_listenLoginStateChanged:: Log out successful'); if (PlatformInfos.isMobile) { - _deletePersistActiveAccount(state); + await _deletePersistActiveAccount(); TwakeApp.router.go('/home/twakeWelcome'); } else { TwakeApp.router.go('/home', extra: true); @@ -421,7 +415,7 @@ class MatrixState extends State Future _handleFirstLoggedIn(Client newActiveClient) async { await setUpToMServicesInLogin(newActiveClient); - _storePersistActiveAccount(newActiveClient); + await _storePersistActiveAccount(newActiveClient); TwakeApp.router.go( '/rooms', extra: LoggedInBodyArgs( @@ -460,10 +454,13 @@ class MatrixState extends State } } - void _deletePersistActiveAccount(LoginState state) async { + Future _deletePersistActiveAccount() async { try { final multipleAccountRepository = getIt.get(); - await multipleAccountRepository.deletePersistActiveAccount(); + await Future.wait([ + multipleAccountRepository.deletePersistActiveAccount(), + _deleteAllTomConfigurations(), + ]); Logs().d( 'MatrixState::_handleLogoutWithMultipleAccount: Delete persist active account success', ); @@ -720,12 +717,12 @@ class MatrixState extends State final persistActiveAccount = await multipleAccountRepository.getPersistActiveAccount(); if (persistActiveAccount == null) { - _storePersistActiveAccount(client); + await _storePersistActiveAccount(client); return; } else { final newActiveClient = getClientByUserId(persistActiveAccount); if (newActiveClient != null) { - setActiveClient(newActiveClient); + await setActiveClient(newActiveClient); } } } catch (e) { @@ -782,6 +779,14 @@ class MatrixState extends State } } + Future _deleteAllTomConfigurations() async { + final hiveCollectionToMDatabase = getIt.get(); + await hiveCollectionToMDatabase.clear(); + Logs().d( + 'MatrixState::_deleteAllTomConfigurations: Delete ToM database success', + ); + } + @override void didChangeAppLifecycleState(AppLifecycleState state) { Logs().i('didChangeAppLifecycleState: AppLifecycleState = $state'); From adf2d4099aaa9f0dc29b331bb817641b1fb2c5ba Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Wed, 22 May 2024 00:21:05 +0700 Subject: [PATCH 3/5] fixup! fixup! TW-1785: Improve logout for multiple homeserver --- lib/widgets/matrix.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 0110c18457..56a4ace5a6 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -764,14 +764,14 @@ class MatrixState extends State Future _setupAuthUrl({ String? url, }) async { - final newAuthUrl = loginHomeserverSummary?.discoveryInformation - ?.additionalProperties["m.authentication"]?["issuer"]; if (url != null) { Logs().e( 'Matrix::_setupAuthUrl: newAuthUrl - $url', ); _authUrl = url; } else { + final newAuthUrl = loginHomeserverSummary?.discoveryInformation + ?.additionalProperties["m.authentication"]?["issuer"]; Logs().e( 'Matrix::_setupAuthUrl: newAuthUrl - $newAuthUrl', ); From b4b4310dbb70de38d75f86dd93c3d2c40a5c44b2 Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Wed, 22 May 2024 00:25:14 +0700 Subject: [PATCH 4/5] fixup! fixup! fixup! TW-1785: Improve logout for multiple homeserver --- lib/pages/settings_dashboard/settings/settings.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pages/settings_dashboard/settings/settings.dart b/lib/pages/settings_dashboard/settings/settings.dart index 73f31a7d79..bd33e7b0aa 100644 --- a/lib/pages/settings_dashboard/settings/settings.dart +++ b/lib/pages/settings_dashboard/settings/settings.dart @@ -108,7 +108,7 @@ class SettingsController extends State with ConnectPageMixin { if (matrix.backgroundPush != null) { await matrix.backgroundPush!.removeCurrentPusher(); } - Future.wait([ + await Future.wait([ matrix.client.logout(), _deleteTomConfigurations(matrix.client), ]); @@ -126,7 +126,7 @@ class SettingsController extends State with ConnectPageMixin { if (matrix.backgroundPush != null) { await matrix.backgroundPush!.removeCurrentPusher(); } - Future.wait([ + await Future.wait([ matrix.client.logout(), _deleteTomConfigurations(matrix.client), ]); From e0d302943e889ffb44d5c635be6afa8ef2123ebe Mon Sep 17 00:00:00 2001 From: HuyNguyen Date: Thu, 23 May 2024 10:22:12 +0700 Subject: [PATCH 5/5] fixup! fixup! fixup! fixup! TW-1785: Improve logout for multiple homeserver --- lib/widgets/matrix.dart | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 56a4ace5a6..2904728166 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -377,13 +377,8 @@ class MatrixState extends State Logs().v('[MATRIX]:_listenLoginStateChanged:: First Log in successful'); _handleFirstLoggedIn(client); } else { - Logs().v('[MATRIX]:_listenLoginStateChanged:: Log out successful'); - if (PlatformInfos.isMobile) { - await _deletePersistActiveAccount(); - TwakeApp.router.go('/home/twakeWelcome'); - } else { - TwakeApp.router.go('/home', extra: true); - } + Logs().v('[MATRIX]:_listenLoginStateChanged:: Last Log out successful'); + await _handleLastLogout(); } } } @@ -457,10 +452,7 @@ class MatrixState extends State Future _deletePersistActiveAccount() async { try { final multipleAccountRepository = getIt.get(); - await Future.wait([ - multipleAccountRepository.deletePersistActiveAccount(), - _deleteAllTomConfigurations(), - ]); + await multipleAccountRepository.deletePersistActiveAccount(); Logs().d( 'MatrixState::_handleLogoutWithMultipleAccount: Delete persist active account success', ); @@ -787,6 +779,16 @@ class MatrixState extends State ); } + Future _handleLastLogout() async { + if (PlatformInfos.isMobile) { + await _deletePersistActiveAccount(); + TwakeApp.router.go('/home/twakeWelcome'); + } else { + TwakeApp.router.go('/home', extra: true); + } + await _deleteAllTomConfigurations(); + } + @override void didChangeAppLifecycleState(AppLifecycleState state) { Logs().i('didChangeAppLifecycleState: AppLifecycleState = $state');