1
0
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:
Federico Maccaroni
2023-03-09 11:16:48 -03:00
committed by GitHub
parent 4d2b53c809
commit a18f74a72a
34 changed files with 1277 additions and 630 deletions

View 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));
}
}
}