mirror of
https://github.com/bitwarden/mobile
synced 2025-12-27 21:53:57 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cc1a501a5 | ||
|
|
b0a8694801 | ||
|
|
1bbe8d8b98 | ||
|
|
cdc41d3bef | ||
|
|
769851adfe | ||
|
|
c988175e50 | ||
|
|
04539af2a6 | ||
|
|
e0efcfbe45 | ||
|
|
57213607a7 | ||
|
|
2cab62fda5 | ||
|
|
99828c7ead | ||
|
|
ab6dde4a11 | ||
|
|
80bd8ba9d1 | ||
|
|
35853a3815 | ||
|
|
cfbbea59e9 | ||
|
|
14d4b2ee29 | ||
|
|
b9c1ab7c1d | ||
|
|
4d96b091f7 | ||
|
|
b6ad3527db | ||
|
|
88fee155db | ||
|
|
f930028920 |
12
.config/dotnet-tools.json
Normal file
12
.config/dotnet-tools.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-format": {
|
||||
"version": "5.1.250801",
|
||||
"commands": [
|
||||
"dotnet-format"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ root = true
|
||||
# Don't use tabs for indentation.
|
||||
[*]
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
# (Please don't specify an indent_size here; that has too many unintended consequences.)
|
||||
|
||||
# Code files
|
||||
|
||||
2
.git-blame-ignore-revs
Normal file
2
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,2 @@
|
||||
# .NET format https://github.com/bitwarden/mobile/pull/1738
|
||||
04539af2a66668b6e85476d5cf318c9150ec4357
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,7 +1,7 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
* text=auto eol=lf
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
|
||||
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@@ -105,6 +105,14 @@ jobs:
|
||||
- name: Restore packages
|
||||
run: nuget restore
|
||||
|
||||
- name: Restore tools
|
||||
run: dotnet tool restore
|
||||
shell: pwsh
|
||||
|
||||
- name: Verify Format
|
||||
run: dotnet tool run dotnet-format --check
|
||||
shell: pwsh
|
||||
|
||||
- name: Run Core tests
|
||||
run: dotnet test test/Core.Test/Core.Test.csproj
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Here is how you can get involved:
|
||||
|
||||
* **Write documentation:** Submit a pull request to the [Bitwarden help repository](https://github.com/bitwarden/help)
|
||||
|
||||
* **Help other users:** Go to the [User-to-User Support category](https://community.bitwarden.com/c/support/) on the Community Forums
|
||||
* **Help other users:** Go to the [Ask the Bitwarden Community category](https://community.bitwarden.com/c/support/) on the Community Forums
|
||||
|
||||
* **Translate:** See the localization (i10n) section below
|
||||
|
||||
@@ -35,6 +35,6 @@ We use a translation tool called [Crowdin](https://crowdin.com) to help manage o
|
||||
|
||||
If you are interested in helping translate the Bitwarden mobile app into another language (or make a translation correction), please register an account at Crowdin and join our project here: https://crowdin.com/project/bitwarden-mobile
|
||||
|
||||
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/profile/kspearrin).
|
||||
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/profile/dwbit).
|
||||
|
||||
You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/
|
||||
|
||||
20
README.md
20
README.md
@@ -33,3 +33,23 @@ Code contributions are welcome! Visual Studio with Xamarin is required to work o
|
||||
Learn more about how to contribute by reading the [`CONTRIBUTING.md`](CONTRIBUTING.md) file.
|
||||
|
||||
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
|
||||
|
||||
### Dotnet-format
|
||||
|
||||
We recently migrated to using dotnet-format as code formatter. All previous branches will need to updated to avoid large merge conflicts using the following steps:
|
||||
|
||||
1. Check out your local Branch
|
||||
2. Run `git merge e0efcfbe45b2a27c73e9593bfd7a71fad2aa7a35`
|
||||
3. Resolve any merge conflicts, commit.
|
||||
4. Run `dotnet tool run dotnet-format`
|
||||
5. Commit
|
||||
6. Run `git merge -Xours 04539af2a66668b6e85476d5cf318c9150ec4357`
|
||||
7. Push
|
||||
|
||||
#### Git blame
|
||||
|
||||
We also recommend that you configure git to ignore the prettier revision using:
|
||||
|
||||
```bash
|
||||
git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
```
|
||||
|
||||
@@ -46,6 +46,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\i
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UiTests", "src\UiTests\UiTests.csproj", "{23FB637B-1705-485F-9464-078FCAF361A8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
|
||||
@@ -446,6 +448,36 @@ Global
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhone.Build.0 = Release|iPhone
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|Any CPU.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhone.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhone.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhone.ActiveCfg = Debug|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhone.Build.0 = Debug|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|Any CPU.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhone.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhone.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.FDroid|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhone.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhone.Build.0 = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@@ -464,6 +496,7 @@ Global
|
||||
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
|
||||
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
{23FB637B-1705-485F-9464-078FCAF361A8} = {D10CA4A9-F866-40E1-B658-F69051236C71}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}
|
||||
|
||||
@@ -64,10 +64,10 @@ namespace Bit.Droid
|
||||
Intent?.Validate();
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
if (!CoreHelpers.InDebugMode())
|
||||
{
|
||||
Window.AddFlags(Android.Views.WindowManagerFlags.Secure);
|
||||
}
|
||||
//if (!CoreHelpers.InDebugMode())
|
||||
//{
|
||||
// Window.AddFlags(Android.Views.WindowManagerFlags.Secure);
|
||||
//}
|
||||
|
||||
#if !DEBUG && !FDROID
|
||||
var appCenterHelper = new AppCenterHelper(_appIdService, _stateService);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?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.18.0" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2.18.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Enums;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Bit.App.Abstractions
|
||||
string[] ProtectedFields { get; }
|
||||
|
||||
Task<bool> ShowPasswordPromptAsync();
|
||||
|
||||
|
||||
Task<(string password, bool valid)> ShowPasswordPromptAndGetItAsync();
|
||||
|
||||
Task<bool> Enabled();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Pages;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Services;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
@@ -208,7 +208,10 @@ namespace Bit.App
|
||||
{
|
||||
await _stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime());
|
||||
}
|
||||
SetTabsPageFromAutofill(isLocked);
|
||||
if (!SetTabsPageFromAutofill(isLocked))
|
||||
{
|
||||
ClearAutofillUri();
|
||||
}
|
||||
await SleptAsync();
|
||||
}
|
||||
}
|
||||
@@ -315,7 +318,7 @@ namespace Bit.App
|
||||
Options.HideAccountSwitcher = await _stateService.GetActiveUserIdAsync() == null;
|
||||
Current.MainPage = new NavigationPage(new LoginPage(email, Options));
|
||||
}
|
||||
else if (await _vaultTimeoutService.IsLockedAsync() ||
|
||||
else if (await _vaultTimeoutService.IsLockedAsync() ||
|
||||
await _vaultTimeoutService.ShouldLockAsync())
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new LockPage(Options));
|
||||
@@ -365,7 +368,15 @@ namespace Bit.App
|
||||
}
|
||||
}
|
||||
|
||||
private void SetTabsPageFromAutofill(bool isLocked)
|
||||
private void ClearAutofillUri()
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri))
|
||||
{
|
||||
Options.Uri = null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool SetTabsPageFromAutofill(bool isLocked)
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri) &&
|
||||
!Options.FromAutofillFramework)
|
||||
@@ -385,7 +396,9 @@ namespace Bit.App
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Prime()
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Bit.App.Controls
|
||||
Opacity = 0;
|
||||
IsVisible = true;
|
||||
this.FadeTo(1, 100);
|
||||
|
||||
|
||||
if (Device.RuntimePlatform == Device.Android && MainFab != null)
|
||||
{
|
||||
// start fab fade-out
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace Bit.App.Controls
|
||||
{
|
||||
_stateService = stateService;
|
||||
_messagingService = messagingService;
|
||||
|
||||
|
||||
SelectAccountCommand = new AsyncCommand<AccountViewCellViewModel>(SelectAccountAsync,
|
||||
onException: ex => logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
|
||||
LongPressAccountCommand = new AsyncCommand<Tuple<ContentPage, AccountViewCellViewModel>>(LongPressAccountAsync,
|
||||
onException: ex => logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using System.Windows.Input;
|
||||
using Bit.Core.Models.View;
|
||||
using System.Windows.Input;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
|
||||
@@ -112,13 +112,13 @@ namespace Bit.App.Controls
|
||||
|
||||
private string GetFirstLetters(string data, int charCount)
|
||||
{
|
||||
var parts = data.Split();
|
||||
var parts = data.Split();
|
||||
if (parts.Length > 1 && charCount <= 2)
|
||||
{
|
||||
var text = "";
|
||||
for (int i = 0; i < charCount; i++)
|
||||
{
|
||||
text += parts[i].Substring(0,1);
|
||||
text += parts[i].Substring(0, 1);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
public static readonly BindableProperty StepperBackgroundColorProperty = BindableProperty.Create(
|
||||
nameof(StepperBackgroundColor), typeof(Color), typeof(ExtendedStepper), Color.Default);
|
||||
|
||||
|
||||
public static readonly BindableProperty StepperForegroundColorProperty = BindableProperty.Create(
|
||||
nameof(StepperForegroundColor), typeof(Color), typeof(ExtendedStepper), Color.Default);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Bit.App.Controls
|
||||
get => (Color)GetValue(StepperBackgroundColorProperty);
|
||||
set => SetValue(StepperBackgroundColorProperty, value);
|
||||
}
|
||||
|
||||
|
||||
public Color StepperForegroundColor
|
||||
{
|
||||
get => (Color)GetValue(StepperForegroundColorProperty);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
@@ -13,7 +13,7 @@ namespace Bit.App.Controls
|
||||
|
||||
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
|
||||
nameof(ButtonCommand), typeof(Command<SendView>), typeof(SendViewCell));
|
||||
|
||||
|
||||
public static readonly BindableProperty ShowOptionsProperty = BindableProperty.Create(
|
||||
nameof(ShowOptions), typeof(bool), typeof(SendViewCell), true, BindingMode.OneWay);
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ namespace Bit.App.Effects
|
||||
{
|
||||
public class FabShadowEffect : RoutingEffect
|
||||
{
|
||||
public FabShadowEffect()
|
||||
: base("Bitwarden.FabShadowEffect")
|
||||
public FabShadowEffect()
|
||||
: base("Bitwarden.FabShadowEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Essentials;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -66,7 +66,7 @@ namespace Bit.App.Pages
|
||||
get => _policy;
|
||||
set => SetProperty(ref _policy, value);
|
||||
}
|
||||
|
||||
|
||||
public string ShowPasswordIcon => ShowPassword ? "" : "";
|
||||
public string MasterPassword { get; set; }
|
||||
public string ConfirmMasterPassword { get; set; }
|
||||
@@ -84,7 +84,7 @@ namespace Bit.App.Pages
|
||||
await CheckPasswordPolicy();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task CheckPasswordPolicy()
|
||||
{
|
||||
Policy = await _policyService.GetMasterPasswordPolicyOptions();
|
||||
@@ -166,7 +166,7 @@ namespace Bit.App.Pages
|
||||
AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
|
||||
<ToolbarItem Text="{u:I18n Save}" Clicked="Submit_Clicked" />
|
||||
<ToolbarItem Text="{u:I18n Save}" Clicked="Submit_Clicked" AutomationId="save_button"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ScrollView>
|
||||
@@ -34,7 +34,8 @@
|
||||
Placeholder="ex. https://bitwarden.company.com"
|
||||
StyleClass="box-value"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding SubmitCommand}" />
|
||||
ReturnCommand="{Binding SubmitCommand}"
|
||||
AutomationId="server_input"/>
|
||||
</StackLayout>
|
||||
<Label
|
||||
Text="{u:I18n SelfHostedEnvironmentFooter}"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.App.Resources;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
Priority="-1"
|
||||
UseOriginalImage="True"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n Account}" />
|
||||
AutomationProperties.Name="{u:I18n Account}"/>
|
||||
<ToolbarItem
|
||||
Icon="cog_environment.png" Clicked="Environment_Clicked" Order="Primary"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
@@ -37,15 +37,18 @@
|
||||
<Image
|
||||
x:Name="_logo"
|
||||
Source="logo.png"
|
||||
VerticalOptions="Center" />
|
||||
VerticalOptions="Center"
|
||||
AutomationId="logo_image"
|
||||
/>
|
||||
<Label Text="{u:I18n LoginOrCreateNewAccount}"
|
||||
StyleClass="text-lg"
|
||||
HorizontalTextAlignment="Center">
|
||||
</Label>
|
||||
HorizontalTextAlignment="Center"/>
|
||||
|
||||
<StackLayout Spacing="5">
|
||||
<Button Text="{u:I18n LogIn}"
|
||||
StyleClass="btn-primary"
|
||||
Clicked="LogIn_Clicked" />
|
||||
Clicked="LogIn_Clicked"
|
||||
AutomationId="homepage_login_button"/>
|
||||
<Button Text="{u:I18n CreateAccount}"
|
||||
Clicked="Register_Clicked" />
|
||||
<Button Text="{u:I18n LogInSso}"
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
|
||||
}
|
||||
|
||||
|
||||
private void Cancel_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
@@ -117,7 +117,7 @@ namespace Bit.App.Pages
|
||||
_vm.StartRegisterAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task StartRegisterAsync()
|
||||
{
|
||||
var page = new RegisterPage(this);
|
||||
@@ -145,7 +145,7 @@ namespace Bit.App.Pages
|
||||
_vm.StartEnvironmentAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task StartEnvironmentAsync()
|
||||
{
|
||||
await _accountListOverlay.HideAsync();
|
||||
|
||||
@@ -272,7 +272,7 @@ namespace Bit.App.Pages
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdf, kdfIterations);
|
||||
var storedKeyHash = await _cryptoService.GetKeyHashAsync();
|
||||
var passwordValid = false;
|
||||
|
||||
|
||||
if (storedKeyHash != null)
|
||||
{
|
||||
passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(MasterPassword, key);
|
||||
|
||||
@@ -56,7 +56,8 @@
|
||||
x:Name="_email"
|
||||
Text="{Binding Email}"
|
||||
Keyboard="Email"
|
||||
StyleClass="box-value">
|
||||
StyleClass="box-value"
|
||||
AutomationId="email_input">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Disabled">
|
||||
@@ -92,7 +93,8 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding LogInCommand}" />
|
||||
ReturnCommand="{Binding LogInCommand}"
|
||||
AutomationId="password_input"/>
|
||||
<controls:IconButton
|
||||
StyleClass="box-row-button, box-row-button-platform"
|
||||
Text="{Binding ShowPasswordIcon}"
|
||||
@@ -107,10 +109,12 @@
|
||||
<StackLayout Padding="10, 0">
|
||||
<Button Text="{u:I18n LogIn}"
|
||||
StyleClass="btn-primary"
|
||||
Clicked="LogIn_Clicked" />
|
||||
Clicked="LogIn_Clicked"
|
||||
AutomationId="loginpage_login_button"/>
|
||||
<Button Text="{u:I18n Cancel}"
|
||||
IsVisible="{Binding ShowCancelButton}"
|
||||
Clicked="Cancel_Clicked" />
|
||||
Clicked="Cancel_Clicked"
|
||||
AutomationId="cancel_button"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -177,7 +177,7 @@ namespace Bit.App.Pages
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
{
|
||||
var page = new UpdateTempPasswordPage();
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Bit.App.Pages
|
||||
get => _showCancelButton;
|
||||
set => SetProperty(ref _showCancelButton, value);
|
||||
}
|
||||
|
||||
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Bit.App.Models;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -99,7 +99,7 @@ namespace Bit.App.Pages
|
||||
var page = new SetPasswordPage(_appOptions, _vm.OrgIdentifier);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
{
|
||||
var page = new UpdateTempPasswordPage();
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace Bit.App.Pages
|
||||
else if (response.ResetMasterPassword)
|
||||
{
|
||||
StartSetPasswordAction?.Invoke();
|
||||
}
|
||||
}
|
||||
else if (response.ForcePasswordReset)
|
||||
{
|
||||
UpdateTempPasswordAction?.Invoke();
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Bit.App.Pages
|
||||
await _vm.SubmitAsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async Task RegistrationSuccessAsync(HomePage homePage)
|
||||
{
|
||||
if (homePage != null)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.Core;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -39,7 +39,7 @@ namespace Bit.App.Pages
|
||||
SubmitCommand = new Command(async () => await SubmitAsync());
|
||||
ShowTerms = !_platformUtilsService.IsSelfHost();
|
||||
}
|
||||
|
||||
|
||||
public ICommand PoliciesClickCommand => new Command<string>((url) =>
|
||||
{
|
||||
_platformUtilsService.LaunchUri(url);
|
||||
@@ -54,20 +54,20 @@ namespace Bit.App.Pages
|
||||
nameof(ShowPasswordIcon)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public bool AcceptPolicies
|
||||
{
|
||||
get => _acceptPolicies;
|
||||
set => SetProperty(ref _acceptPolicies, value);
|
||||
}
|
||||
|
||||
|
||||
public Thickness SwitchMargin
|
||||
{
|
||||
get => Device.RuntimePlatform == Device.Android
|
||||
? new Thickness(0, 0, 0, 0)
|
||||
get => Device.RuntimePlatform == Device.Android
|
||||
? new Thickness(0, 0, 0, 0)
|
||||
: new Thickness(0, 0, 10, 0);
|
||||
}
|
||||
|
||||
|
||||
public bool ShowTerms { get; set; }
|
||||
public Command SubmitCommand { get; }
|
||||
public Command TogglePasswordCommand { get; }
|
||||
@@ -136,7 +136,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
// TODO: Password strength check?
|
||||
|
||||
|
||||
if (showLoading)
|
||||
{
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.CreatingAccount);
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Bit.App.Pages
|
||||
get => _isPolicyInEffect;
|
||||
set => SetProperty(ref _isPolicyInEffect, value);
|
||||
}
|
||||
|
||||
|
||||
public bool ResetPasswordAutoEnroll
|
||||
{
|
||||
get => _resetPasswordAutoEnroll;
|
||||
@@ -220,7 +220,7 @@ namespace Bit.App.Pages
|
||||
// Enroll user
|
||||
await _apiService.PutOrganizationUserResetPasswordEnrollmentAsync(OrgId, userId, resetRequest);
|
||||
}
|
||||
|
||||
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
SetPasswordSuccessAction?.Invoke();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using Bit.App.Controls;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -47,7 +47,8 @@ namespace Bit.App.Pages
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
ToolbarItems.Add(_moreItem);
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
ToolbarItems.Add(_useAnotherTwoStepMethod);
|
||||
}
|
||||
@@ -92,7 +93,8 @@ namespace Bit.App.Pages
|
||||
if (_vm.TotpMethod)
|
||||
{
|
||||
RequestFocus(_totpEntry);
|
||||
} else if (_vm.YubikeyMethod)
|
||||
}
|
||||
else if (_vm.YubikeyMethod)
|
||||
{
|
||||
RequestFocus(_yubikeyTokenEntry);
|
||||
}
|
||||
@@ -187,7 +189,7 @@ namespace Bit.App.Pages
|
||||
var page = new SetPasswordPage(_appOptions, _orgIdentifier);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
{
|
||||
var page = new UpdateTempPasswordPage();
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
@@ -113,7 +113,7 @@ namespace Bit.App.Pages
|
||||
public Action StartSetPasswordAction { get; set; }
|
||||
public Action CloseAction { get; set; }
|
||||
public Action UpdateTempPasswordAction { get; set; }
|
||||
|
||||
|
||||
protected override II18nService i18nService => _i18nService;
|
||||
protected override IEnvironmentService environmentService => _environmentService;
|
||||
protected override IDeviceActionService deviceActionService => _deviceActionService;
|
||||
@@ -293,7 +293,7 @@ namespace Bit.App.Pages
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Validating);
|
||||
}
|
||||
var result = await _authService.LogInTwoFactorAsync(SelectedProviderType.Value, Token, _captchaToken, Remember);
|
||||
|
||||
|
||||
if (result.CaptchaNeeded)
|
||||
{
|
||||
if (await HandleCaptchaAsync(result.CaptchaSiteKey))
|
||||
@@ -304,12 +304,12 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
_captchaToken = null;
|
||||
|
||||
|
||||
var task = Task.Run(() => _syncService.FullSyncAsync(true));
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
_messagingService.Send("listenYubiKeyOTP", false);
|
||||
_broadcasterService.Unsubscribe(nameof(TwoFactorPage));
|
||||
|
||||
|
||||
if (_authingWithSso && result.ResetMasterPassword)
|
||||
{
|
||||
StartSetPasswordAction?.Invoke();
|
||||
@@ -317,7 +317,7 @@ namespace Bit.App.Pages
|
||||
else if (result.ForcePasswordReset)
|
||||
{
|
||||
UpdateTempPasswordAction?.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TwoFactorAuthSuccessAction?.Invoke();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using Bit.App.Resources;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -14,29 +14,29 @@ namespace Bit.App.Pages
|
||||
private readonly string _pageName;
|
||||
|
||||
public UpdateTempPasswordPage()
|
||||
{
|
||||
{
|
||||
// Service Init
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
|
||||
|
||||
// Binding
|
||||
InitializeComponent();
|
||||
_pageName = string.Concat(nameof(UpdateTempPasswordPage), "_", DateTime.UtcNow.Ticks);
|
||||
_vm = BindingContext as UpdateTempPasswordPageViewModel;
|
||||
_vm.Page = this;
|
||||
SetActivityIndicator();
|
||||
|
||||
|
||||
// Actions Declaration
|
||||
_vm.LogOutAction = () =>
|
||||
{
|
||||
_messagingService.Send("logout");
|
||||
};
|
||||
_vm.UpdateTempPasswordSuccessAction = () => Device.BeginInvokeOnMainThread(UpdateTempPasswordSuccess);
|
||||
|
||||
|
||||
// Link fields that will be referenced in codebehind
|
||||
MasterPasswordEntry = _masterPassword;
|
||||
ConfirmMasterPasswordEntry = _confirmMasterPassword;
|
||||
|
||||
|
||||
// Return Types and Commands
|
||||
_masterPassword.ReturnType = ReturnType.Next;
|
||||
_masterPassword.ReturnCommand = new Command(() => _confirmMasterPassword.Focus());
|
||||
@@ -77,7 +77,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UpdateTempPasswordSuccess()
|
||||
{
|
||||
_messagingService.Send("logout");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.App.Resources;
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Request;
|
||||
using Xamarin.Forms;
|
||||
@@ -16,7 +16,7 @@ namespace Bit.App.Pages
|
||||
ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword);
|
||||
SubmitCommand = new Command(async () => await SubmitAsync());
|
||||
}
|
||||
|
||||
|
||||
public Command SubmitCommand { get; }
|
||||
public Command TogglePasswordCommand { get; }
|
||||
public Command ToggleConfirmPasswordCommand { get; }
|
||||
@@ -37,23 +37,23 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task SubmitAsync()
|
||||
{
|
||||
if (!await ValidateMasterPasswordAsync())
|
||||
if (!await ValidateMasterPasswordAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Retrieve details for key generation
|
||||
var kdf = await _stateService.GetKdfTypeAsync();
|
||||
var kdfIterations = await _stateService.GetKdfIterationsAsync();
|
||||
var email = await _stateService.GetEmailAsync();
|
||||
|
||||
|
||||
// Create new key and hash new password
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations);
|
||||
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key);
|
||||
|
||||
|
||||
// Create new encKey for the User
|
||||
var newEncKey = await _cryptoService.RemakeEncKeyAsync(key);
|
||||
|
||||
|
||||
// Create request
|
||||
var request = new UpdateTempPasswordRequest
|
||||
{
|
||||
@@ -61,7 +61,7 @@ namespace Bit.App.Pages
|
||||
NewMasterPasswordHash = masterPasswordHash,
|
||||
MasterPasswordHint = Hint
|
||||
};
|
||||
|
||||
|
||||
// Initiate API action
|
||||
try
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Bit.App.Pages
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
PageTitle = AppResources.VerificationCode;
|
||||
|
||||
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
MainActionCommand = new AsyncCommand(MainActionAsync, allowsMultipleExecutions: false);
|
||||
RequestOTPCommand = new AsyncCommand(RequestOTPAsync, allowsMultipleExecutions: false);
|
||||
@@ -60,7 +60,7 @@ namespace Bit.App.Pages
|
||||
get => _mainActionText;
|
||||
set => SetProperty(ref _mainActionText, value);
|
||||
}
|
||||
|
||||
|
||||
public string SendCodeStatus
|
||||
{
|
||||
get => _sendCodeStatus;
|
||||
|
||||
@@ -35,12 +35,12 @@ namespace Bit.App.Pages
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
|
||||
|
||||
if (IsThemeDirty)
|
||||
{
|
||||
UpdateOnThemeChanged();
|
||||
}
|
||||
|
||||
|
||||
await SaveActivityAsync();
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace Bit.App.Pages
|
||||
VerticalOptions = LayoutOptions.CenterAndExpand,
|
||||
HorizontalOptions = LayoutOptions.Center,
|
||||
Color = ThemeManager.GetResourceColor("PrimaryColor"),
|
||||
AutomationId = "activity_indicator"
|
||||
};
|
||||
if (targetView != null)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
|
||||
@@ -31,7 +31,8 @@ namespace Bit.App.Pages
|
||||
{
|
||||
base.OnAppearing();
|
||||
|
||||
await LoadOnAppearedAsync(_mainLayout, true, async () => {
|
||||
await LoadOnAppearedAsync(_mainLayout, true, async () =>
|
||||
{
|
||||
await _vm.InitAsync();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Bit.App.Pages
|
||||
public partial class GeneratorPage : BaseContentPage, IThemeDirtablePage
|
||||
{
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
|
||||
|
||||
private GeneratorPageViewModel _vm;
|
||||
private readonly bool _fromTabPage;
|
||||
private readonly Action<string> _selectAction;
|
||||
@@ -77,7 +77,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Bit.App.Resources;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -225,7 +225,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PasswordGeneratorPolicyOptions EnforcedPolicyOptions
|
||||
{
|
||||
get => _enforcedPolicyOptions;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
@@ -337,10 +337,10 @@ namespace Bit.App.Pages
|
||||
|
||||
_vm.IsAddFromShare = true;
|
||||
_vm.CopyInsteadOfShareAfterSaving = _appOptions.CopyInsteadOfShareAfterSaving;
|
||||
|
||||
|
||||
var name = _appOptions.CreateSend.Item2;
|
||||
_vm.Send.Name = name;
|
||||
|
||||
|
||||
var type = _appOptions.CreateSend.Item1;
|
||||
if (type == SendType.File)
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Bit.App.Pages
|
||||
private TimeSpan? _expirationTime;
|
||||
private bool _isOverridingPickers;
|
||||
private int? _maxAccessCount;
|
||||
private string[] _additionalSendProperties = new []
|
||||
private string[] _additionalSendProperties = new[]
|
||||
{
|
||||
nameof(IsText),
|
||||
nameof(IsFile),
|
||||
@@ -209,7 +209,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
get => _showPassword;
|
||||
set => SetProperty(ref _showPassword, value,
|
||||
additionalPropertyNames: new []
|
||||
additionalPropertyNames: new[]
|
||||
{
|
||||
nameof(ShowPasswordIcon)
|
||||
});
|
||||
@@ -237,7 +237,7 @@ namespace Bit.App.Pages
|
||||
PageTitle = EditMode ? AppResources.EditSend : AppResources.AddSend;
|
||||
_canAccessPremium = await _stateService.CanAccessPremiumAsync();
|
||||
_emailVerified = await _stateService.GetEmailVerifiedAsync();
|
||||
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||
SendEnabled = !await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||
DisableHideEmail = await AppHelpers.IsHideEmailDisabledByPolicyAsync();
|
||||
SendOptionsPolicyInEffect = SendEnabled && DisableHideEmail;
|
||||
}
|
||||
@@ -381,7 +381,7 @@ namespace Bit.App.Pages
|
||||
|
||||
UpdateSendData();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(NewPassword))
|
||||
if (string.IsNullOrWhiteSpace(NewPassword))
|
||||
{
|
||||
NewPassword = null;
|
||||
}
|
||||
@@ -521,7 +521,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.SendFileEmailVerificationRequired);
|
||||
}
|
||||
|
||||
|
||||
if (IsAddFromShare && Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
_deviceActionService.CloseMainApp();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Controls;
|
||||
@@ -133,7 +133,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private async void RowSelected(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
((ExtendedCollectionView)sender).SelectedItem = null;
|
||||
@@ -160,7 +160,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
var page = new SendsPage(_vm.Filter, _vm.Type != null);
|
||||
var page = new SendsPage(_vm.Filter, _vm.Type);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
}
|
||||
@@ -174,7 +174,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await _vaultTimeoutService.LockAsync(true, true);
|
||||
}
|
||||
|
||||
|
||||
private void About_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
_vm.ShowAbout();
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
}
|
||||
|
||||
public string Title { get; }
|
||||
public string ItemCount { get; }
|
||||
public string ItemCount { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ namespace Bit.App.Pages
|
||||
ShowNoData = false;
|
||||
Loading = true;
|
||||
ShowList = false;
|
||||
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||
SendEnabled = !await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||
var groupedSends = new List<SendGroupingsPageListGroup>();
|
||||
var page = Page as SendGroupingsPage;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Linq;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@@ -12,15 +13,22 @@ namespace Bit.App.Pages
|
||||
private SendsPageViewModel _vm;
|
||||
private bool _hasFocused;
|
||||
|
||||
public SendsPage(Func<SendView, bool> filter, bool type = false)
|
||||
public SendsPage(Func<SendView, bool> filter, SendType? type = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as SendsPageViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.Filter = filter;
|
||||
if (type)
|
||||
if (type != null)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchType;
|
||||
if (type == SendType.File)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchFileSends;
|
||||
}
|
||||
else if (type == SendType.Text)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchTextSends;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -33,6 +41,7 @@ namespace Bit.App.Pages
|
||||
_searchBar.Placeholder = AppResources.Search;
|
||||
_mainLayout.Children.Insert(0, _searchBar);
|
||||
_mainLayout.Children.Insert(1, _separator);
|
||||
ShowModalAnimationDelay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -35,11 +35,11 @@ namespace Bit.App.Pages
|
||||
get => _sendEnabled;
|
||||
set => SetProperty(ref _sendEnabled, value);
|
||||
}
|
||||
|
||||
|
||||
public bool ShowNoData
|
||||
{
|
||||
get => _showNoData;
|
||||
set => SetProperty(ref _showNoData, value, additionalPropertyNames: new []
|
||||
set => SetProperty(ref _showNoData, value, additionalPropertyNames: new[]
|
||||
{
|
||||
nameof(ShowSearchDirection)
|
||||
});
|
||||
@@ -48,7 +48,7 @@ namespace Bit.App.Pages
|
||||
public bool ShowList
|
||||
{
|
||||
get => _showList;
|
||||
set => SetProperty(ref _showList, value, additionalPropertyNames: new []
|
||||
set => SetProperty(ref _showList, value, additionalPropertyNames: new[]
|
||||
{
|
||||
nameof(ShowSearchDirection)
|
||||
});
|
||||
@@ -58,7 +58,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||
SendEnabled = !await AppHelpers.IsSendDisabledByPolicyAsync();
|
||||
if (!string.IsNullOrWhiteSpace((Page as SendsPage).SearchBar.Text))
|
||||
{
|
||||
Search((Page as SendsPage).SearchBar.Text, 200);
|
||||
|
||||
@@ -49,12 +49,12 @@ namespace Bit.App.Pages
|
||||
_vm.ToggleAutofillService();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ToggleInlineAutofill(object sender, EventArgs e)
|
||||
{
|
||||
_vm.ToggleInlineAutofill();
|
||||
}
|
||||
|
||||
|
||||
private void ToggleAccessibility(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
@@ -62,7 +62,7 @@ namespace Bit.App.Pages
|
||||
_vm.ToggleAccessibility();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ToggleDrawOver(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Bit.App.Pages
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly MobileI18nService _i18nService;
|
||||
|
||||
|
||||
private bool _autofillServiceToggled;
|
||||
private bool _inlineAutofillToggled;
|
||||
private bool _accessibilityToggled;
|
||||
@@ -26,9 +26,9 @@ namespace Bit.App.Pages
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService;
|
||||
PageTitle = AppResources.AutofillServices;
|
||||
}
|
||||
|
||||
|
||||
#region Autofill Service
|
||||
|
||||
|
||||
public bool AutofillServiceVisible
|
||||
{
|
||||
get => _deviceActionService.SystemMajorVersion() >= 26;
|
||||
@@ -43,16 +43,16 @@ namespace Bit.App.Pages
|
||||
nameof(InlineAutofillEnabled)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Inline Autofill
|
||||
|
||||
public bool InlineAutofillVisible
|
||||
{
|
||||
get => _deviceActionService.SystemMajorVersion() >= 30;
|
||||
}
|
||||
|
||||
|
||||
public bool InlineAutofillEnabled
|
||||
{
|
||||
get => AutofillServiceToggled;
|
||||
@@ -69,9 +69,9 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Accessibility
|
||||
|
||||
public string AccessibilityDescriptionLabel
|
||||
@@ -97,7 +97,7 @@ namespace Bit.App.Pages
|
||||
return _i18nService.T("AccessibilityDescription4");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool AccessibilityToggled
|
||||
{
|
||||
get => _accessibilityToggled;
|
||||
@@ -109,9 +109,9 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Draw-Over
|
||||
|
||||
|
||||
public bool DrawOverVisible
|
||||
{
|
||||
get => _deviceActionService.SystemMajorVersion() >= 23;
|
||||
@@ -135,12 +135,12 @@ namespace Bit.App.Pages
|
||||
return _i18nService.T("DrawOverDescription3");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool DrawOverEnabled
|
||||
{
|
||||
get => AccessibilityToggled;
|
||||
}
|
||||
|
||||
|
||||
public bool DrawOverToggled
|
||||
{
|
||||
get => _drawOverToggled;
|
||||
@@ -148,7 +148,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
InlineAutofillToggled = await _stateService.GetInlineAutofillEnabledAsync() ?? true;
|
||||
@@ -189,7 +189,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
_deviceActionService.OpenAccessibilityOverlayPermissionSettings();
|
||||
}
|
||||
|
||||
|
||||
public void UpdateEnabled()
|
||||
{
|
||||
AutofillServiceToggled =
|
||||
@@ -197,7 +197,7 @@ namespace Bit.App.Pages
|
||||
AccessibilityToggled = _deviceActionService.AutofillAccessibilityServiceRunning();
|
||||
DrawOverToggled = _deviceActionService.AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
|
||||
|
||||
private async Task UpdateInlineAutofillToggledAsync()
|
||||
{
|
||||
if (_inited)
|
||||
|
||||
@@ -4,11 +4,11 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -77,7 +77,7 @@ namespace Bit.App.Pages
|
||||
InstructionText = _i18nService.T("ExportVaultMasterPasswordDescription");
|
||||
SecretName = _i18nService.T("MasterPassword");
|
||||
}
|
||||
|
||||
|
||||
UpdateWarning();
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
get => _showPassword;
|
||||
set => SetProperty(ref _showPassword, value,
|
||||
additionalPropertyNames: new string[] {nameof(ShowPasswordIcon)});
|
||||
additionalPropertyNames: new string[] { nameof(ShowPasswordIcon) });
|
||||
}
|
||||
|
||||
public bool UseOTPVerification
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.App.Resources;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Bit.App.Resources;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Bit.App.Resources;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Models.View;
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Core.Models.View;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Bit.App.Resources;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using Bit.App.Resources;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace Bit.App.Pages
|
||||
|
||||
async void OnTimePickerPropertyChanged(object sender, PropertyChangedEventArgs args)
|
||||
{
|
||||
var s = (TimePicker) sender;
|
||||
var s = (TimePicker)sender;
|
||||
var time = s.Time.TotalMinutes;
|
||||
if (s.IsFocused && args.PropertyName == "Time")
|
||||
{
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
using ZXing.Client.Result;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -428,7 +428,7 @@ namespace Bit.App.Pages
|
||||
var securityItems = new List<SettingsPageListItem>
|
||||
{
|
||||
new SettingsPageListItem { Name = AppResources.VaultTimeout, SubLabel = _vaultTimeoutDisplayValue },
|
||||
new SettingsPageListItem
|
||||
new SettingsPageListItem
|
||||
{
|
||||
Name = AppResources.VaultTimeoutAction,
|
||||
SubLabel = _vaultTimeoutActionDisplayValue
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
|
||||
|
||||
private NavigationPage _groupingsPage;
|
||||
private NavigationPage _sendGroupingsPage;
|
||||
private NavigationPage _generatorPage;
|
||||
@@ -93,7 +93,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
CurrentPage = _generatorPage;
|
||||
}
|
||||
|
||||
|
||||
public void ResetToSendPage()
|
||||
{
|
||||
CurrentPage = _sendGroupingsPage;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.PlatformConfiguration;
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Bit.App.Pages
|
||||
new KeyValuePair<UriMatchType?, string>(UriMatchType.Exact, AppResources.Exact),
|
||||
new KeyValuePair<UriMatchType?, string>(UriMatchType.Never, AppResources.Never)
|
||||
};
|
||||
|
||||
|
||||
public AddEditPageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
@@ -350,7 +350,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
Cipher.Name += " - " + AppResources.Clone;
|
||||
// If not allowing personal ownership, update cipher's org Id to prompt downstream changes
|
||||
if (Cipher.OrganizationId == null && !AllowPersonal)
|
||||
if (Cipher.OrganizationId == null && !AllowPersonal)
|
||||
{
|
||||
Cipher.OrganizationId = OrganizationId;
|
||||
}
|
||||
@@ -399,7 +399,7 @@ namespace Bit.App.Pages
|
||||
IdentityTitleOptions.FindIndex(k => k.Value == Cipher.Identity.Title);
|
||||
OwnershipSelectedIndex = string.IsNullOrWhiteSpace(Cipher.OrganizationId) ? 0 :
|
||||
OwnershipOptions.FindIndex(k => k.Value == Cipher.OrganizationId);
|
||||
|
||||
|
||||
// If the selected organization is on Index 0 and we've removed the personal option, force refresh
|
||||
if (!AllowPersonal && OwnershipSelectedIndex == 0)
|
||||
{
|
||||
@@ -451,11 +451,11 @@ namespace Bit.App.Pages
|
||||
AppResources.Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if ((!EditMode || CloneMode) && !AllowPersonal && string.IsNullOrWhiteSpace(Cipher.OrganizationId))
|
||||
{
|
||||
await Page.DisplayAlert(AppResources.AnErrorHasOccurred,
|
||||
AppResources.PersonalOwnershipSubmitError,AppResources.Ok);
|
||||
AppResources.PersonalOwnershipSubmitError, AppResources.Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -535,7 +535,7 @@ namespace Bit.App.Pages
|
||||
AppResources.AnErrorHasOccurred);
|
||||
}
|
||||
}
|
||||
catch(Exception genex)
|
||||
catch (Exception genex)
|
||||
{
|
||||
_logger.Exception(genex);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using System;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -15,7 +15,18 @@
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Icon="search.png" Clicked="Search_Clicked" />
|
||||
<controls:ExtendedToolbarItem
|
||||
x:Name="_accountAvatar"
|
||||
IconImageSource="{Binding AvatarImageSource}"
|
||||
Command="{Binding Source={x:Reference _accountListOverlay}, Path=ToggleVisibililtyCommand}"
|
||||
Order="Primary"
|
||||
Priority="-1"
|
||||
UseOriginalImage="True"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n Account}" />
|
||||
<ToolbarItem Icon="search.png" Clicked="Search_Clicked"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n Search}" />
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ContentPage.Resources>
|
||||
@@ -58,7 +69,7 @@
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Padding="20, 0"
|
||||
Spacing="20"
|
||||
IsVisible="{Binding ShowList, Converter={StaticResource inverseBool}}">
|
||||
IsVisible="{Binding ShowNoData}">
|
||||
<Label
|
||||
Text="{Binding NoDataText}"
|
||||
HorizontalTextAlignment="Center"></Label>
|
||||
@@ -88,6 +99,8 @@
|
||||
AbsoluteLayout.LayoutFlags="All"
|
||||
AbsoluteLayout.LayoutBounds="0, 0, 1, 1">
|
||||
</ContentView>
|
||||
|
||||
<!-- Android FAB -->
|
||||
<Button
|
||||
x:Name="_fab"
|
||||
Image="plus.png"
|
||||
@@ -99,6 +112,14 @@
|
||||
<effects:FabShadowEffect />
|
||||
</Button.Effects>
|
||||
</Button>
|
||||
|
||||
<controls:AccountSwitchingOverlayView
|
||||
x:Name="_accountListOverlay"
|
||||
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
|
||||
AbsoluteLayout.LayoutFlags="All"
|
||||
MainPage="{Binding Source={x:Reference _page}}"
|
||||
MainFab="{Binding Source={x:Reference _fab}, Path=.}"
|
||||
BindingContext="{Binding AccountSwitchingOverlayViewModel}"/>
|
||||
</AbsoluteLayout>
|
||||
|
||||
</pages:BaseContentPage>
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -15,7 +14,8 @@ namespace Bit.App.Pages
|
||||
public partial class AutofillCiphersPage : BaseContentPage
|
||||
{
|
||||
private readonly AppOptions _appOptions;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
private readonly ISyncService _syncService;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
|
||||
private AutofillCiphersPageViewModel _vm;
|
||||
@@ -24,17 +24,23 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_appOptions = appOptions;
|
||||
InitializeComponent();
|
||||
SetActivityIndicator(_mainContent);
|
||||
_vm = BindingContext as AutofillCiphersPageViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.Init(appOptions);
|
||||
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
}
|
||||
|
||||
protected async override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
if (_syncService.SyncInProgress)
|
||||
{
|
||||
IsBusy = true;
|
||||
}
|
||||
if (!await AppHelpers.IsVaultTimeoutImmediateAsync())
|
||||
{
|
||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||
@@ -43,13 +49,37 @@ namespace Bit.App.Pages
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_accountAvatar?.OnAppearing();
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
|
||||
_broadcasterService.Subscribe(nameof(AutofillCiphersPage), async (message) =>
|
||||
{
|
||||
if (message.Command == "syncStarted")
|
||||
{
|
||||
Device.BeginInvokeOnMainThread(() => IsBusy = true);
|
||||
}
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
await Task.Delay(500);
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
IsBusy = false;
|
||||
if (_vm.LoadedOnce)
|
||||
{
|
||||
var task = _vm.LoadAsync();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await LoadOnAppearedAsync(_mainLayout, false, async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
catch (Exception e) when(e.Message.Contains("No key."))
|
||||
catch (Exception e) when (e.Message.Contains("No key."))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _vm.LoadAsync();
|
||||
@@ -59,6 +89,11 @@ namespace Bit.App.Pages
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
if (_accountListOverlay.IsVisible)
|
||||
{
|
||||
_accountListOverlay.HideAsync().FireAndForget();
|
||||
return true;
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
_appOptions.Uri = null;
|
||||
@@ -66,6 +101,13 @@ namespace Bit.App.Pages
|
||||
return base.OnBackButtonPressed();
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
IsBusy = false;
|
||||
_accountAvatar?.OnDisappearing();
|
||||
}
|
||||
|
||||
private async void RowSelected(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
((ExtendedCollectionView)sender).SelectedItem = null;
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
@@ -8,9 +12,6 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@@ -23,8 +24,10 @@ namespace Bit.App.Pages
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IPasswordRepromptService _passwordRepromptService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private AppOptions _appOptions;
|
||||
private bool _showNoData;
|
||||
private bool _showList;
|
||||
private string _noDataText;
|
||||
private bool _websiteIconsEnabled;
|
||||
@@ -36,15 +39,30 @@ namespace Bit.App.Pages
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
|
||||
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
|
||||
|
||||
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
|
||||
{
|
||||
AllowAddAccountRow = false
|
||||
};
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public Command CipherOptionsCommand { get; set; }
|
||||
public bool LoadedOnce { get; set; }
|
||||
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { get; set; }
|
||||
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
|
||||
|
||||
public bool ShowNoData
|
||||
{
|
||||
get => _showNoData;
|
||||
set => SetProperty(ref _showNoData, value);
|
||||
}
|
||||
|
||||
public bool ShowList
|
||||
{
|
||||
@@ -65,7 +83,6 @@ namespace Bit.App.Pages
|
||||
|
||||
public void Init(AppOptions appOptions)
|
||||
{
|
||||
_appOptions = appOptions;
|
||||
Uri = appOptions?.Uri;
|
||||
string name = null;
|
||||
if (Uri?.StartsWith(Constants.AndroidAppProtocol) ?? false)
|
||||
@@ -87,8 +104,10 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task LoadAsync()
|
||||
{
|
||||
WebsiteIconsEnabled = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
|
||||
LoadedOnce = true;
|
||||
ShowList = false;
|
||||
ShowNoData = false;
|
||||
WebsiteIconsEnabled = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
|
||||
var groupedItems = new List<GroupingsPageListGroup>();
|
||||
var ciphers = await _cipherService.GetAllDecryptedByUrlAsync(Uri, null);
|
||||
var matching = ciphers.Item1?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
|
||||
@@ -150,6 +169,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
ShowList = groupedItems.Any();
|
||||
ShowNoData = !ShowList;
|
||||
}
|
||||
|
||||
public async Task SelectCipherAsync(CipherView cipher, bool fuzzy)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Bit.App.Controls;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -17,8 +17,7 @@ namespace Bit.App.Pages
|
||||
private CiphersPageViewModel _vm;
|
||||
private bool _hasFocused;
|
||||
|
||||
public CiphersPage(Func<CipherView, bool> filter, bool folder = false, bool collection = false,
|
||||
bool type = false, string autofillUrl = null, bool deleted = false)
|
||||
public CiphersPage(Func<CipherView, bool> filter, string pageTitle = null, string autofillUrl = null, bool deleted = false)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as CiphersPageViewModel;
|
||||
@@ -26,21 +25,9 @@ namespace Bit.App.Pages
|
||||
_vm.Filter = filter;
|
||||
_vm.AutofillUrl = _autofillUrl = autofillUrl;
|
||||
_vm.Deleted = deleted;
|
||||
if (deleted)
|
||||
if (pageTitle != null)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchTrash;
|
||||
}
|
||||
else if (folder)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchFolder;
|
||||
}
|
||||
else if (collection)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchCollection;
|
||||
}
|
||||
else if (type)
|
||||
{
|
||||
_vm.PageTitle = AppResources.SearchType;
|
||||
_vm.PageTitle = string.Format(AppResources.SearchGroup, pageTitle);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -53,6 +40,7 @@ namespace Bit.App.Pages
|
||||
_searchBar.Placeholder = AppResources.Search;
|
||||
_mainLayout.Children.Insert(0, _searchBar);
|
||||
_mainLayout.Children.Insert(1, _separator);
|
||||
ShowModalAnimationDelay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
@@ -6,11 +11,6 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -107,7 +107,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
try
|
||||
{
|
||||
ciphers = await _searchService.SearchCiphersAsync(searchText,
|
||||
ciphers = await _searchService.SearchCiphersAsync(searchText,
|
||||
Filter ?? (c => c.IsDeleted == Deleted), null, cts.Token);
|
||||
cts.Token.ThrowIfCancellationRequested();
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Bit.App.Pages
|
||||
private PreviousPageInfo _previousPage;
|
||||
|
||||
public GroupingsPage(bool mainPage, CipherType? type = null, string folderId = null,
|
||||
string collectionId = null, string pageTitle = null, PreviousPageInfo previousPage = null,
|
||||
string collectionId = null, string pageTitle = null, PreviousPageInfo previousPage = null,
|
||||
bool deleted = false)
|
||||
{
|
||||
_pageName = string.Concat(nameof(GroupingsPage), "_", DateTime.UtcNow.Ticks);
|
||||
@@ -117,7 +117,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await _vm.LoadAsync();
|
||||
}
|
||||
catch (Exception e) when(e.Message.Contains("No key."))
|
||||
catch (Exception e) when (e.Message.Contains("No key."))
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await _vm.LoadAsync();
|
||||
@@ -225,8 +225,7 @@ namespace Bit.App.Pages
|
||||
await _accountListOverlay.HideAsync();
|
||||
if (DoOnce())
|
||||
{
|
||||
var page = new CiphersPage(_vm.Filter, _vm.FolderId != null, _vm.CollectionId != null,
|
||||
_vm.Type != null, deleted: _vm.Deleted);
|
||||
var page = new CiphersPage(_vm.Filter, _vm.MainPage ? null : _vm.PageTitle, deleted: _vm.Deleted);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ namespace Bit.App.Pages
|
||||
protected override async void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
await LoadOnAppearedAsync(_mainLayout, true, async () => {
|
||||
await LoadOnAppearedAsync(_mainLayout, true, async () =>
|
||||
{
|
||||
await _vm.InitAsync();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Bit.App.Resources;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using Bit.App.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -216,7 +216,7 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
|
||||
var options = new List<string> {AppResources.Attachments};
|
||||
var options = new List<string> { AppResources.Attachments };
|
||||
if (_vm.Cipher.OrganizationId == null)
|
||||
{
|
||||
options.Add(AppResources.Clone);
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Core;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -233,7 +233,7 @@ namespace Bit.App.Pages
|
||||
set
|
||||
{
|
||||
SetProperty(ref _totpLow, value);
|
||||
Page.Resources["textTotp"] = ThemeManager.Resources()[value ? "text-danger" : "text-default"];
|
||||
Page.Resources["textTotp"] = ThemeManager.Resources()[value ? "text-danger" : "text-default"];
|
||||
}
|
||||
}
|
||||
public bool IsDeleted => Cipher.IsDeleted;
|
||||
@@ -285,7 +285,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public async void TogglePassword()
|
||||
{
|
||||
if (! await PromptPasswordAsync())
|
||||
if (!await PromptPasswordAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -613,7 +613,7 @@ namespace Bit.App.Pages
|
||||
_attachmentData = null;
|
||||
_attachmentFilename = null;
|
||||
}
|
||||
|
||||
|
||||
private async void CopyAsync(string id, string text = null)
|
||||
{
|
||||
if (_passwordRepromptService.ProtectedFields.Contains(id) && !await PromptPasswordAsync())
|
||||
|
||||
14
src/App/Resources/AppResources.Designer.cs
generated
14
src/App/Resources/AppResources.Designer.cs
generated
@@ -2387,15 +2387,21 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
public static string SearchFolder {
|
||||
public static string SearchFileSends {
|
||||
get {
|
||||
return ResourceManager.GetString("SearchFolder", resourceCulture);
|
||||
return ResourceManager.GetString("SearchFileSends", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string SearchType {
|
||||
public static string SearchTextSends {
|
||||
get {
|
||||
return ResourceManager.GetString("SearchType", resourceCulture);
|
||||
return ResourceManager.GetString("SearchTextSends", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string SearchGroup {
|
||||
get {
|
||||
return ResourceManager.GetString("SearchGroup", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2121,13 +2121,13 @@
|
||||
<value>Μετάβαση στον επόμενο διαθέσιμο λογαριασμό</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
<value>Κλειδωμένος Λογαριασμός</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
<value>Ο λογαριασμός αποσυνδέθηκε επιτυχώς</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
<value>Ο λογαριασμός αφαιρέθηκε επιτυχώς</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Διαγραφή Λογαριασμού</value>
|
||||
|
||||
@@ -276,16 +276,16 @@
|
||||
<value>האם אתה בטוח שברצונך להתנתק?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>הסר/י חשבון</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
<value>האם את/ה בטוח/ה שברצונך להסיר חשבון זה?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>החשבון כבר נוסף</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
<value>האם תרצה לעבור אליו עכשיו?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>סיסמה ראשית</value>
|
||||
@@ -1073,7 +1073,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>שם משפחה</value>
|
||||
</data>
|
||||
<data name="FullName" xml:space="preserve">
|
||||
<value>Full Name</value>
|
||||
<value>שם מלא</value>
|
||||
</data>
|
||||
<data name="LicenseNumber" xml:space="preserve">
|
||||
<value>מספר רשיון</value>
|
||||
@@ -1200,7 +1200,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>מוסתר</value>
|
||||
</data>
|
||||
<data name="FieldTypeLinked" xml:space="preserve">
|
||||
<value>Linked</value>
|
||||
<value>מקושר</value>
|
||||
</data>
|
||||
<data name="FieldTypeText" xml:space="preserve">
|
||||
<value>טקסט</value>
|
||||
@@ -1472,7 +1472,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>בטל נעילה</value>
|
||||
</data>
|
||||
<data name="UnlockVault" xml:space="preserve">
|
||||
<value>Unlock Vault</value>
|
||||
<value>פתח נעילת כספת</value>
|
||||
</data>
|
||||
<data name="ThirtyMinutes" xml:space="preserve">
|
||||
<value>30 דקות</value>
|
||||
@@ -1491,7 +1491,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>הכספת שלך נעולה. הזן את קוד הPIN שלך כדי להמשיך.</value>
|
||||
</data>
|
||||
<data name="VaultLockedIdentity" xml:space="preserve">
|
||||
<value>Your vault is locked. Verify your identity to continue.</value>
|
||||
<value>הכספת שלך נעולה. אמת את זהותך כדי להמשיך.</value>
|
||||
</data>
|
||||
<data name="Dark" xml:space="preserve">
|
||||
<value>כהה</value>
|
||||
@@ -1634,13 +1634,13 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>הזן את הסיסמה הראשית שלך עבור יצוא המידע מהכספת.</value>
|
||||
</data>
|
||||
<data name="SendVerificationCodeToEmail" xml:space="preserve">
|
||||
<value>Send a verification code to your email</value>
|
||||
<value>שליחת קוד אימות לדוא״ל שלך</value>
|
||||
</data>
|
||||
<data name="CodeSent" xml:space="preserve">
|
||||
<value>Code Sent!</value>
|
||||
<value>קוד נשלח!</value>
|
||||
</data>
|
||||
<data name="ConfirmYourIdentity" xml:space="preserve">
|
||||
<value>Confirm your identity to continue.</value>
|
||||
<value>אשר את זהותך כדי להמשיך.</value>
|
||||
</data>
|
||||
<data name="ExportVaultWarning" xml:space="preserve">
|
||||
<value>הקובץ מכיל את פרטי הכספת שלך בפורמט לא מוצפן. מומלץ להעביר את הקובץ רק בדרכים מוצפנות, ומאוד לא מומלץ לשמור או לשלוח את הקובץ הזה בדרכים לא מוצפנות (כדוגמת סתם אימייל). מחק את הקובץ מיד לאחר שסיימת את השימוש בו.</value>
|
||||
@@ -2066,19 +2066,19 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>כרגע לא ניתן לעדכן את הסיסמה</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPassword" xml:space="preserve">
|
||||
<value>Remove Master Password</value>
|
||||
<value>הסרת סיסמה ראשית</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning" xml:space="preserve">
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your Master Password from your account and require SSO to login.</value>
|
||||
<value>{0} משתמש/ת ב־SSO עם הצפנה בניהול לקוחות. המשך התהליך יסיר את סיסמת האב שלך מחשבונך וידרוש SSO כדי להתחבר.</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning2" xml:space="preserve">
|
||||
<value>If you do not want to remove your Master Password, you may leave this organization.</value>
|
||||
<value>אם אינך רוצה להסיר את הסיסמה הראשית שלך, תוכל לעזוב את הארגון הזה.</value>
|
||||
</data>
|
||||
<data name="LeaveOrganization" xml:space="preserve">
|
||||
<value>Leave Organization</value>
|
||||
<value>עזוב ארגון</value>
|
||||
</data>
|
||||
<data name="LeaveOrganizationName" xml:space="preserve">
|
||||
<value>Leave {0}?</value>
|
||||
<value>לעזוב את {0}?</value>
|
||||
</data>
|
||||
<data name="Fido2Title" xml:space="preserve">
|
||||
<value>אימות אינטרנט באמצעות FIDO2</value>
|
||||
@@ -2112,75 +2112,76 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<value>מדיניות אחת או יותר של הארגון שלך מונעות ממך לייצא את הכספת האישית שלך.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>הוספת חשבון</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
<value>פתוח</value>
|
||||
</data>
|
||||
<data name="AccountLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
<value>נעול</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>בוצעה יציאה</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
<value>הוחלף לחשבון הזמין הבא</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
<value>החשבון נעול</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
<value>נותק בהצלחה מהחשבון</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
<value>חשבון נמחק בהצלחה</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
<value>מחק חשבון</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccountIsPermanent" xml:space="preserve">
|
||||
<value>Deleting your account is permanent</value>
|
||||
<value>מחיקת חשבונך היא לצמיתות</value>
|
||||
</data>
|
||||
<data name="DeleteAccountExplanation" xml:space="preserve">
|
||||
<value>Your account and all associated data will be erased and unrecoverable. Are you sure you want to continue?</value>
|
||||
<value>החשבון שלך וכל הנתונים הקשורים יימחקו ולא ניתן יהיה לשחזרם. האם את/ה בטוח/ה שאת/ה רוצה להמשיך?
|
||||
</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccount" xml:space="preserve">
|
||||
<value>Deleting your account</value>
|
||||
<value>מוחק את החשבון שלך</value>
|
||||
</data>
|
||||
<data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve">
|
||||
<value>Your account has been permanently deleted</value>
|
||||
<value>חשבונך נמחק לצמיתות</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Invalid Verification Code.</value>
|
||||
<value>קוד אימות שגוי.</value>
|
||||
</data>
|
||||
<data name="RequestOTP" xml:space="preserve">
|
||||
<value>Request one-time password</value>
|
||||
<value>בקשת סיסמה חד־פעמית</value>
|
||||
</data>
|
||||
<data name="SendCode" xml:space="preserve">
|
||||
<value>Send Code</value>
|
||||
<value>שליחת קוד</value>
|
||||
</data>
|
||||
<data name="Sending" xml:space="preserve">
|
||||
<value>Sending</value>
|
||||
<value>בשליחה</value>
|
||||
</data>
|
||||
<data name="CopySendLinkOnSave" xml:space="preserve">
|
||||
<value>Copy Send link on save</value>
|
||||
<value>העתק קישור שליחה בעת שמירה</value>
|
||||
</data>
|
||||
<data name="SendingCode" xml:space="preserve">
|
||||
<value>Sending code</value>
|
||||
<value>שליחת קוד</value>
|
||||
</data>
|
||||
<data name="Verifying" xml:space="preserve">
|
||||
<value>Verifying</value>
|
||||
<value>אימות</value>
|
||||
</data>
|
||||
<data name="ResendCode" xml:space="preserve">
|
||||
<value>Resend Code</value>
|
||||
<value>שליחת קוד בשנית</value>
|
||||
</data>
|
||||
<data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve">
|
||||
<value>A verification code was sent to your email</value>
|
||||
<value>קוד אימות נשלח לדוא"ל שלך</value>
|
||||
</data>
|
||||
<data name="AnErrorOccurredWhileSendingAVerificationCodeToYourEmailPleaseTryAgain" xml:space="preserve">
|
||||
<value>An error occurred while sending a verification code to your email. Please try again</value>
|
||||
<value>אירעה שגיאה בעת שליחת קוד אימות לדוא"ל שלך. בבקשה נסה שוב</value>
|
||||
</data>
|
||||
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
|
||||
<value>Enter the verification code that was sent to your email</value>
|
||||
<value>הזן את קוד האימות שנשלח לדוא"ל שלך</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2120,13 +2120,13 @@
|
||||
<value>사용 가능한 다음 계정으로 전환함</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
<value>계정 잠김</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
<value>계정이 성공적으로 로그아웃되었습니다</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
<value>계정이 성공적으로 제거되었습니다</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>계정 삭제</value>
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
<value>Konto zostało już dodane</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Czy chcesz przełączyć się na nie teraz?</value>
|
||||
<value>Czy chcesz przełączyć się teraz?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Hasło główne</value>
|
||||
@@ -1162,10 +1162,10 @@
|
||||
<value>Usługa ułatwienia dostępu</value>
|
||||
</data>
|
||||
<data name="AutofillServiceDescription" xml:space="preserve">
|
||||
<value>Usługa autouzupełniania Bitwarden wykorzystuje funkcję Androida, aby wypełniać dane logowania, kart kredytowych i osobistych informacji w aplikacjach na Twoim urządzeniu.</value>
|
||||
<value>Usługa autouzupełniania Bitwarden wykorzystuje funkcję Androida, aby wypełnić dane logowania w innych aplikacjach na Twoim urządzeniu.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Użyj usługi autouzupełniania Bitwarden, aby wypełnić dane logowania, dane kart kredytowych i informacje osobiste w innych aplikacjach.</value>
|
||||
<value>Użyj usługi autouzupełniania Bitwarden, aby wypełnić dane logowania w innych aplikacjach.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
|
||||
<value>Otwórz ustawienia autouzupełniania</value>
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. przejdź do Ustawień systemu iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Dotknij "Hasła i konta"</value>
|
||||
<value>2. Dotknij "Hasła"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Dotknij opcji "Usługa autouzupełniania"</value>
|
||||
|
||||
@@ -659,7 +659,7 @@
|
||||
<value>Re-type Master Password</value>
|
||||
</data>
|
||||
<data name="SearchVault" xml:space="preserve">
|
||||
<value>Search vault</value>
|
||||
<value>Search Vault</value>
|
||||
</data>
|
||||
<data name="Security" xml:space="preserve">
|
||||
<value>Security</value>
|
||||
@@ -1372,11 +1372,15 @@
|
||||
<data name="SearchCollection" xml:space="preserve">
|
||||
<value>Search collection</value>
|
||||
</data>
|
||||
<data name="SearchFolder" xml:space="preserve">
|
||||
<value>Search folder</value>
|
||||
<data name="SearchFileSends" xml:space="preserve">
|
||||
<value>Search File Sends</value>
|
||||
</data>
|
||||
<data name="SearchType" xml:space="preserve">
|
||||
<value>Search type</value>
|
||||
<data name="SearchTextSends" xml:space="preserve">
|
||||
<value>Search Text Sends</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Search {0}</value>
|
||||
<comment>ex: Search Logins</comment>
|
||||
</data>
|
||||
<data name="Type" xml:space="preserve">
|
||||
<value>Type</value>
|
||||
@@ -1538,7 +1542,7 @@
|
||||
<value>Default (System)</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Copy Notes</value>
|
||||
<value>Copy Note</value>
|
||||
</data>
|
||||
<data name="Exit" xml:space="preserve">
|
||||
<value>Exit</value>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Перейдите в 'Настройки' iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Нажмите на пункт "Пароли и учетные записи"</value>
|
||||
<value>2. Нажмите 'Пароли'</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Нажмите 'Автозаполнение паролей'</value>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Prejdite do aplikácie "Nastavenia" pre iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Ťuknite na položku "Heslá & účty"</value>
|
||||
<value>2. Ťuknite na položku "Heslá"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Klepnite na možnosť "Automaticky vypĺňať heslá"</value>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Threading;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using System;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Services
|
||||
|
||||
@@ -14,7 +14,7 @@ using Xamarin.Forms;
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
public class MobilePlatformUtilsService : IPlatformUtilsService
|
||||
{
|
||||
{
|
||||
private static readonly Random _random = new Random();
|
||||
|
||||
private const int DialogPromiseExpiration = 600000; // 10 minutes
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
public class PreferencesStorageService : IStorageService
|
||||
{
|
||||
public static string KeyFormat = "bwPreferencesStorage:{0}";
|
||||
|
||||
|
||||
private readonly string _sharedName;
|
||||
private readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
|
||||
{
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#if !FDROID
|
||||
#if !FDROID
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Response;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Bit.App.Abstractions;
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Models.Response;
|
||||
using Bit.Core.Exceptions;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Bit.Core.Abstractions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bit.App.Services
|
||||
{
|
||||
|
||||
@@ -9,4 +9,4 @@ namespace Bit.App.Styles
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user