mirror of
https://github.com/bitwarden/mobile.git
synced 2024-12-27 17:08:00 +01:00
Initial commit of new TOTP page
This commit is contained in:
parent
b55a450f44
commit
b02c58e362
@ -1,57 +1,48 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2.15.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.NFC"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.CAMERA"/>
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false"/>
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
|
||||
|
||||
<application android:label="Bitwarden" android:theme="@style/LaunchTheme" android:allowBackup="false" tools:replace="android:allowBackup" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:networkSecurityConfig="@xml/network_security_config">
|
||||
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.x8bit.bitwarden.fileprovider" android:exported="false" android:grantUriPermissions="true">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths"/>
|
||||
</provider>
|
||||
|
||||
<meta-data android:name="android.max_aspect" android:value="2.1"/>
|
||||
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions"/>
|
||||
|
||||
<!-- Support for Samsung "Multi Window" mode (for Android < 7.0 users) -->
|
||||
<meta-data android:name="com.samsung.android.sdk.multiwindow.enable" android:value="true"/>
|
||||
<meta-data android:name="com.samsung.android.sdk.multiwindow.penwindow.enable" android:value="true"/>
|
||||
|
||||
<!-- Support for LG "Dual Window" mode (for Android < 7.0 users) -->
|
||||
<meta-data android:name="com.lge.support.SPLIT_WINDOW" android:value="true"/>
|
||||
<!-- Declare MainActivity manually so we can set LaunchMode using API dependant resource -->
|
||||
<activity android:name="com.x8bit.bitwarden.MainActivity" android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|uiMode" android:exported="true" android:icon="@mipmap/ic_launcher" android:label="Bitwarden" android:launchMode="@integer/launchModeAPIlevel" android:theme="@style/LaunchTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<data android:mimeType="application/*"/>
|
||||
<data android:mimeType="image/*"/>
|
||||
<data android:mimeType="video/*"/>
|
||||
<data android:mimeType="text/*"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<!-- Package visibility (for Android 11+) -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="*"/>
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
</manifest>
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<application android:label="Bitwarden" android:theme="@style/LaunchTheme" android:allowBackup="false" tools:replace="android:allowBackup" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:networkSecurityConfig="@xml/network_security_config">
|
||||
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.x8bit.bitwarden.fileprovider" android:exported="false" android:grantUriPermissions="true">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
<meta-data android:name="android.max_aspect" android:value="2.1" />
|
||||
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
|
||||
<!-- Support for Samsung "Multi Window" mode (for Android < 7.0 users) -->
|
||||
<meta-data android:name="com.samsung.android.sdk.multiwindow.enable" android:value="true" />
|
||||
<meta-data android:name="com.samsung.android.sdk.multiwindow.penwindow.enable" android:value="true" />
|
||||
<!-- Support for LG "Dual Window" mode (for Android < 7.0 users) -->
|
||||
<meta-data android:name="com.lge.support.SPLIT_WINDOW" android:value="true" />
|
||||
<!-- Declare MainActivity manually so we can set LaunchMode using API dependant resource -->
|
||||
<activity android:name="com.x8bit.bitwarden.MainActivity" android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|uiMode" android:exported="true" android:icon="@mipmap/ic_launcher" android:label="Bitwarden" android:launchMode="@integer/launchModeAPIlevel" android:theme="@style/LaunchTheme">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/*" />
|
||||
<data android:mimeType="image/*" />
|
||||
<data android:mimeType="video/*" />
|
||||
<data android:mimeType="text/*" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
<!-- Package visibility (for Android 11+) -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="*" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
@ -120,11 +120,19 @@
|
||||
<DependentUpon>SendGroupingsPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="Pages\Authenticator\GeneratorPage.xaml.cs">
|
||||
<DependentUpon>GeneratorPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Condition=" '$(EnableDefaultCompileItems)' == 'true' " Update="Pages\Authenticator\AuthenticatorPage.xaml.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
<Folder Include="Behaviors\" />
|
||||
<Folder Include="Pages\Authenticator\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -414,5 +422,6 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Behaviors\" />
|
||||
<None Remove="Pages\Authenticator\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
39
src/App/Pages/Authenticator/AuthenticatorPage.xaml
Normal file
39
src/App/Pages/Authenticator/AuthenticatorPage.xaml
Normal file
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.Authenticator.AuthenticatorPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
xmlns:pages1="clr-namespace:Bit.App.Pages.Authenticator"
|
||||
x:DataType="pages:GeneratorPageViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
<ContentPage.BindingContext>
|
||||
<pages1:AuthenticatorPageViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<StackLayout>
|
||||
<RefreshView
|
||||
IsVisible="{Binding ShowList}"
|
||||
IsRefreshing="{Binding Refreshing}"
|
||||
Command="{Binding RefreshCommand}">
|
||||
<controls:ExtendedCollectionView
|
||||
ItemsSource="{Binding GroupedItems}"
|
||||
VerticalOptions="FillAndExpand"
|
||||
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
|
||||
IsGrouped="True"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="RowSelected"
|
||||
StyleClass="list, list-platform">
|
||||
|
||||
</controls:ExtendedCollectionView>
|
||||
</RefreshView>
|
||||
|
||||
<StackLayout
|
||||
IsVisible="{Binding !ShowList}">
|
||||
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
|
||||
</pages:BaseContentPage>
|
143
src/App/Pages/Authenticator/AuthenticatorPage.xaml.cs
Normal file
143
src/App/Pages/Authenticator/AuthenticatorPage.xaml.cs
Normal file
@ -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<string> _selectAction;
|
||||
private readonly TabsPage _tabsPage;
|
||||
|
||||
#endregion
|
||||
|
||||
public AuthenticatorPage(bool fromTabPage, Action<string> selectAction = null, TabsPage tabsPage = null)
|
||||
{
|
||||
_tabsPage = tabsPage;
|
||||
InitializeComponent();
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("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<iOS>().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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
75
src/App/Pages/Authenticator/AuthenticatorPageViewModel.cs
Normal file
75
src/App/Pages/Authenticator/AuthenticatorPageViewModel.cs
Normal file
@ -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<IUserService>("userService");
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("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
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
6
src/App/Resources/AppResources.Designer.cs
generated
6
src/App/Resources/AppResources.Designer.cs
generated
@ -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);
|
||||
|
@ -287,6 +287,10 @@
|
||||
<value>My Vault</value>
|
||||
<comment>The title for the vault page.</comment>
|
||||
</data>
|
||||
<data name="Authenticator" xml:space="preserve">
|
||||
<value>Authenticator</value>
|
||||
<comment>Authenticator TOTP feature</comment>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
<comment>Label for an entity name.</comment>
|
||||
|
5
src/iOS.Core/Info.plist
Normal file
5
src/iOS.Core/Info.plist
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict/>
|
||||
</plist>
|
@ -208,5 +208,8 @@
|
||||
<Version>2.0.3</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Info.plist" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user