diff --git a/src/App/Pages/Accounts/LoginPasswordlessPage.xaml b/src/App/Pages/Accounts/LoginPasswordlessPage.xaml
index 2f2c9e9af..6ef2d95c5 100644
--- a/src/App/Pages/Accounts/LoginPasswordlessPage.xaml
+++ b/src/App/Pages/Accounts/LoginPasswordlessPage.xaml
@@ -77,10 +77,12 @@
Margin="0,0,0,57"/>
diff --git a/src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs b/src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs
index f3cac4e2f..7e1731c1e 100644
--- a/src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs
+++ b/src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
namespace Bit.App.Pages
{
@@ -20,6 +21,11 @@ namespace Bit.App.Pages
}
private async void Close_Clicked(object sender, System.EventArgs e)
+ {
+ await Close();
+ }
+
+ public async Task Close()
{
if (DoOnce())
{
diff --git a/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs b/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs
index d053e0c94..6bc84dd78 100644
--- a/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs
+++ b/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs
@@ -6,12 +6,16 @@ using Bit.Core.Utilities;
using Xamarin.Forms;
using Bit.App.Utilities;
using System.Linq;
+using Xamarin.CommunityToolkit.ObjectModel;
+using System.Windows.Input;
namespace Bit.App.Pages
{
public class LoginPasswordlessViewModel : BaseViewModel
{
- private IStateService _stateService;
+ private IAuthService _authService;
+ private IPlatformUtilsService _platformUtilsService;
+ private ILogger _logger;
private string _logInAttempByLabel;
private string _deviceType;
private FormattedString _fingerprintPhraseFormatted;
@@ -24,10 +28,24 @@ namespace Bit.App.Pages
public LoginPasswordlessViewModel()
{
- _stateService = ServiceContainer.Resolve("stateService");
+ _authService = ServiceContainer.Resolve("authService");
+ _platformUtilsService = ServiceContainer.Resolve("platformUtilsService");
+ _logger = ServiceContainer.Resolve("logger");
+
PageTitle = AppResources.LogInRequested;
+
+ AcceptRequestCommand = new AsyncCommand(AcceptRequestAsync,
+ onException: ex => _logger.Exception(ex),
+ allowsMultipleExecutions: false);
+ RejectRequestCommand = new AsyncCommand(RejectRequestAsync,
+ onException: ex => _logger.Exception(ex),
+ allowsMultipleExecutions: false);
}
+ public ICommand AcceptRequestCommand { get; }
+
+ public ICommand RejectRequestCommand { get; }
+
public string Email
{
get => _email;
@@ -139,5 +157,33 @@ namespace Bit.App.Pages
return RequestDate.ToShortTimeString();
}
+
+ private async Task AcceptRequestAsync()
+ {
+ try
+ {
+ var res = await _authService.LogInPasswordlessAcceptAsync();
+ await ((LoginPasswordlessPage)this.Page).Close();
+ _platformUtilsService.ShowToast("info", null, AppResources.LogInAccepted);
+ }
+ catch (Exception ex)
+ {
+ _logger.Exception(ex);
+ }
+ }
+
+ private async Task RejectRequestAsync()
+ {
+ try
+ {
+ var res = await _authService.LogInPasswordlessRejectAsync();
+ await ((LoginPasswordlessPage)this.Page).Close();
+ _platformUtilsService.ShowToast("info", null, AppResources.LogInDenied);
+ }
+ catch (Exception ex)
+ {
+ _logger.Exception(ex);
+ }
+ }
}
}
diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs
index 437344047..535f84bb8 100644
--- a/src/App/Resources/AppResources.Designer.cs
+++ b/src/App/Resources/AppResources.Designer.cs
@@ -4132,5 +4132,17 @@ namespace Bit.App.Resources {
return ResourceManager.GetString("MinutesAgo", resourceCulture);
}
}
+
+ public static string LogInAccepted {
+ get {
+ return ResourceManager.GetString("LogInAccepted", resourceCulture);
+ }
+ }
+
+ public static string LogInDenied {
+ get {
+ return ResourceManager.GetString("LogInDenied", resourceCulture);
+ }
+ }
}
}
diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx
index 7f19959eb..b21f8f70e 100644
--- a/src/App/Resources/AppResources.resx
+++ b/src/App/Resources/AppResources.resx
@@ -2305,4 +2305,10 @@
minutes ago
+
+ Log in accepted
+
+
+ Log in denied
+
diff --git a/src/Core/Abstractions/IAuthService.cs b/src/Core/Abstractions/IAuthService.cs
index b480348a9..7291d036a 100644
--- a/src/Core/Abstractions/IAuthService.cs
+++ b/src/Core/Abstractions/IAuthService.cs
@@ -25,6 +25,11 @@ namespace Bit.Core.Abstractions
Task LogInSsoAsync(string code, string codeVerifier, string redirectUrl, string orgId);
Task LogInCompleteAsync(string email, string masterPassword, TwoFactorProviderType twoFactorProvider, string twoFactorToken, bool? remember = null);
Task LogInTwoFactorAsync(TwoFactorProviderType twoFactorProvider, string twoFactorToken, string captchaToken, bool? remember = null);
+
+ Task GetLogInPasswordlessRequestsAsync();
+ Task LogInPasswordlessAcceptAsync();
+ Task LogInPasswordlessRejectAsync();
+
void LogOut(Action callback);
void Init();
}
diff --git a/src/Core/Services/AuthService.cs b/src/Core/Services/AuthService.cs
index 7316a758e..ff0ca81ac 100644
--- a/src/Core/Services/AuthService.cs
+++ b/src/Core/Services/AuthService.cs
@@ -468,5 +468,9 @@ namespace Bit.Core.Services
TwoFactorProvidersData = null;
SelectedTwoFactorProviderType = null;
}
+
+ public async Task GetLogInPasswordlessRequestsAsync() => await Task.FromResult(new AuthResult());
+ public async Task LogInPasswordlessAcceptAsync() => await Task.FromResult(new AuthResult());
+ public async Task LogInPasswordlessRejectAsync() => await Task.FromResult(new AuthResult());
}
}