mirror of
https://github.com/bitwarden/mobile
synced 2025-12-19 17:53:47 +00:00
[PM-1129] iOS 16 Third-Party 2FA OTP handling (#2409)
* [EC-980] Added iOS otpauth handler (#2370) * EC-980 added Bitwarden as otpauth scheme handler * EC-980 Fix format * [EC-981] OTP handling - Set to selected cipher (#2404) * EC-981 Started adding OTP to existing cipher. Reused AutofillCiphersPage for the cipher selection and refactored it so that we have more code reuse * EC-981 Fix navigation on otp handling * EC-981 Fix formatting * EC-981 Added otp cipher selection callout and add close toolbar item when needed * PM-1131 implemented cipher creation from otp handling flow with otp key filled (#2407) * PM-1133 Updated empty states for search and cipher selection on otp flow (#2408)
This commit is contained in:
committed by
GitHub
parent
4d2b53c809
commit
a18f74a72a
79
src/App/Pages/Vault/OTPCipherSelectionPageViewModel.cs
Normal file
79
src/App/Pages/Vault/OTPCipherSelectionPageViewModel.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class OTPCipherSelectionPageViewModel : CipherSelectionPageViewModel
|
||||
{
|
||||
private readonly ISearchService _searchService = ServiceContainer.Resolve<ISearchService>();
|
||||
|
||||
private OtpData _otpData;
|
||||
private Models.AppOptions _appOptions;
|
||||
|
||||
public override bool ShowCallout => !ShowNoData;
|
||||
|
||||
public override void Init(Models.AppOptions options)
|
||||
{
|
||||
_appOptions = options;
|
||||
_otpData = options.OtpData.Value;
|
||||
|
||||
Name = _otpData.Issuer ?? _otpData.AccountName;
|
||||
PageTitle = string.Format(AppResources.ItemsForUri, Name ?? "--");
|
||||
NoDataText = string.Format(AppResources.ThereAreNoItemsInYourVaultThatMatchX, Name ?? "--")
|
||||
+ Environment.NewLine
|
||||
+ AppResources.SearchForAnItemOrAddANewItem;
|
||||
}
|
||||
|
||||
protected override async Task<List<GroupingsPageListGroup>> LoadGroupedItemsAsync()
|
||||
{
|
||||
var groupedItems = new List<GroupingsPageListGroup>();
|
||||
var allCiphers = await _cipherService.GetAllDecryptedAsync();
|
||||
var ciphers = await _searchService.SearchCiphersAsync(_otpData.Issuer ?? _otpData.AccountName,
|
||||
c => c.Type == CipherType.Login && !c.IsDeleted, allCiphers);
|
||||
|
||||
if (ciphers?.Any() ?? false)
|
||||
{
|
||||
groupedItems.Add(
|
||||
new GroupingsPageListGroup(ciphers.Select(c => new GroupingsPageListItem { Cipher = c }).ToList(),
|
||||
AppResources.MatchingItems,
|
||||
ciphers.Count,
|
||||
false,
|
||||
true));
|
||||
}
|
||||
|
||||
return groupedItems;
|
||||
}
|
||||
|
||||
protected override async Task SelectCipherAsync(IGroupingsPageListItem item)
|
||||
{
|
||||
if (!(item is GroupingsPageListItem listItem) || listItem.Cipher is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var cipher = listItem.Cipher;
|
||||
|
||||
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var editCipherPage = new CipherAddEditPage(cipher.Id, appOptions: _appOptions);
|
||||
await Page.Navigation.PushModalAsync(new NavigationPage(editCipherPage));
|
||||
return;
|
||||
}
|
||||
|
||||
protected override async Task AddCipherAsync()
|
||||
{
|
||||
var pageForLogin = new CipherAddEditPage(null, CipherType.Login, name: Name, appOptions: _appOptions);
|
||||
await Page.Navigation.PushModalAsync(new NavigationPage(pageForLogin));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user