1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-19 01:33:22 +00:00

PM-3385 Fix MP reprompt item level when no MP hash is stored like logging in with TDE. Also refactor code to be more maintainable (#2687)

This commit is contained in:
Federico Maccaroni
2023-08-14 13:47:52 -03:00
committed by GitHub
parent d183baefa3
commit afeec41500
10 changed files with 52 additions and 45 deletions

View File

@@ -1,4 +1,5 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Enums;
namespace Bit.App.Abstractions namespace Bit.App.Abstractions
{ {
@@ -6,7 +7,7 @@ namespace Bit.App.Abstractions
{ {
string[] ProtectedFields { get; } string[] ProtectedFields { get; }
Task<bool> ShowPasswordPromptAsync(); Task<bool> PromptAndCheckPasswordIfNeededAsync(CipherRepromptType repromptType = CipherRepromptType.Password);
Task<(string password, bool valid)> ShowPasswordPromptAndGetItAsync(); Task<(string password, bool valid)> ShowPasswordPromptAndGetItAsync();
} }

View File

@@ -82,7 +82,7 @@ namespace Bit.App.Pages
return; return;
} }
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync()) if (!await _passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
return; return;
} }

View File

@@ -698,12 +698,12 @@ namespace Bit.App.Pages
public async Task<bool> PromptPasswordAsync() public async Task<bool> PromptPasswordAsync()
{ {
if (Cipher.Reprompt == CipherRepromptType.None || _passwordReprompted) if (_passwordReprompted)
{ {
return true; return true;
} }
return _passwordReprompted = await _passwordRepromptService.ShowPasswordPromptAsync(); return _passwordReprompted = await _passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(Cipher.Reprompt);
} }
private async Task<bool> CanCloneAsync() private async Task<bool> CanCloneAsync()

View File

@@ -191,7 +191,7 @@ namespace Bit.App.Pages
if (_appOptions?.OtpData != null) if (_appOptions?.OtpData != null)
{ {
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync()) if (!await _passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
return; return;
} }
@@ -208,7 +208,7 @@ namespace Bit.App.Pages
} }
else if (selection == AppResources.Autofill || selection == AppResources.AutofillAndSave) else if (selection == AppResources.Autofill || selection == AppResources.AutofillAndSave)
{ {
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync()) if (!await _passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
return; return;
} }

View File

@@ -60,7 +60,7 @@ namespace Bit.App.Pages
var cipher = listItem.Cipher; var cipher = listItem.Cipher;
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync()) if (!await _passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
return; return;
} }

View File

@@ -2,6 +2,7 @@
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums;
namespace Bit.App.Services namespace Bit.App.Services
{ {
@@ -18,8 +19,13 @@ namespace Bit.App.Services
public string[] ProtectedFields { get; } = { "LoginTotp", "LoginPassword", "H_FieldValue", "CardNumber", "CardCode" }; public string[] ProtectedFields { get; } = { "LoginTotp", "LoginPassword", "H_FieldValue", "CardNumber", "CardCode" };
public async Task<bool> ShowPasswordPromptAsync() public async Task<bool> PromptAndCheckPasswordIfNeededAsync(CipherRepromptType repromptType = CipherRepromptType.Password)
{ {
if (repromptType == CipherRepromptType.None || await ShouldByPassMasterPasswordRepromptAsync())
{
return true;
}
return await _platformUtilsService.ShowPasswordDialogAsync(AppResources.PasswordConfirmation, AppResources.PasswordConfirmationDesc, ValidatePasswordAsync); return await _platformUtilsService.ShowPasswordDialogAsync(AppResources.PasswordConfirmation, AppResources.PasswordConfirmationDesc, ValidatePasswordAsync);
} }
@@ -38,5 +44,10 @@ namespace Bit.App.Services
return await _cryptoService.CompareAndUpdateKeyHashAsync(password, null); return await _cryptoService.CompareAndUpdateKeyHashAsync(password, null);
} }
private async Task<bool> ShouldByPassMasterPasswordRepromptAsync()
{
return await _cryptoService.GetMasterKeyHashAsync() is null;
}
} }
} }

View File

