|
|
|
|
@ -1,11 +1,20 @@
|
|
|
|
|
import 'dart:async';
|
|
|
|
|
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
|
|
|
|
import 'package:collection/collection.dart';
|
|
|
|
|
import 'package:file_picker/file_picker.dart';
|
|
|
|
|
import 'package:fluffychat/config/app_config.dart';
|
|
|
|
|
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
|
|
|
|
|
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|
|
|
|
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
|
|
|
|
import 'package:fluffychat/utils/platform_infos.dart';
|
|
|
|
|
import 'package:fluffychat/utils/tor_stub.dart'
|
|
|
|
|
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
|
|
|
|
|
import 'package:fluffychat/widgets/app_lock.dart';
|
|
|
|
|
import 'package:fluffychat/widgets/matrix.dart';
|
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
|
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
|
|
|
import 'package:flutter_web_auth_2/flutter_web_auth_2.dart';
|
|
|
|
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|
|
|
|
@ -14,18 +23,8 @@ import 'package:hive_flutter/hive_flutter.dart';
|
|
|
|
|
import 'package:matrix/matrix.dart';
|
|
|
|
|
import 'package:universal_html/html.dart' as html;
|
|
|
|
|
|
|
|
|
|
import 'package:fluffychat/config/app_config.dart';
|
|
|
|
|
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart';
|
|
|
|
|
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|
|
|
|
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
|
|
|
|
import 'package:fluffychat/utils/platform_infos.dart';
|
|
|
|
|
import 'package:fluffychat/widgets/app_lock.dart';
|
|
|
|
|
import 'package:fluffychat/widgets/matrix.dart';
|
|
|
|
|
import '../../utils/localized_exception_extension.dart';
|
|
|
|
|
|
|
|
|
|
import 'package:fluffychat/utils/tor_stub.dart'
|
|
|
|
|
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
|
|
|
|
|
|
|
|
|
|
class HomeserverPicker extends StatefulWidget {
|
|
|
|
|
const HomeserverPicker({super.key});
|
|
|
|
|
|
|
|
|
|
@ -131,34 +130,67 @@ class HomeserverPickerController extends State<HomeserverPicker> {
|
|
|
|
|
? '${html.window.origin!}/auth.html'
|
|
|
|
|
: '${AppConfig.appOpenUrlScheme.toLowerCase()}://login';
|
|
|
|
|
//Pangea#
|
|
|
|
|
final url =
|
|
|
|
|
'${Matrix.of(context).getLoginClient().homeserver?.toString()}/_matrix/client/r0/login/sso/redirect/${Uri.encodeComponent(id)}?redirectUrl=${Uri.encodeQueryComponent(redirectUrl)}';
|
|
|
|
|
final url = Matrix.of(context).getLoginClient().homeserver!.replace(
|
|
|
|
|
path: '/_matrix/client/v3/login/sso/redirect${id == null ? '' : '/$id'}',
|
|
|
|
|
queryParameters: {'redirectUrl': redirectUrl},
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
final urlScheme = isDefaultPlatform
|
|
|
|
|
? Uri.parse(redirectUrl).scheme
|
|
|
|
|
: "http://localhost:3001";
|
|
|
|
|
final result = await FlutterWebAuth2.authenticate(
|
|
|
|
|
url: url.toString(),
|
|
|
|
|
callbackUrlScheme: urlScheme,
|
|
|
|
|
);
|
|
|
|
|
// #Pangea
|
|
|
|
|
// final result = await FlutterWebAuth2.authenticate(
|
|
|
|
|
// url: url.toString(),
|
|
|
|
|
// callbackUrlScheme: urlScheme,
|
|
|
|
|
// );
|
|
|
|
|
String result;
|
|
|
|
|
try {
|
|
|
|
|
result = await FlutterWebAuth2.authenticate(
|
|
|
|
|
url: url.toString(),
|
|
|
|
|
callbackUrlScheme: urlScheme,
|
|
|
|
|
);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
if (err is PlatformException && err.code == 'CANCELED') {
|
|
|
|
|
debugPrint("user cancelled SSO login");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ErrorHandler.logError(
|
|
|
|
|
e: err,
|
|
|
|
|
s: StackTrace.current,
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// Pangea#
|
|
|
|
|
final token = Uri.parse(result).queryParameters['loginToken'];
|
|
|
|
|
if (token?.isEmpty ?? false) return;
|
|
|
|
|
|
|
|
|
|
// #Pangea
|
|
|
|
|
final loginRes = await showFutureLoadingDialog(
|
|
|
|
|
// await showFutureLoadingDialog(
|
|
|
|
|
// Pangea#
|
|
|
|
|
context: context,
|
|
|
|
|
future: () => Matrix.of(context).getLoginClient().login(
|
|
|
|
|
setState(() {
|
|
|
|
|
error = null;
|
|
|
|
|
isLoading = isLoggingIn = true;
|
|
|
|
|
});
|
|
|
|
|
try {
|
|
|
|
|
// #Pangea
|
|
|
|
|
final loginRes = await Matrix.of(context).getLoginClient().login(
|
|
|
|
|
// await Matrix.of(context).getLoginClient().login(
|
|
|
|
|
// Pangea#
|
|
|
|
|
LoginType.mLoginToken,
|
|
|
|
|
token: token,
|
|
|
|
|
initialDeviceDisplayName: PlatformInfos.clientName,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
//Pangea#
|
|
|
|
|
if (loginRes.result != null) {
|
|
|
|
|
GoogleAnalytics.login(provider.name!, loginRes.result!.userId);
|
|
|
|
|
);
|
|
|
|
|
// #Pangea
|
|
|
|
|
GoogleAnalytics.login(provider.name!, loginRes.userId);
|
|
|
|
|
// Pangea#
|
|
|
|
|
} catch (e) {
|
|
|
|
|
setState(() {
|
|
|
|
|
error = e.toLocalizedString(context);
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
if (mounted) {
|
|
|
|
|
setState(() {
|
|
|
|
|
isLoading = isLoggingIn = false;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//Pangea#
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<IdentityProvider>? get identityProviders {
|
|
|
|
|
|