mirror of
https://github.com/bitwarden/mobile
synced 2025-12-19 17:53:47 +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:
committed by
GitHub
parent
d183baefa3
commit
afeec41500
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user