@@ -99,60 +99,55 @@ namespace Bit.App.Utilities
{ {
await page.Navigation.PushModalAsync(new NavigationPage(new CipherDetailsPage(cipher.Id))); await page.Navigation.PushModalAsync(new NavigationPage(new CipherDetailsPage(cipher.Id)));
} }
else if (selection == AppResources.Edit) else if (selection == AppResources.Edit
&&
await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
if (cipher.Reprompt == CipherRepromptType.None || await passwordRepromptService.ShowPasswordPromptAsync()) await page.Navigation.PushModalAsync(new NavigationPage(new CipherAddEditPage(cipher.Id)));
{
await page.Navigation.PushModalAsync(new NavigationPage(new CipherAddEditPage(cipher.Id)));
}
} }
else if (selection == AppResources.CopyUsername) else if (selection == AppResources.CopyUsername)
{ {
await clipboardService.CopyTextAsync(cipher.Type == CipherType.Login ? cipher.Login.Username : cipher.Fido2Key.UserName); await clipboardService.CopyTextAsync(cipher.Type == CipherType.Login ? cipher.Login.Username : cipher.Fido2Key.UserName);
platformUtilsService.ShowToastForCopiedValue(AppResources.Username); platformUtilsService.ShowToastForCopiedValue(AppResources.Username);
} }
else if (selection == AppResources.CopyPassword) else if (selection == AppResources.CopyPassword
&&
await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
if (cipher.Reprompt == CipherRepromptType.None || await passwordRepromptService.ShowPasswordPromptAsync()) await clipboardService.CopyTextAsync(cipher.Login.Password);
{ platformUtilsService.ShowToastForCopiedValue(AppResources.Password);
await clipboardService.CopyTextAsync(cipher.Login.Password); var task = eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedPassword, cipher.Id);
platformUtilsService.ShowToastForCopiedValue(AppResources.Password);
var task = eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedPassword, cipher.Id);
}
} }
else if (selection == AppResources.CopyTotp) else if (selection == AppResources.CopyTotp
&&
await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
if (cipher.Reprompt == CipherRepromptType.None || await passwordRepromptService.ShowPasswordPromptAsync()) var totpService = ServiceContainer.Resolve<ITotpService>("totpService");
var totp = await totpService.GetCodeAsync(cipher.Login.Totp);
if (!string.IsNullOrWhiteSpace(totp))
{ {
var totpService = ServiceContainer.Resolve<ITotpService>("totpService"); await clipboardService.CopyTextAsync(totp);
var totp = await totpService.GetCodeAsync(cipher.Login.Totp); platformUtilsService.ShowToastForCopiedValue(AppResources.VerificationCodeTotp);
if (!string.IsNullOrWhiteSpace(totp))
{
await clipboardService.CopyTextAsync(totp);
platformUtilsService.ShowToastForCopiedValue(AppResources.VerificationCodeTotp);
}
} }
} }
else if (selection == AppResources.Launch && cipher.CanLaunch) else if (selection == AppResources.Launch && cipher.CanLaunch)
{ {
platformUtilsService.LaunchUri(cipher.LaunchUri); platformUtilsService.LaunchUri(cipher.LaunchUri);
} }
else if (selection == AppResources.CopyNumber) else if (selection == AppResources.CopyNumber
&&
await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
if (cipher.Reprompt == CipherRepromptType.None || await passwordRepromptService.ShowPasswordPromptAsync()) await clipboardService.CopyTextAsync(cipher.Card.Number);
{ platformUtilsService.ShowToastForCopiedValue(AppResources.Number);
await clipboardService.CopyTextAsync(cipher.Card.Number);
platformUtilsService.ShowToastForCopiedValue(AppResources.Number);
}
} }
else if (selection == AppResources.CopySecurityCode) else if (selection == AppResources.CopySecurityCode
&&
await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(cipher.Reprompt))
{ {
if (cipher.Reprompt == CipherRepromptType.None || await passwordRepromptService.ShowPasswordPromptAsync()) await clipboardService.CopyTextAsync(cipher.Card.Code);
{ platformUtilsService.ShowToastForCopiedValue(AppResources.SecurityCode);
await clipboardService.CopyTextAsync(cipher.Card.Code); eventService.CollectAsync(EventType.Cipher_ClientCopiedCardCode, cipher.Id).FireAndForget();
platformUtilsService.ShowToastForCopiedValue(AppResources.SecurityCode);
var task = eventService.CollectAsync(Core.Enums.EventType.Cipher_ClientCopiedCardCode, cipher.Id);
}
} }
else if (selection == AppResources.CopyNotes) else if (selection == AppResources.CopyNotes)
{ {

View File

@@ -313,7 +313,7 @@ namespace Bit.iOS.Autofill
// Add a timeout to resolve keyboard not always showing up. // Add a timeout to resolve keyboard not always showing up.
await Task.Delay(250); await Task.Delay(250);
var passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"); var passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
if (!await passwordRepromptService.ShowPasswordPromptAsync()) if (!await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync())
{ {
var err = new NSError(new NSString("ASExtensionErrorDomain"), var err = new NSError(new NSString("ASExtensionErrorDomain"),
Convert.ToInt32(ASExtensionErrorCode.UserCanceled), null); Convert.ToInt32(ASExtensionErrorCode.UserCanceled), null);

View File

@@ -33,7 +33,7 @@ namespace Bit.iOS.Autofill.Utilities
return; return;
} }
if (item.Reprompt != Bit.Core.Enums.CipherRepromptType.None && !await passwordRepromptService.ShowPasswordPromptAsync()) if (!await passwordRepromptService.PromptAndCheckPasswordIfNeededAsync(item.Reprompt))
{ {
return; return;
} }

View File

@@ -126,7 +126,7 @@ namespace Bit.iOS.Extension
return; return;
} }
if (item.Reprompt != Bit.Core.Enums.CipherRepromptType.None && !await _controller.PasswordRepromptService.ShowPasswordPromptAsync()) if (!await _controller.PasswordRepromptService.PromptAndCheckPasswordIfNeededAsync(item.Reprompt))
{ {
return; return;
} }