diff --git a/src/Android/Properties/AndroidManifest.xml b/src/Android/Properties/AndroidManifest.xml
index 0f6dd1eff..62e056bf9 100644
--- a/src/Android/Properties/AndroidManifest.xml
+++ b/src/Android/Properties/AndroidManifest.xml
@@ -1,57 +1,48 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/App/App.csproj b/src/App/App.csproj
index c9ab94f02..a75bc0237 100644
--- a/src/App/App.csproj
+++ b/src/App/App.csproj
@@ -120,11 +120,19 @@
SendGroupingsPage.xaml
Code
+
+ GeneratorPage.xaml
+ Code
+
+
+ Code
+
+
@@ -414,5 +422,6 @@
+
diff --git a/src/App/Pages/Authenticator/AuthenticatorPage.xaml b/src/App/Pages/Authenticator/AuthenticatorPage.xaml
new file mode 100644
index 000000000..ed5e551c8
--- /dev/null
+++ b/src/App/Pages/Authenticator/AuthenticatorPage.xaml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App/Pages/Authenticator/AuthenticatorPage.xaml.cs b/src/App/Pages/Authenticator/AuthenticatorPage.xaml.cs
new file mode 100644
index 000000000..ea25b66d1
--- /dev/null
+++ b/src/App/Pages/Authenticator/AuthenticatorPage.xaml.cs
@@ -0,0 +1,143 @@
+using Bit.App.Resources;
+using System;
+using System.Threading.Tasks;
+using Bit.Core.Abstractions;
+using Bit.Core.Utilities;
+using Xamarin.Forms;
+using Xamarin.Forms.PlatformConfiguration;
+using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
+
+namespace Bit.App.Pages.Authenticator
+{
+ public partial class AuthenticatorPage : BaseContentPage
+ {
+ #region Members
+
+ private readonly IBroadcasterService _broadcasterService;
+ private AuthenticatorPageViewModel _vm;
+ private readonly bool _fromTabPage;
+ private readonly Action _selectAction;
+ private readonly TabsPage _tabsPage;
+
+ #endregion
+
+ public AuthenticatorPage(bool fromTabPage, Action selectAction = null, TabsPage tabsPage = null)
+ {
+ _tabsPage = tabsPage;
+ InitializeComponent();
+ _broadcasterService = ServiceContainer.Resolve("broadcasterService");
+ _vm = BindingContext as AuthenticatorPageViewModel;
+ _vm.Page = this;
+ _fromTabPage = fromTabPage;
+ _selectAction = selectAction;
+ var isIos = Device.RuntimePlatform == Device.iOS;
+ if (selectAction != null)
+ {
+ if (isIos)
+ {
+ ToolbarItems.Add(_closeItem);
+ }
+ ToolbarItems.Add(_selectItem);
+ }
+ else
+ {
+ if (isIos)
+ {
+ ToolbarItems.Add(_moreItem);
+ }
+ else
+ {
+ ToolbarItems.Add(_historyItem);
+ }
+ }
+ if (isIos)
+ {
+ _typePicker.On().SetUpdateMode(UpdateMode.WhenFinished);
+ }
+ }
+
+ public async Task InitAsync()
+ {
+ await _vm.InitAsync();
+ }
+
+ protected async override void OnAppearing()
+ {
+ base.OnAppearing();
+ if (!_fromTabPage)
+ {
+ await InitAsync();
+ }
+ _broadcasterService.Subscribe(nameof(GeneratorPage), async (message) =>
+ {
+ if (message.Command == "updatedTheme")
+ {
+ Device.BeginInvokeOnMainThread(() =>
+ {
+ //_vm.RedrawPassword();
+ });
+ }
+ });
+ }
+
+ protected override void OnDisappearing()
+ {
+ base.OnDisappearing();
+ _broadcasterService.Unsubscribe(nameof(GeneratorPage));
+ }
+
+ protected override bool OnBackButtonPressed()
+ {
+ if (Device.RuntimePlatform == Device.Android && _tabsPage != null)
+ {
+ _tabsPage.ResetToVaultPage();
+ return true;
+ }
+ return base.OnBackButtonPressed();
+ }
+
+ private async void Copy_Clicked(object sender, EventArgs e)
+ {
+ //await _vm.CopyAsync();
+ }
+
+ private async void More_Clicked(object sender, EventArgs e)
+ {
+ if (!DoOnce())
+ {
+ return;
+ }
+ var selection = await DisplayActionSheet(AppResources.Options, AppResources.Cancel,
+ null, AppResources.PasswordHistory);
+ if (selection == AppResources.PasswordHistory)
+ {
+ var page = new GeneratorHistoryPage();
+ await Navigation.PushModalAsync(new Xamarin.Forms.NavigationPage(page));
+ }
+ }
+
+ private void Select_Clicked(object sender, EventArgs e)
+ {
+ _selectAction?.Invoke(_vm.Password);
+ }
+
+ private async void History_Clicked(object sender, EventArgs e)
+ {
+ var page = new GeneratorHistoryPage();
+ await Navigation.PushModalAsync(new Xamarin.Forms.NavigationPage(page));
+ }
+
+ private async void LengthSlider_DragCompleted(object sender, EventArgs e)
+ {
+ await _vm.SliderChangedAsync();
+ }
+
+ private async void Close_Clicked(object sender, EventArgs e)
+ {
+ if (DoOnce())
+ {
+ await Navigation.PopModalAsync();
+ }
+ }
+ }
+}
diff --git a/src/App/Pages/Authenticator/AuthenticatorPageViewModel.cs b/src/App/Pages/Authenticator/AuthenticatorPageViewModel.cs
new file mode 100644
index 000000000..eaa466bd2
--- /dev/null
+++ b/src/App/Pages/Authenticator/AuthenticatorPageViewModel.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Threading.Tasks;
+using Bit.Core.Abstractions;
+using Bit.Core.Utilities;
+
+namespace Bit.App.Pages.Authenticator
+{
+ public class AuthenticatorPageViewModel : BaseViewModel
+ {
+ #region Members
+
+ private readonly IClipboardService _clipboardService;
+ private bool _showList;
+ private bool _refreshing;
+ private readonly IUserService _userService;
+ private readonly IVaultTimeoutService _vaultTimeoutService;
+
+ #endregion
+
+ #region Ctor
+
+ public AuthenticatorPageViewModel()
+ {
+ _userService = ServiceContainer.Resolve("userService");
+ _vaultTimeoutService = ServiceContainer.Resolve("vaultTimeoutService");
+ }
+
+ #endregion
+
+ #region Methods
+
+ public async Task InitAsync() { }
+
+ public async Task CopyAsync()
+ {
+ //await _clipboardService.CopyTextAsync(Password);
+ //_platformUtilsService.ShowToast("success", null,
+ // string.Format(AppResources.ValueHasBeenCopied, AppResources.Password));
+ }
+
+ public async Task LoadAsync()
+ {
+ var authed = await _userService.IsAuthenticatedAsync();
+ if (!authed)
+ {
+ return;
+ }
+ if (await _vaultTimeoutService.IsLockedAsync())
+ {
+ return;
+ }
+
+ this.ShowList = true;
+ this.Refreshing = false;
+ }
+
+ #endregion
+
+ #region Properties
+
+ public bool ShowList
+ {
+ get => _showList;
+ set => SetProperty(ref _showList, value);
+ }
+
+ public bool Refreshing
+ {
+ get => _refreshing;
+ set => SetProperty(ref _refreshing, value);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/App/Pages/TabsPage.cs b/src/App/Pages/TabsPage.cs
index 098b213b4..62a89abca 100644
--- a/src/App/Pages/TabsPage.cs
+++ b/src/App/Pages/TabsPage.cs
@@ -13,6 +13,7 @@ namespace Bit.App.Pages
private readonly IKeyConnectorService _keyConnectorService;
private NavigationPage _groupingsPage;
+ private NavigationPage _authenticatorPage;
private NavigationPage _sendGroupingsPage;
private NavigationPage _generatorPage;
@@ -26,8 +27,15 @@ namespace Bit.App.Pages
Title = AppResources.MyVault,
IconImageSource = "lock.png"
};
+
Children.Add(_groupingsPage);
+ _authenticatorPage = new NavigationPage(new Authenticator.AuthenticatorPage(true, null, this))
+ {
+ Title = AppResources.Authenticator,
+ IconImageSource = "info.png"
+ };
+
_sendGroupingsPage = new NavigationPage(new SendGroupingsPage(true, null, null, appOptions))
{
Title = AppResources.Send,
diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs
index e32b4c101..6a04b29b6 100644
--- a/src/App/Resources/AppResources.Designer.cs
+++ b/src/App/Resources/AppResources.Designer.cs
@@ -329,6 +329,12 @@ namespace Bit.App.Resources {
}
}
+ public static string Authenticator {
+ get {
+ return ResourceManager.GetString("Authenticator", resourceCulture);
+ }
+ }
+
public static string Name {
get {
return ResourceManager.GetString("Name", resourceCulture);
diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx
index e357191bc..f6eebec02 100644
--- a/src/App/Resources/AppResources.resx
+++ b/src/App/Resources/AppResources.resx
@@ -287,6 +287,10 @@
My Vault
The title for the vault page.
+
+ Authenticator
+ Authenticator TOTP feature
+
Name
Label for an entity name.
diff --git a/src/iOS.Core/Info.plist b/src/iOS.Core/Info.plist
new file mode 100644
index 000000000..0c67376eb
--- /dev/null
+++ b/src/iOS.Core/Info.plist
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/iOS.Core/iOS.Core.csproj b/src/iOS.Core/iOS.Core.csproj
index a2353acf8..ee8d95ddf 100644
--- a/src/iOS.Core/iOS.Core.csproj
+++ b/src/iOS.Core/iOS.Core.csproj
@@ -208,5 +208,8 @@
2.0.3
+
+
+
\ No newline at end of file