mirror of
https://github.com/bitwarden/android.git
synced 2024-12-24 18:08:26 +03:00
listen to yubikey
This commit is contained in:
parent
822fc7f308
commit
58d101659a
4 changed files with 121 additions and 6 deletions
|
@ -32,6 +32,8 @@ namespace Bit.Droid
|
|||
private IBroadcasterService _broadcasterService;
|
||||
private PendingIntent _lockAlarmPendingIntent;
|
||||
private AppOptions _appOptions;
|
||||
private Java.Util.Regex.Pattern _otpPattern =
|
||||
Java.Util.Regex.Pattern.Compile("^.*?([cbdefghijklnrtuv]{32,64})$");
|
||||
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
|
@ -70,9 +72,38 @@ namespace Bit.Droid
|
|||
{
|
||||
Finish();
|
||||
}
|
||||
else if(message.Command == "listenYubiKeyOTP")
|
||||
{
|
||||
ListenYubiKey((bool)message.Data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnPause()
|
||||
{
|
||||
base.OnPause();
|
||||
ListenYubiKey(false);
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
if(_deviceActionService.SupportsNfc())
|
||||
{
|
||||
try
|
||||
{
|
||||
_messagingService.Send("resumeYubiKey");
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNewIntent(Intent intent)
|
||||
{
|
||||
base.OnNewIntent(intent);
|
||||
ParseYubiKey(intent.DataString);
|
||||
}
|
||||
|
||||
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions,
|
||||
[GeneratedEnum] Permission[] grantResults)
|
||||
{
|
||||
|
@ -191,5 +222,19 @@ namespace Bit.Droid
|
|||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
private void ParseYubiKey(string data)
|
||||
{
|
||||
if(data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var otpMatch = _otpPattern.Matcher(data);
|
||||
if(otpMatch.Matches())
|
||||
{
|
||||
var otp = otpMatch.Group(1);
|
||||
_messagingService.Send("gotYubiKeyOTP", otp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,28 @@
|
|||
using Bit.App.Controls;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class TwoFactorPage : BaseContentPage
|
||||
{
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
|
||||
private TwoFactorPageViewModel _vm;
|
||||
|
||||
public TwoFactorPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
SetActivityIndicator();
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_vm = BindingContext as TwoFactorPageViewModel;
|
||||
_vm.Page = this;
|
||||
DuoWebView = _duoWebView;
|
||||
SetActivityIndicator();
|
||||
}
|
||||
|
||||
public HybridWebView DuoWebView { get; set; }
|
||||
|
@ -34,9 +42,28 @@ namespace Bit.App.Pages
|
|||
ToolbarItems.Remove(_continueItem);
|
||||
}
|
||||
}
|
||||
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
_broadcasterService.Subscribe(nameof(TwoFactorPage), async (message) =>
|
||||
{
|
||||
if(message.Command == "gotYubiKeyOTP")
|
||||
{
|
||||
if(_vm.YubikeyMethod)
|
||||
{
|
||||
_vm.Token = (string)message.Data;
|
||||
await _vm.SubmitAsync();
|
||||
}
|
||||
}
|
||||
else if(message.Command == "resumeYubiKey")
|
||||
{
|
||||
if(_vm.YubikeyMethod)
|
||||
{
|
||||
_messagingService.Send("listenYubiKeyOTP", true);
|
||||
}
|
||||
}
|
||||
});
|
||||
await LoadOnAppearedAsync(_scrollView, true, () =>
|
||||
{
|
||||
_vm.Init();
|
||||
|
@ -44,6 +71,31 @@ namespace Bit.App.Pages
|
|||
});
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
if(!_vm.YubikeyMethod)
|
||||
{
|
||||
_messagingService.Send("listenYubiKeyOTP", false);
|
||||
_broadcasterService.Unsubscribe(nameof(TwoFactorPage));
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
// ref: https://github.com/bitwarden/mobile/issues/350
|
||||
if(_vm.YubikeyMethod)
|
||||
{
|
||||
if(Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
_messagingService.Send("listenYubiKeyOTP", false);
|
||||
_broadcasterService.Unsubscribe(nameof(TwoFactorPage));
|
||||
}
|
||||
return base.OnBackButtonPressed();
|
||||
}
|
||||
|
||||
private async void Continue_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if(DoOnce())
|
||||
|
|
|
@ -21,6 +21,8 @@ namespace Bit.App.Pages
|
|||
private readonly IApiService _apiService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IEnvironmentService _environmentService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
|
||||
private bool _u2fSupported = false;
|
||||
private TwoFactorProviderType? _selectedProviderType;
|
||||
|
@ -36,6 +38,8 @@ namespace Bit.App.Pages
|
|||
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
|
||||
PageTitle = AppResources.TwoStepLogin;
|
||||
}
|
||||
|
@ -122,9 +126,11 @@ namespace Bit.App.Pages
|
|||
case TwoFactorProviderType.U2f:
|
||||
// TODO
|
||||
break;
|
||||
case TwoFactorProviderType.YubiKey:
|
||||
_messagingService.Send("listenYubiKeyOTP", true);
|
||||
break;
|
||||
case TwoFactorProviderType.Duo:
|
||||
case TwoFactorProviderType.OrganizationDuo:
|
||||
page.RemoveContinueButton();
|
||||
var host = WebUtility.UrlEncode(providerData["Host"] as string);
|
||||
var req = WebUtility.UrlEncode(providerData["Signature"] as string);
|
||||
page.DuoWebView.Uri = $"{_webVaultUrl}/duo-connector.html?host={host}&request={req}";
|
||||
|
@ -135,7 +141,6 @@ namespace Bit.App.Pages
|
|||
});
|
||||
break;
|
||||
case TwoFactorProviderType.Email:
|
||||
page.AddContinueButton();
|
||||
TwoFactorEmail = providerData["Email"] as string;
|
||||
if(_authService.TwoFactorProvidersData.Count > 1)
|
||||
{
|
||||
|
@ -143,9 +148,21 @@ namespace Bit.App.Pages
|
|||
}
|
||||
break;
|
||||
default:
|
||||
page.AddContinueButton();
|
||||
break;
|
||||
}
|
||||
|
||||
if(!YubikeyMethod)
|
||||
{
|
||||
_messagingService.Send("listenYubiKeyOTP", false);
|
||||
}
|
||||
if(DuoMethod)
|
||||
{
|
||||
page.RemoveContinueButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
page.AddContinueButton();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SubmitAsync()
|
||||
|
@ -172,6 +189,8 @@ namespace Bit.App.Pages
|
|||
await _authService.LogInTwoFactorAsync(SelectedProviderType.Value, Token, Remember);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
var task = Task.Run(() => _syncService.FullSyncAsync(true));
|
||||
_messagingService.Send("listenYubiKeyOTP", false);
|
||||
_broadcasterService.Unsubscribe(nameof(TwoFactorPage));
|
||||
Application.Current.MainPage = new TabsPage();
|
||||
}
|
||||
catch(ApiException e)
|
||||
|
@ -202,7 +221,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public async Task<bool> SendEmailAsync(bool showLoading, bool doToast)
|
||||
{
|
||||
if(SelectedProviderType != TwoFactorProviderType.Email)
|
||||
if(!EmailMethod)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ namespace Bit.App.Pages
|
|||
protected async override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
// await _syncService.FullSyncAsync(true);
|
||||
_broadcasterService.Subscribe(_pageName, async (message) =>
|
||||
{
|
||||
if(message.Command == "syncCompleted")
|
||||
|
|
Loading…
Reference in a new issue