From daf7768dfdfb3e831b34bd371ecf6b0d86b70ca8 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 19 Jun 2022 18:00:47 +0300 Subject: [PATCH] Microsoft Login --- lib/constants.dart | 3 -- lib/data/models/user_model.dart | 1 + lib/ui/auth/login_vm.dart | 6 +-- lib/ui/settings/user_details_vm.dart | 57 ++++++++++++++++++++++++++++ lib/utils/i18n.dart | 12 ++++++ 5 files changed, 73 insertions(+), 6 deletions(-) diff --git a/lib/constants.dart b/lib/constants.dart index c11e63608..0ae7a46ff 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -94,9 +94,6 @@ const String kProductPlanEnterprise5 = 'v1_enterprise_5_yearly'; const String kProductPlanEnterprise10 = 'v1_enterprise_10_yearly'; const String kProductPlanEnterprise20 = 'v1_enterprise_20_yearly'; -const String kOAuthProviderMicrosoft = 'microsoft'; -const String kOAuthProviderGoogle = 'google'; - const kProductPlans = [ kProductPlanPro, kProductPlanEnterprise2, diff --git a/lib/data/models/user_model.dart b/lib/data/models/user_model.dart index af393e699..088e41a05 100644 --- a/lib/data/models/user_model.dart +++ b/lib/data/models/user_model.dart @@ -146,6 +146,7 @@ abstract class UserEntity extends Object UserEntity._(); static const OAUTH_PROVIDER_GOOGLE = 'google'; + static const OAUTH_PROVIDER_MICROSOFT = 'microsoft'; @override @memoized diff --git a/lib/ui/auth/login_vm.dart b/lib/ui/auth/login_vm.dart index 3792b0b2e..ae3ebb816 100644 --- a/lib/ui/auth/login_vm.dart +++ b/lib/ui/auth/login_vm.dart @@ -6,12 +6,12 @@ import 'package:flutter/material.dart'; // Package imports: import 'package:flutter_redux/flutter_redux.dart'; +import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:redux/redux.dart'; import 'package:shared_preferences/shared_preferences.dart'; // Project imports: import 'package:invoiceninja_flutter/constants.dart'; -import 'package:invoiceninja_flutter/data/models/token_model.dart'; import 'package:invoiceninja_flutter/redux/app/app_actions.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/auth/auth_actions.dart'; @@ -171,7 +171,7 @@ class LoginVM { url: _formatApiUrl(url), secret: secret.trim(), platform: getPlatform(context), - provider: kOAuthProviderGoogle, + provider: UserEntity.OAUTH_PROVIDER_GOOGLE, oneTimePassword: oneTimePassword, )); completer.future.then((_) => _handleLogin(context: context)); @@ -200,7 +200,7 @@ class LoginVM { completer: completer, idToken: idToken, accessToken: accessToken, - provider: kOAuthProviderGoogle, + provider: UserEntity.OAUTH_PROVIDER_GOOGLE, )); completer.future .then((_) => _handleLogin(context: context, isSignUp: true)); diff --git a/lib/ui/settings/user_details_vm.dart b/lib/ui/settings/user_details_vm.dart index 4d44f3014..424a9b7a7 100644 --- a/lib/ui/settings/user_details_vm.dart +++ b/lib/ui/settings/user_details_vm.dart @@ -23,6 +23,9 @@ import 'package:invoiceninja_flutter/utils/dialogs.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/oauth.dart'; +import 'package:invoiceninja_flutter/utils/web_stub.dart' + if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart'; + class UserDetailsScreen extends StatelessWidget { const UserDetailsScreen({Key key}) : super(key: key); static const String route = '/$kSettings/$kSettingsUserDetails'; @@ -51,6 +54,8 @@ class UserDetailsVM { @required this.onConnectGmailPressed, @required this.onDisconnectGmailPressed, @required this.onDisableTwoFactorPressed, + @required this.onConnectMicrosoftPressed, + @required this.onDisconnectMicrosoftPressed, }); static UserDetailsVM fromStore(Store store) { @@ -201,6 +206,56 @@ class UserDetailsVM { } }); }, + onDisconnectMicrosoftPressed: (context) { + if (!state.user.hasPassword) { + showErrorDialog( + context: context, + message: AppLocalization.of(context).pleaseFirstSetAPassword); + return; + } + + confirmCallback( + context: context, + callback: (_) { + passwordCallback( + context: context, + callback: (password, idToken) { + final completer = snackBarCompleter(context, + AppLocalization.of(context).disconnectedMicrosoft); + store.dispatch( + SaveAuthUserRequest( + user: state.user.rebuild((b) => b..oauthProvider = ''), + password: password, + idToken: idToken, + completer: completer, + ), + ); + }); + }); + }, + onConnectMicrosoftPressed: (context) { + final completer = snackBarCompleter( + context, AppLocalization.of(context).connectedMicrosoft); + + passwordCallback( + context: context, + callback: (password, idToken) async { + try { + WebUtils.microsoftLogin((idToken, accessToken) { + store.dispatch( + ConnecOAuthUserRequest( + provider: UserEntity.OAUTH_PROVIDER_MICROSOFT, + password: password, + idToken: idToken, + completer: completer, + ), + ); + }); + } catch (error) { + showErrorDialog(context: context, message: error); + } + }); + }, onSavePressed: (context) { Debouncer.runOnComplete(() { final localization = AppLocalization.of(context); @@ -265,6 +320,8 @@ class UserDetailsVM { final Function(BuildContext) onSavePressed; final Function(BuildContext) onConnectGooglePressed; final Function(BuildContext) onDisconnectGooglePressed; + final Function(BuildContext) onConnectMicrosoftPressed; + final Function(BuildContext) onDisconnectMicrosoftPressed; final Function(BuildContext, Completer, String) onConnectGmailPressed; final Function(BuildContext) onDisconnectGmailPressed; final Function(BuildContext) onDisableTwoFactorPressed; diff --git a/lib/utils/i18n.dart b/lib/utils/i18n.dart index 98863b595..b5c868b2b 100644 --- a/lib/utils/i18n.dart +++ b/lib/utils/i18n.dart @@ -16,6 +16,8 @@ mixin LocalizationsProvider on LocaleCodeAware { static final Map> _localizedValues = { 'en': { // STARTER: lang key - do not remove comment + 'connected_microsoft': 'Successfully connected Microsoft', + 'disconnected_microsoft': 'Successfully disconnected Microsoft', 'microsoft_sign_in': 'Login with Microsoft', 'microsoft_sign_up': 'Sign up with Microsoft', 'emailed_purchase_order': 'Successfully queued purchase order to be sent', @@ -70711,6 +70713,16 @@ mixin LocalizationsProvider on LocaleCodeAware { _localizedValues['en']['microsoft_sign_in'] ?? ''; + String get disconnectedMicrosoft => + _localizedValues[localeCode]['disconnected_microsoft'] ?? + _localizedValues['en']['disconnected_microsoft'] ?? + ''; + + String get connectedMicrosoft => + _localizedValues[localeCode]['connected_google'] ?? + _localizedValues['en']['connected_googlek'] ?? + ''; + // STARTER: lang field - do not remove comment String lookup(String key) {