diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1b3f5182c..5161a4d83 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -106,7 +106,7 @@ - + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 51765d1c9..e828d1713 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -35,6 +35,7 @@ ShareMedia-$(PRODUCT_BUNDLE_IDENTIFIER) im.fluffychat + chat.fluffy matrix diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart index 347554f69..d865b6eee 100644 --- a/lib/config/app_config.dart +++ b/lib/config/app_config.dart @@ -21,7 +21,6 @@ abstract class AppConfig { static const double spaceBorderRadius = 11.0; static const double columnWidth = 360.0; - static const String website = 'https://fluffy.chat'; static const String enablePushTutorial = 'https://fluffy.chat/faq/#push_without_google_services'; static const String encryptionTutorial = @@ -31,7 +30,7 @@ abstract class AppConfig { static const String howDoIGetStickersTutorial = 'https://fluffy.chat/faq/#how_do_i_get_stickers'; static const String appId = 'im.fluffychat.FluffyChat'; - static const String appOpenUrlScheme = 'im.fluffychat'; + static const String appOpenUrlScheme = 'chat.fluffy'; static const String sourceCodeUrl = 'https://github.com/krille-chan/fluffychat'; @@ -54,12 +53,6 @@ abstract class AppConfig { path: 'krille-chan/fluffychat/refs/heads/main/recommended_homeservers.json', ); - static final Uri privacyUrl = Uri( - scheme: 'https', - host: 'fluffy.chat', - path: '/en/privacy', - ); - static const String mainIsolatePortName = 'main_isolate'; static const String pushIsolatePortName = 'push_isolate'; } diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index d8522e955..f7d7a13ed 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -55,7 +55,17 @@ enum AppSettings { enableSoftLogout('chat.fluffy.enable_soft_logout', false), enableMatrixNativeOIDC('chat.fluffy.enable_matrix_native_oidc', false), presetHomeserver('chat.fluffy.preset_homeserver', ''), - welcomeText('chat.fluffy.welcome_text', ''); + welcomeText('chat.fluffy.welcome_text', ''), + website('chat.fluffy.website_url', 'https://fluffy.chat'), + logoUrl( + 'chat.fluffy.logo_url', + 'https://fluffy.chat/assets/favicon.png', + ), + privacyPolicy( + 'chat.fluffy.privacy_policy_url', + 'https://fluffy.chat/en/privacy', + ), + tos('chat.fluffy.tos_url', 'https://fluffy.chat/en/tos'); final String key; final T defaultValue; diff --git a/lib/pages/intro/intro_page.dart b/lib/pages/intro/intro_page.dart index 46fd7e5d0..95950bbc7 100644 --- a/lib/pages/intro/intro_page.dart +++ b/lib/pages/intro/intro_page.dart @@ -2,10 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_linkify/flutter_linkify.dart'; import 'package:go_router/go_router.dart'; -import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher_string.dart'; -import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/pages/intro/flows/restore_backup_flow.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -58,7 +57,7 @@ class IntroPage extends StatelessWidget { ), ), PopupMenuItem( - onTap: () => launchUrl(AppConfig.privacyUrl), + onTap: () => launchUrlString(AppSettings.privacyPolicy.value), child: Row( mainAxisSize: .min, children: [ diff --git a/lib/pages/intro/intro_page_presenter.dart b/lib/pages/intro/intro_page_presenter.dart index fa702bee5..9188a4dbd 100644 --- a/lib/pages/intro/intro_page_presenter.dart +++ b/lib/pages/intro/intro_page_presenter.dart @@ -77,6 +77,7 @@ class _IntroPagePresenterState extends State { final client = await Matrix.of(context).getLoginClient(); await client.checkHomeserver(homeserverUrl); await client.oidcLogin(session: session, code: code, state: state); + if (context.mounted) context.go('/backup'); } catch (e, s) { Logs().w('Unable to login via OIDC', e, s); if (mounted) { diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index 20b841466..e8ad37dfe 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -3,8 +3,9 @@ import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher/url_launcher_string.dart'; -import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -200,7 +201,7 @@ class SettingsView extends StatelessWidget { ListTile( leading: const Icon(Icons.privacy_tip_outlined), title: Text(L10n.of(context).privacy), - onTap: () => launchUrl(AppConfig.privacyUrl), + onTap: () => launchUrlString(AppSettings.privacyPolicy.value), ), ListTile( leading: const Icon(Icons.info_outline_rounded), diff --git a/lib/pages/sign_in/sign_in_page.dart b/lib/pages/sign_in/sign_in_page.dart index c5b499225..242ee57eb 100644 --- a/lib/pages/sign_in/sign_in_page.dart +++ b/lib/pages/sign_in/sign_in_page.dart @@ -98,19 +98,11 @@ class SignInPage extends StatelessWidget { final website = server.website; return Semantics( identifier: 'homeserver_tile_$i', - child: RadioListTile.adaptive( + child: RadioListTile( value: server, enabled: state.loginLoading.connectionState != ConnectionState.waiting, - radioScaleFactor: - FluffyThemes.isColumnMode(context) || - { - TargetPlatform.iOS, - TargetPlatform.macOS, - }.contains(theme.platform) - ? 2 - : 1, title: Row( children: [ Expanded( diff --git a/lib/utils/sign_in_flows/calc_redirect_url.dart b/lib/utils/sign_in_flows/calc_redirect_url.dart new file mode 100644 index 000000000..ef0f800da --- /dev/null +++ b/lib/utils/sign_in_flows/calc_redirect_url.dart @@ -0,0 +1,27 @@ +import 'package:flutter/foundation.dart'; + +import 'package:universal_html/html.dart' as html; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; + +(Uri redirectUrl, String urlScheme) calcRedirectUrl({ + bool withAuthHtmlPath = false, +}) { + var redirectUrl = kIsWeb + ? Uri.parse(html.window.location.href.split('#').first.split('?').first) + : (PlatformInfos.isMobile || PlatformInfos.isMacOS) + ? Uri.parse('${AppConfig.appOpenUrlScheme.toLowerCase()}:/login') + : Uri.parse('http://localhost:3001/login'); + + if (kIsWeb && withAuthHtmlPath) { + redirectUrl = redirectUrl.resolveUri(Uri(pathSegments: ['auth.html'])); + } + + final urlScheme = + (PlatformInfos.isMobile || PlatformInfos.isWeb || PlatformInfos.isMacOS) + ? redirectUrl.scheme + : 'http://localhost:3001'; + + return (redirectUrl, urlScheme); +} diff --git a/lib/utils/sign_in_flows/check_homeserver.dart b/lib/utils/sign_in_flows/check_homeserver.dart index 5b1436152..85f7a3712 100644 --- a/lib/utils/sign_in_flows/check_homeserver.dart +++ b/lib/utils/sign_in_flows/check_homeserver.dart @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:fluffychat/config/setting_keys.dart'; @@ -73,6 +74,7 @@ Future connectToHomeserverFlow( context.go('/backup'); } } catch (e, s) { + Logs().w('Unable to login', e, s); setState(AsyncSnapshot.withError(ConnectionState.done, e, s)); if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/utils/sign_in_flows/oidc_login.dart b/lib/utils/sign_in_flows/oidc_login.dart index 46c94efa0..0fb9f2c77 100644 --- a/lib/utils/sign_in_flows/oidc_login.dart +++ b/lib/utils/sign_in_flows/oidc_login.dart @@ -6,12 +6,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_web_auth_2/flutter_web_auth_2.dart'; import 'package:matrix/matrix.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:universal_html/html.dart' as html; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/oidc_session_json_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/utils/sign_in_flows/calc_redirect_url.dart'; Future oidcLoginFlow( Client client, @@ -19,24 +18,16 @@ Future oidcLoginFlow( bool signUp, ) async { Logs().i('Starting Matrix Native OIDC Flow...'); - final redirectUrl = kIsWeb - ? Uri.parse(html.window.location.href.split('#').first.split('?').first) - : (PlatformInfos.isMobile || PlatformInfos.isMacOS) - ? Uri.parse('${AppConfig.appOpenUrlScheme.toLowerCase()}:/login') - : Uri.parse('http://localhost:3001/login'); - final urlScheme = - (PlatformInfos.isMobile || PlatformInfos.isWeb || PlatformInfos.isMacOS) - ? redirectUrl.scheme - : 'http://localhost:3001'; + final (redirectUrl, urlScheme) = calcRedirectUrl(); - final clientUri = Uri.parse(AppConfig.website); + final clientUri = Uri.parse(AppSettings.website.value); final supportWebPlatform = kIsWeb && kReleaseMode && redirectUrl.scheme == 'https' && redirectUrl.host.contains(clientUri.host); - if (!supportWebPlatform) { + if (kIsWeb && !supportWebPlatform) { Logs().w( 'OIDC Application Type web is not supported. Using native now. Please use this instance not in production!', ); @@ -50,9 +41,9 @@ Future oidcLoginFlow( clientInformation: OidcClientInformation( clientName: AppSettings.applicationName.value, clientUri: clientUri, - logoUri: Uri.parse('https://fluffy.chat/assets/favicon.png'), - tosUri: null, - policyUri: AppConfig.privacyUrl, + logoUri: Uri.parse(AppSettings.logoUrl.value), + tosUri: Uri.parse(AppSettings.tos.value), + policyUri: Uri.parse(AppSettings.privacyPolicy.value), ), ); diff --git a/lib/utils/sign_in_flows/sso_login.dart b/lib/utils/sign_in_flows/sso_login.dart index 335cb3399..1721a2ead 100644 --- a/lib/utils/sign_in_flows/sso_login.dart +++ b/lib/utils/sign_in_flows/sso_login.dart @@ -1,40 +1,28 @@ -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_web_auth_2/flutter_web_auth_2.dart'; import 'package:matrix/matrix.dart'; -import 'package:universal_html/html.dart' as html; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/utils/sign_in_flows/calc_redirect_url.dart'; Future ssoLoginFlow( Client client, BuildContext context, bool signUp, ) async { - final redirectUrl = kIsWeb - ? Uri.parse( - html.window.location.href, - ).resolveUri(Uri(pathSegments: ['auth.html'])).toString() - : (PlatformInfos.isMobile || PlatformInfos.isMacOS) - ? '${AppConfig.appOpenUrlScheme.toLowerCase()}://login' - : 'http://localhost:3001//login'; + final (redirectUrl, urlScheme) = calcRedirectUrl(withAuthHtmlPath: true); Logs().i('Starting legacy SSO Flow with redirect URL', redirectUrl); final url = client.homeserver!.replace( path: '/_matrix/client/v3/login/sso/redirect', queryParameters: { - 'redirectUrl': redirectUrl, + 'redirectUrl': redirectUrl.toString(), 'action': signUp ? 'register' : 'login', }, ); - final urlScheme = - (PlatformInfos.isMobile || PlatformInfos.isWeb || PlatformInfos.isMacOS) - ? Uri.parse(redirectUrl).scheme - : 'http://localhost:3001'; final result = await FlutterWebAuth2.authenticate( url: url.toString(), callbackUrlScheme: urlScheme, diff --git a/lib/widgets/layouts/login_scaffold.dart b/lib/widgets/layouts/login_scaffold.dart index 944ca3919..49b368614 100644 --- a/lib/widgets/layouts/login_scaffold.dart +++ b/lib/widgets/layouts/login_scaffold.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:particles_network/particles_network.dart'; -import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/l10n/l10n.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -118,7 +118,7 @@ class _PrivacyButtons extends StatelessWidget { mainAxisAlignment: mainAxisAlignment, children: [ TextButton( - onPressed: () => launchUrlString(AppConfig.website), + onPressed: () => launchUrlString(AppSettings.website.value), child: Text(L10n.of(context).website, style: shadowTextStyle), ), TextButton( @@ -126,7 +126,7 @@ class _PrivacyButtons extends StatelessWidget { child: Text(L10n.of(context).help, style: shadowTextStyle), ), TextButton( - onPressed: () => launchUrl(AppConfig.privacyUrl), + onPressed: () => launchUrlString(AppSettings.privacyPolicy.value), child: Text(L10n.of(context).privacy, style: shadowTextStyle), ), TextButton(