From 845006ba8abbec26863a9e60068b4e549f34a160 Mon Sep 17 00:00:00 2001 From: Arthi-chaud Date: Sat, 5 Mar 2022 23:52:36 +0100 Subject: [PATCH] Mobile Client: connected Service filter: fix --- mobile/lib/src/aeris_api.dart | 22 +++++++++++++++++++- mobile/lib/src/models/service.dart | 4 ++++ mobile/lib/src/views/authorization_page.dart | 17 ++++++++++----- mobile/lib/src/views/login_page.dart | 16 +++++++++++++- mobile/lib/src/views/setup_action_page.dart | 14 ++++++------- mobile/pubspec.lock | 7 +++++++ mobile/pubspec.yaml | 1 + 7 files changed, 67 insertions(+), 14 deletions(-) diff --git a/mobile/lib/src/aeris_api.dart b/mobile/lib/src/aeris_api.dart index bcd73d0..7de1443 100644 --- a/mobile/lib/src/aeris_api.dart +++ b/mobile/lib/src/aeris_api.dart @@ -64,6 +64,16 @@ class AerisAPI { return createConnection(username, password); } + Future createConnectionFromService(Service service, String code) async { + http.Response response = await _requestAPI( + '/auth/${service.name.toLowerCase()}/signin?code=$code', + AerisAPIRequestType.post, {}); + if (!response.ok) { + return false; + } + return await registerJWT(jsonDecode(response.body)['jwt']); + } + /// On success, sets API as connected to given user. Returns false if connection false Future createConnection(String username, String password) async { http.Response response = @@ -74,8 +84,11 @@ class AerisAPI { if (!response.ok) { return false; } + return await registerJWT(jsonDecode(response.body)['jwt']); + } + + Future registerJWT(String jwt) async { try { - final String jwt = jsonDecode(response.body)['jwt']; await GetIt.I().setString('jwt', jwt); _connected = true; _jwt = jwt; @@ -134,6 +147,13 @@ class AerisAPI { return "$baseRoute/auth/$serviceName/url?redirect_uri=$deepLinkRoute/authorization/$serviceName"; } + String getServiceSignInURL(Service service) { + final serviceName = service == const Service.youtube() + ? "google" + : service.name.toLowerCase(); + return "$baseRoute/auth/$serviceName/url?redirect_uri=$deepLinkRoute/authorization/signin/$serviceName"; + } + /// Send PUT request to update Pipeline, returns false if failed Future editPipeline(Pipeline updatedPipeline) async { var res = await _requestAPI('/workflow/${updatedPipeline.id}', diff --git a/mobile/lib/src/models/service.dart b/mobile/lib/src/models/service.dart index 2ccf842..3d177ce 100644 --- a/mobile/lib/src/models/service.dart +++ b/mobile/lib/src/models/service.dart @@ -29,6 +29,9 @@ class Service { /// Get full url for OAuth2 String get authUrl => GetIt.I().getServiceAuthURL(this); + /// Get full url for OAuth2 to register + String get authSignInUrl => GetIt.I().getServiceSignInURL(this); + const Service.spotify() : name = "Spotify", url = "https://www.spotify.com", @@ -78,6 +81,7 @@ class Service { static Service factory(String name) { if (name.toLowerCase() == "git") return const Service.github(); if (name.toLowerCase() == "ani") return const Service.anilist(); + if (name.toLowerCase() == "google") return const Service.youtube(); for (Service service in Service.all()) { if (service.name.toLowerCase() == name.toLowerCase()) return service; } diff --git a/mobile/lib/src/views/authorization_page.dart b/mobile/lib/src/views/authorization_page.dart index daba6ba..e3bf057 100644 --- a/mobile/lib/src/views/authorization_page.dart +++ b/mobile/lib/src/views/authorization_page.dart @@ -1,6 +1,8 @@ +import 'package:aeris/src/aeris_api.dart'; import 'package:aeris/src/models/service.dart'; import 'package:aeris/src/providers/services_provider.dart'; import 'package:flutter/material.dart'; +import 'package:get_it/get_it.dart'; import 'package:loading_indicator/loading_indicator.dart'; import 'package:provider/provider.dart'; @@ -11,13 +13,18 @@ class AuthorizationPage extends StatelessWidget { Widget build(BuildContext context) { final route = ModalRoute.of(context)!.settings.name!; final code = Uri.parse(route).queryParameters['code']!; - final serviceName = Uri.parse(route).pathSegments.last; + final segments = Uri.parse(route).pathSegments; + final serviceName = segments.removeLast(); final service = Service.factory(serviceName); - Provider.of(context, listen: false).addService(service, code).then((_) { - Provider.of(context, listen: false).notifyListeners(); - Navigator.pop(context); - }); + if (segments.removeLast() == 'signin') { + GetIt.I().createConnectionFromService(service, code).then((value) => Navigator.pop(context)); + } else { + Provider.of(context, listen: false).addService(service, code).then((_) { + Provider.of(context, listen: false).notifyListeners(); + Navigator.pop(context); + }); + } return Container( alignment: Alignment.center, child: LoadingIndicator( diff --git a/mobile/lib/src/views/login_page.dart b/mobile/lib/src/views/login_page.dart index 2078fe0..b157dcb 100644 --- a/mobile/lib/src/views/login_page.dart +++ b/mobile/lib/src/views/login_page.dart @@ -1,10 +1,13 @@ import 'package:aeris/src/aeris_api.dart'; import 'package:aeris/main.dart'; +import 'package:aeris/src/models/service.dart'; import 'package:aeris/src/widgets/aeris_page.dart'; import 'package:flutter_login/flutter_login.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:get_it/get_it.dart'; +import 'package:line_icons/line_icon.dart'; +import 'package:url_launcher/url_launcher.dart'; /// Login Page Widget class LoginPage extends StatelessWidget { @@ -56,6 +59,17 @@ class LoginPage extends StatelessWidget { }, onSubmitAnimationCompleted: () { Navigator.of(context).pushNamedAndRemoveUntil('/home', (route) => false); - })); + }, + loginProviders: [ + for (var service in Service.all().where((element) => element != const Service.utils()).toList()) + LoginProvider( + icon: LineIcon.alternateGithub().icon, + label: service.name, + callback: () { + launch(Uri.parse(service.authSignInUrl).toString(), forceSafariVC: false); + } + ) + ], + )); } } diff --git a/mobile/lib/src/views/setup_action_page.dart b/mobile/lib/src/views/setup_action_page.dart index f598615..94b59e7 100644 --- a/mobile/lib/src/views/setup_action_page.dart +++ b/mobile/lib/src/views/setup_action_page.dart @@ -40,26 +40,26 @@ class SetupActionPage extends StatefulWidget { } class _SetupActionPageState extends State { - Service? serviceState; + late Service serviceState; List? availableActions; @override void initState() { super.initState(); serviceState = widget.action.service; - availableActions = GetIt.I().getActionsFor(serviceState!, widget.action); + availableActions = GetIt.I().getActionsFor(serviceState, widget.action); } Widget serviceDropdown(List services) { return DropdownButton( - value: serviceState, + value: services.contains(serviceState) ? serviceState : services[0], elevation: 8, underline: Container(), onChanged: (service) { setState(() { - serviceState = service; + serviceState = service!; availableActions = - GetIt.I().getActionsFor(service!, widget.action); + GetIt.I().getActionsFor(service, widget.action); }); }, items: services.map>((Service service) { @@ -176,7 +176,7 @@ class _SetupActionPageState extends State { parameters: availableAction.parameters.map((param) { if (widget.action.service.name == - serviceState!.name && + serviceState.name && widget.action.name == availableAction.name) { var previousParams = widget.action.parameters @@ -189,7 +189,7 @@ class _SetupActionPageState extends State { return param; }).toList(), onValidate: (parameters) { - widget.action.service = serviceState!; + widget.action.service = serviceState; widget.action.parameters = ActionParameter.fromJSON(parameters); widget.action.name = availableAction.name; diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index 5b0d21c..eb01c62 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -322,6 +322,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.6.3" + line_icons: + dependency: "direct main" + description: + name: line_icons + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" lints: dependency: transitive description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 6ce185b..0085c77 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -61,6 +61,7 @@ dependencies: flutter_typeahead: ^3.2.4 simple_autocomplete_formfield: ^0.3.0 positioned_tap_detector_2: ^1.0.4 + line_icons: ^2.0.1 dev_dependencies: flutter_launcher_icons: "^0.9.2"