diff --git a/src/Android/Android.csproj b/src/Android/Android.csproj
index 7abf7d6dd..4825654e1 100644
--- a/src/Android/Android.csproj
+++ b/src/Android/Android.csproj
@@ -156,6 +156,7 @@
+
diff --git a/src/Android/Assets/bwi-font.ttf b/src/Android/Assets/bwi-font.ttf
index 358fca186..7c7afd4cd 100644
Binary files a/src/Android/Assets/bwi-font.ttf and b/src/Android/Assets/bwi-font.ttf differ
diff --git a/src/Android/Effects/RemoveFontPaddingEffect.cs b/src/Android/Effects/RemoveFontPaddingEffect.cs
new file mode 100644
index 000000000..1f7cf1297
--- /dev/null
+++ b/src/Android/Effects/RemoveFontPaddingEffect.cs
@@ -0,0 +1,23 @@
+using Android.Widget;
+using Bit.Droid.Effects;
+using Xamarin.Forms;
+using Xamarin.Forms.Platform.Android;
+
+[assembly: ExportEffect(typeof(RemoveFontPaddingEffect), nameof(RemoveFontPaddingEffect))]
+namespace Bit.Droid.Effects
+{
+ public class RemoveFontPaddingEffect : PlatformEffect
+ {
+ protected override void OnAttached()
+ {
+ if (Control is TextView textView)
+ {
+ textView.SetIncludeFontPadding(false);
+ }
+ }
+
+ protected override void OnDetached()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/App/App.csproj b/src/App/App.csproj
index 9305cd38c..c60580e2d 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -139,6 +139,7 @@
+
@@ -430,5 +431,6 @@
+
diff --git a/src/App/Controls/IconButton.cs b/src/App/Controls/IconButton.cs
index e7f8cd787..64f44b023 100644
--- a/src/App/Controls/IconButton.cs
+++ b/src/App/Controls/IconButton.cs
@@ -1,4 +1,5 @@
-using Xamarin.Forms;
+using Bit.App.Effects;
+using Xamarin.Forms;
namespace Bit.App.Controls
{
@@ -16,6 +17,8 @@ namespace Bit.App.Controls
FontFamily = "bwi-font.ttf#bwi-font";
break;
}
+
+ Effects.Add(new RemoveFontPaddingEffect());
}
}
}
diff --git a/src/App/Controls/IconLabel.cs b/src/App/Controls/IconLabel.cs
index fce9159f6..ee21eb234 100644
--- a/src/App/Controls/IconLabel.cs
+++ b/src/App/Controls/IconLabel.cs
@@ -1,4 +1,5 @@
-using Xamarin.Forms;
+using Bit.App.Effects;
+using Xamarin.Forms;
namespace Bit.App.Controls
{
@@ -17,6 +18,8 @@ namespace Bit.App.Controls
FontFamily = "bwi-font.ttf#bwi-font";
break;
}
+
+ Effects.Add(new RemoveFontPaddingEffect());
}
}
}
diff --git a/src/App/Controls/IconLabelButton/IconLabelButton.xaml b/src/App/Controls/IconLabelButton/IconLabelButton.xaml
new file mode 100644
index 000000000..5b88dcd91
--- /dev/null
+++ b/src/App/Controls/IconLabelButton/IconLabelButton.xaml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Controls/IconLabelButton/IconLabelButton.xaml.cs b/src/App/Controls/IconLabelButton/IconLabelButton.xaml.cs
new file mode 100644
index 000000000..ebd99360c
--- /dev/null
+++ b/src/App/Controls/IconLabelButton/IconLabelButton.xaml.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+using Bit.Core.Models.Domain;
+using Xamarin.Forms;
+using Xamarin.Forms.Xaml;
+
+namespace Bit.App.Controls
+{
+ public partial class IconLabelButton : Frame
+ {
+ public static readonly BindableProperty IconProperty = BindableProperty.Create(
+ nameof(Icon), typeof(string), typeof(IconLabelButton));
+
+ public static readonly BindableProperty LabelProperty = BindableProperty.Create(
+ nameof(Label), typeof(string), typeof(IconLabelButton));
+
+ public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
+ nameof(ButtonCommand), typeof(Command), typeof(IconLabelButton));
+
+ public static readonly BindableProperty IconLabelColorProperty = BindableProperty.Create(
+ nameof(IconLabelColor), typeof(Color), typeof(IconLabelButton), Color.White);
+
+ public static readonly BindableProperty IconLabelBackgroundColorProperty = BindableProperty.Create(
+ nameof(IconLabelBackgroundColor), typeof(Color), typeof(IconLabelButton), Color.White);
+
+ public static readonly BindableProperty IconLabelBorderColorProperty = BindableProperty.Create(
+ nameof(IconLabelBorderColor), typeof(Color), typeof(IconLabelButton), Color.White);
+
+ public IconLabelButton()
+ {
+ InitializeComponent();
+ }
+
+ public string Icon
+ {
+ get => GetValue(IconProperty) as string;
+ set => SetValue(IconProperty, value);
+ }
+
+ public string Label
+ {
+ get => GetValue(LabelProperty) as string;
+ set => SetValue(LabelProperty, value);
+ }
+
+ public ICommand ButtonCommand
+ {
+ get => GetValue(ButtonCommandProperty) as ICommand;
+ set => SetValue(ButtonCommandProperty, value);
+ }
+
+ public Color IconLabelColor
+ {
+ get { return (Color)GetValue(IconLabelColorProperty); }
+ set { SetValue(IconLabelColorProperty, value); }
+ }
+
+ public Color IconLabelBackgroundColor
+ {
+ get { return (Color)GetValue(IconLabelBackgroundColorProperty); }
+ set { SetValue(IconLabelBackgroundColorProperty, value); }
+ }
+
+ public Color IconLabelBorderColor
+ {
+ get { return (Color)GetValue(IconLabelBorderColorProperty); }
+ set { SetValue(IconLabelBorderColorProperty, value); }
+ }
+ }
+}
+
diff --git a/src/App/Effects/RemoveFontPaddingEffect.cs b/src/App/Effects/RemoveFontPaddingEffect.cs
new file mode 100644
index 000000000..56f1579f3
--- /dev/null
+++ b/src/App/Effects/RemoveFontPaddingEffect.cs
@@ -0,0 +1,13 @@
+using System;
+using Xamarin.Forms;
+
+namespace Bit.App.Effects
+{
+ public class RemoveFontPaddingEffect : RoutingEffect
+ {
+ public RemoveFontPaddingEffect()
+ : base("Bitwarden.RemoveFontPaddingEffect")
+ { }
+ }
+}
+
diff --git a/src/App/Pages/Accounts/HintPage.xaml.cs b/src/App/Pages/Accounts/HintPage.xaml.cs
index b1f1d762a..0fe7cd6fe 100644
--- a/src/App/Pages/Accounts/HintPage.xaml.cs
+++ b/src/App/Pages/Accounts/HintPage.xaml.cs
@@ -6,11 +6,12 @@ namespace Bit.App.Pages
{
private HintPageViewModel _vm;
- public HintPage()
+ public HintPage(string email = null)
{
InitializeComponent();
_vm = BindingContext as HintPageViewModel;
_vm.Page = this;
+ _vm.Email = email;
if (Device.RuntimePlatform == Device.Android)
{
ToolbarItems.RemoveAt(0);
diff --git a/src/App/Pages/Accounts/HintPageViewModel.cs b/src/App/Pages/Accounts/HintPageViewModel.cs
index 2e59f98c9..11e7890f6 100644
--- a/src/App/Pages/Accounts/HintPageViewModel.cs
+++ b/src/App/Pages/Accounts/HintPageViewModel.cs
@@ -15,6 +15,7 @@ namespace Bit.App.Pages
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IApiService _apiService;
private readonly ILogger _logger;
+ private string _email;
public HintPageViewModel()
{
@@ -34,7 +35,12 @@ namespace Bit.App.Pages
}
public ICommand SubmitCommand { get; }
- public string Email { get; set; }
+
+ public string Email
+ {
+ get => _email;
+ set => SetProperty(ref _email, value);
+ }
public async Task SubmitAsync()
{
diff --git a/src/App/Pages/Accounts/HomePage.xaml b/src/App/Pages/Accounts/HomePage.xaml
index 8276861e1..40f631b28 100644
--- a/src/App/Pages/Accounts/HomePage.xaml
+++ b/src/App/Pages/Accounts/HomePage.xaml
@@ -24,6 +24,7 @@
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Accounts/HomePage.xaml.cs b/src/App/Pages/Accounts/HomePage.xaml.cs
index f01fccef0..ebf30d873 100644
--- a/src/App/Pages/Accounts/HomePage.xaml.cs
+++ b/src/App/Pages/Accounts/HomePage.xaml.cs
@@ -10,28 +10,35 @@ namespace Bit.App.Pages
{
public partial class HomePage : BaseContentPage
{
+ private bool _checkRememberedEmail;
private readonly HomeViewModel _vm;
private readonly AppOptions _appOptions;
private IBroadcasterService _broadcasterService;
- public HomePage(AppOptions appOptions = null)
+ public HomePage(AppOptions appOptions = null, bool checkRememberedEmail = true)
{
_broadcasterService = ServiceContainer.Resolve("broadcasterService");
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as HomeViewModel;
_vm.Page = this;
- _vm.StartLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartLoginAsync());
+ _vm.CheckHasRememberedEmail = checkRememberedEmail;
+ _vm.ShowCancelButton = _appOptions?.IosExtension ?? false;
+ _vm.StartLoginAction = async () => await StartLoginAsync();
_vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
_vm.StartEnvironmentAction = () => Device.BeginInvokeOnMainThread(async () => await StartEnvironmentAsync());
+ _vm.CloseAction = async () =>
+ {
+ await _accountListOverlay.HideAsync();
+ await Navigation.PopModalAsync();
+ };
UpdateLogo();
- if (_appOptions?.IosExtension ?? false)
+ if (!_vm.ShowCancelButton)
{
- _vm.ShowCancelButton = true;
+ ToolbarItems.Remove(_closeButton);
}
-
if (_appOptions?.HideAccountSwitcher ?? false)
{
ToolbarItems.Remove(_accountAvatar);
@@ -64,6 +71,8 @@ namespace Bit.App.Pages
});
}
});
+
+ _vm.CheckNavigateLoginStep();
}
protected override bool OnBackButtonPressed()
@@ -96,28 +105,12 @@ namespace Bit.App.Pages
}
}
- private void LogIn_Clicked(object sender, EventArgs e)
- {
- if (DoOnce())
- {
- _vm.StartLoginAction();
- }
- }
-
private async Task StartLoginAsync()
{
- var page = new LoginPage(null, _appOptions);
+ var page = new LoginPage(_vm.Email, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
- private void Register_Clicked(object sender, EventArgs e)
- {
- if (DoOnce())
- {
- _vm.StartRegisterAction();
- }
- }
-
private async Task StartRegisterAsync()
{
var page = new RegisterPage(this);
diff --git a/src/App/Pages/Accounts/HomePageViewModel.cs b/src/App/Pages/Accounts/HomePageViewModel.cs
index bd44d5567..1b014c2d2 100644
--- a/src/App/Pages/Accounts/HomePageViewModel.cs
+++ b/src/App/Pages/Accounts/HomePageViewModel.cs
@@ -1,8 +1,14 @@
using System;
+using System.Threading.Tasks;
using Bit.App.Controls;
using Bit.App.Resources;
+using Bit.App.Utilities;
using Bit.Core.Abstractions;
+using Bit.Core.Services;
using Bit.Core.Utilities;
+using Xamarin.CommunityToolkit.ObjectModel;
+using Xamarin.Essentials;
+using Xamarin.Forms;
namespace Bit.App.Pages
{
@@ -12,19 +18,33 @@ namespace Bit.App.Pages
private readonly IMessagingService _messagingService;
private bool _showCancelButton;
+ private bool _rememberEmail;
+ private string _email;
+ private bool _isEmailEnabled;
+ private bool _canLogin;
+ private IPlatformUtilsService _platformUtilsService;
+ private ILogger _logger;
public HomeViewModel()
{
_stateService = ServiceContainer.Resolve("stateService");
_messagingService = ServiceContainer.Resolve("messagingService");
- var logger = ServiceContainer.Resolve("logger");
+ _platformUtilsService = ServiceContainer.Resolve();
+ _logger = ServiceContainer.Resolve("logger");
PageTitle = AppResources.Bitwarden;
- AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, logger)
+ AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
{
AllowActiveAccountSelection = true
};
+ RememberEmailCommand = new Command(() => RememberEmail = !RememberEmail);
+ ContinueCommand = new AsyncCommand(ContinueToLoginStepAsync, allowsMultipleExecutions: false);
+ CreateAccountCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(StartRegisterAction),
+ onException: _logger.Exception, allowsMultipleExecutions: false);
+ CloseCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(CloseAction),
+ onException: _logger.Exception, allowsMultipleExecutions: false);
+ InitAsync().FireAndForget();
}
public bool ShowCancelButton
@@ -33,11 +53,92 @@ namespace Bit.App.Pages
set => SetProperty(ref _showCancelButton, value);
}
+ public bool RememberEmail
+ {
+ get => _rememberEmail;
+ set => SetProperty(ref _rememberEmail, value);
+ }
+
+ public string Email
+ {
+ get => _email;
+ set => SetProperty(ref _email, value,
+ additionalPropertyNames: new[] { nameof(CanContinue) });
+ }
+
+ public bool CanContinue => !string.IsNullOrEmpty(Email);
+
+ public bool CheckHasRememberedEmail { get; set; }
+
+ public FormattedString CreateAccountText
+ {
+ get
+ {
+ var fs = new FormattedString();
+ fs.Spans.Add(new Span
+ {
+ Text = $"{AppResources.NewAroundHere} "
+ });
+ fs.Spans.Add(new Span
+ {
+ Text = AppResources.CreateAccount,
+ TextColor = ThemeManager.GetResourceColor("PrimaryColor")
+ });
+ return fs;
+ }
+ }
+
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
public Action StartLoginAction { get; set; }
public Action StartRegisterAction { get; set; }
public Action StartSsoLoginAction { get; set; }
public Action StartEnvironmentAction { get; set; }
public Action CloseAction { get; set; }
+ public Command RememberEmailCommand { get; set; }
+ public AsyncCommand ContinueCommand { get; }
+ public AsyncCommand CloseCommand { get; }
+ public AsyncCommand CreateAccountCommand { get; }
+
+ public async Task InitAsync()
+ {
+ Email = await _stateService.GetRememberedEmailAsync();
+ RememberEmail = !string.IsNullOrEmpty(Email);
+ }
+
+ public void CheckNavigateLoginStep()
+ {
+ if (CheckHasRememberedEmail && RememberEmail)
+ {
+ StartLoginAction();
+ }
+ CheckHasRememberedEmail = false;
+ }
+
+ public async Task ContinueToLoginStepAsync()
+ {
+ try
+ {
+ if (string.IsNullOrWhiteSpace(Email))
+ {
+ await _platformUtilsService.ShowDialogAsync(
+ string.Format(AppResources.ValidationFieldRequired, AppResources.EmailAddress),
+ AppResources.AnErrorHasOccurred, AppResources.Ok);
+ return;
+ }
+ if (!Email.Contains("@"))
+ {
+ await _platformUtilsService.ShowDialogAsync(AppResources.InvalidEmail, AppResources.AnErrorHasOccurred,
+ AppResources.Ok);
+ return;
+ }
+ await _stateService.SetRememberedEmailAsync(RememberEmail ? Email : null);
+ StartLoginAction();
+ }
+ catch (Exception ex)
+ {
+ _logger.Exception(ex);
+ await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage, AppResources.AnErrorHasOccurred, AppResources.Ok);
+ }
+ }
}
}
diff --git a/src/App/Pages/Accounts/LoginPage.xaml b/src/App/Pages/Accounts/LoginPage.xaml
index e1627cb04..11ea61e99 100644
--- a/src/App/Pages/Accounts/LoginPage.xaml
+++ b/src/App/Pages/Accounts/LoginPage.xaml
@@ -4,6 +4,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.LoginPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
+ xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:u="clr-namespace:Bit.App.Utilities"
x:DataType="pages:LoginPageViewModel"
@@ -46,33 +47,13 @@
Order="Secondary" />
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -81,6 +62,7 @@
+
-
-
diff --git a/src/App/Pages/Accounts/LoginPage.xaml.cs b/src/App/Pages/Accounts/LoginPage.xaml.cs
index b6e74e1c9..01e9e6194 100644
--- a/src/App/Pages/Accounts/LoginPage.xaml.cs
+++ b/src/App/Pages/Accounts/LoginPage.xaml.cs
@@ -4,6 +4,7 @@ using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
+using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -25,6 +26,7 @@ namespace Bit.App.Pages
_vm.Page = this;
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
+ _vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
_vm.UpdateTempPasswordAction =
() => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
_vm.CloseAction = async () =>
@@ -42,9 +44,6 @@ namespace Bit.App.Pages
_vm.Email = email;
MasterPasswordEntry = _masterPassword;
- _email.ReturnType = ReturnType.Next;
- _email.ReturnCommand = new Command(() => _masterPassword.Focus());
-
if (Device.RuntimePlatform == Device.iOS)
{
ToolbarItems.Add(_moreItem);
@@ -85,7 +84,7 @@ namespace Bit.App.Pages
await _vm.InitAsync();
if (!_inputFocused)
{
- RequestFocus(string.IsNullOrWhiteSpace(_vm.Email) ? _email : _masterPassword);
+ RequestFocus(_masterPassword);
_inputFocused = true;
}
}
@@ -115,11 +114,25 @@ namespace Bit.App.Pages
}
}
+ private void LogInSSO_Clicked(object sender, EventArgs e)
+ {
+ if (DoOnce())
+ {
+ _vm.StartSsoLoginAction();
+ }
+ }
+
+ private async Task StartSsoLoginAsync()
+ {
+ var page = new LoginSsoPage(_appOptions);
+ await Navigation.PushModalAsync(new NavigationPage(page));
+ }
+
private void Hint_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
- Navigation.PushModalAsync(new NavigationPage(new HintPage()));
+ _vm.ShowMasterPasswordHintAsync().FireAndForget();
}
}
diff --git a/src/App/Pages/Accounts/LoginPageViewModel.cs b/src/App/Pages/Accounts/LoginPageViewModel.cs
index 593b55e91..9377daae5 100644
--- a/src/App/Pages/Accounts/LoginPageViewModel.cs
+++ b/src/App/Pages/Accounts/LoginPageViewModel.cs
@@ -3,11 +3,13 @@ using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.App.Controls;
+using Bit.App.Models;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Exceptions;
+using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
@@ -25,12 +27,14 @@ namespace Bit.App.Pages
private readonly II18nService _i18nService;
private readonly IMessagingService _messagingService;
private readonly ILogger _logger;
-
+ private readonly IApiService _apiService;
+ private readonly IAppIdService _appIdService;
private bool _showPassword;
private bool _showCancelButton;
private string _email;
private string _masterPassword;
private bool _isEmailEnabled;
+ private bool _isKnownDevice;
public LoginPageViewModel()
{
@@ -43,6 +47,8 @@ namespace Bit.App.Pages
_i18nService = ServiceContainer.Resolve("i18nService");
_messagingService = ServiceContainer.Resolve("messagingService");
_logger = ServiceContainer.Resolve("logger");
+ _apiService = ServiceContainer.Resolve();
+ _appIdService = ServiceContainer.Resolve();
PageTitle = AppResources.Bitwarden;
TogglePasswordCommand = new Command(TogglePassword);
@@ -76,7 +82,11 @@ namespace Bit.App.Pages
public string Email
{
get => _email;
- set => SetProperty(ref _email, value);
+ set => SetProperty(ref _email, value,
+ additionalPropertyNames: new string[]
+ {
+ nameof(LoggingInAsText)
+ });
}
public string MasterPassword
@@ -91,6 +101,12 @@ namespace Bit.App.Pages
set => SetProperty(ref _isEmailEnabled, value);
}
+ public bool IsKnownDevice
+ {
+ get => _isKnownDevice;
+ set => SetProperty(ref _isKnownDevice, value);
+ }
+
public bool IsIosExtension { get; set; }
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
@@ -100,9 +116,11 @@ namespace Bit.App.Pages
public ICommand MoreCommand { get; internal set; }
public string ShowPasswordIcon => ShowPassword ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
+ public string LoggingInAsText => string.Format(AppResources.LoggingInAsX, Email);
public Action StartTwoFactorAction { get; set; }
public Action LogInSuccessAction { get; set; }
public Action UpdateTempPasswordAction { get; set; }
+ public Action StartSsoLoginAction { get; set; }
public Action CloseAction { get; set; }
protected override II18nService i18nService => _i18nService;
@@ -112,10 +130,14 @@ namespace Bit.App.Pages
public async Task InitAsync()
{
+ await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
if (string.IsNullOrWhiteSpace(Email))
{
Email = await _stateService.GetRememberedEmailAsync();
}
+ var deviceIdentifier = await _appIdService.GetAppIdAsync();
+ IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier);
+ await _deviceActionService.HideLoadingAsync();
}
public async Task LogInAsync(bool showLoading = true, bool checkForExistingAccount = false)
@@ -170,7 +192,6 @@ namespace Bit.App.Pages
}
var response = await _authService.LogInAsync(Email, MasterPassword, _captchaToken);
- await _stateService.SetRememberedEmailAsync(Email);
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
if (response.CaptchaNeeded)
@@ -223,12 +244,7 @@ namespace Bit.App.Pages
if (selection == AppResources.GetPasswordHint)
{
- var hintNavigationPage = new NavigationPage(new HintPage());
- if (IsIosExtension)
- {
- ThemeManager.ApplyResourcesTo(hintNavigationPage);
- }
- await Page.Navigation.PushModalAsync(hintNavigationPage);
+ await ShowMasterPasswordHintAsync();
}
else if (selection == AppResources.RemoveAccount)
{
@@ -236,6 +252,16 @@ namespace Bit.App.Pages
}
}
+ public async Task ShowMasterPasswordHintAsync()
+ {
+ var hintNavigationPage = new NavigationPage(new HintPage(Email));
+ if (IsIosExtension)
+ {
+ ThemeManager.ApplyResourcesTo(hintNavigationPage);
+ }
+ await Page.Navigation.PushModalAsync(hintNavigationPage);
+ }
+
public void TogglePassword()
{
ShowPassword = !ShowPassword;
diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs
index 84ff963d6..a98953e55 100644
--- a/src/App/Resources/AppResources.Designer.cs
+++ b/src/App/Resources/AppResources.Designer.cs
@@ -2893,6 +2893,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Get master password hint.
+ ///
+ public static string GetMasterPasswordwordHint {
+ get {
+ return ResourceManager.GetString("GetMasterPasswordwordHint", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Get your master password hint.
///
@@ -3406,6 +3415,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Logging in as {0}.
+ ///
+ public static string LoggingInAsX {
+ get {
+ return ResourceManager.GetString("LoggingInAsX", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Log In.
///
@@ -3434,10 +3452,11 @@ namespace Bit.App.Resources {
}
///
- /// Looks up a localized string similar to Login attempt from {0}. Do you want to switch to this account?.
+ /// Looks up a localized string similar to Login attempt from:
+ ///{0}
+ ///Do you want to switch to this account?.
///
- public static string LoginAttemptFromXDoYouWantToSwitchToThisAccount
- {
+ public static string LoginAttemptFromXDoYouWantToSwitchToThisAccount {
get {
return ResourceManager.GetString("LoginAttemptFromXDoYouWantToSwitchToThisAccount", resourceCulture);
}
@@ -3542,6 +3561,24 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Log In with another device.
+ ///
+ public static string LogInWithAnotherDevice {
+ get {
+ return ResourceManager.GetString("LogInWithAnotherDevice", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Log In with master password.
+ ///
+ public static string LogInWithMasterPassword {
+ get {
+ return ResourceManager.GetString("LogInWithMasterPassword", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Log out.
///
@@ -3947,6 +3984,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to New around here?.
+ ///
+ public static string NewAroundHere {
+ get {
+ return ResourceManager.GetString("NewAroundHere", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to New custom field.
///
@@ -4181,6 +4227,15 @@ namespace Bit.App.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Not you?.
+ ///
+ public static string NotYou {
+ get {
+ return ResourceManager.GetString("NotYou", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to This login does not have a username or password configured..
///
diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx
index a803ee150..03f1c7aba 100644
--- a/src/App/Resources/AppResources.resx
+++ b/src/App/Resources/AppResources.resx
@@ -2473,4 +2473,22 @@ select Add TOTP to store the key safely
{0}
Do you want to switch to this account?
+
+ New around here?
+
+
+ Get master password hint
+
+
+ Logging in as {0}
+
+
+ Not you?
+
+
+ Log In with master password
+
+
+ Log In with another device
+
diff --git a/src/App/Styles/Android.xaml b/src/App/Styles/Android.xaml
index 243f42b7e..51c2e37aa 100644
--- a/src/App/Styles/Android.xaml
+++ b/src/App/Styles/Android.xaml
@@ -80,6 +80,7 @@
Value="{DynamicResource StepperForegroundColor}" />
-
+
+
+
+
diff --git a/src/App/Styles/iOS.xaml b/src/App/Styles/iOS.xaml
index f6bd66a4c..b6041bcce 100644
--- a/src/App/Styles/iOS.xaml
+++ b/src/App/Styles/iOS.xaml
@@ -93,6 +93,7 @@
Value="{DynamicResource StepperForegroundColor}" />