From a2d37102a46f37cd053a376c107114a1d5e5dcef Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sat, 18 Sep 2021 12:50:02 +0200 Subject: [PATCH] feat: Multi account login working --- lib/pages/homeserver_picker.dart | 18 +++++++------- lib/pages/login.dart | 26 +++++++++++---------- lib/pages/signup.dart | 2 +- lib/pages/views/homeserver_picker_view.dart | 2 +- lib/pages/views/login_view.dart | 2 +- lib/pages/views/signup_view.dart | 2 +- lib/utils/client_manager.dart | 3 ++- lib/widgets/matrix.dart | 24 +++++++++---------- 8 files changed, 41 insertions(+), 38 deletions(-) diff --git a/lib/pages/homeserver_picker.dart b/lib/pages/homeserver_picker.dart index 3060089e..c3fa0df7 100644 --- a/lib/pages/homeserver_picker.dart +++ b/lib/pages/homeserver_picker.dart @@ -47,13 +47,13 @@ class HomeserverPickerController extends State { showFutureLoadingDialog( context: context, future: () async { - if (Matrix.of(context).client.homeserver == null) { - await Matrix.of(context).client.checkHomeserver( + if (Matrix.of(context).getLoginClient().homeserver == null) { + await Matrix.of(context).getLoginClient().checkHomeserver( await Store() .getItem(HomeserverPickerController.ssoHomeserverKey), ); } - await Matrix.of(context).createLoginClient().login( + await Matrix.of(context).getLoginClient().login( LoginType.mLoginToken, token: token, initialDeviceDisplayName: PlatformInfos.clientName, @@ -117,7 +117,7 @@ class HomeserverPickerController extends State { isLoading = true; }); final wellKnown = - await Matrix.of(context).client.checkHomeserver(homeserver); + await Matrix.of(context).getLoginClient().checkHomeserver(homeserver); var jitsi = wellKnown?.additionalProperties ?.tryGet>('im.vector.riot.jitsi') @@ -177,13 +177,13 @@ class HomeserverPickerController extends State { .any((flow) => flow['type'] == AuthenticationTypes.sso); Future> getLoginTypes() async { - _rawLoginTypes ??= await Matrix.of(context).client.request( + _rawLoginTypes ??= await Matrix.of(context).getLoginClient().request( RequestType.GET, '/client/r0/login', ); if (registrationSupported == null) { try { - await Matrix.of(context).client.register(); + await Matrix.of(context).getLoginClient().register(); registrationSupported = true; } on MatrixException catch (e) { registrationSupported = e.requireAdditionalAuthentication ?? false; @@ -200,14 +200,14 @@ class HomeserverPickerController extends State { if (kIsWeb) { // We store the homserver in the local storage instead of a redirect // parameter because of possible CSRF attacks. - Store().setItem( - ssoHomeserverKey, Matrix.of(context).client.homeserver.toString()); + Store().setItem(ssoHomeserverKey, + Matrix.of(context).getLoginClient().homeserver.toString()); } final redirectUrl = kIsWeb ? AppConfig.webBaseUrl + '/#/' : AppConfig.appOpenUrlScheme.toLowerCase() + '://login'; final url = - '${Matrix.of(context).client.homeserver?.toString()}/_matrix/client/r0/login/sso/redirect/${Uri.encodeComponent(id)}?redirectUrl=${Uri.encodeQueryComponent(redirectUrl)}'; + '${Matrix.of(context).getLoginClient().homeserver?.toString()}/_matrix/client/r0/login/sso/redirect/${Uri.encodeComponent(id)}?redirectUrl=${Uri.encodeQueryComponent(redirectUrl)}'; if (PlatformInfos.isMobile) { browser ??= ChromeSafariBrowser(); browser.open(url: Uri.parse(url)); diff --git a/lib/pages/login.dart b/lib/pages/login.dart index dfa685a2..30a7d20a 100644 --- a/lib/pages/login.dart +++ b/lib/pages/login.dart @@ -64,7 +64,7 @@ class LoginController extends State { } else { identifier = AuthenticationUserIdentifier(user: username); } - await matrix.createLoginClient().login(LoginType.mLoginPassword, + await matrix.getLoginClient().login(LoginType.mLoginPassword, identifier: identifier, // To stay compatible with older server versions // ignore: deprecated_member_use @@ -98,12 +98,13 @@ class LoginController extends State { setState(() => usernameError = null); if (!userId.isValidMatrixId) return; try { - final oldHomeserver = Matrix.of(context).client.homeserver; + final oldHomeserver = Matrix.of(context).getLoginClient().homeserver; var newDomain = Uri.https(userId.domain, ''); - Matrix.of(context).client.homeserver = newDomain; + Matrix.of(context).getLoginClient().homeserver = newDomain; DiscoveryInformation wellKnownInformation; try { - wellKnownInformation = await Matrix.of(context).client.getWellknown(); + wellKnownInformation = + await Matrix.of(context).getLoginClient().getWellknown(); if (wellKnownInformation.mHomeserver?.baseUrl?.toString()?.isNotEmpty ?? false) { newDomain = wellKnownInformation.mHomeserver.baseUrl; @@ -120,8 +121,8 @@ class LoginController extends State { .checkHomeserver(newDomain) .catchError((e) => null), ); - if (Matrix.of(context).client.homeserver == null) { - Matrix.of(context).client.homeserver = oldHomeserver; + if (Matrix.of(context).getLoginClient().homeserver == null) { + Matrix.of(context).getLoginClient().homeserver = oldHomeserver; // okay, the server we checked does not appear to be a matrix server Logs().v( '$newDomain is not running a homeserver, asking to use $oldHomeserver'); @@ -177,11 +178,12 @@ class LoginController extends State { final clientSecret = DateTime.now().millisecondsSinceEpoch.toString(); final response = await showFutureLoadingDialog( context: context, - future: () => Matrix.of(context).client.requestTokenToResetPasswordEmail( - clientSecret, - input.single, - sendAttempt++, - ), + future: () => + Matrix.of(context).getLoginClient().requestTokenToResetPasswordEmail( + clientSecret, + input.single, + sendAttempt++, + ), ); if (response.error != null) return; final ok = await showOkAlertDialog( @@ -210,7 +212,7 @@ class LoginController extends State { if (password == null) return; final success = await showFutureLoadingDialog( context: context, - future: () => Matrix.of(context).client.changePassword( + future: () => Matrix.of(context).getLoginClient().changePassword( password.single, auth: AuthenticationThreePidCreds( type: AuthenticationTypes.emailIdentity, diff --git a/lib/pages/signup.dart b/lib/pages/signup.dart index b9c3ba4a..020316c7 100644 --- a/lib/pages/signup.dart +++ b/lib/pages/signup.dart @@ -37,7 +37,7 @@ class SignupPageController extends State { setState(() => loading = true); try { - final client = Matrix.of(context).createLoginClient(); + final client = Matrix.of(context).getLoginClient(); await client.uiaRequestBackground( (auth) => client.register( username: usernameController.text, diff --git a/lib/pages/views/homeserver_picker_view.dart b/lib/pages/views/homeserver_picker_view.dart index 90787b6c..173d9778 100644 --- a/lib/pages/views/homeserver_picker_view.dart +++ b/lib/pages/views/homeserver_picker_view.dart @@ -100,7 +100,7 @@ class HomeserverPickerView extends StatelessWidget { imageUrl: Uri.parse( identityProvider.icon) .getDownloadLink( - Matrix.of(context).client) + Matrix.of(context).getLoginClient()) .toString(), width: 24, height: 24, diff --git a/lib/pages/views/login_view.dart b/lib/pages/views/login_view.dart index fffd7f91..f87cc377 100644 --- a/lib/pages/views/login_view.dart +++ b/lib/pages/views/login_view.dart @@ -19,7 +19,7 @@ class LoginView extends StatelessWidget { elevation: 0, title: Text( L10n.of(context).logInTo(Matrix.of(context) - .client + .getLoginClient() .homeserver .toString() .replaceFirst('https://', '')), diff --git a/lib/pages/views/signup_view.dart b/lib/pages/views/signup_view.dart index 8d77628c..320f2209 100644 --- a/lib/pages/views/signup_view.dart +++ b/lib/pages/views/signup_view.dart @@ -38,7 +38,7 @@ class SignupPageView extends StatelessWidget { labelText: L10n.of(context).username, prefixText: '@', suffixText: - ':${Matrix.of(context).client.homeserver.host}'), + ':${Matrix.of(context).getLoginClient().homeserver.host}'), ), ), Divider(), diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 0f3bde35..e3db51fc 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -11,7 +11,7 @@ import 'matrix_sdk_extensions.dart/flutter_matrix_hive_database.dart'; abstract class ClientManager { static const String clientNamespace = 'im.fluffychat.store.clients'; static Future> getClients() async { - final clientNames = {PlatformInfos.clientName}; + final clientNames = {}; try { final rawClientNames = await Store().getItem(clientNamespace); if (rawClientNames != null) { @@ -23,6 +23,7 @@ abstract class ClientManager { Logs().w('Client names in store are corrupted', e, s); await Store().deleteItem(clientNamespace); } + if (clientNames.isEmpty) clientNames.add(PlatformInfos.clientName); return clientNames.map(createClient).toList(); } diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 27f6e8a3..4c65ce98 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -78,23 +78,23 @@ class MatrixState extends State with WidgetsBindingObserver { return _activeClient; } - Client createLoginClient() { + Client _loginClientCandidate; + + Client getLoginClient() { final multiAccount = client.isLogged(); - final newClient = multiAccount - ? ClientManager.createClient(client.generateUniqueTransactionId()) - : client; - if (multiAccount) { - // Add to client list - newClient.onLoginStateChanged.stream + if (!multiAccount) return client; + _loginClientCandidate ??= ClientManager.createClient( + client.generateUniqueTransactionId()) + ..onLoginStateChanged + .stream .where((l) => l == LoginState.loggedIn) .first .then((_) { - widget.clients.add(client); - ClientManager.addClientNameToStore(client.clientName); - _registerSubs(client.clientName); + widget.clients.add(_loginClientCandidate); + ClientManager.addClientNameToStore(_loginClientCandidate.clientName); + _registerSubs(_loginClientCandidate.clientName); }); - } - return newClient; + return _loginClientCandidate; } Client getClientByName(String name) => widget.clients