EC-297 Fix possible crash when copying password on cipher item view. Also improved a bit the code of copying commands (#1974)

This commit is contained in:
Federico Maccaroni 2022-07-05 18:14:46 -03:00 committed by GitHub
parent e2502e2e0c
commit d246d1dece
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 26 deletions

View file

@ -28,17 +28,25 @@ namespace Bit.Droid.Services
public async Task CopyTextAsync(string text, int expiresInMs = -1, bool isSensitive = true) public async Task CopyTextAsync(string text, int expiresInMs = -1, bool isSensitive = true)
{ {
// Xamarin.Essentials.Clipboard currently doesn't support the IS_SENSITIVE flag for API 33+ try
if ((int)Build.VERSION.SdkInt < 33)
{ {
await Clipboard.SetTextAsync(text); // Xamarin.Essentials.Clipboard currently doesn't support the IS_SENSITIVE flag for API 33+
} if ((int)Build.VERSION.SdkInt < 33)
else {
{ await Clipboard.SetTextAsync(text);
CopyToClipboard(text, isSensitive); }
} else
{
CopyToClipboard(text, isSensitive);
}
await ClearClipboardAlarmAsync(expiresInMs); await ClearClipboardAlarmAsync(expiresInMs);
}
catch (Java.Lang.SecurityException ex) when (ex.Message.Contains("does not belong to"))
{
// #1962 Just ignore, the content is copied either way but there is some app interfiering in the process
// that the OS catches and just throws this exception.
}
} }
public bool IsCopyNotificationHandledByPlatform() public bool IsCopyNotificationHandledByPlatform()

View file

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
@ -11,6 +12,7 @@ using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@ -28,6 +30,7 @@ namespace Bit.App.Pages
private readonly IPasswordRepromptService _passwordRepromptService; private readonly IPasswordRepromptService _passwordRepromptService;
private readonly ILocalizeService _localizeService; private readonly ILocalizeService _localizeService;
private readonly IClipboardService _clipboardService; private readonly IClipboardService _clipboardService;
private readonly ILogger _logger;
private CipherView _cipher; private CipherView _cipher;
private List<ViewPageFieldViewModel> _fields; private List<ViewPageFieldViewModel> _fields;
@ -58,10 +61,11 @@ namespace Bit.App.Pages
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"); _passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
_localizeService = ServiceContainer.Resolve<ILocalizeService>("localizeService"); _localizeService = ServiceContainer.Resolve<ILocalizeService>("localizeService");
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService"); _clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
_logger = ServiceContainer.Resolve<ILogger>("logger");
CopyCommand = new Command<string>((id) => CopyAsync(id, null)); CopyCommand = new AsyncCommand<string>((id) => CopyAsync(id, null), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
CopyUriCommand = new Command<LoginUriView>(CopyUri); CopyUriCommand = new AsyncCommand<LoginUriView>(uriView => CopyAsync("LoginUri", uriView.Uri), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
CopyFieldCommand = new Command<FieldView>(CopyField); CopyFieldCommand = new AsyncCommand<FieldView>(field => CopyAsync(field.Type == FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
LaunchUriCommand = new Command<LoginUriView>(LaunchUri); LaunchUriCommand = new Command<LoginUriView>(LaunchUri);
TogglePasswordCommand = new Command(TogglePassword); TogglePasswordCommand = new Command(TogglePassword);
ToggleCardNumberCommand = new Command(ToggleCardNumber); ToggleCardNumberCommand = new Command(ToggleCardNumber);
@ -72,9 +76,9 @@ namespace Bit.App.Pages
PageTitle = AppResources.ViewItem; PageTitle = AppResources.ViewItem;
} }
public Command CopyCommand { get; set; } public ICommand CopyCommand { get; set; }
public Command CopyUriCommand { get; set; } public ICommand CopyUriCommand { get; set; }
public Command CopyFieldCommand { get; set; } public ICommand CopyFieldCommand { get; set; }
public Command LaunchUriCommand { get; set; } public Command LaunchUriCommand { get; set; }
public Command TogglePasswordCommand { get; set; } public Command TogglePasswordCommand { get; set; }
public Command ToggleCardNumberCommand { get; set; } public Command ToggleCardNumberCommand { get; set; }
@ -616,7 +620,7 @@ namespace Bit.App.Pages
_attachmentFilename = null; _attachmentFilename = null;
} }
private async void CopyAsync(string id, string text = null) private async Task CopyAsync(string id, string text = null)
{ {
if (_passwordRepromptService.ProtectedFields.Contains(id) && !await PromptPasswordAsync()) if (_passwordRepromptService.ProtectedFields.Contains(id) && !await PromptPasswordAsync())
{ {
@ -680,16 +684,6 @@ namespace Bit.App.Pages
} }
} }
private void CopyUri(LoginUriView uri)
{
CopyAsync("LoginUri", uri.Uri);
}
private void CopyField(FieldView field)
{
CopyAsync(field.Type == Core.Enums.FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value);
}
private void LaunchUri(LoginUriView uri) private void LaunchUri(LoginUriView uri)
{ {
if (uri.CanLaunch && (Page as BaseContentPage).DoOnce()) if (uri.CanLaunch && (Page as BaseContentPage).DoOnce())