1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-16 16:23:29 +00:00

[PM-2293] Refactor AuthRequestType enum. Add label. Remove unnecessary actions.

This commit is contained in:
André Bispo
2023-07-07 17:09:13 +01:00
parent 109a84607a
commit 7bcf1c377f
15 changed files with 67 additions and 61 deletions

View File

@@ -19,9 +19,7 @@ namespace Bit.App.Pages
{ {
InitializeComponent(); InitializeComponent();
_vm = BindingContext as LoginApproveDeviceViewModel; _vm = BindingContext as LoginApproveDeviceViewModel;
_vm.StartTwoFactorAction = () => StartTwoFactorAsync().FireAndForget(); ; _vm.LogInWithMasterPassword = () => StartLogInWithMasterPassword().FireAndForget();
_vm.LogInSuccessAction = () => LogInSuccessAsync().FireAndForget(); ;
_vm.UpdateTempPasswordAction = () => UpdateTempPasswordAsync().FireAndForget(); ;
_vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget(); _vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget();
_vm.RequestAdminApprovalAction = () => RequestAdminApprovalAsync().FireAndForget(); _vm.RequestAdminApprovalAction = () => RequestAdminApprovalAsync().FireAndForget();
_vm.CloseAction = () => { Navigation.PopModalAsync(); }; _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); var page = new TwoFactorPage(false, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page)); 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() 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)); await Navigation.PushModalAsync(new NavigationPage(page));
} }

View File

@@ -7,8 +7,10 @@ using Bit.App.Utilities.AccountManagement;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Request; using Bit.Core.Models.Request;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel; using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {
@@ -28,9 +30,7 @@ namespace Bit.App.Pages
public ICommand ApproveWithMasterPasswordCommand { get; } public ICommand ApproveWithMasterPasswordCommand { get; }
public ICommand ContinueCommand { get; } public ICommand ContinueCommand { get; }
public Action StartTwoFactorAction { get; set; } public Action LogInWithMasterPassword { get; set; }
public Action LogInSuccessAction { get; set; }
public Action UpdateTempPasswordAction { get; set; }
public Action LogInWithDeviceAction { get; set; } public Action LogInWithDeviceAction { get; set; }
public Action RequestAdminApprovalAction { get; set; } public Action RequestAdminApprovalAction { get; set; }
public Action CloseAction { get; set; } public Action CloseAction { get; set; }
@@ -42,15 +42,15 @@ namespace Bit.App.Pages
PageTitle = AppResources.LoggedIn; PageTitle = AppResources.LoggedIn;
ApproveWithMyOtherDeviceCommand = new AsyncCommand(InitAsync, ApproveWithMyOtherDeviceCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithDeviceAction),
onException: ex => HandleException(ex), onException: ex => HandleException(ex),
allowsMultipleExecutions: false); allowsMultipleExecutions: false);
RequestAdminApprovalCommand = new AsyncCommand(RequestAdminApproval, RequestAdminApprovalCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(RequestAdminApprovalAction),
onException: ex => HandleException(ex), onException: ex => HandleException(ex),
allowsMultipleExecutions: false); allowsMultipleExecutions: false);
ApproveWithMasterPasswordCommand = new AsyncCommand(InitAsync, ApproveWithMasterPasswordCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithMasterPassword),
onException: ex => HandleException(ex), onException: ex => HandleException(ex),
allowsMultipleExecutions: false); allowsMultipleExecutions: false);
@@ -59,6 +59,8 @@ namespace Bit.App.Pages
allowsMultipleExecutions: false); allowsMultipleExecutions: false);
} }
public string LoggingInAsText => string.Format(AppResources.LoggingInAsX, Email);
public bool RememberThisDevice public bool RememberThisDevice
{ {
get => _rememberThisDevice; get => _rememberThisDevice;
@@ -92,7 +94,10 @@ namespace Bit.App.Pages
public string Email public string Email
{ {
get => _email; get => _email;
set => SetProperty(ref _email, value); set => SetProperty(ref _email, value, additionalPropertyNames:
new string[] {
nameof(LoggingInAsText)
});
} }
public async Task InitAsync() public async Task InitAsync()
@@ -119,18 +124,6 @@ namespace Bit.App.Pages
HandleException(ex); HandleException(ex);
} }
} }
private Task RequestAdminApproval()
{
try
{
RequestAdminApprovalAction?.Invoke();
}
catch (Exception ex)
{
HandleException(ex);
}
}
} }
} }

View File

@@ -136,7 +136,7 @@ namespace Bit.App.Pages
private async Task StartLoginWithDeviceAsync() 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)); await Navigation.PushModalAsync(new NavigationPage(page));
} }

View File

