From 7bcf1c377fbf615ffd2d92d33cb7c797ece6160b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Bispo?= Date: Fri, 7 Jul 2023 17:09:13 +0100 Subject: [PATCH] [PM-2293] Refactor AuthRequestType enum. Add label. Remove unnecessary actions. --- .../Accounts/LoginApproveDevicePage.xaml.cs | 23 ++------------ .../Accounts/LoginApproveDeviceViewModel.cs | 31 +++++++------------ src/App/Pages/Accounts/LoginPage.xaml.cs | 2 +- .../LoginPasswordlessRequestViewModel.cs | 10 +++--- src/App/Pages/Accounts/LoginSsoPage.xaml.cs | 2 +- .../Pages/Accounts/LoginSsoPageViewModel.cs | 9 ++++++ src/App/Resources/AppResources.Designer.cs | 18 +++++++++++ src/App/Resources/AppResources.resx | 6 ++++ src/Core/Abstractions/IAuthService.cs | 2 +- src/Core/Enums/AuthRequestType.cs | 7 +++-- .../Request/PasswordlessCreateLoginRequest.cs | 8 ++--- src/Core/Services/AuthService.cs | 4 +-- .../CredentialProviderViewController.cs | 2 +- src/iOS.Extension/LoadingViewController.cs | 2 +- .../LoadingViewController.cs | 2 +- 15 files changed, 67 insertions(+), 61 deletions(-) diff --git a/src/App/Pages/Accounts/LoginApproveDevicePage.xaml.cs b/src/App/Pages/Accounts/LoginApproveDevicePage.xaml.cs index d201bc326..4a8bf77fa 100644 --- a/src/App/Pages/Accounts/LoginApproveDevicePage.xaml.cs +++ b/src/App/Pages/Accounts/LoginApproveDevicePage.xaml.cs @@ -19,9 +19,7 @@ namespace Bit.App.Pages { InitializeComponent(); _vm = BindingContext as LoginApproveDeviceViewModel; - _vm.StartTwoFactorAction = () => StartTwoFactorAsync().FireAndForget(); ; - _vm.LogInSuccessAction = () => LogInSuccessAsync().FireAndForget(); ; - _vm.UpdateTempPasswordAction = () => UpdateTempPasswordAsync().FireAndForget(); ; + _vm.LogInWithMasterPassword = () => StartLogInWithMasterPassword().FireAndForget(); _vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget(); _vm.RequestAdminApprovalAction = () => RequestAdminApprovalAsync().FireAndForget(); _vm.CloseAction = () => { Navigation.PopModalAsync(); }; @@ -42,31 +40,16 @@ namespace Bit.App.Pages } } - private async Task StartTwoFactorAsync() + private async Task StartLogInWithMasterPassword() { var page = new TwoFactorPage(false, _appOptions); await Navigation.PushModalAsync(new NavigationPage(page)); } - private async Task LogInSuccessAsync() - { - if (AppHelpers.SetAlternateMainPage(_appOptions)) - { - return; - } - var previousPage = await AppHelpers.ClearPreviousPage(); - Application.Current.MainPage = new TabsPage(_appOptions, previousPage); - } - - private async Task UpdateTempPasswordAsync() - { - var page = new UpdateTempPasswordPage(); - await Navigation.PushModalAsync(new NavigationPage(page)); - } private async Task StartLoginWithDeviceAsync() { - var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.LoginWithDevice, _appOptions); + var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.AuthenticateAndUnlock, _appOptions); await Navigation.PushModalAsync(new NavigationPage(page)); } diff --git a/src/App/Pages/Accounts/LoginApproveDeviceViewModel.cs b/src/App/Pages/Accounts/LoginApproveDeviceViewModel.cs index 5ce43c2a6..f5b4de484 100644 --- a/src/App/Pages/Accounts/LoginApproveDeviceViewModel.cs +++ b/src/App/Pages/Accounts/LoginApproveDeviceViewModel.cs @@ -7,8 +7,10 @@ using Bit.App.Utilities.AccountManagement; using Bit.Core.Abstractions; using Bit.Core.Enums; using Bit.Core.Models.Request; +using Bit.Core.Services; using Bit.Core.Utilities; using Xamarin.CommunityToolkit.ObjectModel; +using Xamarin.Forms; namespace Bit.App.Pages { @@ -28,9 +30,7 @@ namespace Bit.App.Pages public ICommand ApproveWithMasterPasswordCommand { get; } public ICommand ContinueCommand { get; } - public Action StartTwoFactorAction { get; set; } - public Action LogInSuccessAction { get; set; } - public Action UpdateTempPasswordAction { get; set; } + public Action LogInWithMasterPassword { get; set; } public Action LogInWithDeviceAction { get; set; } public Action RequestAdminApprovalAction { get; set; } public Action CloseAction { get; set; } @@ -42,15 +42,15 @@ namespace Bit.App.Pages PageTitle = AppResources.LoggedIn; - ApproveWithMyOtherDeviceCommand = new AsyncCommand(InitAsync, + ApproveWithMyOtherDeviceCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithDeviceAction), onException: ex => HandleException(ex), allowsMultipleExecutions: false); - RequestAdminApprovalCommand = new AsyncCommand(RequestAdminApproval, + RequestAdminApprovalCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(RequestAdminApprovalAction), onException: ex => HandleException(ex), allowsMultipleExecutions: false); - ApproveWithMasterPasswordCommand = new AsyncCommand(InitAsync, + ApproveWithMasterPasswordCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithMasterPassword), onException: ex => HandleException(ex), allowsMultipleExecutions: false); @@ -59,6 +59,8 @@ namespace Bit.App.Pages allowsMultipleExecutions: false); } + public string LoggingInAsText => string.Format(AppResources.LoggingInAsX, Email); + public bool RememberThisDevice { get => _rememberThisDevice; @@ -92,7 +94,10 @@ namespace Bit.App.Pages public string Email { get => _email; - set => SetProperty(ref _email, value); + set => SetProperty(ref _email, value, additionalPropertyNames: + new string[] { + nameof(LoggingInAsText) + }); } public async Task InitAsync() @@ -119,18 +124,6 @@ namespace Bit.App.Pages HandleException(ex); } } - - private Task RequestAdminApproval() - { - try - { - RequestAdminApprovalAction?.Invoke(); - } - catch (Exception ex) - { - HandleException(ex); - } - } } } diff --git a/src/App/Pages/Accounts/LoginPage.xaml.cs b/src/App/Pages/Accounts/LoginPage.xaml.cs index fd1fa7a09..d486acc50 100644 --- a/src/App/Pages/Accounts/LoginPage.xaml.cs +++ b/src/App/Pages/Accounts/LoginPage.xaml.cs @@ -136,7 +136,7 @@ namespace Bit.App.Pages private async Task StartLoginWithDeviceAsync() { - var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.LoginWithDevice, _appOptions); + var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.AuthenticateAndUnlock, _appOptions); await Navigation.PushModalAsync(new NavigationPage(page)); } diff --git a/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs b/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs index f18dcb6be..557b5a31c 100644 --- a/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs +++ b/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs @@ -84,7 +84,7 @@ namespace Bit.App.Pages get { switch (_authRequestType) { - case AuthRequestType.LoginWithDevice: + case AuthRequestType.AuthenticateAndUnlock: return AppResources.LogInInitiated; case AuthRequestType.AdminApproval: return AppResources.AdminApprovalRequested; @@ -100,7 +100,7 @@ namespace Bit.App.Pages { switch (_authRequestType) { - case AuthRequestType.LoginWithDevice: + case AuthRequestType.AuthenticateAndUnlock: return AppResources.ANotificationHasBeenSentToYourDevice; case AuthRequestType.AdminApproval: return AppResources.YourRequestHasBeenSentToYourAdmin; @@ -116,7 +116,7 @@ namespace Bit.App.Pages { switch (_authRequestType) { - case AuthRequestType.LoginWithDevice: + case AuthRequestType.AuthenticateAndUnlock: return AppResources.PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice; case AuthRequestType.AdminApproval: return AppResources.YouWillBeNotifiedOnceApproved; @@ -132,7 +132,7 @@ namespace Bit.App.Pages { switch (_authRequestType) { - case AuthRequestType.LoginWithDevice: + case AuthRequestType.AuthenticateAndUnlock: return AppResources.NeedAnotherOption; case AuthRequestType.AdminApproval: return AppResources.TroubleLoggingIn; @@ -245,7 +245,7 @@ namespace Bit.App.Pages { await Device.InvokeOnMainThreadAsync(() => _deviceActionService.ShowLoadingAsync(AppResources.Loading)); - var response = await _authService.PasswordlessCreateLoginRequestAsync(_email); + var response = await _authService.PasswordlessCreateLoginRequestAsync(_email, AuthRequestType); if (response != null) { FingerprintPhrase = response.FingerprintPhrase; diff --git a/src/App/Pages/Accounts/LoginSsoPage.xaml.cs b/src/App/Pages/Accounts/LoginSsoPage.xaml.cs index a910c9454..a3acfe106 100644 --- a/src/App/Pages/Accounts/LoginSsoPage.xaml.cs +++ b/src/App/Pages/Accounts/LoginSsoPage.xaml.cs @@ -112,7 +112,7 @@ namespace Bit.App.Pages await AppHelpers.ClearPreviousPage(); // Just for testing the screen - Application.Current.MainPage = new NavigationPage(new LoginApproveDevicePage(_appOptions)); + Application.Current.MainPage = new NavigationPage(new LoginApproveDevicePage(_vm.Email, _appOptions)); return; if (await _vaultTimeoutService.IsLockedAsync()) diff --git a/src/App/Pages/Accounts/LoginSsoPageViewModel.cs b/src/App/Pages/Accounts/LoginSsoPageViewModel.cs index fbf9bf4f2..b24124ef4 100644 --- a/src/App/Pages/Accounts/LoginSsoPageViewModel.cs +++ b/src/App/Pages/Accounts/LoginSsoPageViewModel.cs @@ -31,6 +31,7 @@ namespace Bit.App.Pages private readonly IOrganizationService _organizationService; private string _orgIdentifier; + private string _email; public LoginSsoPageViewModel() { @@ -57,6 +58,12 @@ namespace Bit.App.Pages set => SetProperty(ref _orgIdentifier, value); } + public string Email + { + get => _email; + set => SetProperty(ref _email, value); + } + public ICommand LogInCommand { get; } public Action StartTwoFactorAction { get; set; } public Action StartSetPasswordAction { get; set; } @@ -77,6 +84,8 @@ namespace Bit.App.Pages { OrgIdentifier = await _stateService.GetRememberedOrgIdentifierAsync(); } + + Email = await _stateService.GetRememberedEmailAsync(); } catch (Exception ex) { diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index 695ee49ae..b94605494 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -3298,6 +3298,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Invalid API token. + /// + public static string InvalidAPIToken { + get { + return ResourceManager.GetString("InvalidAPIToken", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid email address.. /// @@ -3631,6 +3640,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Logging in as {0}. + /// + public static string LoggingInAsX { + get { + return ResourceManager.GetString("LoggingInAsX", resourceCulture); + } + } + /// /// Looks up a localized string similar to Logging in as {0} on {1}. /// diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx index fa171495e..280aef95e 100644 --- a/src/App/Resources/AppResources.resx +++ b/src/App/Resources/AppResources.resx @@ -2658,6 +2658,9 @@ Do you want to switch to this account? Invalid API key + + Invalid API token + Admin approval requested @@ -2670,4 +2673,7 @@ Do you want to switch to this account? Trouble logging in? + + Logging in as {0} + diff --git a/src/Core/Abstractions/IAuthService.cs b/src/Core/Abstractions/IAuthService.cs index e26438743..d463b83a9 100644 --- a/src/Core/Abstractions/IAuthService.cs +++ b/src/Core/Abstractions/IAuthService.cs @@ -34,7 +34,7 @@ namespace Bit.Core.Abstractions Task GetPasswordlessLoginRequestByIdAsync(string id); Task GetPasswordlessLoginResponseAsync(string id, string accessCode); Task PasswordlessLoginAsync(string id, string pubKey, bool requestApproved); - Task PasswordlessCreateLoginRequestAsync(string email); + Task PasswordlessCreateLoginRequestAsync(string email, AuthRequestType authRequestType); void LogOut(Action callback); void Init(); diff --git a/src/Core/Enums/AuthRequestType.cs b/src/Core/Enums/AuthRequestType.cs index d646bc59f..febfe97f4 100644 --- a/src/Core/Enums/AuthRequestType.cs +++ b/src/Core/Enums/AuthRequestType.cs @@ -1,10 +1,11 @@ using System; namespace Bit.Core.Enums { - public enum AuthRequestType + public enum AuthRequestType : byte { - LoginWithDevice, - AdminApproval, + AuthenticateAndUnlock = 0, + Unlock = 1, + AdminApproval = 2 } } diff --git a/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs b/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs index aeaff5f1f..c46c1d6e9 100644 --- a/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs +++ b/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs @@ -1,4 +1,6 @@ using System; +using Bit.Core.Enums; + namespace Bit.Core.Models.Request { public class PasswordlessCreateLoginRequest @@ -25,10 +27,4 @@ namespace Bit.Core.Models.Request public string FingerprintPhrase { get; set; } } - - public enum AuthRequestType : byte - { - AuthenticateAndUnlock = 0, - Unlock = 1 - } } diff --git a/src/Core/Services/AuthService.cs b/src/Core/Services/AuthService.cs index b0ce4effd..b2c89bd34 100644 --- a/src/Core/Services/AuthService.cs +++ b/src/Core/Services/AuthService.cs @@ -599,7 +599,7 @@ namespace Bit.Core.Services return await PopulateFingerprintPhraseAsync(response, await _stateService.GetEmailAsync()); } - public async Task PasswordlessCreateLoginRequestAsync(string email) + public async Task PasswordlessCreateLoginRequestAsync(string email, AuthRequestType authRequestType) { var deviceId = await _appIdService.GetAppIdAsync(); var keyPair = await _cryptoFunctionService.RsaGenerateKeyPairAsync(2048); @@ -607,7 +607,7 @@ namespace Bit.Core.Services var fingerprintPhrase = string.Join("-", generatedFingerprintPhrase); var publicB64 = Convert.ToBase64String(keyPair.Item1); var accessCode = await _passwordGenerationService.GeneratePasswordAsync(PasswordGenerationOptions.CreateDefault.WithLength(25)); - var passwordlessCreateLoginRequest = new PasswordlessCreateLoginRequest(email, publicB64, deviceId, accessCode, AuthRequestType.AuthenticateAndUnlock, fingerprintPhrase); + var passwordlessCreateLoginRequest = new PasswordlessCreateLoginRequest(email, publicB64, deviceId, accessCode, authRequestType, fingerprintPhrase); var response = await _apiService.PostCreateRequestAsync(passwordlessCreateLoginRequest); if (response != null) diff --git a/src/iOS.Autofill/CredentialProviderViewController.cs b/src/iOS.Autofill/CredentialProviderViewController.cs index 973a316f5..71c8cf660 100644 --- a/src/iOS.Autofill/CredentialProviderViewController.cs +++ b/src/iOS.Autofill/CredentialProviderViewController.cs @@ -515,7 +515,7 @@ namespace Bit.iOS.Autofill { var appOptions = new AppOptions { IosExtension = true }; var app = new App.App(appOptions); - var loginWithDevicePage = new LoginPasswordlessRequestPage(email, AuthRequestType.LoginWithDevice, appOptions); + var loginWithDevicePage = new LoginPasswordlessRequestPage(email, AuthRequestType.AuthenticateAndUnlock, appOptions); ThemeManager.SetTheme(app.Resources); ThemeManager.ApplyResourcesTo(loginWithDevicePage); if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) diff --git a/src/iOS.Extension/LoadingViewController.cs b/src/iOS.Extension/LoadingViewController.cs index 654c7bb88..f9e2bfd3d 100644 --- a/src/iOS.Extension/LoadingViewController.cs +++ b/src/iOS.Extension/LoadingViewController.cs @@ -537,7 +537,7 @@ namespace Bit.iOS.Extension { var appOptions = new AppOptions { IosExtension = true }; var app = new App.App(appOptions); - var loginWithDevicePage = new LoginPasswordlessRequestPage(email, AuthRequestType.LoginWithDevice, appOptions); + var loginWithDevicePage = new LoginPasswordlessRequestPage(email, AuthRequestType.AuthenticateAndUnlock, appOptions); ThemeManager.SetTheme(app.Resources); ThemeManager.ApplyResourcesTo(loginWithDevicePage); if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) diff --git a/src/iOS.ShareExtension/LoadingViewController.cs b/src/iOS.ShareExtension/LoadingViewController.cs index 0a91e9d38..46629d457 100644 --- a/src/iOS.ShareExtension/LoadingViewController.cs +++ b/src/iOS.ShareExtension/LoadingViewController.cs @@ -350,7 +350,7 @@ namespace Bit.iOS.ShareExtension private void LaunchLoginWithDevice(string email = null) { - var loginWithDevicePage = new LoginPasswordlessRequestPage(email, AuthRequestType.LoginWithDevice, _appOptions.Value); + var loginWithDevicePage = new LoginPasswordlessRequestPage(email, AuthRequestType.AuthenticateAndUnlock, _appOptions.Value); SetupAppAndApplyResources(loginWithDevicePage); if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) {