1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-28 06:03:40 +00:00

Compare commits

..

21 Commits

Author SHA1 Message Date
Alison Fernandes
9cc1a501a5 Merge branch 'master' into uitests 2022-04-27 23:28:47 +01:00
Alison Fernandes
b0a8694801 Implemented AccountSwitching UI tests 2022-04-27 23:27:53 +01:00
github-actions[bot]
1bbe8d8b98 Bumped version to 2.18.1 (#1894)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-27 09:04:29 -07:00
github-actions[bot]
cdc41d3bef Bumped version to 2.18.0 (#1893)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-27 08:24:29 -07:00
Oscar Hinton
769851adfe Update .gitattributes to fix build issue (#1892) 2022-04-26 16:51:58 -04:00
Oscar Hinton
c988175e50 [TI-8] Add .git-blame-ignore-revs (#1891) 2022-04-26 11:27:13 -04:00
Oscar Hinton
04539af2a6 Run dotnet format (#1738) 2022-04-26 17:21:17 +02:00
Oscar Hinton
e0efcfbe45 Add dotnet-format tool (#1737) 2022-04-26 17:21:07 +02:00
Federico Maccaroni
57213607a7 PS-291 Fix password history to update the collection on the main thread to load correctly (#1890) 2022-04-25 17:43:55 -04:00
Federico Maccaroni
2cab62fda5 TDL-13 Removed workaround of null reference on LabelRenderer given that Xamarin forms has been updated with the fix (#1889) 2022-04-25 16:09:47 -03:00
sneakernuts
99828c7ead Switched org (#1887) 2022-04-22 13:35:19 +00:00
mp-bw
ab6dde4a11 update XF and revert old workarounds (#1885) 2022-04-21 21:29:47 -04:00
dwbit
80bd8ba9d1 Change source string 'copy notes' to 'copy note' (#1881)
Change the value for 'copy notes' to 'copy note' since it is applying a single action on 1 item. This source string is already 'copy note' in the browser extension.
2022-04-21 08:03:21 -04:00
dwbit
35853a3815 Contribution Documentation edits (#1880)
* Update crowdin manager and forum category

Updating Crowdin contact from Kyle to dwbit. Update 'User-to-User Support' forum category to 'Ask the Bitwarden Community'

* Text corrections

Correcting title of forum category

* Add 'category' to text change

Update the 'Ask the Bitwarden Community' text change.
2022-04-20 23:25:37 +01:00
mp-bw
cfbbea59e9 account switching in autofill UI (Android) (#1882) 2022-04-19 20:38:17 -04:00
Jake Fink
14d4b2ee29 [BEEEP] add context to search titles (#1878)
* add more descriptive titles to search pages

* add App Resources
2022-04-10 13:00:52 -04:00
Alison Fernandes
b9c1ab7c1d Added Id to the activity indicator 2022-04-10 00:03:40 +01:00
Alison Fernandes
4d96b091f7 Enabling screenshots temporarily. 2022-04-09 00:32:24 +01:00
github-actions[bot]
b6ad3527db Autosync the updated translations (#1877)
Co-authored-by: github-actions <>
2022-04-08 11:52:21 +02:00
Alison Fernandes
88fee155db Added UI test project 2022-04-05 00:35:48 +01:00
Alison Fernandes
f930028920 Added id's to views in preparation for UI tests 2022-04-05 00:29:35 +01:00
269 changed files with 1973 additions and 832 deletions

12
.config/dotnet-tools.json Normal file
View File

@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-format": {
"version": "5.1.250801",
"commands": [
"dotnet-format"
]
}
}
}

View File

@@ -6,6 +6,7 @@ root = true
# Don't use tabs for indentation. # Don't use tabs for indentation.
[*] [*]
indent_style = space indent_style = space
end_of_line = lf
# (Please don't specify an indent_size here; that has too many unintended consequences.) # (Please don't specify an indent_size here; that has too many unintended consequences.)
# Code files # Code files

2
.git-blame-ignore-revs Normal file
View File

@@ -0,0 +1,2 @@
# .NET format https://github.com/bitwarden/mobile/pull/1738
04539af2a66668b6e85476d5cf318c9150ec4357

2
.gitattributes vendored
View File

@@ -1,7 +1,7 @@
############################################################################### ###############################################################################
# Set default behavior to automatically normalize line endings. # Set default behavior to automatically normalize line endings.
############################################################################### ###############################################################################
* text=auto * text=auto eol=lf
############################################################################### ###############################################################################
# Set default behavior for command prompt diff. # Set default behavior for command prompt diff.

View File

@@ -105,6 +105,14 @@ jobs:
- name: Restore packages - name: Restore packages
run: nuget restore 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 - name: Run Core tests
run: dotnet test test/Core.Test/Core.Test.csproj run: dotnet test test/Core.Test/Core.Test.csproj

View File

@@ -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) * **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 * **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 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/ You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/

View File

@@ -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. 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. 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
```

View File

@@ -46,6 +46,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.ShareExtension", "src\i
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Autofill", "src\iOS.Autofill\iOS.Autofill.csproj", "{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UiTests", "src\UiTests\UiTests.csproj", "{23FB637B-1705-485F-9464-078FCAF361A8}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU 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|iPhone.Build.0 = Release|iPhone
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator {8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A}.Release|iPhoneSimulator.Build.0 = 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 EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -464,6 +496,7 @@ Global
{8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA} {8AE548D9-A567-4E97-995E-93EC7DB0FDE0} = {8904C536-C67D-420F-9971-51B26574C3AA}
{F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71} {F8C3F648-EA5A-4719-8005-85D1690B1655} = {D10CA4A9-F866-40E1-B658-F69051236C71}
{8A3ECD75-3EC8-4CB3-B3A2-A73A724C279A} = {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 EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410} SolutionGuid = {7D436EA3-8B7E-45D2-8D14-0730BD2E0410}

View File

@@ -64,10 +64,10 @@ namespace Bit.Droid
Intent?.Validate(); Intent?.Validate();
base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState);
if (!CoreHelpers.InDebugMode()) //if (!CoreHelpers.InDebugMode())
{ //{
Window.AddFlags(Android.Views.WindowManagerFlags.Secure); // Window.AddFlags(Android.Views.WindowManagerFlags.Secure);
} //}
#if !DEBUG && !FDROID #if !DEBUG && !FDROID
var appCenterHelper = new AppCenterHelper(_appIdService, _stateService); var appCenterHelper = new AppCenterHelper(_appIdService, _stateService);

View File

@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version='1.0' encoding='UTF-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2.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"/> <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>

View File

@@ -1,6 +1,6 @@
using Bit.Core.Enums; using System.Threading.Tasks;
using Bit.Core.Enums;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using System.Threading.Tasks;
namespace Bit.App.Abstractions namespace Bit.App.Abstractions
{ {

View File

@@ -7,7 +7,7 @@ namespace Bit.App.Abstractions
string[] ProtectedFields { get; } string[] ProtectedFields { get; }
Task<bool> ShowPasswordPromptAsync(); Task<bool> ShowPasswordPromptAsync();
Task<(string password, bool valid)> ShowPasswordPromptAndGetItAsync(); Task<(string password, bool valid)> ShowPasswordPromptAndGetItAsync();
Task<bool> Enabled(); Task<bool> Enabled();

View File

@@ -1,5 +1,5 @@
using Newtonsoft.Json.Linq; using System.Threading.Tasks;
using System.Threading.Tasks; using Newtonsoft.Json.Linq;
namespace Bit.App.Abstractions namespace Bit.App.Abstractions
{ {

View File

@@ -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.Models;
using Bit.App.Pages; using Bit.App.Pages;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Services; using Bit.App.Services;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.Core.Enums;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Xaml; using Xamarin.Forms.Xaml;
@@ -208,7 +208,10 @@ namespace Bit.App
{ {
await _stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime()); await _stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime());
} }
SetTabsPageFromAutofill(isLocked); if (!SetTabsPageFromAutofill(isLocked))
{
ClearAutofillUri();
}
await SleptAsync(); await SleptAsync();
} }
} }
@@ -315,7 +318,7 @@ namespace Bit.App
Options.HideAccountSwitcher = await _stateService.GetActiveUserIdAsync() == null; Options.HideAccountSwitcher = await _stateService.GetActiveUserIdAsync() == null;
Current.MainPage = new NavigationPage(new LoginPage(email, Options)); Current.MainPage = new NavigationPage(new LoginPage(email, Options));
} }
else if (await _vaultTimeoutService.IsLockedAsync() || else if (await _vaultTimeoutService.IsLockedAsync() ||
await _vaultTimeoutService.ShouldLockAsync()) await _vaultTimeoutService.ShouldLockAsync())
{ {
Current.MainPage = new NavigationPage(new LockPage(Options)); 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) && if (Device.RuntimePlatform == Device.Android && !string.IsNullOrWhiteSpace(Options.Uri) &&
!Options.FromAutofillFramework) !Options.FromAutofillFramework)
@@ -385,7 +396,9 @@ namespace Bit.App
} }
}); });
}); });
return true;
} }
return false;
} }
private void Prime() private void Prime()

View File

@@ -99,7 +99,7 @@ namespace Bit.App.Controls
Opacity = 0; Opacity = 0;
IsVisible = true; IsVisible = true;
this.FadeTo(1, 100); this.FadeTo(1, 100);
if (Device.RuntimePlatform == Device.Android && MainFab != null) if (Device.RuntimePlatform == Device.Android && MainFab != null)
{ {
// start fab fade-out // start fab fade-out

View File

@@ -22,11 +22,11 @@ namespace Bit.App.Controls
{ {
_stateService = stateService; _stateService = stateService;
_messagingService = messagingService; _messagingService = messagingService;
SelectAccountCommand = new AsyncCommand<AccountViewCellViewModel>(SelectAccountAsync, SelectAccountCommand = new AsyncCommand<AccountViewCellViewModel>(SelectAccountAsync,
onException: ex => logger.Exception(ex), onException: ex => logger.Exception(ex),
allowsMultipleExecutions: false); allowsMultipleExecutions: false);
LongPressAccountCommand = new AsyncCommand<Tuple<ContentPage, AccountViewCellViewModel>>(LongPressAccountAsync, LongPressAccountCommand = new AsyncCommand<Tuple<ContentPage, AccountViewCellViewModel>>(LongPressAccountAsync,
onException: ex => logger.Exception(ex), onException: ex => logger.Exception(ex),
allowsMultipleExecutions: false); allowsMultipleExecutions: false);

View File

@@ -1,5 +1,5 @@
using System.Windows.Input;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using System.Windows.Input;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Controls namespace Bit.App.Controls

View File

@@ -112,13 +112,13 @@ namespace Bit.App.Controls
private string GetFirstLetters(string data, int charCount) private string GetFirstLetters(string data, int charCount)
{ {
var parts = data.Split(); var parts = data.Split();
if (parts.Length > 1 && charCount <= 2) if (parts.Length > 1 && charCount <= 2)
{ {
var text = ""; var text = "";
for (int i = 0; i < charCount; i++) for (int i = 0; i < charCount; i++)
{ {
text += parts[i].Substring(0,1); text += parts[i].Substring(0, 1);
} }
return text; return text;
} }

View File

@@ -6,7 +6,7 @@ namespace Bit.App.Controls
{ {
public static readonly BindableProperty StepperBackgroundColorProperty = BindableProperty.Create( public static readonly BindableProperty StepperBackgroundColorProperty = BindableProperty.Create(
nameof(StepperBackgroundColor), typeof(Color), typeof(ExtendedStepper), Color.Default); nameof(StepperBackgroundColor), typeof(Color), typeof(ExtendedStepper), Color.Default);
public static readonly BindableProperty StepperForegroundColorProperty = BindableProperty.Create( public static readonly BindableProperty StepperForegroundColorProperty = BindableProperty.Create(
nameof(StepperForegroundColor), typeof(Color), typeof(ExtendedStepper), Color.Default); nameof(StepperForegroundColor), typeof(Color), typeof(ExtendedStepper), Color.Default);
@@ -15,7 +15,7 @@ namespace Bit.App.Controls
get => (Color)GetValue(StepperBackgroundColorProperty); get => (Color)GetValue(StepperBackgroundColorProperty);
set => SetValue(StepperBackgroundColorProperty, value); set => SetValue(StepperBackgroundColorProperty, value);
} }
public Color StepperForegroundColor public Color StepperForegroundColor
{ {
get => (Color)GetValue(StepperForegroundColorProperty); get => (Color)GetValue(StepperForegroundColorProperty);

View File

@@ -1,4 +1,4 @@
using System; using System;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
@@ -13,7 +13,7 @@ namespace Bit.App.Controls
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create( public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
nameof(ButtonCommand), typeof(Command<SendView>), typeof(SendViewCell)); nameof(ButtonCommand), typeof(Command<SendView>), typeof(SendViewCell));
public static readonly BindableProperty ShowOptionsProperty = BindableProperty.Create( public static readonly BindableProperty ShowOptionsProperty = BindableProperty.Create(
nameof(ShowOptions), typeof(bool), typeof(SendViewCell), true, BindingMode.OneWay); nameof(ShowOptions), typeof(bool), typeof(SendViewCell), true, BindingMode.OneWay);

View File

@@ -4,8 +4,8 @@ namespace Bit.App.Effects
{ {
public class FabShadowEffect : RoutingEffect public class FabShadowEffect : RoutingEffect
{ {
public FabShadowEffect() public FabShadowEffect()
: base("Bitwarden.FabShadowEffect") : base("Bitwarden.FabShadowEffect")
{ } { }
} }
} }

View File

@@ -1,12 +1,12 @@
using Bit.App.Resources; using System.Collections.Generic;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using Xamarin.Essentials; using Xamarin.Essentials;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -66,7 +66,7 @@ namespace Bit.App.Pages
get => _policy; get => _policy;
set => SetProperty(ref _policy, value); set => SetProperty(ref _policy, value);
} }
public string ShowPasswordIcon => ShowPassword ? "" : ""; public string ShowPasswordIcon => ShowPassword ? "" : "";
public string MasterPassword { get; set; } public string MasterPassword { get; set; }
public string ConfirmMasterPassword { get; set; } public string ConfirmMasterPassword { get; set; }
@@ -84,7 +84,7 @@ namespace Bit.App.Pages
await CheckPasswordPolicy(); await CheckPasswordPolicy();
} }
} }
private async Task CheckPasswordPolicy() private async Task CheckPasswordPolicy()
{ {
Policy = await _policyService.GetMasterPasswordPolicyOptions(); Policy = await _policyService.GetMasterPasswordPolicyOptions();
@@ -166,7 +166,7 @@ namespace Bit.App.Pages
AppResources.AnErrorHasOccurred, AppResources.Ok); AppResources.AnErrorHasOccurred, AppResources.Ok);
return false; return false;
} }
return true; return true;
} }

View File

@@ -14,7 +14,7 @@
<ContentPage.ToolbarItems> <ContentPage.ToolbarItems>
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" /> <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> </ContentPage.ToolbarItems>
<ScrollView> <ScrollView>
@@ -34,7 +34,8 @@
Placeholder="ex. https://bitwarden.company.com" Placeholder="ex. https://bitwarden.company.com"
StyleClass="box-value" StyleClass="box-value"
ReturnType="Go" ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" /> ReturnCommand="{Binding SubmitCommand}"
AutomationId="server_input"/>
</StackLayout> </StackLayout>
<Label <Label
Text="{u:I18n SelfHostedEnvironmentFooter}" Text="{u:I18n SelfHostedEnvironmentFooter}"

View File

@@ -1,8 +1,8 @@
using Bit.Core.Abstractions; using System;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -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.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -1,9 +1,9 @@
using Bit.App.Abstractions; using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -23,7 +23,7 @@
Priority="-1" Priority="-1"
UseOriginalImage="True" UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True" AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" /> AutomationProperties.Name="{u:I18n Account}"/>
<ToolbarItem <ToolbarItem
Icon="cog_environment.png" Clicked="Environment_Clicked" Order="Primary" Icon="cog_environment.png" Clicked="Environment_Clicked" Order="Primary"
AutomationProperties.IsInAccessibleTree="True" AutomationProperties.IsInAccessibleTree="True"
@@ -37,15 +37,18 @@
<Image <Image
x:Name="_logo" x:Name="_logo"
Source="logo.png" Source="logo.png"
VerticalOptions="Center" /> VerticalOptions="Center"
AutomationId="logo_image"
/>
<Label Text="{u:I18n LoginOrCreateNewAccount}" <Label Text="{u:I18n LoginOrCreateNewAccount}"
StyleClass="text-lg" StyleClass="text-lg"
HorizontalTextAlignment="Center"> HorizontalTextAlignment="Center"/>
</Label>
<StackLayout Spacing="5"> <StackLayout Spacing="5">
<Button Text="{u:I18n LogIn}" <Button Text="{u:I18n LogIn}"
StyleClass="btn-primary" StyleClass="btn-primary"
Clicked="LogIn_Clicked" /> Clicked="LogIn_Clicked"
AutomationId="homepage_login_button"/>
<Button Text="{u:I18n CreateAccount}" <Button Text="{u:I18n CreateAccount}"
Clicked="Register_Clicked" /> Clicked="Register_Clicked" />
<Button Text="{u:I18n LogInSso}" <Button Text="{u:I18n LogInSso}"

View File

@@ -87,7 +87,7 @@ namespace Bit.App.Pages
{ {
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png"; _logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
} }
private void Cancel_Clicked(object sender, EventArgs e) private void Cancel_Clicked(object sender, EventArgs e)
{ {
if (DoOnce()) if (DoOnce())
@@ -117,7 +117,7 @@ namespace Bit.App.Pages
_vm.StartRegisterAction(); _vm.StartRegisterAction();
} }
} }
private async Task StartRegisterAsync() private async Task StartRegisterAsync()
{ {
var page = new RegisterPage(this); var page = new RegisterPage(this);
@@ -145,7 +145,7 @@ namespace Bit.App.Pages
_vm.StartEnvironmentAction(); _vm.StartEnvironmentAction();
} }
} }
private async Task StartEnvironmentAsync() private async Task StartEnvironmentAsync()
{ {
await _accountListOverlay.HideAsync(); await _accountListOverlay.HideAsync();

View File

@@ -272,7 +272,7 @@ namespace Bit.App.Pages
var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdf, kdfIterations); var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdf, kdfIterations);
var storedKeyHash = await _cryptoService.GetKeyHashAsync(); var storedKeyHash = await _cryptoService.GetKeyHashAsync();
var passwordValid = false; var passwordValid = false;
if (storedKeyHash != null) if (storedKeyHash != null)
{ {
passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(MasterPassword, key); passwordValid = await _cryptoService.CompareAndUpdateKeyHashAsync(MasterPassword, key);

View File

@@ -56,7 +56,8 @@
x:Name="_email" x:Name="_email"
Text="{Binding Email}" Text="{Binding Email}"
Keyboard="Email" Keyboard="Email"
StyleClass="box-value"> StyleClass="box-value"
AutomationId="email_input">
<VisualStateManager.VisualStateGroups> <VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates"> <VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled"> <VisualState x:Name="Disabled">
@@ -92,7 +93,8 @@
Grid.Row="1" Grid.Row="1"
Grid.Column="0" Grid.Column="0"
ReturnType="Go" ReturnType="Go"
ReturnCommand="{Binding LogInCommand}" /> ReturnCommand="{Binding LogInCommand}"
AutomationId="password_input"/>
<controls:IconButton <controls:IconButton
StyleClass="box-row-button, box-row-button-platform" StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}" Text="{Binding ShowPasswordIcon}"
@@ -107,10 +109,12 @@
<StackLayout Padding="10, 0"> <StackLayout Padding="10, 0">
<Button Text="{u:I18n LogIn}" <Button Text="{u:I18n LogIn}"
StyleClass="btn-primary" StyleClass="btn-primary"
Clicked="LogIn_Clicked" /> Clicked="LogIn_Clicked"
AutomationId="loginpage_login_button"/>
<Button Text="{u:I18n Cancel}" <Button Text="{u:I18n Cancel}"
IsVisible="{Binding ShowCancelButton}" IsVisible="{Binding ShowCancelButton}"
Clicked="Cancel_Clicked" /> Clicked="Cancel_Clicked"
AutomationId="cancel_button"/>
</StackLayout> </StackLayout>
</StackLayout> </StackLayout>
</ScrollView> </ScrollView>

View File

@@ -177,7 +177,7 @@ namespace Bit.App.Pages
var previousPage = await AppHelpers.ClearPreviousPage(); var previousPage = await AppHelpers.ClearPreviousPage();
Application.Current.MainPage = new TabsPage(_appOptions, previousPage); Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
} }
private async Task UpdateTempPasswordAsync() private async Task UpdateTempPasswordAsync()
{ {
var page = new UpdateTempPasswordPage(); var page = new UpdateTempPasswordPage();

View File

@@ -67,7 +67,7 @@ namespace Bit.App.Pages
get => _showCancelButton; get => _showCancelButton;
set => SetProperty(ref _showCancelButton, value); set => SetProperty(ref _showCancelButton, value);
} }
public string Email public string Email
{ {
get => _email; get => _email;

View File

@@ -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.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -99,7 +99,7 @@ namespace Bit.App.Pages
var page = new SetPasswordPage(_appOptions, _vm.OrgIdentifier); var page = new SetPasswordPage(_appOptions, _vm.OrgIdentifier);
await Navigation.PushModalAsync(new NavigationPage(page)); await Navigation.PushModalAsync(new NavigationPage(page));
} }
private async Task UpdateTempPasswordAsync() private async Task UpdateTempPasswordAsync()
{ {
var page = new UpdateTempPasswordPage(); var page = new UpdateTempPasswordPage();

View File

@@ -1,13 +1,13 @@
using Bit.App.Abstractions; using System;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using Xamarin.Essentials; using Xamarin.Essentials;
using Xamarin.Forms; using Xamarin.Forms;
@@ -170,7 +170,7 @@ namespace Bit.App.Pages
else if (response.ResetMasterPassword) else if (response.ResetMasterPassword)
{ {
StartSetPasswordAction?.Invoke(); StartSetPasswordAction?.Invoke();
} }
else if (response.ForcePasswordReset) else if (response.ForcePasswordReset)
{ {
UpdateTempPasswordAction?.Invoke(); UpdateTempPasswordAction?.Invoke();

View File

@@ -55,7 +55,7 @@ namespace Bit.App.Pages
await _vm.SubmitAsync(); await _vm.SubmitAsync();
} }
} }
private async Task RegistrationSuccessAsync(HomePage homePage) private async Task RegistrationSuccessAsync(HomePage homePage)
{ {
if (homePage != null) if (homePage != null)

View File

@@ -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.App.Resources;
using Bit.Core;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Request; using Bit.Core.Models.Request;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.Core;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -39,7 +39,7 @@ namespace Bit.App.Pages
SubmitCommand = new Command(async () => await SubmitAsync()); SubmitCommand = new Command(async () => await SubmitAsync());
ShowTerms = !_platformUtilsService.IsSelfHost(); ShowTerms = !_platformUtilsService.IsSelfHost();
} }
public ICommand PoliciesClickCommand => new Command<string>((url) => public ICommand PoliciesClickCommand => new Command<string>((url) =>
{ {
_platformUtilsService.LaunchUri(url); _platformUtilsService.LaunchUri(url);
@@ -54,20 +54,20 @@ namespace Bit.App.Pages
nameof(ShowPasswordIcon) nameof(ShowPasswordIcon)
}); });
} }
public bool AcceptPolicies public bool AcceptPolicies
{ {
get => _acceptPolicies; get => _acceptPolicies;
set => SetProperty(ref _acceptPolicies, value); set => SetProperty(ref _acceptPolicies, value);
} }
public Thickness SwitchMargin public Thickness SwitchMargin
{ {
get => Device.RuntimePlatform == Device.Android get => Device.RuntimePlatform == Device.Android
? new Thickness(0, 0, 0, 0) ? new Thickness(0, 0, 0, 0)
: new Thickness(0, 0, 10, 0); : new Thickness(0, 0, 10, 0);
} }
public bool ShowTerms { get; set; } public bool ShowTerms { get; set; }
public Command SubmitCommand { get; } public Command SubmitCommand { get; }
public Command TogglePasswordCommand { get; } public Command TogglePasswordCommand { get; }
@@ -136,7 +136,7 @@ namespace Bit.App.Pages
} }
// TODO: Password strength check? // TODO: Password strength check?
if (showLoading) if (showLoading)
{ {
await _deviceActionService.ShowLoadingAsync(AppResources.CreatingAccount); await _deviceActionService.ShowLoadingAsync(AppResources.CreatingAccount);

View File

@@ -1,17 +1,17 @@
using Bit.App.Abstractions; using System;
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.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core; using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Models.Request;
using Bit.Core.Utilities;
using Xamarin.Essentials; using Xamarin.Essentials;
using Xamarin.Forms; using Xamarin.Forms;
@@ -63,7 +63,7 @@ namespace Bit.App.Pages
get => _isPolicyInEffect; get => _isPolicyInEffect;
set => SetProperty(ref _isPolicyInEffect, value); set => SetProperty(ref _isPolicyInEffect, value);
} }
public bool ResetPasswordAutoEnroll public bool ResetPasswordAutoEnroll
{ {
get => _resetPasswordAutoEnroll; get => _resetPasswordAutoEnroll;
@@ -220,7 +220,7 @@ namespace Bit.App.Pages
// Enroll user // Enroll user
await _apiService.PutOrganizationUserResetPasswordEnrollmentAsync(OrgId, userId, resetRequest); await _apiService.PutOrganizationUserResetPasswordEnrollmentAsync(OrgId, userId, resetRequest);
} }
await _deviceActionService.HideLoadingAsync(); await _deviceActionService.HideLoadingAsync();
SetPasswordSuccessAction?.Invoke(); SetPasswordSuccessAction?.Invoke();
} }

View File

@@ -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.Models;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -47,7 +47,8 @@ namespace Bit.App.Pages
if (Device.RuntimePlatform == Device.iOS) if (Device.RuntimePlatform == Device.iOS)
{ {
ToolbarItems.Add(_moreItem); ToolbarItems.Add(_moreItem);
} else }
else
{ {
ToolbarItems.Add(_useAnotherTwoStepMethod); ToolbarItems.Add(_useAnotherTwoStepMethod);
} }
@@ -92,7 +93,8 @@ namespace Bit.App.Pages
if (_vm.TotpMethod) if (_vm.TotpMethod)
{ {
RequestFocus(_totpEntry); RequestFocus(_totpEntry);
} else if (_vm.YubikeyMethod) }
else if (_vm.YubikeyMethod)
{ {
RequestFocus(_yubikeyTokenEntry); RequestFocus(_yubikeyTokenEntry);
} }
@@ -187,7 +189,7 @@ namespace Bit.App.Pages
var page = new SetPasswordPage(_appOptions, _orgIdentifier); var page = new SetPasswordPage(_appOptions, _orgIdentifier);
await Navigation.PushModalAsync(new NavigationPage(page)); await Navigation.PushModalAsync(new NavigationPage(page));
} }
private async Task UpdateTempPasswordAsync() private async Task UpdateTempPasswordAsync()
{ {
var page = new UpdateTempPasswordPage(); var page = new UpdateTempPasswordPage();

View File

@@ -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.Resources;
using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Request; using Bit.Core.Models.Request;
using Bit.Core.Utilities; 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 Newtonsoft.Json;
using Xamarin.Essentials; using Xamarin.Essentials;
using Xamarin.Forms; using Xamarin.Forms;
@@ -113,7 +113,7 @@ namespace Bit.App.Pages
public Action StartSetPasswordAction { get; set; } public Action StartSetPasswordAction { get; set; }
public Action CloseAction { get; set; } public Action CloseAction { get; set; }
public Action UpdateTempPasswordAction { get; set; } public Action UpdateTempPasswordAction { get; set; }
protected override II18nService i18nService => _i18nService; protected override II18nService i18nService => _i18nService;
protected override IEnvironmentService environmentService => _environmentService; protected override IEnvironmentService environmentService => _environmentService;
protected override IDeviceActionService deviceActionService => _deviceActionService; protected override IDeviceActionService deviceActionService => _deviceActionService;
@@ -293,7 +293,7 @@ namespace Bit.App.Pages
await _deviceActionService.ShowLoadingAsync(AppResources.Validating); await _deviceActionService.ShowLoadingAsync(AppResources.Validating);
} }
var result = await _authService.LogInTwoFactorAsync(SelectedProviderType.Value, Token, _captchaToken, Remember); var result = await _authService.LogInTwoFactorAsync(SelectedProviderType.Value, Token, _captchaToken, Remember);
if (result.CaptchaNeeded) if (result.CaptchaNeeded)
{ {
if (await HandleCaptchaAsync(result.CaptchaSiteKey)) if (await HandleCaptchaAsync(result.CaptchaSiteKey))
@@ -304,12 +304,12 @@ namespace Bit.App.Pages
return; return;
} }
_captchaToken = null; _captchaToken = null;
var task = Task.Run(() => _syncService.FullSyncAsync(true)); var task = Task.Run(() => _syncService.FullSyncAsync(true));
await _deviceActionService.HideLoadingAsync(); await _deviceActionService.HideLoadingAsync();
_messagingService.Send("listenYubiKeyOTP", false); _messagingService.Send("listenYubiKeyOTP", false);
_broadcasterService.Unsubscribe(nameof(TwoFactorPage)); _broadcasterService.Unsubscribe(nameof(TwoFactorPage));
if (_authingWithSso && result.ResetMasterPassword) if (_authingWithSso && result.ResetMasterPassword)
{ {
StartSetPasswordAction?.Invoke(); StartSetPasswordAction?.Invoke();
@@ -317,7 +317,7 @@ namespace Bit.App.Pages
else if (result.ForcePasswordReset) else if (result.ForcePasswordReset)
{ {
UpdateTempPasswordAction?.Invoke(); UpdateTempPasswordAction?.Invoke();
} }
else else
{ {
TwoFactorAuthSuccessAction?.Invoke(); TwoFactorAuthSuccessAction?.Invoke();

View File

@@ -1,7 +1,7 @@
using System;
using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using Bit.App.Resources;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -14,29 +14,29 @@ namespace Bit.App.Pages
private readonly string _pageName; private readonly string _pageName;
public UpdateTempPasswordPage() public UpdateTempPasswordPage()
{ {
// Service Init // Service Init
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService"); _messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"); _platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
// Binding // Binding
InitializeComponent(); InitializeComponent();
_pageName = string.Concat(nameof(UpdateTempPasswordPage), "_", DateTime.UtcNow.Ticks); _pageName = string.Concat(nameof(UpdateTempPasswordPage), "_", DateTime.UtcNow.Ticks);
_vm = BindingContext as UpdateTempPasswordPageViewModel; _vm = BindingContext as UpdateTempPasswordPageViewModel;
_vm.Page = this; _vm.Page = this;
SetActivityIndicator(); SetActivityIndicator();
// Actions Declaration // Actions Declaration
_vm.LogOutAction = () => _vm.LogOutAction = () =>
{ {
_messagingService.Send("logout"); _messagingService.Send("logout");
}; };
_vm.UpdateTempPasswordSuccessAction = () => Device.BeginInvokeOnMainThread(UpdateTempPasswordSuccess); _vm.UpdateTempPasswordSuccessAction = () => Device.BeginInvokeOnMainThread(UpdateTempPasswordSuccess);
// Link fields that will be referenced in codebehind // Link fields that will be referenced in codebehind
MasterPasswordEntry = _masterPassword; MasterPasswordEntry = _masterPassword;
ConfirmMasterPasswordEntry = _confirmMasterPassword; ConfirmMasterPasswordEntry = _confirmMasterPassword;
// Return Types and Commands // Return Types and Commands
_masterPassword.ReturnType = ReturnType.Next; _masterPassword.ReturnType = ReturnType.Next;
_masterPassword.ReturnCommand = new Command(() => _confirmMasterPassword.Focus()); _masterPassword.ReturnCommand = new Command(() => _confirmMasterPassword.Focus());
@@ -77,7 +77,7 @@ namespace Bit.App.Pages
} }
} }
} }
private void UpdateTempPasswordSuccess() private void UpdateTempPasswordSuccess()
{ {
_messagingService.Send("logout"); _messagingService.Send("logout");

View File

@@ -1,6 +1,6 @@
using Bit.App.Resources; using System;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Request; using Bit.Core.Models.Request;
using Xamarin.Forms; using Xamarin.Forms;
@@ -16,7 +16,7 @@ namespace Bit.App.Pages
ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword); ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword);
SubmitCommand = new Command(async () => await SubmitAsync()); SubmitCommand = new Command(async () => await SubmitAsync());
} }
public Command SubmitCommand { get; } public Command SubmitCommand { get; }
public Command TogglePasswordCommand { get; } public Command TogglePasswordCommand { get; }
public Command ToggleConfirmPasswordCommand { get; } public Command ToggleConfirmPasswordCommand { get; }
@@ -37,23 +37,23 @@ namespace Bit.App.Pages
public async Task SubmitAsync() public async Task SubmitAsync()
{ {
if (!await ValidateMasterPasswordAsync()) if (!await ValidateMasterPasswordAsync())
{ {
return; return;
} }
// Retrieve details for key generation // Retrieve details for key generation
var kdf = await _stateService.GetKdfTypeAsync(); var kdf = await _stateService.GetKdfTypeAsync();
var kdfIterations = await _stateService.GetKdfIterationsAsync(); var kdfIterations = await _stateService.GetKdfIterationsAsync();
var email = await _stateService.GetEmailAsync(); var email = await _stateService.GetEmailAsync();
// Create new key and hash new password // Create new key and hash new password
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations); var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations);
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key); var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key);
// Create new encKey for the User // Create new encKey for the User
var newEncKey = await _cryptoService.RemakeEncKeyAsync(key); var newEncKey = await _cryptoService.RemakeEncKeyAsync(key);
// Create request // Create request
var request = new UpdateTempPasswordRequest var request = new UpdateTempPasswordRequest
{ {
@@ -61,7 +61,7 @@ namespace Bit.App.Pages
NewMasterPasswordHash = masterPasswordHash, NewMasterPasswordHash = masterPasswordHash,
MasterPasswordHint = Hint MasterPasswordHint = Hint
}; };
// Initiate API action // Initiate API action
try try
{ {

View File

@@ -36,7 +36,7 @@ namespace Bit.App.Pages
_logger = ServiceContainer.Resolve<ILogger>("logger"); _logger = ServiceContainer.Resolve<ILogger>("logger");
PageTitle = AppResources.VerificationCode; PageTitle = AppResources.VerificationCode;
TogglePasswordCommand = new Command(TogglePassword); TogglePasswordCommand = new Command(TogglePassword);
MainActionCommand = new AsyncCommand(MainActionAsync, allowsMultipleExecutions: false); MainActionCommand = new AsyncCommand(MainActionAsync, allowsMultipleExecutions: false);
RequestOTPCommand = new AsyncCommand(RequestOTPAsync, allowsMultipleExecutions: false); RequestOTPCommand = new AsyncCommand(RequestOTPAsync, allowsMultipleExecutions: false);
@@ -60,7 +60,7 @@ namespace Bit.App.Pages
get => _mainActionText; get => _mainActionText;
set => SetProperty(ref _mainActionText, value); set => SetProperty(ref _mainActionText, value);
} }
public string SendCodeStatus public string SendCodeStatus
{ {
get => _sendCodeStatus; get => _sendCodeStatus;

View File

@@ -35,12 +35,12 @@ namespace Bit.App.Pages
protected async override void OnAppearing() protected async override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
if (IsThemeDirty) if (IsThemeDirty)
{ {
UpdateOnThemeChanged(); UpdateOnThemeChanged();
} }
await SaveActivityAsync(); await SaveActivityAsync();
} }
@@ -70,6 +70,7 @@ namespace Bit.App.Pages
VerticalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center,
Color = ThemeManager.GetResourceColor("PrimaryColor"), Color = ThemeManager.GetResourceColor("PrimaryColor"),
AutomationId = "activity_indicator"
}; };
if (targetView != null) if (targetView != null)
{ {

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;

View File

@@ -31,7 +31,8 @@ namespace Bit.App.Pages
{ {
base.OnAppearing(); base.OnAppearing();
await LoadOnAppearedAsync(_mainLayout, true, async () => { await LoadOnAppearedAsync(_mainLayout, true, async () =>
{
await _vm.InitAsync(); await _vm.InitAsync();
}); });
} }

View File

@@ -12,7 +12,7 @@ namespace Bit.App.Pages
public partial class GeneratorPage : BaseContentPage, IThemeDirtablePage public partial class GeneratorPage : BaseContentPage, IThemeDirtablePage
{ {
private readonly IBroadcasterService _broadcasterService; private readonly IBroadcasterService _broadcasterService;
private GeneratorPageViewModel _vm; private GeneratorPageViewModel _vm;
private readonly bool _fromTabPage; private readonly bool _fromTabPage;
private readonly Action<string> _selectAction; private readonly Action<string> _selectAction;
@@ -77,7 +77,7 @@ namespace Bit.App.Pages
} }
}); });
} }
protected override void OnDisappearing() protected override void OnDisappearing()
{ {
base.OnDisappearing(); base.OnDisappearing();

View File

@@ -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.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -225,7 +225,7 @@ namespace Bit.App.Pages
} }
} }
} }
public PasswordGeneratorPolicyOptions EnforcedPolicyOptions public PasswordGeneratorPolicyOptions EnforcedPolicyOptions
{ {
get => _enforcedPolicyOptions; get => _enforcedPolicyOptions;

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Models; using Bit.App.Models;
@@ -337,10 +337,10 @@ namespace Bit.App.Pages
_vm.IsAddFromShare = true; _vm.IsAddFromShare = true;
_vm.CopyInsteadOfShareAfterSaving = _appOptions.CopyInsteadOfShareAfterSaving; _vm.CopyInsteadOfShareAfterSaving = _appOptions.CopyInsteadOfShareAfterSaving;
var name = _appOptions.CreateSend.Item2; var name = _appOptions.CreateSend.Item2;
_vm.Send.Name = name; _vm.Send.Name = name;
var type = _appOptions.CreateSend.Item1; var type = _appOptions.CreateSend.Item1;
if (type == SendType.File) if (type == SendType.File)
{ {

View File

@@ -40,7 +40,7 @@ namespace Bit.App.Pages
private TimeSpan? _expirationTime; private TimeSpan? _expirationTime;
private bool _isOverridingPickers; private bool _isOverridingPickers;
private int? _maxAccessCount; private int? _maxAccessCount;
private string[] _additionalSendProperties = new [] private string[] _additionalSendProperties = new[]
{ {
nameof(IsText), nameof(IsText),
nameof(IsFile), nameof(IsFile),
@@ -209,7 +209,7 @@ namespace Bit.App.Pages
{ {
get => _showPassword; get => _showPassword;
set => SetProperty(ref _showPassword, value, set => SetProperty(ref _showPassword, value,
additionalPropertyNames: new [] additionalPropertyNames: new[]
{ {
nameof(ShowPasswordIcon) nameof(ShowPasswordIcon)
}); });
@@ -237,7 +237,7 @@ namespace Bit.App.Pages
PageTitle = EditMode ? AppResources.EditSend : AppResources.AddSend; PageTitle = EditMode ? AppResources.EditSend : AppResources.AddSend;
_canAccessPremium = await _stateService.CanAccessPremiumAsync(); _canAccessPremium = await _stateService.CanAccessPremiumAsync();
_emailVerified = await _stateService.GetEmailVerifiedAsync(); _emailVerified = await _stateService.GetEmailVerifiedAsync();
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync(); SendEnabled = !await AppHelpers.IsSendDisabledByPolicyAsync();
DisableHideEmail = await AppHelpers.IsHideEmailDisabledByPolicyAsync(); DisableHideEmail = await AppHelpers.IsHideEmailDisabledByPolicyAsync();
SendOptionsPolicyInEffect = SendEnabled && DisableHideEmail; SendOptionsPolicyInEffect = SendEnabled && DisableHideEmail;
} }
@@ -381,7 +381,7 @@ namespace Bit.App.Pages
UpdateSendData(); UpdateSendData();
if (string.IsNullOrWhiteSpace(NewPassword)) if (string.IsNullOrWhiteSpace(NewPassword))
{ {
NewPassword = null; NewPassword = null;
} }
@@ -521,7 +521,7 @@ namespace Bit.App.Pages
{ {
await _platformUtilsService.ShowDialogAsync(AppResources.SendFileEmailVerificationRequired); await _platformUtilsService.ShowDialogAsync(AppResources.SendFileEmailVerificationRequired);
} }
if (IsAddFromShare && Device.RuntimePlatform == Device.Android) if (IsAddFromShare && Device.RuntimePlatform == Device.Android)
{ {
_deviceActionService.CloseMainApp(); _deviceActionService.CloseMainApp();

View File

@@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Controls; using Bit.App.Controls;
@@ -133,7 +133,7 @@ namespace Bit.App.Pages
} }
} }
} }
private async void RowSelected(object sender, SelectionChangedEventArgs e) private async void RowSelected(object sender, SelectionChangedEventArgs e)
{ {
((ExtendedCollectionView)sender).SelectedItem = null; ((ExtendedCollectionView)sender).SelectedItem = null;
@@ -160,7 +160,7 @@ namespace Bit.App.Pages
{ {
if (DoOnce()) 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)); await Navigation.PushModalAsync(new NavigationPage(page));
} }
} }
@@ -174,7 +174,7 @@ namespace Bit.App.Pages
{ {
await _vaultTimeoutService.LockAsync(true, true); await _vaultTimeoutService.LockAsync(true, true);
} }
private void About_Clicked(object sender, EventArgs e) private void About_Clicked(object sender, EventArgs e)
{ {
_vm.ShowAbout(); _vm.ShowAbout();

View File

@@ -9,6 +9,6 @@
} }
public string Title { get; } public string Title { get; }
public string ItemCount { get; } public string ItemCount { get; }
} }
} }

View File

@@ -136,7 +136,7 @@ namespace Bit.App.Pages
ShowNoData = false; ShowNoData = false;
Loading = true; Loading = true;
ShowList = false; ShowList = false;
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync(); SendEnabled = !await AppHelpers.IsSendDisabledByPolicyAsync();
var groupedSends = new List<SendGroupingsPageListGroup>(); var groupedSends = new List<SendGroupingsPageListGroup>();
var page = Page as SendGroupingsPage; var page = Page as SendGroupingsPage;

View File

@@ -2,6 +2,7 @@
using System.Linq; using System.Linq;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Enums;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Xamarin.Forms; using Xamarin.Forms;
@@ -12,15 +13,22 @@ namespace Bit.App.Pages
private SendsPageViewModel _vm; private SendsPageViewModel _vm;
private bool _hasFocused; private bool _hasFocused;
public SendsPage(Func<SendView, bool> filter, bool type = false) public SendsPage(Func<SendView, bool> filter, SendType? type = null)
{ {
InitializeComponent(); InitializeComponent();
_vm = BindingContext as SendsPageViewModel; _vm = BindingContext as SendsPageViewModel;
_vm.Page = this; _vm.Page = this;
_vm.Filter = filter; _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 else
{ {
@@ -33,6 +41,7 @@ namespace Bit.App.Pages
_searchBar.Placeholder = AppResources.Search; _searchBar.Placeholder = AppResources.Search;
_mainLayout.Children.Insert(0, _searchBar); _mainLayout.Children.Insert(0, _searchBar);
_mainLayout.Children.Insert(1, _separator); _mainLayout.Children.Insert(1, _separator);
ShowModalAnimationDelay = 0;
} }
else else
{ {

View File

@@ -35,11 +35,11 @@ namespace Bit.App.Pages
get => _sendEnabled; get => _sendEnabled;
set => SetProperty(ref _sendEnabled, value); set => SetProperty(ref _sendEnabled, value);
} }
public bool ShowNoData public bool ShowNoData
{ {
get => _showNoData; get => _showNoData;
set => SetProperty(ref _showNoData, value, additionalPropertyNames: new [] set => SetProperty(ref _showNoData, value, additionalPropertyNames: new[]
{ {
nameof(ShowSearchDirection) nameof(ShowSearchDirection)
}); });
@@ -48,7 +48,7 @@ namespace Bit.App.Pages
public bool ShowList public bool ShowList
{ {
get => _showList; get => _showList;
set => SetProperty(ref _showList, value, additionalPropertyNames: new [] set => SetProperty(ref _showList, value, additionalPropertyNames: new[]
{ {
nameof(ShowSearchDirection) nameof(ShowSearchDirection)
}); });
@@ -58,7 +58,7 @@ namespace Bit.App.Pages
public async Task InitAsync() public async Task InitAsync()
{ {
SendEnabled = ! await AppHelpers.IsSendDisabledByPolicyAsync(); SendEnabled = !await AppHelpers.IsSendDisabledByPolicyAsync();
if (!string.IsNullOrWhiteSpace((Page as SendsPage).SearchBar.Text)) if (!string.IsNullOrWhiteSpace((Page as SendsPage).SearchBar.Text))
{ {
Search((Page as SendsPage).SearchBar.Text, 200); Search((Page as SendsPage).SearchBar.Text, 200);

View File

@@ -49,12 +49,12 @@ namespace Bit.App.Pages
_vm.ToggleAutofillService(); _vm.ToggleAutofillService();
} }
} }
private void ToggleInlineAutofill(object sender, EventArgs e) private void ToggleInlineAutofill(object sender, EventArgs e)
{ {
_vm.ToggleInlineAutofill(); _vm.ToggleInlineAutofill();
} }
private void ToggleAccessibility(object sender, EventArgs e) private void ToggleAccessibility(object sender, EventArgs e)
{ {
if (DoOnce()) if (DoOnce())
@@ -62,7 +62,7 @@ namespace Bit.App.Pages
_vm.ToggleAccessibility(); _vm.ToggleAccessibility();
} }
} }
private void ToggleDrawOver(object sender, EventArgs e) private void ToggleDrawOver(object sender, EventArgs e)
{ {
if (DoOnce()) if (DoOnce())

View File

@@ -12,7 +12,7 @@ namespace Bit.App.Pages
private readonly IDeviceActionService _deviceActionService; private readonly IDeviceActionService _deviceActionService;
private readonly IStateService _stateService; private readonly IStateService _stateService;
private readonly MobileI18nService _i18nService; private readonly MobileI18nService _i18nService;
private bool _autofillServiceToggled; private bool _autofillServiceToggled;
private bool _inlineAutofillToggled; private bool _inlineAutofillToggled;
private bool _accessibilityToggled; private bool _accessibilityToggled;
@@ -26,9 +26,9 @@ namespace Bit.App.Pages
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService; _i18nService = ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService;
PageTitle = AppResources.AutofillServices; PageTitle = AppResources.AutofillServices;
} }
#region Autofill Service #region Autofill Service
public bool AutofillServiceVisible public bool AutofillServiceVisible
{ {
get => _deviceActionService.SystemMajorVersion() >= 26; get => _deviceActionService.SystemMajorVersion() >= 26;
@@ -43,16 +43,16 @@ namespace Bit.App.Pages
nameof(InlineAutofillEnabled) nameof(InlineAutofillEnabled)
}); });
} }
#endregion #endregion
#region Inline Autofill #region Inline Autofill
public bool InlineAutofillVisible public bool InlineAutofillVisible
{ {
get => _deviceActionService.SystemMajorVersion() >= 30; get => _deviceActionService.SystemMajorVersion() >= 30;
} }
public bool InlineAutofillEnabled public bool InlineAutofillEnabled
{ {
get => AutofillServiceToggled; get => AutofillServiceToggled;
@@ -69,9 +69,9 @@ namespace Bit.App.Pages
} }
} }
} }
#endregion #endregion
#region Accessibility #region Accessibility
public string AccessibilityDescriptionLabel public string AccessibilityDescriptionLabel
@@ -97,7 +97,7 @@ namespace Bit.App.Pages
return _i18nService.T("AccessibilityDescription4"); return _i18nService.T("AccessibilityDescription4");
} }
} }
public bool AccessibilityToggled public bool AccessibilityToggled
{ {
get => _accessibilityToggled; get => _accessibilityToggled;
@@ -109,9 +109,9 @@ namespace Bit.App.Pages
} }
#endregion #endregion
#region Draw-Over #region Draw-Over
public bool DrawOverVisible public bool DrawOverVisible
{ {
get => _deviceActionService.SystemMajorVersion() >= 23; get => _deviceActionService.SystemMajorVersion() >= 23;
@@ -135,12 +135,12 @@ namespace Bit.App.Pages
return _i18nService.T("DrawOverDescription3"); return _i18nService.T("DrawOverDescription3");
} }
} }
public bool DrawOverEnabled public bool DrawOverEnabled
{ {
get => AccessibilityToggled; get => AccessibilityToggled;
} }
public bool DrawOverToggled public bool DrawOverToggled
{ {
get => _drawOverToggled; get => _drawOverToggled;
@@ -148,7 +148,7 @@ namespace Bit.App.Pages
} }
#endregion #endregion
public async Task InitAsync() public async Task InitAsync()
{ {
InlineAutofillToggled = await _stateService.GetInlineAutofillEnabledAsync() ?? true; InlineAutofillToggled = await _stateService.GetInlineAutofillEnabledAsync() ?? true;
@@ -189,7 +189,7 @@ namespace Bit.App.Pages
} }
_deviceActionService.OpenAccessibilityOverlayPermissionSettings(); _deviceActionService.OpenAccessibilityOverlayPermissionSettings();
} }
public void UpdateEnabled() public void UpdateEnabled()
{ {
AutofillServiceToggled = AutofillServiceToggled =
@@ -197,7 +197,7 @@ namespace Bit.App.Pages
AccessibilityToggled = _deviceActionService.AutofillAccessibilityServiceRunning(); AccessibilityToggled = _deviceActionService.AutofillAccessibilityServiceRunning();
DrawOverToggled = _deviceActionService.AutofillAccessibilityOverlayPermitted(); DrawOverToggled = _deviceActionService.AutofillAccessibilityOverlayPermitted();
} }
private async Task UpdateInlineAutofillToggledAsync() private async Task UpdateInlineAutofillToggledAsync()
{ {
if (_inited) if (_inited)

View File

@@ -4,11 +4,11 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -77,7 +77,7 @@ namespace Bit.App.Pages
InstructionText = _i18nService.T("ExportVaultMasterPasswordDescription"); InstructionText = _i18nService.T("ExportVaultMasterPasswordDescription");
SecretName = _i18nService.T("MasterPassword"); SecretName = _i18nService.T("MasterPassword");
} }
UpdateWarning(); UpdateWarning();
} }
@@ -109,7 +109,7 @@ namespace Bit.App.Pages
{ {
get => _showPassword; get => _showPassword;
set => SetProperty(ref _showPassword, value, set => SetProperty(ref _showPassword, value,
additionalPropertyNames: new string[] {nameof(ShowPasswordIcon)}); additionalPropertyNames: new string[] { nameof(ShowPasswordIcon) });
} }
public bool UseOTPVerification public bool UseOTPVerification

View File

@@ -1,7 +1,7 @@
using Bit.App.Resources; using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Threading.Tasks;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {

View File

@@ -1,5 +1,5 @@
using Bit.App.Resources; using System.Collections.Generic;
using System.Collections.Generic; using Bit.App.Resources;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -1,10 +1,10 @@
using Bit.App.Abstractions; using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -1,7 +1,7 @@
using Bit.Core.Models.View; using System;
using System;
using System.Linq; using System.Linq;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.Core.Models.View;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -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.Abstractions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {

View File

@@ -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.App.Utilities;
using Bit.Core; using Bit.Core;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -59,7 +59,7 @@ namespace Bit.App.Pages
async void OnTimePickerPropertyChanged(object sender, PropertyChangedEventArgs args) async void OnTimePickerPropertyChanged(object sender, PropertyChangedEventArgs args)
{ {
var s = (TimePicker) sender; var s = (TimePicker)sender;
var time = s.Time.TotalMinutes; var time = s.Time.TotalMinutes;
if (s.IsFocused && args.PropertyName == "Time") if (s.IsFocused && args.PropertyName == "Time")
{ {

View File

@@ -1,16 +1,16 @@
using Bit.App.Abstractions; using System;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms; using Xamarin.Forms;
using ZXing.Client.Result; using ZXing.Client.Result;
using Xamarin.CommunityToolkit.ObjectModel;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {
@@ -428,7 +428,7 @@ namespace Bit.App.Pages
var securityItems = new List<SettingsPageListItem> var securityItems = new List<SettingsPageListItem>
{ {
new SettingsPageListItem { Name = AppResources.VaultTimeout, SubLabel = _vaultTimeoutDisplayValue }, new SettingsPageListItem { Name = AppResources.VaultTimeout, SubLabel = _vaultTimeoutDisplayValue },
new SettingsPageListItem new SettingsPageListItem
{ {
Name = AppResources.VaultTimeoutAction, Name = AppResources.VaultTimeoutAction,
SubLabel = _vaultTimeoutActionDisplayValue SubLabel = _vaultTimeoutActionDisplayValue

View File

@@ -1,9 +1,9 @@
using Bit.App.Abstractions; using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Threading.Tasks;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {

View File

@@ -12,7 +12,7 @@ namespace Bit.App.Pages
{ {
private readonly IMessagingService _messagingService; private readonly IMessagingService _messagingService;
private readonly IKeyConnectorService _keyConnectorService; private readonly IKeyConnectorService _keyConnectorService;
private NavigationPage _groupingsPage; private NavigationPage _groupingsPage;
private NavigationPage _sendGroupingsPage; private NavigationPage _sendGroupingsPage;
private NavigationPage _generatorPage; private NavigationPage _generatorPage;
@@ -93,7 +93,7 @@ namespace Bit.App.Pages
{ {
CurrentPage = _generatorPage; CurrentPage = _generatorPage;
} }
public void ResetToSendPage() public void ResetToSendPage()
{ {
CurrentPage = _sendGroupingsPage; CurrentPage = _sendGroupingsPage;

View File

@@ -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.Models;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Essentials; using Xamarin.Essentials;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration; using Xamarin.Forms.PlatformConfiguration;

View File

@@ -65,7 +65,7 @@ namespace Bit.App.Pages
new KeyValuePair<UriMatchType?, string>(UriMatchType.Exact, AppResources.Exact), new KeyValuePair<UriMatchType?, string>(UriMatchType.Exact, AppResources.Exact),
new KeyValuePair<UriMatchType?, string>(UriMatchType.Never, AppResources.Never) new KeyValuePair<UriMatchType?, string>(UriMatchType.Never, AppResources.Never)
}; };
public AddEditPageViewModel() public AddEditPageViewModel()
{ {
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"); _deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
@@ -350,7 +350,7 @@ namespace Bit.App.Pages
{ {
Cipher.Name += " - " + AppResources.Clone; Cipher.Name += " - " + AppResources.Clone;
// If not allowing personal ownership, update cipher's org Id to prompt downstream changes // 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; Cipher.OrganizationId = OrganizationId;
} }
@@ -399,7 +399,7 @@ namespace Bit.App.Pages
IdentityTitleOptions.FindIndex(k => k.Value == Cipher.Identity.Title); IdentityTitleOptions.FindIndex(k => k.Value == Cipher.Identity.Title);
OwnershipSelectedIndex = string.IsNullOrWhiteSpace(Cipher.OrganizationId) ? 0 : OwnershipSelectedIndex = string.IsNullOrWhiteSpace(Cipher.OrganizationId) ? 0 :
OwnershipOptions.FindIndex(k => k.Value == Cipher.OrganizationId); 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 the selected organization is on Index 0 and we've removed the personal option, force refresh
if (!AllowPersonal && OwnershipSelectedIndex == 0) if (!AllowPersonal && OwnershipSelectedIndex == 0)
{ {
@@ -451,11 +451,11 @@ namespace Bit.App.Pages
AppResources.Ok); AppResources.Ok);
return false; return false;
} }
if ((!EditMode || CloneMode) && !AllowPersonal && string.IsNullOrWhiteSpace(Cipher.OrganizationId)) if ((!EditMode || CloneMode) && !AllowPersonal && string.IsNullOrWhiteSpace(Cipher.OrganizationId))
{ {
await Page.DisplayAlert(AppResources.AnErrorHasOccurred, await Page.DisplayAlert(AppResources.AnErrorHasOccurred,
AppResources.PersonalOwnershipSubmitError,AppResources.Ok); AppResources.PersonalOwnershipSubmitError, AppResources.Ok);
return false; return false;
} }
@@ -535,7 +535,7 @@ namespace Bit.App.Pages
AppResources.AnErrorHasOccurred); AppResources.AnErrorHasOccurred);
} }
} }
catch(Exception genex) catch (Exception genex)
{ {
_logger.Exception(genex); _logger.Exception(genex);
await _deviceActionService.HideLoadingAsync(); await _deviceActionService.HideLoadingAsync();

View File

@@ -1,6 +1,6 @@
using Bit.Core.Abstractions; using System;
using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -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.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -15,7 +15,18 @@
</ContentPage.BindingContext> </ContentPage.BindingContext>
<ContentPage.ToolbarItems> <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.ToolbarItems>
<ContentPage.Resources> <ContentPage.Resources>
@@ -58,7 +69,7 @@
VerticalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
Padding="20, 0" Padding="20, 0"
Spacing="20" Spacing="20"
IsVisible="{Binding ShowList, Converter={StaticResource inverseBool}}"> IsVisible="{Binding ShowNoData}">
<Label <Label
Text="{Binding NoDataText}" Text="{Binding NoDataText}"
HorizontalTextAlignment="Center"></Label> HorizontalTextAlignment="Center"></Label>
@@ -88,6 +99,8 @@
AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"> AbsoluteLayout.LayoutBounds="0, 0, 1, 1">
</ContentView> </ContentView>
<!-- Android FAB -->
<Button <Button
x:Name="_fab" x:Name="_fab"
Image="plus.png" Image="plus.png"
@@ -99,6 +112,14 @@
<effects:FabShadowEffect /> <effects:FabShadowEffect />
</Button.Effects> </Button.Effects>
</Button> </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> </AbsoluteLayout>
</pages:BaseContentPage> </pages:BaseContentPage>

View File

@@ -1,13 +1,12 @@
using Bit.App.Models; using System;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Controls; using Bit.App.Controls;
using Bit.App.Models;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -15,7 +14,8 @@ namespace Bit.App.Pages
public partial class AutofillCiphersPage : BaseContentPage public partial class AutofillCiphersPage : BaseContentPage
{ {
private readonly AppOptions _appOptions; private readonly AppOptions _appOptions;
private readonly IPlatformUtilsService _platformUtilsService; private readonly IBroadcasterService _broadcasterService;
private readonly ISyncService _syncService;
private readonly IVaultTimeoutService _vaultTimeoutService; private readonly IVaultTimeoutService _vaultTimeoutService;
private AutofillCiphersPageViewModel _vm; private AutofillCiphersPageViewModel _vm;
@@ -24,17 +24,23 @@ namespace Bit.App.Pages
{ {
_appOptions = appOptions; _appOptions = appOptions;
InitializeComponent(); InitializeComponent();
SetActivityIndicator(_mainContent);
_vm = BindingContext as AutofillCiphersPageViewModel; _vm = BindingContext as AutofillCiphersPageViewModel;
_vm.Page = this; _vm.Page = this;
_vm.Init(appOptions); _vm.Init(appOptions);
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"); _broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService"); _vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
} }
protected async override void OnAppearing() protected async override void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
if (_syncService.SyncInProgress)
{
IsBusy = true;
}
if (!await AppHelpers.IsVaultTimeoutImmediateAsync()) if (!await AppHelpers.IsVaultTimeoutImmediateAsync())
{ {
await _vaultTimeoutService.CheckVaultTimeoutAsync(); await _vaultTimeoutService.CheckVaultTimeoutAsync();
@@ -43,13 +49,37 @@ namespace Bit.App.Pages
{ {
return; 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 () => await LoadOnAppearedAsync(_mainLayout, false, async () =>
{ {
try try
{ {
await _vm.LoadAsync(); 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 Task.Delay(1000);
await _vm.LoadAsync(); await _vm.LoadAsync();
@@ -59,6 +89,11 @@ namespace Bit.App.Pages
protected override bool OnBackButtonPressed() protected override bool OnBackButtonPressed()
{ {
if (_accountListOverlay.IsVisible)
{
_accountListOverlay.HideAsync().FireAndForget();
return true;
}
if (Device.RuntimePlatform == Device.Android) if (Device.RuntimePlatform == Device.Android)
{ {
_appOptions.Uri = null; _appOptions.Uri = null;
@@ -66,6 +101,13 @@ namespace Bit.App.Pages
return base.OnBackButtonPressed(); return base.OnBackButtonPressed();
} }
protected override void OnDisappearing()
{
base.OnDisappearing();
IsBusy = false;
_accountAvatar?.OnDisappearing();
}
private async void RowSelected(object sender, SelectionChangedEventArgs e) private async void RowSelected(object sender, SelectionChangedEventArgs e)
{ {
((ExtendedCollectionView)sender).SelectedItem = null; ((ExtendedCollectionView)sender).SelectedItem = null;

View File

@@ -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.Models;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
@@ -8,9 +12,6 @@ using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.CommunityToolkit.ObjectModel; using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms; using Xamarin.Forms;
@@ -23,8 +24,10 @@ namespace Bit.App.Pages
private readonly ICipherService _cipherService; private readonly ICipherService _cipherService;
private readonly IStateService _stateService; private readonly IStateService _stateService;
private readonly IPasswordRepromptService _passwordRepromptService; private readonly IPasswordRepromptService _passwordRepromptService;
private readonly IMessagingService _messagingService;
private readonly ILogger _logger;
private AppOptions _appOptions; private bool _showNoData;
private bool _showList; private bool _showList;
private string _noDataText; private string _noDataText;
private bool _websiteIconsEnabled; private bool _websiteIconsEnabled;
@@ -36,15 +39,30 @@ namespace Bit.App.Pages
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService"); _deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService"); _stateService = ServiceContainer.Resolve<IStateService>("stateService");
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService"); _passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_logger = ServiceContainer.Resolve<ILogger>("logger");
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>(); GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync); CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
{
AllowAddAccountRow = false
};
} }
public string Name { get; set; } public string Name { get; set; }
public string Uri { get; set; } public string Uri { get; set; }
public Command CipherOptionsCommand { get; set; } public Command CipherOptionsCommand { get; set; }
public bool LoadedOnce { get; set; }
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { 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 public bool ShowList
{ {
@@ -65,7 +83,6 @@ namespace Bit.App.Pages
public void Init(AppOptions appOptions) public void Init(AppOptions appOptions)
{ {
_appOptions = appOptions;
Uri = appOptions?.Uri; Uri = appOptions?.Uri;
string name = null; string name = null;
if (Uri?.StartsWith(Constants.AndroidAppProtocol) ?? false) if (Uri?.StartsWith(Constants.AndroidAppProtocol) ?? false)
@@ -87,8 +104,10 @@ namespace Bit.App.Pages
public async Task LoadAsync() public async Task LoadAsync()
{ {
WebsiteIconsEnabled = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault(); LoadedOnce = true;
ShowList = false; ShowList = false;
ShowNoData = false;
WebsiteIconsEnabled = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
var groupedItems = new List<GroupingsPageListGroup>(); var groupedItems = new List<GroupingsPageListGroup>();
var ciphers = await _cipherService.GetAllDecryptedByUrlAsync(Uri, null); var ciphers = await _cipherService.GetAllDecryptedByUrlAsync(Uri, null);
var matching = ciphers.Item1?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList(); var matching = ciphers.Item1?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
@@ -150,6 +169,7 @@ namespace Bit.App.Pages
} }
} }
ShowList = groupedItems.Any(); ShowList = groupedItems.Any();
ShowNoData = !ShowList;
} }
public async Task SelectCipherAsync(CipherView cipher, bool fuzzy) public async Task SelectCipherAsync(CipherView cipher, bool fuzzy)

View File

@@ -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.App.Resources;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Linq;
using Bit.App.Controls;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -17,8 +17,7 @@ namespace Bit.App.Pages
private CiphersPageViewModel _vm; private CiphersPageViewModel _vm;
private bool _hasFocused; private bool _hasFocused;
public CiphersPage(Func<CipherView, bool> filter, bool folder = false, bool collection = false, public CiphersPage(Func<CipherView, bool> filter, string pageTitle = null, string autofillUrl = null, bool deleted = false)
bool type = false, string autofillUrl = null, bool deleted = false)
{ {
InitializeComponent(); InitializeComponent();
_vm = BindingContext as CiphersPageViewModel; _vm = BindingContext as CiphersPageViewModel;
@@ -26,21 +25,9 @@ namespace Bit.App.Pages
_vm.Filter = filter; _vm.Filter = filter;
_vm.AutofillUrl = _autofillUrl = autofillUrl; _vm.AutofillUrl = _autofillUrl = autofillUrl;
_vm.Deleted = deleted; _vm.Deleted = deleted;
if (deleted) if (pageTitle != null)
{ {
_vm.PageTitle = AppResources.SearchTrash; _vm.PageTitle = string.Format(AppResources.SearchGroup, pageTitle);
}
else if (folder)
{
_vm.PageTitle = AppResources.SearchFolder;
}
else if (collection)
{
_vm.PageTitle = AppResources.SearchCollection;
}
else if (type)
{
_vm.PageTitle = AppResources.SearchType;
} }
else else
{ {
@@ -53,6 +40,7 @@ namespace Bit.App.Pages
_searchBar.Placeholder = AppResources.Search; _searchBar.Placeholder = AppResources.Search;
_mainLayout.Children.Insert(0, _searchBar); _mainLayout.Children.Insert(0, _searchBar);
_mainLayout.Children.Insert(1, _separator); _mainLayout.Children.Insert(1, _separator);
ShowModalAnimationDelay = 0;
} }
else else
{ {

View File

@@ -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.App.Resources;
using Bit.Core; using Bit.Core;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
@@ -6,11 +11,6 @@ using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -107,7 +107,7 @@ namespace Bit.App.Pages
} }
try try
{ {
ciphers = await _searchService.SearchCiphersAsync(searchText, ciphers = await _searchService.SearchCiphersAsync(searchText,
Filter ?? (c => c.IsDeleted == Deleted), null, cts.Token); Filter ?? (c => c.IsDeleted == Deleted), null, cts.Token);
cts.Token.ThrowIfCancellationRequested(); cts.Token.ThrowIfCancellationRequested();
} }

View File

@@ -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.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.Domain; using Bit.Core.Models.Domain;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {

View File

@@ -27,7 +27,7 @@ namespace Bit.App.Pages
private PreviousPageInfo _previousPage; private PreviousPageInfo _previousPage;
public GroupingsPage(bool mainPage, CipherType? type = null, string folderId = null, 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) bool deleted = false)
{ {
_pageName = string.Concat(nameof(GroupingsPage), "_", DateTime.UtcNow.Ticks); _pageName = string.Concat(nameof(GroupingsPage), "_", DateTime.UtcNow.Ticks);
@@ -117,7 +117,7 @@ namespace Bit.App.Pages
{ {
await _vm.LoadAsync(); 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 Task.Delay(1000);
await _vm.LoadAsync(); await _vm.LoadAsync();
@@ -225,8 +225,7 @@ namespace Bit.App.Pages
await _accountListOverlay.HideAsync(); await _accountListOverlay.HideAsync();
if (DoOnce()) if (DoOnce())
{ {
var page = new CiphersPage(_vm.Filter, _vm.FolderId != null, _vm.CollectionId != null, var page = new CiphersPage(_vm.Filter, _vm.MainPage ? null : _vm.PageTitle, deleted: _vm.Deleted);
_vm.Type != null, deleted: _vm.Deleted);
await Navigation.PushModalAsync(new NavigationPage(page)); await Navigation.PushModalAsync(new NavigationPage(page));
} }
} }

View File

@@ -23,7 +23,8 @@ namespace Bit.App.Pages
protected override async void OnAppearing() protected override async void OnAppearing()
{ {
base.OnAppearing(); base.OnAppearing();
await LoadOnAppearedAsync(_mainLayout, true, async () => { await LoadOnAppearedAsync(_mainLayout, true, async () =>
{
await _vm.InitAsync(); await _vm.InitAsync();
}); });
} }

View File

@@ -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.Abstractions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages

View File

@@ -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.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Bit.App.Pages namespace Bit.App.Pages
{ {

View File

@@ -1,9 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -216,7 +216,7 @@ namespace Bit.App.Pages
return; return;
} }
var options = new List<string> {AppResources.Attachments}; var options = new List<string> { AppResources.Attachments };
if (_vm.Cipher.OrganizationId == null) if (_vm.Cipher.OrganizationId == null)
{ {
options.Add(AppResources.Clone); options.Add(AppResources.Clone);

View File

@@ -1,16 +1,16 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Exceptions; using Bit.Core.Exceptions;
using Bit.Core.Models.View; using Bit.Core.Models.View;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Bit.Core;
using Xamarin.Forms; using Xamarin.Forms;
namespace Bit.App.Pages namespace Bit.App.Pages
@@ -233,7 +233,7 @@ namespace Bit.App.Pages
set set
{ {
SetProperty(ref _totpLow, value); 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; public bool IsDeleted => Cipher.IsDeleted;
@@ -285,7 +285,7 @@ namespace Bit.App.Pages
public async void TogglePassword() public async void TogglePassword()
{ {
if (! await PromptPasswordAsync()) if (!await PromptPasswordAsync())
{ {
return; return;
} }
@@ -613,7 +613,7 @@ namespace Bit.App.Pages
_attachmentData = null; _attachmentData = null;
_attachmentFilename = null; _attachmentFilename = null;
} }
private async void CopyAsync(string id, string text = null) private async void CopyAsync(string id, string text = null)
{ {
if (_passwordRepromptService.ProtectedFields.Contains(id) && !await PromptPasswordAsync()) if (_passwordRepromptService.ProtectedFields.Contains(id) && !await PromptPasswordAsync())

View File

@@ -2387,15 +2387,21 @@ namespace Bit.App.Resources {
} }
} }
public static string SearchFolder { public static string SearchFileSends {
get { get {
return ResourceManager.GetString("SearchFolder", resourceCulture); return ResourceManager.GetString("SearchFileSends", resourceCulture);
} }
} }
public static string SearchType { public static string SearchTextSends {
get { get {
return ResourceManager.GetString("SearchType", resourceCulture); return ResourceManager.GetString("SearchTextSends", resourceCulture);
}
}
public static string SearchGroup {
get {
return ResourceManager.GetString("SearchGroup", resourceCulture);
} }
} }

View File

@@ -2121,13 +2121,13 @@
<value>Μετάβαση στον επόμενο διαθέσιμο λογαριασμό</value> <value>Μετάβαση στον επόμενο διαθέσιμο λογαριασμό</value>
</data> </data>
<data name="AccountLockedSuccessfully" xml:space="preserve"> <data name="AccountLockedSuccessfully" xml:space="preserve">
<value>Account Locked</value> <value>Κλειδωμένος Λογαριασμός</value>
</data> </data>
<data name="AccountLoggedOutSuccessfully" xml:space="preserve"> <data name="AccountLoggedOutSuccessfully" xml:space="preserve">
<value>Account logged out successfully</value> <value>Ο λογαριασμός αποσυνδέθηκε επιτυχώς</value>
</data> </data>
<data name="AccountRemovedSuccessfully" xml:space="preserve"> <data name="AccountRemovedSuccessfully" xml:space="preserve">
<value>Account removed successfully</value> <value>Ο λογαριασμός αφαιρέθηκε επιτυχώς</value>
</data> </data>
<data name="DeleteAccount" xml:space="preserve"> <data name="DeleteAccount" xml:space="preserve">
<value>Διαγραφή Λογαριασμού</value> <value>Διαγραφή Λογαριασμού</value>

View File

@@ -276,16 +276,16 @@
<value>האם אתה בטוח שברצונך להתנתק?</value> <value>האם אתה בטוח שברצונך להתנתק?</value>
</data> </data>
<data name="RemoveAccount" xml:space="preserve"> <data name="RemoveAccount" xml:space="preserve">
<value>Remove Account</value> <value>הסר/י חשבון</value>
</data> </data>
<data name="RemoveAccountConfirmation" xml:space="preserve"> <data name="RemoveAccountConfirmation" xml:space="preserve">
<value>Are you sure you want to remove this account?</value> <value>האם את/ה בטוח/ה שברצונך להסיר חשבון זה?</value>
</data> </data>
<data name="AccountAlreadyAdded" xml:space="preserve"> <data name="AccountAlreadyAdded" xml:space="preserve">
<value>Account Already Added</value> <value>החשבון כבר נוסף</value>
</data> </data>
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve"> <data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
<value>Would you like to switch to it now?</value> <value>האם תרצה לעבור אליו עכשיו?</value>
</data> </data>
<data name="MasterPassword" xml:space="preserve"> <data name="MasterPassword" xml:space="preserve">
<value>סיסמה ראשית</value> <value>סיסמה ראשית</value>
@@ -1073,7 +1073,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>שם משפחה</value> <value>שם משפחה</value>
</data> </data>
<data name="FullName" xml:space="preserve"> <data name="FullName" xml:space="preserve">
<value>Full Name</value> <value>שם מלא</value>
</data> </data>
<data name="LicenseNumber" xml:space="preserve"> <data name="LicenseNumber" xml:space="preserve">
<value>מספר רשיון</value> <value>מספר רשיון</value>
@@ -1200,7 +1200,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>מוסתר</value> <value>מוסתר</value>
</data> </data>
<data name="FieldTypeLinked" xml:space="preserve"> <data name="FieldTypeLinked" xml:space="preserve">
<value>Linked</value> <value>מקושר</value>
</data> </data>
<data name="FieldTypeText" xml:space="preserve"> <data name="FieldTypeText" xml:space="preserve">
<value>טקסט</value> <value>טקסט</value>
@@ -1472,7 +1472,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>בטל נעילה</value> <value>בטל נעילה</value>
</data> </data>
<data name="UnlockVault" xml:space="preserve"> <data name="UnlockVault" xml:space="preserve">
<value>Unlock Vault</value> <value>פתח נעילת כספת</value>
</data> </data>
<data name="ThirtyMinutes" xml:space="preserve"> <data name="ThirtyMinutes" xml:space="preserve">
<value>30 דקות</value> <value>30 דקות</value>
@@ -1491,7 +1491,7 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>הכספת שלך נעולה. הזן את קוד הPIN שלך כדי להמשיך.</value> <value>הכספת שלך נעולה. הזן את קוד הPIN שלך כדי להמשיך.</value>
</data> </data>
<data name="VaultLockedIdentity" xml:space="preserve"> <data name="VaultLockedIdentity" xml:space="preserve">
<value>Your vault is locked. Verify your identity to continue.</value> <value>הכספת שלך נעולה. אמת את זהותך כדי להמשיך.</value>
</data> </data>
<data name="Dark" xml:space="preserve"> <data name="Dark" xml:space="preserve">
<value>כהה</value> <value>כהה</value>
@@ -1634,13 +1634,13 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>הזן את הסיסמה הראשית שלך עבור יצוא המידע מהכספת.</value> <value>הזן את הסיסמה הראשית שלך עבור יצוא המידע מהכספת.</value>
</data> </data>
<data name="SendVerificationCodeToEmail" xml:space="preserve"> <data name="SendVerificationCodeToEmail" xml:space="preserve">
<value>Send a verification code to your email</value> <value>שליחת קוד אימות לדוא״ל שלך</value>
</data> </data>
<data name="CodeSent" xml:space="preserve"> <data name="CodeSent" xml:space="preserve">
<value>Code Sent!</value> <value>קוד נשלח!</value>
</data> </data>
<data name="ConfirmYourIdentity" xml:space="preserve"> <data name="ConfirmYourIdentity" xml:space="preserve">
<value>Confirm your identity to continue.</value> <value>אשר את זהותך כדי להמשיך.</value>
</data> </data>
<data name="ExportVaultWarning" xml:space="preserve"> <data name="ExportVaultWarning" xml:space="preserve">
<value>הקובץ מכיל את פרטי הכספת שלך בפורמט לא מוצפן. מומלץ להעביר את הקובץ רק בדרכים מוצפנות, ומאוד לא מומלץ לשמור או לשלוח את הקובץ הזה בדרכים לא מוצפנות (כדוגמת סתם אימייל). מחק את הקובץ מיד לאחר שסיימת את השימוש בו.</value> <value>הקובץ מכיל את פרטי הכספת שלך בפורמט לא מוצפן. מומלץ להעביר את הקובץ רק בדרכים מוצפנות, ומאוד לא מומלץ לשמור או לשלוח את הקובץ הזה בדרכים לא מוצפנות (כדוגמת סתם אימייל). מחק את הקובץ מיד לאחר שסיימת את השימוש בו.</value>
@@ -2066,19 +2066,19 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>כרגע לא ניתן לעדכן את הסיסמה</value> <value>כרגע לא ניתן לעדכן את הסיסמה</value>
</data> </data>
<data name="RemoveMasterPassword" xml:space="preserve"> <data name="RemoveMasterPassword" xml:space="preserve">
<value>Remove Master Password</value> <value>הסרת סיסמה ראשית</value>
</data> </data>
<data name="RemoveMasterPasswordWarning" xml:space="preserve"> <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>
<data name="RemoveMasterPasswordWarning2" xml:space="preserve"> <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>
<data name="LeaveOrganization" xml:space="preserve"> <data name="LeaveOrganization" xml:space="preserve">
<value>Leave Organization</value> <value>עזוב ארגון</value>
</data> </data>
<data name="LeaveOrganizationName" xml:space="preserve"> <data name="LeaveOrganizationName" xml:space="preserve">
<value>Leave {0}?</value> <value>לעזוב את {0}?</value>
</data> </data>
<data name="Fido2Title" xml:space="preserve"> <data name="Fido2Title" xml:space="preserve">
<value>אימות אינטרנט באמצעות FIDO2</value> <value>אימות אינטרנט באמצעות FIDO2</value>
@@ -2112,75 +2112,76 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>מדיניות אחת או יותר של הארגון שלך מונעות ממך לייצא את הכספת האישית שלך.</value> <value>מדיניות אחת או יותר של הארגון שלך מונעות ממך לייצא את הכספת האישית שלך.</value>
</data> </data>
<data name="AddAccount" xml:space="preserve"> <data name="AddAccount" xml:space="preserve">
<value>Add Account</value> <value>הוספת חשבון</value>
</data> </data>
<data name="AccountUnlocked" xml:space="preserve"> <data name="AccountUnlocked" xml:space="preserve">
<value>Unlocked</value> <value>פתוח</value>
</data> </data>
<data name="AccountLocked" xml:space="preserve"> <data name="AccountLocked" xml:space="preserve">
<value>Locked</value> <value>נעול</value>
</data> </data>
<data name="AccountLoggedOut" xml:space="preserve"> <data name="AccountLoggedOut" xml:space="preserve">
<value>Logged Out</value> <value>בוצעה יציאה</value>
</data> </data>
<data name="AccountSwitchedAutomatically" xml:space="preserve"> <data name="AccountSwitchedAutomatically" xml:space="preserve">
<value>Switched to next available account</value> <value>הוחלף לחשבון הזמין הבא</value>
</data> </data>
<data name="AccountLockedSuccessfully" xml:space="preserve"> <data name="AccountLockedSuccessfully" xml:space="preserve">
<value>Account Locked</value> <value>החשבון נעול</value>
</data> </data>
<data name="AccountLoggedOutSuccessfully" xml:space="preserve"> <data name="AccountLoggedOutSuccessfully" xml:space="preserve">
<value>Account logged out successfully</value> <value>נותק בהצלחה מהחשבון</value>
</data> </data>
<data name="AccountRemovedSuccessfully" xml:space="preserve"> <data name="AccountRemovedSuccessfully" xml:space="preserve">
<value>Account removed successfully</value> <value>חשבון נמחק בהצלחה</value>
</data> </data>
<data name="DeleteAccount" xml:space="preserve"> <data name="DeleteAccount" xml:space="preserve">
<value>Delete Account</value> <value>מחק חשבון</value>
</data> </data>
<data name="DeletingYourAccountIsPermanent" xml:space="preserve"> <data name="DeletingYourAccountIsPermanent" xml:space="preserve">
<value>Deleting your account is permanent</value> <value>מחיקת חשבונך היא לצמיתות</value>
</data> </data>
<data name="DeleteAccountExplanation" xml:space="preserve"> <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>
<data name="DeletingYourAccount" xml:space="preserve"> <data name="DeletingYourAccount" xml:space="preserve">
<value>Deleting your account</value> <value>מוחק את החשבון שלך</value>
</data> </data>
<data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve"> <data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve">
<value>Your account has been permanently deleted</value> <value>חשבונך נמחק לצמיתות</value>
</data> </data>
<data name="InvalidVerificationCode" xml:space="preserve"> <data name="InvalidVerificationCode" xml:space="preserve">
<value>Invalid Verification Code.</value> <value>קוד אימות שגוי.</value>
</data> </data>
<data name="RequestOTP" xml:space="preserve"> <data name="RequestOTP" xml:space="preserve">
<value>Request one-time password</value> <value>בקשת סיסמה חד־פעמית</value>
</data> </data>
<data name="SendCode" xml:space="preserve"> <data name="SendCode" xml:space="preserve">
<value>Send Code</value> <value>שליחת קוד</value>
</data> </data>
<data name="Sending" xml:space="preserve"> <data name="Sending" xml:space="preserve">
<value>Sending</value> <value>בשליחה</value>
</data> </data>
<data name="CopySendLinkOnSave" xml:space="preserve"> <data name="CopySendLinkOnSave" xml:space="preserve">
<value>Copy Send link on save</value> <value>העתק קישור שליחה בעת שמירה</value>
</data> </data>
<data name="SendingCode" xml:space="preserve"> <data name="SendingCode" xml:space="preserve">
<value>Sending code</value> <value>שליחת קוד</value>
</data> </data>
<data name="Verifying" xml:space="preserve"> <data name="Verifying" xml:space="preserve">
<value>Verifying</value> <value>אימות</value>
</data> </data>
<data name="ResendCode" xml:space="preserve"> <data name="ResendCode" xml:space="preserve">
<value>Resend Code</value> <value>שליחת קוד בשנית</value>
</data> </data>
<data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve"> <data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve">
<value>A verification code was sent to your email</value> <value>קוד אימות נשלח לדוא"ל שלך</value>
</data> </data>
<data name="AnErrorOccurredWhileSendingAVerificationCodeToYourEmailPleaseTryAgain" xml:space="preserve"> <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>
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve"> <data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
<value>Enter the verification code that was sent to your email</value> <value>הזן את קוד האימות שנשלח לדוא"ל שלך</value>
</data> </data>
</root> </root>

View File

@@ -2120,13 +2120,13 @@
<value>사용 가능한 다음 계정으로 전환함</value> <value>사용 가능한 다음 계정으로 전환함</value>
</data> </data>
<data name="AccountLockedSuccessfully" xml:space="preserve"> <data name="AccountLockedSuccessfully" xml:space="preserve">
<value>Account Locked</value> <value>계정 잠김</value>
</data> </data>
<data name="AccountLoggedOutSuccessfully" xml:space="preserve"> <data name="AccountLoggedOutSuccessfully" xml:space="preserve">
<value>Account logged out successfully</value> <value>계정이 성공적으로 로그아웃되었습니다</value>
</data> </data>
<data name="AccountRemovedSuccessfully" xml:space="preserve"> <data name="AccountRemovedSuccessfully" xml:space="preserve">
<value>Account removed successfully</value> <value>계정이 성공적으로 제거되었습니다</value>
</data> </data>
<data name="DeleteAccount" xml:space="preserve"> <data name="DeleteAccount" xml:space="preserve">
<value>계정 삭제</value> <value>계정 삭제</value>

View File

@@ -285,7 +285,7 @@
<value>Konto zostało już dodane</value> <value>Konto zostało już dodane</value>
</data> </data>
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve"> <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>
<data name="MasterPassword" xml:space="preserve"> <data name="MasterPassword" xml:space="preserve">
<value>Hasło główne</value> <value>Hasło główne</value>
@@ -1162,10 +1162,10 @@
<value>Usługa ułatwienia dostępu</value> <value>Usługa ułatwienia dostępu</value>
</data> </data>
<data name="AutofillServiceDescription" xml:space="preserve"> <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>
<data name="BitwardenAutofillServiceDescription" xml:space="preserve"> <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>
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve"> <data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
<value>Otwórz ustawienia autouzupełniania</value> <value>Otwórz ustawienia autouzupełniania</value>
@@ -1299,7 +1299,7 @@
<value>1. przejdź do Ustawień systemu iOS</value> <value>1. przejdź do Ustawień systemu iOS</value>
</data> </data>
<data name="AutofillTurnOn2" xml:space="preserve"> <data name="AutofillTurnOn2" xml:space="preserve">
<value>2. Dotknij "Hasła i konta"</value> <value>2. Dotknij "Hasła"</value>
</data> </data>
<data name="AutofillTurnOn3" xml:space="preserve"> <data name="AutofillTurnOn3" xml:space="preserve">
<value>3. Dotknij opcji "Usługa autouzupełniania"</value> <value>3. Dotknij opcji "Usługa autouzupełniania"</value>

View File

@@ -659,7 +659,7 @@
<value>Re-type Master Password</value> <value>Re-type Master Password</value>
</data> </data>
<data name="SearchVault" xml:space="preserve"> <data name="SearchVault" xml:space="preserve">
<value>Search vault</value> <value>Search Vault</value>
</data> </data>
<data name="Security" xml:space="preserve"> <data name="Security" xml:space="preserve">
<value>Security</value> <value>Security</value>
@@ -1372,11 +1372,15 @@
<data name="SearchCollection" xml:space="preserve"> <data name="SearchCollection" xml:space="preserve">
<value>Search collection</value> <value>Search collection</value>
</data> </data>
<data name="SearchFolder" xml:space="preserve"> <data name="SearchFileSends" xml:space="preserve">
<value>Search folder</value> <value>Search File Sends</value>
</data> </data>
<data name="SearchType" xml:space="preserve"> <data name="SearchTextSends" xml:space="preserve">
<value>Search type</value> <value>Search Text Sends</value>
</data>
<data name="SearchGroup" xml:space="preserve">
<value>Search {0}</value>
<comment>ex: Search Logins</comment>
</data> </data>
<data name="Type" xml:space="preserve"> <data name="Type" xml:space="preserve">
<value>Type</value> <value>Type</value>
@@ -1538,7 +1542,7 @@
<value>Default (System)</value> <value>Default (System)</value>
</data> </data>
<data name="CopyNotes" xml:space="preserve"> <data name="CopyNotes" xml:space="preserve">
<value>Copy Notes</value> <value>Copy Note</value>
</data> </data>
<data name="Exit" xml:space="preserve"> <data name="Exit" xml:space="preserve">
<value>Exit</value> <value>Exit</value>

View File

@@ -1299,7 +1299,7 @@
<value>1. Перейдите в 'Настройки' iOS</value> <value>1. Перейдите в 'Настройки' iOS</value>
</data> </data>
<data name="AutofillTurnOn2" xml:space="preserve"> <data name="AutofillTurnOn2" xml:space="preserve">
<value>2. Нажмите на пункт "Пароли и учетные записи"</value> <value>2. Нажмите 'Пароли'</value>
</data> </data>
<data name="AutofillTurnOn3" xml:space="preserve"> <data name="AutofillTurnOn3" xml:space="preserve">
<value>3. Нажмите 'Автозаполнение паролей'</value> <value>3. Нажмите 'Автозаполнение паролей'</value>

View File

@@ -1299,7 +1299,7 @@
<value>1. Prejdite do aplikácie "Nastavenia" pre iOS</value> <value>1. Prejdite do aplikácie "Nastavenia" pre iOS</value>
</data> </data>
<data name="AutofillTurnOn2" xml:space="preserve"> <data name="AutofillTurnOn2" xml:space="preserve">
<value>2. Ťuknite na položku "Heslá &amp; účty"</value> <value>2. Ťuknite na položku "Heslá"</value>
</data> </data>
<data name="AutofillTurnOn3" xml:space="preserve"> <data name="AutofillTurnOn3" xml:space="preserve">
<value>3. Klepnite na možnosť "Automaticky vypĺňať heslá"</value> <value>3. Klepnite na možnosť "Automaticky vypĺňať heslá"</value>

View File

@@ -1,11 +1,11 @@
using Bit.App.Resources; using System;
using Bit.Core.Abstractions;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Reflection; using System.Reflection;
using System.Resources; using System.Resources;
using System.Threading; using System.Threading;
using Bit.App.Resources;
using Bit.Core.Abstractions;
namespace Bit.App.Services namespace Bit.App.Services
{ {

View File

@@ -1,8 +1,8 @@
using System.Threading.Tasks; using System;
using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using System;
using Bit.Core.Utilities; using Bit.Core.Utilities;
namespace Bit.App.Services namespace Bit.App.Services

View File

@@ -14,7 +14,7 @@ using Xamarin.Forms;
namespace Bit.App.Services namespace Bit.App.Services
{ {
public class MobilePlatformUtilsService : IPlatformUtilsService public class MobilePlatformUtilsService : IPlatformUtilsService
{ {
private static readonly Random _random = new Random(); private static readonly Random _random = new Random();
private const int DialogPromiseExpiration = 600000; // 10 minutes private const int DialogPromiseExpiration = 600000; // 10 minutes

View File

@@ -1,8 +1,8 @@
using Bit.Core; using System;
using Bit.Core.Abstractions;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core;
using Bit.Core.Abstractions;
namespace Bit.App.Services namespace Bit.App.Services
{ {

View File

@@ -1,6 +1,6 @@
using Newtonsoft.Json.Linq; using System.Threading.Tasks;
using Bit.App.Abstractions; using Bit.App.Abstractions;
using System.Threading.Tasks; using Newtonsoft.Json.Linq;
namespace Bit.App.Services namespace Bit.App.Services
{ {

View File

@@ -1,15 +1,15 @@
using Bit.Core.Abstractions; using System;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
using System;
using System.Threading.Tasks;
namespace Bit.App.Services namespace Bit.App.Services
{ {
public class PreferencesStorageService : IStorageService public class PreferencesStorageService : IStorageService
{ {
public static string KeyFormat = "bwPreferencesStorage:{0}"; public static string KeyFormat = "bwPreferencesStorage:{0}";
private readonly string _sharedName; private readonly string _sharedName;
private readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings private readonly JsonSerializerSettings _jsonSettings = new JsonSerializerSettings
{ {

View File

@@ -1,17 +1,17 @@
#if !FDROID #if !FDROID
using System;
using System.Diagnostics; 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;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Bit.App.Abstractions;
using System;
using Xamarin.Forms; 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 namespace Bit.App.Services
{ {

View File

@@ -1,7 +1,7 @@
using Bit.Core.Abstractions; using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Serialization; using Newtonsoft.Json.Serialization;
using System.Threading.Tasks;
namespace Bit.App.Services namespace Bit.App.Services
{ {

View File

@@ -9,4 +9,4 @@ namespace Bit.App.Styles
InitializeComponent(); InitializeComponent();
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More