@@ -84,7 +84,7 @@ namespace Bit.App.Pages
get get
{ {
switch (_authRequestType) { switch (_authRequestType) {
case AuthRequestType.LoginWithDevice: case AuthRequestType.AuthenticateAndUnlock:
return AppResources.LogInInitiated; return AppResources.LogInInitiated;
case AuthRequestType.AdminApproval: case AuthRequestType.AdminApproval:
return AppResources.AdminApprovalRequested; return AppResources.AdminApprovalRequested;
@@ -100,7 +100,7 @@ namespace Bit.App.Pages
{ {
switch (_authRequestType) switch (_authRequestType)
{ {
case AuthRequestType.LoginWithDevice: case AuthRequestType.AuthenticateAndUnlock:
return AppResources.ANotificationHasBeenSentToYourDevice; return AppResources.ANotificationHasBeenSentToYourDevice;
case AuthRequestType.AdminApproval: case AuthRequestType.AdminApproval:
return AppResources.YourRequestHasBeenSentToYourAdmin; return AppResources.YourRequestHasBeenSentToYourAdmin;
@@ -116,7 +116,7 @@ namespace Bit.App.Pages
{ {
switch (_authRequestType) switch (_authRequestType)
{ {
case AuthRequestType.LoginWithDevice: case AuthRequestType.AuthenticateAndUnlock:
return AppResources.PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice; return AppResources.PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice;
case AuthRequestType.AdminApproval: case AuthRequestType.AdminApproval:
return AppResources.YouWillBeNotifiedOnceApproved; return AppResources.YouWillBeNotifiedOnceApproved;
@@ -132,7 +132,7 @@ namespace Bit.App.Pages
{ {
switch (_authRequestType) switch (_authRequestType)
{ {
case AuthRequestType.LoginWithDevice: case AuthRequestType.AuthenticateAndUnlock:
return AppResources.NeedAnotherOption; return AppResources.NeedAnotherOption;
case AuthRequestType.AdminApproval: case AuthRequestType.AdminApproval:
return AppResources.TroubleLoggingIn; return AppResources.TroubleLoggingIn;
@@ -245,7 +245,7 @@ namespace Bit.App.Pages
{ {
await Device.InvokeOnMainThreadAsync(() => _deviceActionService.ShowLoadingAsync(AppResources.Loading)); await Device.InvokeOnMainThreadAsync(() => _deviceActionService.ShowLoadingAsync(AppResources.Loading));
var response = await _authService.PasswordlessCreateLoginRequestAsync(_email); var response = await _authService.PasswordlessCreateLoginRequestAsync(_email, AuthRequestType);
if (response != null) if (response != null)
{ {
FingerprintPhrase = response.FingerprintPhrase; FingerprintPhrase = response.FingerprintPhrase;

View File

@@ -112,7 +112,7 @@ namespace Bit.App.Pages
await AppHelpers.ClearPreviousPage(); await AppHelpers.ClearPreviousPage();
// Just for testing the screen // Just for testing the screen
Application.Current.MainPage = new NavigationPage(new LoginApproveDevicePage(_appOptions)); Application.Current.MainPage = new NavigationPage(new LoginApproveDevicePage(_vm.Email, _appOptions));
return; return;
if (await _vaultTimeoutService.IsLockedAsync()) if (await _vaultTimeoutService.IsLockedAsync())

View File

@@ -31,6 +31,7 @@ namespace Bit.App.Pages
private readonly IOrganizationService _organizationService; private readonly IOrganizationService _organizationService;
private string _orgIdentifier; private string _orgIdentifier;
private string _email;
public LoginSsoPageViewModel() public LoginSsoPageViewModel()
{ {
@@ -57,6 +58,12 @@ namespace Bit.App.Pages
set => SetProperty(ref _orgIdentifier, value); set => SetProperty(ref _orgIdentifier, value);
} }
public string Email
{
get => _email;
set => SetProperty(ref _email, value);
}
public ICommand LogInCommand { get; } public ICommand LogInCommand { get; }
public Action StartTwoFactorAction { get; set; } public Action StartTwoFactorAction { get; set; }
public Action StartSetPasswordAction { get; set; } public Action StartSetPasswordAction { get; set; }
@@ -77,6 +84,8 @@ namespace Bit.App.Pages
{ {
OrgIdentifier = await _stateService.GetRememberedOrgIdentifierAsync(); OrgIdentifier = await _stateService.GetRememberedOrgIdentifierAsync();
} }
Email = await _stateService.GetRememberedEmailAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -3298,6 +3298,15 @@ namespace Bit.App.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Invalid API token.
/// </summary>
public static string InvalidAPIToken {
get {
return ResourceManager.GetString("InvalidAPIToken", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Invalid email address.. /// Looks up a localized string similar to Invalid email address..
/// </summary> /// </summary>
@@ -3631,6 +3640,15 @@ namespace Bit.App.Resources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Logging in as {0}.
/// </summary>
public static string LoggingInAsX {
get {
return ResourceManager.GetString("LoggingInAsX", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Logging in as {0} on {1}. /// Looks up a localized string similar to Logging in as {0} on {1}.
/// </summary> /// </summary>

View File

@@ -2658,6 +2658,9 @@ Do you want to switch to this account?</value>
<data name="InvalidAPIKey" xml:space="preserve"> <data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value> <value>Invalid API key</value>
</data> </data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
<data name="AdminApprovalRequested" xml:space="preserve"> <data name="AdminApprovalRequested" xml:space="preserve">
<value>Admin approval requested</value> <value>Admin approval requested</value>
</data> </data>
@@ -2670,4 +2673,7 @@ Do you want to switch to this account?</value>
<data name="TroubleLoggingIn" xml:space="preserve"> <data name="TroubleLoggingIn" xml:space="preserve">
<value>Trouble logging in?</value> <value>Trouble logging in?</value>
</data> </data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
</data>
</root> </root>

View File

@@ -34,7 +34,7 @@ namespace Bit.Core.Abstractions
Task<PasswordlessLoginResponse> GetPasswordlessLoginRequestByIdAsync(string id); Task<PasswordlessLoginResponse> GetPasswordlessLoginRequestByIdAsync(string id);
Task<PasswordlessLoginResponse> GetPasswordlessLoginResponseAsync(string id, string accessCode); Task<PasswordlessLoginResponse> GetPasswordlessLoginResponseAsync(string id, string accessCode);
Task<PasswordlessLoginResponse> PasswordlessLoginAsync(string id, string pubKey, bool requestApproved); Task<PasswordlessLoginResponse> PasswordlessLoginAsync(string id, string pubKey, bool requestApproved);
Task<PasswordlessLoginResponse> PasswordlessCreateLoginRequestAsync(string email); Task<PasswordlessLoginResponse> PasswordlessCreateLoginRequestAsync(string email, AuthRequestType authRequestType);
void LogOut(Action callback); void LogOut(Action callback);
void Init(); void Init();

View File

@@ -1,10 +1,11 @@
using System; using System;
namespace Bit.Core.Enums namespace Bit.Core.Enums
{ {
public enum AuthRequestType public enum AuthRequestType : byte
{ {
LoginWithDevice, AuthenticateAndUnlock = 0,
AdminApproval, Unlock = 1,
AdminApproval = 2
} }
} }

View File

@@ -1,4 +1,6 @@
using System; using System;
using Bit.Core.Enums;
namespace Bit.Core.Models.Request namespace Bit.Core.Models.Request
{ {
public class PasswordlessCreateLoginRequest public class PasswordlessCreateLoginRequest
@@ -25,10 +27,4 @@ namespace Bit.Core.Models.Request
public string FingerprintPhrase { get; set; } public string FingerprintPhrase { get; set; }
} }
public enum AuthRequestType : byte
{
AuthenticateAndUnlock = 0,
Unlock = 1
}
} }

View File

@@ -599,7 +599,7 @@ namespace Bit.Core.Services
return await PopulateFingerprintPhraseAsync(response, await _stateService.GetEmailAsync()); return await PopulateFingerprintPhraseAsync(response, await _stateService.GetEmailAsync());
} }
public async Task<PasswordlessLoginResponse> PasswordlessCreateLoginRequestAsync(string email) public async Task<PasswordlessLoginResponse> PasswordlessCreateLoginRequestAsync(string email, AuthRequestType authRequestType)
{ {
var deviceId = await _appIdService.GetAppIdAsync(); var deviceId = await _appIdService.GetAppIdAsync();
var keyPair = await _cryptoFunctionService.RsaGenerateKeyPairAsync(2048); var keyPair = await _cryptoFunctionService.RsaGenerateKeyPairAsync(2048);
@@ -607,7 +607,7 @@ namespace Bit.Core.Services
var fingerprintPhrase = string.Join("-", generatedFingerprintPhrase); var fingerprintPhrase = string.Join("-", generatedFingerprintPhrase);
var publicB64 = Convert.ToBase64String(keyPair.Item1); var publicB64 = Convert.ToBase64String(keyPair.Item1);
var accessCode = await _passwordGenerationService.GeneratePasswordAsync(PasswordGenerationOptions.CreateDefault.WithLength(25)); 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); var response = await _apiService.PostCreateRequestAsync(passwordlessCreateLoginRequest);
if (response != null) if (response != null)

View File

@@ -515,7 +515,7 @@ namespace Bit.iOS.Autofill
{ {
var appOptions = new AppOptions { IosExtension = true }; var appOptions = new AppOptions { IosExtension = true };
var app = new App.App(appOptions); 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.SetTheme(app.Resources);
ThemeManager.ApplyResourcesTo(loginWithDevicePage); ThemeManager.ApplyResourcesTo(loginWithDevicePage);
if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm)

View File

@@ -537,7 +537,7 @@ namespace Bit.iOS.Extension
{ {
var appOptions = new AppOptions { IosExtension = true }; var appOptions = new AppOptions { IosExtension = true };
var app = new App.App(appOptions); 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.SetTheme(app.Resources);
ThemeManager.ApplyResourcesTo(loginWithDevicePage); ThemeManager.ApplyResourcesTo(loginWithDevicePage);
if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm)

View File

@@ -350,7 +350,7 @@ namespace Bit.iOS.ShareExtension
private void LaunchLoginWithDevice(string email = null) 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); SetupAppAndApplyResources(loginWithDevicePage);
if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm)
{ {