mirror of
https://github.com/bitwarden/android.git
synced 2025-01-12 11:17:30 +03:00
search for autofilling
This commit is contained in:
parent
29951207ec
commit
b8cbd5e0aa
3 changed files with 105 additions and 10 deletions
|
@ -1,13 +1,18 @@
|
||||||
using Bit.App.Models;
|
using Bit.App.Models;
|
||||||
|
using Bit.App.Resources;
|
||||||
|
using Bit.Core.Abstractions;
|
||||||
using Bit.Core.Enums;
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace Bit.App.Pages
|
namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
public partial class AutofillCiphersPage : BaseContentPage
|
public partial class AutofillCiphersPage : BaseContentPage
|
||||||
{
|
{
|
||||||
private AutofillCiphersPageViewModel _vm;
|
|
||||||
private readonly AppOptions _appOptions;
|
private readonly AppOptions _appOptions;
|
||||||
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
|
|
||||||
|
private AutofillCiphersPageViewModel _vm;
|
||||||
|
|
||||||
public AutofillCiphersPage(AppOptions appOptions)
|
public AutofillCiphersPage(AppOptions appOptions)
|
||||||
{
|
{
|
||||||
|
@ -17,6 +22,8 @@ namespace Bit.App.Pages
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
_fab.Clicked = AddButton_Clicked;
|
_fab.Clicked = AddButton_Clicked;
|
||||||
_vm.Init(appOptions);
|
_vm.Init(appOptions);
|
||||||
|
|
||||||
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async override void OnAppearing()
|
protected async override void OnAppearing()
|
||||||
|
@ -60,7 +67,14 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
private void Search_Clicked(object sender, System.EventArgs e)
|
private void Search_Clicked(object sender, System.EventArgs e)
|
||||||
{
|
{
|
||||||
|
var page = new CiphersPage(null, autofillUrl: _vm.Uri);
|
||||||
|
Application.Current.MainPage = new NavigationPage(page);
|
||||||
|
_platformUtilsService.ShowToast("info", null,
|
||||||
|
string.Format(AppResources.BitwardenAutofillServiceSearch, _vm.Name),
|
||||||
|
new System.Collections.Generic.Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["longDuration"] = true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Bit.App.Resources;
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Resources;
|
||||||
using Bit.Core.Models.View;
|
using Bit.Core.Models.View;
|
||||||
|
using Bit.Core.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
@ -7,16 +9,20 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
public partial class CiphersPage : BaseContentPage
|
public partial class CiphersPage : BaseContentPage
|
||||||
{
|
{
|
||||||
|
private readonly string _autofillUrl;
|
||||||
|
private readonly IDeviceActionService _deviceActionService;
|
||||||
|
|
||||||
private CiphersPageViewModel _vm;
|
private CiphersPageViewModel _vm;
|
||||||
private bool _hasFocused;
|
private bool _hasFocused;
|
||||||
|
|
||||||
public CiphersPage(Func<CipherView, bool> filter, bool folder = false, bool collection = false,
|
public CiphersPage(Func<CipherView, bool> filter, bool folder = false, bool collection = false,
|
||||||
bool type = false)
|
bool type = false, string autofillUrl = null)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_vm = BindingContext as CiphersPageViewModel;
|
_vm = BindingContext as CiphersPageViewModel;
|
||||||
_vm.Page = this;
|
_vm.Page = this;
|
||||||
_vm.Filter = filter;
|
_vm.Filter = filter;
|
||||||
|
_vm.AutofillUrl = _autofillUrl = autofillUrl;
|
||||||
if(folder)
|
if(folder)
|
||||||
{
|
{
|
||||||
_vm.PageTitle = AppResources.SearchFolder;
|
_vm.PageTitle = AppResources.SearchFolder;
|
||||||
|
@ -33,6 +39,8 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
_vm.PageTitle = AppResources.SearchVault;
|
_vm.PageTitle = AppResources.SearchVault;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchBar SearchBar => _searchBar;
|
public SearchBar SearchBar => _searchBar;
|
||||||
|
@ -43,9 +51,12 @@ namespace Bit.App.Pages
|
||||||
if(!_hasFocused)
|
if(!_hasFocused)
|
||||||
{
|
{
|
||||||
_hasFocused = true;
|
_hasFocused = true;
|
||||||
|
if(string.IsNullOrWhiteSpace(_autofillUrl))
|
||||||
|
{
|
||||||
RequestFocus(_searchBar);
|
RequestFocus(_searchBar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
|
private void SearchBar_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +81,10 @@ namespace Bit.App.Pages
|
||||||
|
|
||||||
protected override bool OnBackButtonPressed()
|
protected override bool OnBackButtonPressed()
|
||||||
{
|
{
|
||||||
|
if(string.IsNullOrWhiteSpace(_autofillUrl))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
GoBack();
|
GoBack();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -80,8 +95,15 @@ namespace Bit.App.Pages
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(string.IsNullOrWhiteSpace(_autofillUrl))
|
||||||
|
{
|
||||||
Navigation.PopModalAsync(false);
|
Navigation.PopModalAsync(false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_deviceActionService.CloseAutofill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
|
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
using Bit.App.Resources;
|
using Bit.App.Abstractions;
|
||||||
|
using Bit.App.Resources;
|
||||||
using Bit.Core.Abstractions;
|
using Bit.Core.Abstractions;
|
||||||
|
using Bit.Core.Enums;
|
||||||
|
using Bit.Core.Exceptions;
|
||||||
using Bit.Core.Models.View;
|
using Bit.Core.Models.View;
|
||||||
using Bit.Core.Utilities;
|
using Bit.Core.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
@ -15,6 +19,7 @@ namespace Bit.App.Pages
|
||||||
private readonly IPlatformUtilsService _platformUtilsService;
|
private readonly IPlatformUtilsService _platformUtilsService;
|
||||||
private readonly ICipherService _cipherService;
|
private readonly ICipherService _cipherService;
|
||||||
private readonly ISearchService _searchService;
|
private readonly ISearchService _searchService;
|
||||||
|
private readonly IDeviceActionService _deviceActionService;
|
||||||
private CancellationTokenSource _searchCancellationTokenSource;
|
private CancellationTokenSource _searchCancellationTokenSource;
|
||||||
|
|
||||||
private string _searchText;
|
private string _searchText;
|
||||||
|
@ -26,6 +31,7 @@ namespace Bit.App.Pages
|
||||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||||
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||||
_searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
_searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||||
|
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||||
|
|
||||||
Ciphers = new ExtendedObservableCollection<CipherView>();
|
Ciphers = new ExtendedObservableCollection<CipherView>();
|
||||||
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
|
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
|
||||||
|
@ -34,6 +40,7 @@ namespace Bit.App.Pages
|
||||||
public Command CipherOptionsCommand { get; set; }
|
public Command CipherOptionsCommand { get; set; }
|
||||||
public ExtendedObservableCollection<CipherView> Ciphers { get; set; }
|
public ExtendedObservableCollection<CipherView> Ciphers { get; set; }
|
||||||
public Func<CipherView, bool> Filter { get; set; }
|
public Func<CipherView, bool> Filter { get; set; }
|
||||||
|
public string AutofillUrl { get; set; }
|
||||||
|
|
||||||
public string SearchText
|
public string SearchText
|
||||||
{
|
{
|
||||||
|
@ -99,10 +106,62 @@ namespace Bit.App.Pages
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SelectCipherAsync(CipherView cipher)
|
public async Task SelectCipherAsync(CipherView cipher)
|
||||||
|
{
|
||||||
|
string selection = null;
|
||||||
|
if(!string.IsNullOrWhiteSpace(AutofillUrl))
|
||||||
|
{
|
||||||
|
var options = new List<string> { AppResources.Autofill };
|
||||||
|
if(cipher.Type == CipherType.Login)
|
||||||
|
{
|
||||||
|
options.Add(AppResources.AutofillAndSave);
|
||||||
|
}
|
||||||
|
options.Add(AppResources.View);
|
||||||
|
selection = await Page.DisplayActionSheet(AppResources.AutofillOrView, AppResources.Cancel, null,
|
||||||
|
options.ToArray());
|
||||||
|
}
|
||||||
|
if(selection == AppResources.View || string.IsNullOrWhiteSpace(AutofillUrl))
|
||||||
{
|
{
|
||||||
var page = new ViewPage(cipher.Id);
|
var page = new ViewPage(cipher.Id);
|
||||||
await Page.Navigation.PushModalAsync(new NavigationPage(page));
|
await Page.Navigation.PushModalAsync(new NavigationPage(page));
|
||||||
}
|
}
|
||||||
|
else if(selection == AppResources.Autofill || selection == AppResources.AutofillAndSave)
|
||||||
|
{
|
||||||
|
if(selection == AppResources.AutofillAndSave)
|
||||||
|
{
|
||||||
|
var uris = cipher.Login?.Uris?.ToList();
|
||||||
|
if(uris == null)
|
||||||
|
{
|
||||||
|
uris = new List<LoginUriView>();
|
||||||
|
}
|
||||||
|
uris.Add(new LoginUriView
|
||||||
|
{
|
||||||
|
Uri = AutofillUrl,
|
||||||
|
Match = null
|
||||||
|
});
|
||||||
|
cipher.Login.Uris = uris;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
|
||||||
|
await _cipherService.SaveWithServerAsync(await _cipherService.EncryptAsync(cipher));
|
||||||
|
await _deviceActionService.HideLoadingAsync();
|
||||||
|
}
|
||||||
|
catch(ApiException e)
|
||||||
|
{
|
||||||
|
await _deviceActionService.HideLoadingAsync();
|
||||||
|
await Page.DisplayAlert(AppResources.AnErrorHasOccurred, e.Error.GetSingleMessage(),
|
||||||
|
AppResources.Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(_deviceActionService.SystemMajorVersion() < 21)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_deviceActionService.Autofill(cipher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void CipherOptionsAsync(CipherView cipher)
|
private async void CipherOptionsAsync(CipherView cipher)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue