[EC-341] Fix show alternative 2FA on iOS extensions (#2011)

* EC-341 Fix show alternative 2FA on iOS extensions

* EC-341 Fix iOS.Core.csproj reference
This commit is contained in:
Federico Maccaroni 2022-08-04 16:42:41 -03:00 committed by GitHub
parent 2c8406d0ad
commit ae4e8e2d8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 80 additions and 28 deletions

View file

@ -17,15 +17,19 @@
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" <ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
x:Name="_cancelItem" /> x:Name="_cancelItem" />
</ContentPage.ToolbarItems> </ContentPage.ToolbarItems>
<ContentPage.Resources> <ContentPage.Resources>
<ResourceDictionary> <ResourceDictionary>
<u:InverseBoolConverter x:Key="inverseBool" /> <u:InverseBoolConverter x:Key="inverseBool" />
<u:IsNullConverter x:Key="isNull" /> <u:IsNullConverter x:Key="isNull" />
<ToolbarItem Icon="more_vert.png" Clicked="More_Clicked" Order="Primary" <ToolbarItem
x:Name="_moreItem" x:Key="moreItem" x:Name="_moreItem"
AutomationProperties.IsInAccessibleTree="True" x:Key="moreItem"
AutomationProperties.Name="{u:I18n Options}" /> Icon="more_vert.png"
Order="Primary"
Command="{Binding MoreCommand}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
<ToolbarItem Text="{u:I18n UseAnotherTwoStepMethod}" <ToolbarItem Text="{u:I18n UseAnotherTwoStepMethod}"
Clicked="Methods_Clicked" Clicked="Methods_Clicked"
Order="Secondary" Order="Secondary"

View file

@ -2,7 +2,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Models; using Bit.App.Models;
using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
@ -137,21 +136,6 @@ namespace Bit.App.Pages
} }
} }
private async void More_Clicked(object sender, EventArgs e)
{
if (!DoOnce())
{
return;
}
var selection = await DisplayActionSheet(AppResources.Options, AppResources.Cancel, null, AppResources.UseAnotherTwoStepMethod);
if (selection == AppResources.UseAnotherTwoStepMethod)
{
await _vm.AnotherMethodAsync();
}
}
private async void ResendEmail_Clicked(object sender, EventArgs e) private async void ResendEmail_Clicked(object sender, EventArgs e)
{ {
if (DoOnce()) if (DoOnce())

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
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;
@ -12,6 +13,7 @@ using Bit.Core.Exceptions;
using Bit.Core.Models.Request; using Bit.Core.Models.Request;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Newtonsoft.Json; using Newtonsoft.Json;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Essentials; using Xamarin.Essentials;
using Xamarin.Forms; using Xamarin.Forms;
@ -30,6 +32,7 @@ namespace Bit.App.Pages
private readonly IStateService _stateService; private readonly IStateService _stateService;
private readonly II18nService _i18nService; private readonly II18nService _i18nService;
private readonly IAppIdService _appIdService; private readonly IAppIdService _appIdService;
private readonly ILogger _logger;
private TwoFactorProviderType? _selectedProviderType; private TwoFactorProviderType? _selectedProviderType;
private string _totpInstruction; private string _totpInstruction;
@ -51,9 +54,11 @@ namespace Bit.App.Pages
_stateService = ServiceContainer.Resolve<IStateService>("stateService"); _stateService = ServiceContainer.Resolve<IStateService>("stateService");
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService"); _i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService"); _appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
_logger = ServiceContainer.Resolve<ILogger>();
PageTitle = AppResources.TwoStepLogin; PageTitle = AppResources.TwoStepLogin;
SubmitCommand = new Command(async () => await SubmitAsync()); SubmitCommand = new Command(async () => await SubmitAsync());
MoreCommand = new AsyncCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
} }
public string TotpInstruction public string TotpInstruction
@ -111,6 +116,7 @@ namespace Bit.App.Pages
}); });
} }
public Command SubmitCommand { get; } public Command SubmitCommand { get; }
public ICommand MoreCommand { get; }
public Action TwoFactorAuthSuccessAction { get; set; } public Action TwoFactorAuthSuccessAction { get; set; }
public Action StartSetPasswordAction { get; set; } public Action StartSetPasswordAction { get; set; }
public Action CloseAction { get; set; } public Action CloseAction { get; set; }
@ -337,6 +343,15 @@ namespace Bit.App.Pages
} }
} }
private async Task MoreAsync()
{
var selection = await _deviceActionService.DisplayActionSheetAsync(AppResources.Options, AppResources.Cancel, null, AppResources.UseAnotherTwoStepMethod);
if (selection == AppResources.UseAnotherTwoStepMethod)
{
await AnotherMethodAsync();
}
}
public async Task AnotherMethodAsync() public async Task AnotherMethodAsync()
{ {
var supportedProviders = _authService.GetSupportedTwoFactorProviders(); var supportedProviders = _authService.GetSupportedTwoFactorProviders();

View file

@ -18,6 +18,7 @@ using CoreNFC;
using Foundation; using Foundation;
using UIKit; using UIKit;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
namespace Bit.iOS.Autofill namespace Bit.iOS.Autofill
{ {

View file

@ -253,6 +253,17 @@
<ItemGroup> <ItemGroup>
<BundleResource Include="Resources\logo_white%403x.png" /> <BundleResource Include="Resources\logo_white%403x.png" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<BundleResource Include="..\iOS\Resources\more_vert.png">
<Link>Resources\more_vert.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert%402x.png">
<Link>Resources\more_vert%402x.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert%403x.png">
<Link>Resources\more_vert%403x.png</Link>
</BundleResource>
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes"> <PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>4.4.0</Version> <Version>4.4.0</Version>

View file

@ -84,6 +84,12 @@ namespace Bit.iOS.Core.Services
HideLoadingAsync().GetAwaiter().GetResult(); HideLoadingAsync().GetAwaiter().GetResult();
} }
var vc = GetPresentedViewController();
if (vc is null)
{
return Task.CompletedTask;
}
var result = new TaskCompletionSource<int>(); var result = new TaskCompletionSource<int>();
var loadingIndicator = new UIActivityIndicatorView(new CGRect(10, 5, 50, 50)); var loadingIndicator = new UIActivityIndicatorView(new CGRect(10, 5, 50, 50));
@ -96,8 +102,7 @@ namespace Bit.iOS.Core.Services
_progressAlert.View.TintColor = UIColor.Black; _progressAlert.View.TintColor = UIColor.Black;
_progressAlert.View.Add(loadingIndicator); _progressAlert.View.Add(loadingIndicator);
var vc = GetPresentedViewController(); vc.PresentViewController(_progressAlert, false, () => result.TrySetResult(0));
vc?.PresentViewController(_progressAlert, false, () => result.TrySetResult(0));
return result.Task; return result.Task;
} }
@ -205,6 +210,12 @@ namespace Bit.iOS.Core.Services
string text = null, string okButtonText = null, string cancelButtonText = null, string text = null, string okButtonText = null, string cancelButtonText = null,
bool numericKeyboard = false, bool autofocus = true, bool password = false) bool numericKeyboard = false, bool autofocus = true, bool password = false)
{ {
var vc = GetPresentedViewController();
if (vc is null)
{
return null;
}
var result = new TaskCompletionSource<string>(); var result = new TaskCompletionSource<string>();
var alert = UIAlertController.Create(title ?? string.Empty, description, UIAlertControllerStyle.Alert); var alert = UIAlertController.Create(title ?? string.Empty, description, UIAlertControllerStyle.Alert);
UITextField input = null; UITextField input = null;
@ -234,8 +245,7 @@ namespace Bit.iOS.Core.Services
input.KeyboardAppearance = UIKeyboardAppearance.Dark; input.KeyboardAppearance = UIKeyboardAppearance.Dark;
} }
}); });
var vc = GetPresentedViewController(); vc.PresentViewController(alert, true, null);
vc?.PresentViewController(alert, true, null);
return result.Task; return result.Task;
} }
@ -312,6 +322,12 @@ namespace Bit.iOS.Core.Services
public Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons) public Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons)
{ {
var vc = GetPresentedViewController();
if (vc is null)
{
return null;
}
var result = new TaskCompletionSource<string>(); var result = new TaskCompletionSource<string>();
var alert = UIAlertController.Create(title ?? string.Empty, message, UIAlertControllerStyle.Alert); var alert = UIAlertController.Create(title ?? string.Empty, message, UIAlertControllerStyle.Alert);
if (!string.IsNullOrWhiteSpace(cancel)) if (!string.IsNullOrWhiteSpace(cancel))
@ -328,8 +344,7 @@ namespace Bit.iOS.Core.Services
result.TrySetResult(button); result.TrySetResult(button);
})); }));
} }
var vc = GetPresentedViewController(); vc.PresentViewController(alert, true, null);
vc?.PresentViewController(alert, true, null);
return result.Task; return result.Task;
} }
@ -340,8 +355,12 @@ namespace Bit.iOS.Core.Services
{ {
return app.MainPage.DisplayActionSheet(title, cancel, destruction, buttons); return app.MainPage.DisplayActionSheet(title, cancel, destruction, buttons);
} }
var result = new TaskCompletionSource<string>();
var vc = GetPresentedViewController(); var vc = GetPresentedViewController();
if (vc is null)
{
return null;
}
var result = new TaskCompletionSource<string>();
var sheet = UIAlertController.Create(title, null, UIAlertControllerStyle.ActionSheet); var sheet = UIAlertController.Create(title, null, UIAlertControllerStyle.ActionSheet);
if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad) if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad)
{ {

View file

@ -230,6 +230,15 @@
<BundleResource Include="Resources\yubikey.png" /> <BundleResource Include="Resources\yubikey.png" />
<BundleResource Include="Resources\yubikey%403x.png" /> <BundleResource Include="Resources\yubikey%403x.png" />
<BundleResource Include="Resources\yubikey%402x.png" /> <BundleResource Include="Resources\yubikey%402x.png" />
<BundleResource Include="..\iOS\Resources\more_vert.png">
<Link>Resources\more_vert.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert%402x.png">
<Link>Resources\more_vert%402x.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert%403x.png">
<Link>Resources\more_vert%403x.png</Link>
</BundleResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes"> <PackageReference Include="Microsoft.AppCenter.Crashes">

View file

@ -227,6 +227,15 @@
<BundleResource Include="..\iOS\Resources\logo.png"> <BundleResource Include="..\iOS\Resources\logo.png">
<Link>Resources\logo.png</Link> <Link>Resources\logo.png</Link>
</BundleResource> </BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert.png">
<Link>Resources\more_vert.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert%402x.png">
<Link>Resources\more_vert%402x.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\more_vert%403x.png">
<Link>Resources\more_vert%403x.png</Link>
</BundleResource>
<BundleResource Include="..\iOS\Resources\bwi-font.ttf"> <BundleResource Include="..\iOS\Resources\bwi-font.ttf">
<Link>Resources\bwi-font.ttf</Link> <Link>Resources\bwi-font.ttf</Link>
</BundleResource> </BundleResource>