mirror of
https://github.com/bitwarden/android.git
synced 2024-12-26 19:08:32 +03:00
Merge branch 'feature/maui-migration' of https://github.com/bitwarden/mobile into feature/maui-migration
# Conflicts: # src/Core/Pages/Settings/OtherSettingsPageViewModel.cs
This commit is contained in:
commit
16ada4993c
148 changed files with 1755 additions and 942 deletions
9
.github/CODEOWNERS
vendored
9
.github/CODEOWNERS
vendored
|
@ -20,12 +20,15 @@ src/watchOS @bitwarden/team-vault-dev
|
|||
## Tools team files ##
|
||||
src/Core/Services/EmailForwarders @bitwarden/team-tools-dev
|
||||
|
||||
|
||||
## Crowdin Sync files ##
|
||||
src/App/Resources @bitwarden/tech-leads
|
||||
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization @bitwarden/tech-leads
|
||||
src/App/Resources @bitwarden/team-tools-dev
|
||||
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization @bitwarden/team-tools-dev
|
||||
store/apple @bitwarden/team-tools-dev
|
||||
store/google @bitwarden/team-tools-dev
|
||||
|
||||
## Locales ##
|
||||
src/App/Resources/AppResources.Designer.cs
|
||||
src/App/Resources/AppResources.resx
|
||||
src/watchOS/bitwarden/bitwarden\ WatchKit\ Extension/Localization/en.lproj
|
||||
store/apple/en
|
||||
store/google/en
|
||||
|
|
2
.github/workflows/crowdin-pull.yml
vendored
2
.github/workflows/crowdin-pull.yml
vendored
|
@ -24,7 +24,7 @@ jobs:
|
|||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
|
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
@ -42,7 +42,7 @@ jobs:
|
|||
|
||||
- name: Check Release Version
|
||||
id: version
|
||||
uses: bitwarden/gh-actions/release-version-check@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/release-version-check@main
|
||||
with:
|
||||
release-type: ${{ github.event.inputs.release_type }}
|
||||
project-type: xamarin
|
||||
|
|
12
.github/workflows/version-bump.yml
vendored
12
.github/workflows/version-bump.yml
vendored
|
@ -28,7 +28,7 @@ jobs:
|
|||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||
with:
|
||||
keyvault: "bitwarden-ci"
|
||||
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
|
@ -45,31 +45,31 @@ jobs:
|
|||
run: git switch -c version_bump_${{ github.event.inputs.version_number }}
|
||||
|
||||
- name: Bump Version - Android XML
|
||||
uses: bitwarden/gh-actions/version-bump@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/Android/Properties/AndroidManifest.xml"
|
||||
|
||||
- name: Bump Version - iOS.Autofill
|
||||
uses: bitwarden/gh-actions/version-bump@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS.Autofill/Info.plist"
|
||||
|
||||
- name: Bump Version - iOS.Extension
|
||||
uses: bitwarden/gh-actions/version-bump@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS.Extension/Info.plist"
|
||||
|
||||
- name: Bump Version - iOS.ShareExtension
|
||||
uses: bitwarden/gh-actions/version-bump@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS.ShareExtension/Info.plist"
|
||||
|
||||
- name: Bump Version - iOS
|
||||
uses: bitwarden/gh-actions/version-bump@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/version-bump@main
|
||||
with:
|
||||
version: ${{ github.event.inputs.version_number }}
|
||||
file_path: "./src/iOS/Info.plist"
|
||||
|
|
2
.github/workflows/workflow-linter.yml
vendored
2
.github/workflows/workflow-linter.yml
vendored
|
@ -8,4 +8,4 @@ on:
|
|||
|
||||
jobs:
|
||||
call-workflow:
|
||||
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@4a7ddc1b38ca5cb4e3e43578f4df5cabe4f55a67
|
||||
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@main
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Models.Response;
|
||||
using DeviceType = Bit.Core.Enums.DeviceType;
|
||||
|
@ -52,7 +51,7 @@ namespace Bit.Core.Abstractions
|
|||
Task<TResponse> SendAsync<TRequest, TResponse>(HttpMethod method, string path,
|
||||
TRequest body, bool authed, bool hasResponse, Action<HttpRequestMessage> alterRequest, bool logoutOnUnauthorized = true, bool sendToIdentity = false);
|
||||
Task<HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage, CancellationToken cancellationToken = default);
|
||||
void SetUrls(EnvironmentUrls urls);
|
||||
void SetUrls(EnvironmentUrlData urls);
|
||||
[Obsolete("Mar 25 2021: This method has been deprecated in favor of direct uploads. This method still exists for backward compatibility with old server versions.")]
|
||||
Task<CipherResponse> PostCipherAttachmentLegacyAsync(string id, MultipartFormDataContent data);
|
||||
Task<AttachmentUploadDataResponse> PostCipherAttachmentAsync(string id, AttachmentRequest request);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data;
|
||||
using BwRegion = Bit.Core.Enums.Region;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
|
@ -12,10 +12,12 @@ namespace Bit.Core.Abstractions
|
|||
string NotificationsUrl { get; set; }
|
||||
string WebVaultUrl { get; set; }
|
||||
string EventsUrl { get; set; }
|
||||
BwRegion SelectedRegion { get; set; }
|
||||
|
||||
string GetWebVaultUrl(bool returnNullIfDefault = false);
|
||||
string GetWebSendUrl();
|
||||
Task<EnvironmentUrlData> SetUrlsAsync(EnvironmentUrlData urls);
|
||||
string GetCurrentDomain();
|
||||
Task SetUrlsFromStorageAsync();
|
||||
Task<EnvironmentUrlData> SetRegionAsync(BwRegion region, EnvironmentUrlData selfHostedUrls = null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.Response;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Services;
|
||||
using BwRegion = Bit.Core.Enums.Region;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
|
@ -185,6 +182,10 @@ namespace Bit.Core.Abstractions
|
|||
void SetConfigs(ConfigResponse value);
|
||||
Task<bool> GetShouldTrustDeviceAsync();
|
||||
Task SetShouldTrustDeviceAsync(bool value);
|
||||
Task SetUserHasMasterPasswordAsync(bool value, string userId = null);
|
||||
Task<BwRegion?> GetActiveUserRegionAsync();
|
||||
Task<BwRegion?> GetPreAuthRegionAsync();
|
||||
Task SetPreAuthRegionAsync(BwRegion value);
|
||||
[Obsolete("Use GetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")]
|
||||
Task<string> GetPinProtectedAsync(string userId = null);
|
||||
[Obsolete("Use SetPinKeyEncryptedUserKeyAsync instead, left for migration purposes")]
|
||||
|
|
|
@ -178,6 +178,11 @@ namespace Bit.App
|
|||
new NavigationPage(new UpdateTempPasswordPage()));
|
||||
});
|
||||
}
|
||||
else if (message.Command == Constants.ForceSetPassword)
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(
|
||||
new NavigationPage(new SetPasswordPage(orgIdentifier: (string)message.Data))));
|
||||
}
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
await _configService.GetAsync(true);
|
||||
|
|
|
@ -46,6 +46,7 @@ namespace Bit.Core
|
|||
public const string PreLoginEmailKey = "preLoginEmailKey";
|
||||
public const string ConfigsKey = "configsKey";
|
||||
public const string DisplayEuEnvironmentFlag = "display-eu-environment";
|
||||
public const string RegionEnvironment = "regionEnvironment";
|
||||
|
||||
/// <summary>
|
||||
/// This key is used to store the value of "ShouldConnectToWatch" of the last user that had logged in
|
||||
|
@ -56,6 +57,7 @@ namespace Bit.Core
|
|||
public const string AppLocaleKey = "appLocale";
|
||||
public const string ClearSensitiveFields = "clearSensitiveFields";
|
||||
public const string ForceUpdatePassword = "forceUpdatePassword";
|
||||
public const string ForceSetPassword = "forceSetPassword";
|
||||
public const string ShouldTrustDevice = "shouldTrustDevice";
|
||||
public const int SelectFileRequestCode = 42;
|
||||
public const int SelectFilePermissionRequestCode = 43;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Windows.Input;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
|
@ -37,17 +37,14 @@ namespace Bit.App.Controls
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
ToggleVisibililtyCommand = new AsyncCommand(ToggleVisibilityAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
ToggleVisibililtyCommand = new AsyncRelayCommand(ToggleVisibilityAsync,
|
||||
AsyncRelayCommandOptions.None);
|
||||
|
||||
SelectAccountCommand = new AsyncCommand<AccountViewCellViewModel>(SelectAccountAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
SelectAccountCommand = new AsyncRelayCommand<AccountViewCellViewModel>(SelectAccountAsync,
|
||||
AsyncRelayCommandOptions.None);
|
||||
|
||||
LongPressAccountCommand = new AsyncCommand<AccountViewCellViewModel>(LongPressAccountAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
LongPressAccountCommand = new AsyncRelayCommand<AccountViewCellViewModel>(LongPressAccountAsync,
|
||||
AsyncRelayCommandOptions.None);
|
||||
}
|
||||
|
||||
public AccountSwitchingOverlayViewModel ViewModel => BindingContext as AccountSwitchingOverlayViewModel;
|
||||
|
@ -70,13 +67,20 @@ namespace Bit.App.Controls
|
|||
|
||||
public async Task ToggleVisibilityAsync()
|
||||
{
|
||||
if (IsVisible)
|
||||
try
|
||||
{
|
||||
await HideAsync();
|
||||
if (IsVisible)
|
||||
{
|
||||
await HideAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await ShowAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
await ShowAsync();
|
||||
_logger.Value.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,12 +176,13 @@ namespace Bit.App.Controls
|
|||
|
||||
private async Task LongPressAccountAsync(AccountViewCellViewModel item)
|
||||
{
|
||||
if (!LongPressAccountEnabled || item == null || !item.IsAccount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (!LongPressAccountEnabled || item == null || !item.IsAccount)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await Task.Delay(100);
|
||||
await HideAsync();
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ namespace Bit.App.Controls
|
|||
_stateService = stateService;
|
||||
_messagingService = messagingService;
|
||||
|
||||
SelectAccountCommand = new AsyncCommand<AccountViewCellViewModel>(SelectAccountAsync,
|
||||
SelectAccountCommand = CreateDefaultAsyncRelayCommand<AccountViewCellViewModel>(SelectAccountAsync,
|
||||
onException: ex => logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
LongPressAccountCommand = new AsyncCommand<Tuple<ContentPage, AccountViewCellViewModel>>(LongPressAccountAsync,
|
||||
LongPressAccountCommand = CreateDefaultAsyncRelayCommand<Tuple<ContentPage, AccountViewCellViewModel>>(LongPressAccountAsync,
|
||||
onException: ex => logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ namespace Bit.App.Controls
|
|||
public class BaseSettingItemView : ContentView
|
||||
{
|
||||
public static readonly BindableProperty TitleProperty = BindableProperty.Create(
|
||||
nameof(Title), typeof(string), typeof(SwitchItemView), null, BindingMode.OneWay);
|
||||
nameof(Title), typeof(string), typeof(SwitchItemView), null);
|
||||
|
||||
public static readonly BindableProperty SubtitleProperty = BindableProperty.Create(
|
||||
nameof(Subtitle), typeof(string), typeof(SwitchItemView), null, BindingMode.OneWay);
|
||||
nameof(Subtitle), typeof(string), typeof(SwitchItemView), null);
|
||||
|
||||
public string Title
|
||||
{
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Bit.App.Controls
|
|||
public partial class SettingChooserItemView : BaseSettingItemView
|
||||
{
|
||||
public static readonly BindableProperty DisplayValueProperty = BindableProperty.Create(
|
||||
nameof(DisplayValue), typeof(string), typeof(SettingChooserItemView), null, BindingMode.OneWay);
|
||||
nameof(DisplayValue), typeof(string), typeof(SettingChooserItemView), null);
|
||||
|
||||
public static readonly BindableProperty ChooseCommandProperty = BindableProperty.Create(
|
||||
nameof(ChooseCommand), typeof(ICommand), typeof(ExternalLinkItemView));
|
||||
|
|
10
src/Core/Enums/Region.cs
Normal file
10
src/Core/Enums/Region.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace Bit.Core.Enums
|
||||
{
|
||||
public enum Region
|
||||
{
|
||||
US,
|
||||
EU,
|
||||
SelfHosted
|
||||
}
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ namespace Bit.App.Lists.ItemViewModels.CustomFields
|
|||
_eventService = eventService;
|
||||
|
||||
CopyFieldCommand = new Command(() => copyFieldCommand?.Execute(Field));
|
||||
ToggleHiddenValueCommand = new AsyncCommand(ToggleHiddenValueAsync, null, ex =>
|
||||
ToggleHiddenValueCommand = CreateDefaultAsyncRelayCommand(ToggleHiddenValueAsync, null, ex =>
|
||||
{
|
||||
//#if !FDROID
|
||||
// Microsoft.AppCenter.Crashes.Crashes.TrackError(ex);
|
||||
|
|
|
@ -1,9 +1,34 @@
|
|||
namespace Bit.Core.Models.Data
|
||||
using System.Text.RegularExpressions;
|
||||
using Bit.Core.Utilities;
|
||||
using BwRegion = Bit.Core.Enums.Region;
|
||||
|
||||
namespace Bit.Core.Models.Data
|
||||
{
|
||||
public class EnvironmentUrlData
|
||||
{
|
||||
public static EnvironmentUrlData DefaultUS = new EnvironmentUrlData { Base = "https://vault.bitwarden.com" };
|
||||
public static EnvironmentUrlData DefaultEU = new EnvironmentUrlData { Base = "https://vault.bitwarden.eu" };
|
||||
public static EnvironmentUrlData DefaultUS = new EnvironmentUrlData
|
||||
{
|
||||
Base = "https://vault.bitwarden.com",
|
||||
Api = "https://api.bitwarden.com",
|
||||
Identity = "https://identity.bitwarden.com",
|
||||
Icons = "https://icons.bitwarden.net",
|
||||
WebVault = "https://vault.bitwarden.com",
|
||||
Notifications = "https://notifications.bitwarden.com",
|
||||
Events = "https://events.bitwarden.com",
|
||||
Domain = "bitwarden.com"
|
||||
};
|
||||
|
||||
public static EnvironmentUrlData DefaultEU = new EnvironmentUrlData
|
||||
{
|
||||
Base = "https://vault.bitwarden.eu",
|
||||
Api = "https://api.bitwarden.eu",
|
||||
Identity = "https://identity.bitwarden.eu",
|
||||
Icons = "https://icons.bitwarden.eu",
|
||||
WebVault = "https://vault.bitwarden.eu",
|
||||
Notifications = "https://notifications.bitwarden.eu",
|
||||
Events = "https://events.bitwarden.eu",
|
||||
Domain = "bitwarden.eu"
|
||||
};
|
||||
|
||||
public string Base { get; set; }
|
||||
public string Api { get; set; }
|
||||
|
@ -12,6 +37,7 @@
|
|||
public string Notifications { get; set; }
|
||||
public string WebVault { get; set; }
|
||||
public string Events { get; set; }
|
||||
public string Domain { get; set; }
|
||||
|
||||
public bool IsEmpty => string.IsNullOrEmpty(Base)
|
||||
&& string.IsNullOrEmpty(Api)
|
||||
|
@ -20,5 +46,63 @@
|
|||
&& string.IsNullOrEmpty(Notifications)
|
||||
&& string.IsNullOrEmpty(WebVault)
|
||||
&& string.IsNullOrEmpty(Events);
|
||||
|
||||
public BwRegion Region
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Base == BwRegion.US.BaseUrl())
|
||||
{
|
||||
return BwRegion.US;
|
||||
}
|
||||
if (Base == BwRegion.EU.BaseUrl())
|
||||
{
|
||||
return BwRegion.EU;
|
||||
}
|
||||
return BwRegion.SelfHosted;
|
||||
}
|
||||
}
|
||||
|
||||
public EnvironmentUrlData FormatUrls()
|
||||
{
|
||||
return new EnvironmentUrlData
|
||||
{
|
||||
Base = FormatUrl(Base),
|
||||
Api = FormatUrl(Api),
|
||||
Identity = FormatUrl(Identity),
|
||||
Icons = FormatUrl(Icons),
|
||||
Notifications = FormatUrl(Notifications),
|
||||
WebVault = FormatUrl(WebVault),
|
||||
Events = FormatUrl(Events)
|
||||
};
|
||||
}
|
||||
|
||||
private string FormatUrl(string url)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
url = Regex.Replace(url, "\\/+$", string.Empty);
|
||||
if (!url.StartsWith("http://") && !url.StartsWith("https://"))
|
||||
{
|
||||
url = string.Concat("https://", url);
|
||||
}
|
||||
return url.Trim();
|
||||
}
|
||||
|
||||
public string GetDomainOrHostname()
|
||||
{
|
||||
var url = WebVault ?? Base ?? Api ?? Identity;
|
||||
if (string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
if (url.Contains(BwRegion.US.Domain()) || url.Contains(BwRegion.EU.Domain()))
|
||||
{
|
||||
return CoreHelpers.GetDomain(url);
|
||||
}
|
||||
return CoreHelpers.GetHostname(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,5 +15,6 @@
|
|||
public bool ManagePolicies { get; set; }
|
||||
public bool ManageSso { get; set; }
|
||||
public bool ManageUsers { get; set; }
|
||||
public bool ManageResetPassword { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using BwRegion = Bit.Core.Enums.Region;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
|
@ -102,12 +102,14 @@ namespace Bit.Core.Models.Domain
|
|||
return;
|
||||
}
|
||||
|
||||
Region = copy.Region;
|
||||
EnvironmentUrls = copy.EnvironmentUrls;
|
||||
VaultTimeout = copy.VaultTimeout;
|
||||
VaultTimeoutAction = copy.VaultTimeoutAction;
|
||||
ScreenCaptureAllowed = copy.ScreenCaptureAllowed;
|
||||
}
|
||||
|
||||
public BwRegion? Region;
|
||||
public EnvironmentUrlData EnvironmentUrls;
|
||||
[Obsolete("Feb 10 2023: VaultTimeout has been deprecated in favor of stored prefs to retain value after logout. It remains here to allow for migration during app upgrade.")]
|
||||
public int? VaultTimeout;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
public class EnvironmentUrls
|
||||
{
|
||||
public string Base { get; set; }
|
||||
public string Api { get; set; }
|
||||
public string Identity { get; set; }
|
||||
public string Events { get; set; }
|
||||
}
|
||||
}
|
|
@ -11,6 +11,12 @@
|
|||
/// Occurs when a user logs in with a master password that does not meet an organization's master password
|
||||
/// policy that is enforced on login.
|
||||
/// </summary>
|
||||
WeakMasterPasswordOnLogin
|
||||
WeakMasterPasswordOnLogin,
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a TDE user without a password obtains the password reset permission.
|
||||
/// Set post login & decryption client side and by server in sync (to catch logged in users).
|
||||
/// </summary>
|
||||
TdeUserWithoutPasswordHasPasswordResetPermission,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,11 @@ namespace Bit.Core.Models.Domain
|
|||
case ForwardedEmailServiceType.DuckDuckGo:
|
||||
return new ForwarderOptions { ApiKey = DuckDuckGoApiKey };
|
||||
case ForwardedEmailServiceType.Fastmail:
|
||||
return new ForwarderOptions { ApiKey = FastMailApiKey };
|
||||
return new FastmailForwarderOptions
|
||||
{
|
||||
ApiKey = FastMailApiKey,
|
||||
Website = EmailWebsite
|
||||
};
|
||||
case ForwardedEmailServiceType.FirefoxRelay:
|
||||
return new ForwarderOptions { ApiKey = FirefoxRelayApiAccessToken };
|
||||
case ForwardedEmailServiceType.SimpleLogin:
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Bit.Core.Models.Request
|
|||
public string MasterPasswordHash { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string MasterPasswordHint { get; set; }
|
||||
public KeysRequest Keys { get; set; }
|
||||
public KeysRequest? Keys { get; set; }
|
||||
public KdfType Kdf { get; set; }
|
||||
public int KdfIterations { get; set; }
|
||||
public int? KdfMemory { get; set; }
|
||||
|
|
|
@ -20,5 +20,6 @@ namespace Bit.Core.Models.Response
|
|||
public List<ProfileOrganizationResponse> Organizations { get; set; }
|
||||
public bool UsesKeyConnector { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
public bool HasManageResetPasswordPermission { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,21 +22,7 @@ namespace Bit.Core.Models.View
|
|||
Email = a.Profile?.Email;
|
||||
Name = a.Profile?.Name;
|
||||
AvatarColor = a.Profile?.AvatarColor;
|
||||
Hostname = ParseEndpoint(a.Settings?.EnvironmentUrls);
|
||||
}
|
||||
|
||||
private string ParseEndpoint(EnvironmentUrlData urls)
|
||||
{
|
||||
var url = urls?.WebVault ?? urls?.Base;
|
||||
if (!string.IsNullOrWhiteSpace(url))
|
||||
{
|
||||
if (url.Contains("bitwarden.com") || url.Contains("bitwarden.eu"))
|
||||
{
|
||||
return CoreHelpers.GetDomain(url);
|
||||
}
|
||||
return CoreHelpers.GetHostname(url);
|
||||
}
|
||||
return string.Empty;
|
||||
Hostname = a.Settings?.EnvironmentUrls?.GetDomainOrHostname();
|
||||
}
|
||||
|
||||
public bool IsAccount { get; set; }
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.App.Utilities;
|
||||
using BwRegion = Bit.Core.Enums.Region;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -19,14 +16,25 @@ namespace Bit.App.Pages
|
|||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
|
||||
PageTitle = AppResources.Settings;
|
||||
BaseUrl = _environmentService.BaseUrl == EnvironmentUrlData.DefaultEU.Base || EnvironmentUrlData.DefaultUS.Base == _environmentService.BaseUrl ?
|
||||
string.Empty : _environmentService.BaseUrl;
|
||||
SubmitCommand = CreateDefaultAsyncRelayCommand(SubmitAsync, onException: OnSubmitException, allowsMultipleExecutions: false);
|
||||
Init();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
if (_environmentService.SelectedRegion != BwRegion.SelfHosted ||
|
||||
_environmentService.BaseUrl == BwRegion.US.BaseUrl() ||
|
||||
_environmentService.BaseUrl == BwRegion.EU.BaseUrl())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BaseUrl = _environmentService.BaseUrl;
|
||||
WebVaultUrl = _environmentService.WebVaultUrl;
|
||||
ApiUrl = _environmentService.ApiUrl;
|
||||
IdentityUrl = _environmentService.IdentityUrl;
|
||||
IconsUrl = _environmentService.IconsUrl;
|
||||
NotificationsUrls = _environmentService.NotificationsUrl;
|
||||
SubmitCommand = new AsyncCommand(SubmitAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public ICommand SubmitCommand { get; }
|
||||
|
@ -46,8 +54,7 @@ namespace Bit.App.Pages
|
|||
await Page.DisplayAlert(AppResources.AnErrorHasOccurred, AppResources.EnvironmentPageUrlsError, AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
var resUrls = await _environmentService.SetUrlsAsync(new Core.Models.Data.EnvironmentUrlData
|
||||
var urls = new Core.Models.Data.EnvironmentUrlData
|
||||
{
|
||||
Base = BaseUrl,
|
||||
Api = ApiUrl,
|
||||
|
@ -55,7 +62,8 @@ namespace Bit.App.Pages
|
|||
WebVault = WebVaultUrl,
|
||||
Icons = IconsUrl,
|
||||
Notifications = NotificationsUrls
|
||||
});
|
||||
};
|
||||
var resUrls = await _environmentService.SetRegionAsync(urls.Region, urls);
|
||||
|
||||
// re-set urls since service can change them, ex: prefixing https://
|
||||
BaseUrl = resUrls.Base;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.App.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -25,7 +23,7 @@ namespace Bit.App.Pages
|
|||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
|
||||
PageTitle = AppResources.PasswordHint;
|
||||
SubmitCommand = new AsyncCommand(SubmitAsync,
|
||||
SubmitCommand = CreateDefaultAsyncRelayCommand(SubmitAsync,
|
||||
onException: ex =>
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
|
|
|
@ -58,7 +58,6 @@ namespace Bit.App.Pages
|
|||
try
|
||||
{
|
||||
_accountAvatar?.OnAppearing();
|
||||
|
||||
if (!_appOptions?.HideAccountSwitcher ?? false)
|
||||
{
|
||||
await MainThread.InvokeOnMainThreadAsync(async () => _vm.AvatarImageSource = await GetAvatarImageSourceAsync(false));
|
||||
|
@ -71,14 +70,14 @@ namespace Bit.App.Pages
|
|||
}
|
||||
});
|
||||
|
||||
await _vm.UpdateEnvironment();
|
||||
await _vm.UpdateEnvironmentAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Value?.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void OnNavigatingFrom(NavigatingFromEventArgs args)
|
||||
{
|
||||
base.OnNavigatingFrom(args);
|
||||
|
@ -89,7 +88,7 @@ namespace Bit.App.Pages
|
|||
|
||||
protected override bool OnBackButtonPressed()
|
||||
{
|
||||
if (_accountListOverlay.IsVisible)
|
||||
if (_accountListOverlay.IsVisible)
|
||||
{
|
||||
_accountListOverlay.HideAsync().FireAndForget();
|
||||
return true;
|
||||
|
|
|
@ -1,23 +1,17 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using BwRegion = Bit.Core.Enums.Region;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class HomeViewModel : BaseViewModel
|
||||
{
|
||||
private const string LOGGING_IN_ON_US = "bitwarden.com";
|
||||
private const string LOGGING_IN_ON_EU = "bitwarden.eu";
|
||||
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
|
@ -50,12 +44,12 @@ namespace Bit.App.Pages
|
|||
AllowActiveAccountSelection = true
|
||||
};
|
||||
RememberEmailCommand = new Command(() => RememberEmail = !RememberEmail);
|
||||
ContinueCommand = new AsyncCommand(ContinueToLoginStepAsync, allowsMultipleExecutions: false);
|
||||
CreateAccountCommand = new AsyncCommand(async () => Device.InvokeOnMainThreadAsync(StartRegisterAction),
|
||||
ContinueCommand = CreateDefaultAsyncRelayCommand(ContinueToLoginStepAsync, allowsMultipleExecutions: false);
|
||||
CreateAccountCommand = CreateDefaultAsyncRelayCommand(async () => Device.InvokeOnMainThreadAsync(StartRegisterAction),
|
||||
onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
CloseCommand = new AsyncCommand(async () => Device.InvokeOnMainThreadAsync(CloseAction),
|
||||
CloseCommand = CreateDefaultAsyncRelayCommand(async () => Device.InvokeOnMainThreadAsync(CloseAction),
|
||||
onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
ShowEnvironmentPickerCommand = new AsyncCommand(ShowEnvironmentPickerAsync,
|
||||
ShowEnvironmentPickerCommand = CreateDefaultAsyncRelayCommand(ShowEnvironmentPickerAsync,
|
||||
onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
InitAsync().FireAndForget();
|
||||
}
|
||||
|
@ -113,10 +107,10 @@ namespace Bit.App.Pages
|
|||
public Action StartEnvironmentAction { get; set; }
|
||||
public Action CloseAction { get; set; }
|
||||
public Command RememberEmailCommand { get; set; }
|
||||
public AsyncCommand ContinueCommand { get; }
|
||||
public AsyncCommand CloseCommand { get; }
|
||||
public AsyncCommand CreateAccountCommand { get; }
|
||||
public AsyncCommand ShowEnvironmentPickerCommand { get; }
|
||||
public AsyncRelayCommand ContinueCommand { get; }
|
||||
public AsyncRelayCommand CloseCommand { get; }
|
||||
public AsyncRelayCommand CreateAccountCommand { get; }
|
||||
public AsyncRelayCommand ShowEnvironmentPickerCommand { get; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
|
@ -166,10 +160,10 @@ namespace Bit.App.Pages
|
|||
{
|
||||
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag);
|
||||
var options = _displayEuEnvironment
|
||||
? new string[] { LOGGING_IN_ON_US, LOGGING_IN_ON_EU, AppResources.SelfHosted }
|
||||
: new string[] { LOGGING_IN_ON_US, AppResources.SelfHosted };
|
||||
? new string[] { BwRegion.US.Domain(), BwRegion.EU.Domain(), AppResources.SelfHosted }
|
||||
: new string[] { BwRegion.US.Domain(), AppResources.SelfHosted };
|
||||
|
||||
await Device.InvokeOnMainThreadAsync(async () =>
|
||||
await MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
var result = await Page.DisplayActionSheet(AppResources.LoggingInOn, AppResources.Cancel, null, options);
|
||||
|
||||
|
@ -184,35 +178,23 @@ namespace Bit.App.Pages
|
|||
return;
|
||||
}
|
||||
|
||||
await _environmentService.SetUrlsAsync(result == LOGGING_IN_ON_EU ? EnvironmentUrlData.DefaultEU : EnvironmentUrlData.DefaultUS);
|
||||
await _environmentService.SetRegionAsync(result == BwRegion.EU.Domain() ? BwRegion.EU : BwRegion.US);
|
||||
await _configService.GetAsync(true);
|
||||
SelectedEnvironmentName = result;
|
||||
});
|
||||
}
|
||||
|
||||
public async Task UpdateEnvironment()
|
||||
public async Task UpdateEnvironmentAsync()
|
||||
{
|
||||
var environmentsSaved = await _stateService.GetPreAuthEnvironmentUrlsAsync();
|
||||
if (environmentsSaved == null || environmentsSaved.IsEmpty)
|
||||
var region = _environmentService.SelectedRegion;
|
||||
if (region == BwRegion.SelfHosted)
|
||||
{
|
||||
await _environmentService.SetUrlsAsync(EnvironmentUrlData.DefaultUS);
|
||||
environmentsSaved = EnvironmentUrlData.DefaultUS;
|
||||
SelectedEnvironmentName = LOGGING_IN_ON_US;
|
||||
return;
|
||||
}
|
||||
|
||||
if (environmentsSaved.Base == EnvironmentUrlData.DefaultUS.Base)
|
||||
{
|
||||
SelectedEnvironmentName = LOGGING_IN_ON_US;
|
||||
}
|
||||
else if (environmentsSaved.Base == EnvironmentUrlData.DefaultEU.Base)
|
||||
{
|
||||
SelectedEnvironmentName = LOGGING_IN_ON_EU;
|
||||
SelectedEnvironmentName = AppResources.SelfHosted;
|
||||
await _configService.GetAsync(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _configService.GetAsync(true);
|
||||
SelectedEnvironmentName = AppResources.SelfHosted;
|
||||
SelectedEnvironmentName = region.Domain();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,13 +208,8 @@ namespace Bit.App.Pages
|
|||
_logger.Exception(new NullReferenceException("Email not found in storage"));
|
||||
return;
|
||||
}
|
||||
var webVault = _environmentService.GetWebVaultUrl(true);
|
||||
if (string.IsNullOrWhiteSpace(webVault))
|
||||
{
|
||||
webVault = "https://bitwarden.com";
|
||||
}
|
||||
var webVaultHostname = CoreHelpers.GetHostname(webVault);
|
||||
LoggedInAsText = string.Format(AppResources.LoggedInAsOn, _email, webVaultHostname);
|
||||
|
||||
LoggedInAsText = string.Format(AppResources.LoggedInAsOn, _email, _environmentService.GetCurrentDomain());
|
||||
if (PinEnabled)
|
||||
{
|
||||
PageTitle = AppResources.VerifyPIN;
|
||||
|
|
|
@ -55,19 +55,19 @@ namespace Bit.App.Pages
|
|||
PageTitle = AppResources.LogInInitiated;
|
||||
RememberThisDevice = true;
|
||||
|
||||
ApproveWithMyOtherDeviceCommand = new AsyncCommand(() => SetDeviceTrustAndInvokeAsync(LogInWithDeviceAction),
|
||||
ApproveWithMyOtherDeviceCommand = CreateDefaultAsyncRelayCommand(() => SetDeviceTrustAndInvokeAsync(LogInWithDeviceAction),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
RequestAdminApprovalCommand = new AsyncCommand(() => SetDeviceTrustAndInvokeAsync(RequestAdminApprovalAction),
|
||||
RequestAdminApprovalCommand = CreateDefaultAsyncRelayCommand(() => SetDeviceTrustAndInvokeAsync(RequestAdminApprovalAction),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
ApproveWithMasterPasswordCommand = new AsyncCommand(() => SetDeviceTrustAndInvokeAsync(LogInWithMasterPasswordAction),
|
||||
ApproveWithMasterPasswordCommand = CreateDefaultAsyncRelayCommand(() => SetDeviceTrustAndInvokeAsync(LogInWithMasterPasswordAction),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
ContinueCommand = new AsyncCommand(CreateNewSsoUserAsync,
|
||||
ContinueCommand = CreateDefaultAsyncRelayCommand(CreateNewSsoUserAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@ namespace Bit.App.Pages
|
|||
PageTitle = AppResources.Bitwarden;
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
LogInCommand = new Command(async () => await LogInAsync());
|
||||
MoreCommand = new AsyncCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
LogInWithDeviceCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithDeviceAction), onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
MoreCommand = CreateDefaultAsyncRelayCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
LogInWithDeviceCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(LogInWithDeviceAction), onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
|
||||
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
|
||||
{
|
||||
|
@ -163,7 +163,7 @@ namespace Bit.App.Pages
|
|||
Email = await _stateService.GetRememberedEmailAsync();
|
||||
}
|
||||
CanRemoveAccount = await _stateService.GetActiveUserEmailAsync() != Email;
|
||||
EnvironmentDomainName = CoreHelpers.GetDomain((await _stateService.GetPreAuthEnvironmentUrlsAsync())?.Base);
|
||||
EnvironmentDomainName = _environmentService.GetCurrentDomain();
|
||||
IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, await _appIdService.GetAppIdAsync());
|
||||
}
|
||||
catch (ApiException apiEx) when (apiEx.Error.StatusCode == System.Net.HttpStatusCode.Unauthorized)
|
||||
|
|
|
@ -56,11 +56,11 @@ namespace Bit.App.Pages
|
|||
_cryptoFunctionService = ServiceContainer.Resolve<ICryptoFunctionService>();
|
||||
_cryptoService = ServiceContainer.Resolve<ICryptoService>();
|
||||
|
||||
CreatePasswordlessLoginCommand = new AsyncCommand(CreatePasswordlessLoginAsync,
|
||||
CreatePasswordlessLoginCommand = CreateDefaultAsyncRelayCommand(CreatePasswordlessLoginAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
CloseCommand = new AsyncCommand(() => MainThread.InvokeOnMainThreadAsync(CloseAction),
|
||||
CloseCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(CloseAction),
|
||||
onException: _logger.Exception,
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -39,10 +39,10 @@ namespace Bit.App.Pages
|
|||
|
||||
PageTitle = AppResources.LogInRequested;
|
||||
|
||||
AcceptRequestCommand = new AsyncCommand(() => PasswordlessLoginAsync(true),
|
||||
AcceptRequestCommand = CreateDefaultAsyncRelayCommand(() => PasswordlessLoginAsync(true),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
RejectRequestCommand = new AsyncCommand(() => PasswordlessLoginAsync(false),
|
||||
RejectRequestCommand = CreateDefaultAsyncRelayCommand(() => PasswordlessLoginAsync(false),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace Bit.App.Pages
|
|||
_cryptoService = ServiceContainer.Resolve<ICryptoService>();
|
||||
|
||||
PageTitle = AppResources.Bitwarden;
|
||||
LogInCommand = new AsyncCommand(LogInAsync, allowsMultipleExecutions: false);
|
||||
LogInCommand = CreateDefaultAsyncRelayCommand(LogInAsync, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public string OrgIdentifier
|
||||
|
@ -231,19 +231,18 @@ namespace Bit.App.Pages
|
|||
StartDeviceApprovalOptionsAction?.Invoke();
|
||||
return;
|
||||
}
|
||||
// If user doesn't have a MP, but has reset password permission, they must set a MP
|
||||
if (!decryptOptions.HasMasterPassword &&
|
||||
decryptOptions.TrustedDeviceOption.HasManageResetPasswordPermission)
|
||||
{
|
||||
StartSetPasswordAction?.Invoke();
|
||||
return;
|
||||
}
|
||||
// Update temp password only if the device is trusted and therefore has a decrypted User Key set
|
||||
if (response.ForcePasswordReset)
|
||||
{
|
||||
UpdateTempPasswordAction?.Invoke();
|
||||
return;
|
||||
}
|
||||
// If user doesn't have a MP, but has reset password permission, they must set a MP
|
||||
if (!decryptOptions.HasMasterPassword &&
|
||||
decryptOptions.TrustedDeviceOption.HasManageResetPasswordPermission)
|
||||
{
|
||||
await _stateService.SetForcePasswordResetReasonAsync(ForcePasswordResetReason.TdeUserWithoutPasswordHasPasswordResetPermission);
|
||||
}
|
||||
// Device is trusted and has keys, so we can decrypt
|
||||
_syncService.FullSyncAsync(true).FireAndForget();
|
||||
SsoAuthSuccessAction?.Invoke();
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<StackLayout Spacing="20">
|
||||
<StackLayout StyleClass="box">
|
||||
<StackLayout StyleClass="box-row">
|
||||
<Label Text="{u:I18n SetMasterPasswordSummary}"
|
||||
<Label Text="{Binding SetMasterPasswordSummary}"
|
||||
StyleClass="text-md"
|
||||
HorizontalTextAlignment="Start"></Label>
|
||||
</StackLayout>
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
|
@ -13,9 +9,6 @@ using Bit.Core.Exceptions;
|
|||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.Networking;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -29,6 +22,7 @@ namespace Bit.App.Pages
|
|||
private readonly IPolicyService _policyService;
|
||||
private readonly IPasswordGenerationService _passwordGenerationService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly ISyncService _syncService;
|
||||
|
||||
private bool _showPassword;
|
||||
private bool _isPolicyInEffect;
|
||||
|
@ -47,6 +41,7 @@ namespace Bit.App.Pages
|
|||
_passwordGenerationService =
|
||||
ServiceContainer.Resolve<IPasswordGenerationService>("passwordGenerationService");
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_syncService = ServiceContainer.Resolve<ISyncService>();
|
||||
|
||||
PageTitle = AppResources.SetMasterPassword;
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
|
@ -101,11 +96,17 @@ namespace Bit.App.Pages
|
|||
public Action CloseAction { get; set; }
|
||||
public string OrgIdentifier { get; set; }
|
||||
public string OrgId { get; set; }
|
||||
public ForcePasswordResetReason? ForceSetPasswordReason { get; private set; }
|
||||
|
||||
public string SetMasterPasswordSummary => ForceSetPasswordReason == ForcePasswordResetReason.TdeUserWithoutPasswordHasPasswordResetPermission
|
||||
? AppResources.YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword
|
||||
: AppResources.YourOrganizationRequiresYouToSetAMasterPassword;
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
await CheckPasswordPolicy();
|
||||
|
||||
ForceSetPasswordReason = await _stateService.GetForcePasswordResetReasonAsync();
|
||||
TriggerPropertyChanged(nameof(SetMasterPasswordSummary));
|
||||
try
|
||||
{
|
||||
var response = await _apiService.GetOrganizationAutoEnrollStatusAsync(OrgIdentifier);
|
||||
|
@ -172,8 +173,7 @@ namespace Bit.App.Pages
|
|||
|
||||
var (newUserKey, newProtectedUserKey) = await _cryptoService.EncryptUserKeyWithMasterKeyAsync(newMasterKey,
|
||||
await _cryptoService.GetUserKeyAsync() ?? await _cryptoService.MakeUserKeyAsync());
|
||||
|
||||
var (newPublicKey, newProtectedPrivateKey) = await _cryptoService.MakeKeyPairAsync(newUserKey);
|
||||
var keysRequest = await GetKeysForSetPasswordRequestAsync(newUserKey);
|
||||
var request = new SetPasswordRequest
|
||||
{
|
||||
MasterPasswordHash = masterPasswordHash,
|
||||
|
@ -184,16 +184,12 @@ namespace Bit.App.Pages
|
|||
KdfMemory = kdfConfig.Memory,
|
||||
KdfParallelism = kdfConfig.Parallelism,
|
||||
OrgIdentifier = OrgIdentifier,
|
||||
Keys = new KeysRequest
|
||||
{
|
||||
PublicKey = newPublicKey,
|
||||
EncryptedPrivateKey = newProtectedPrivateKey.EncryptedString
|
||||
}
|
||||
Keys = keysRequest
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.CreatingAccount);
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
|
||||
// Set Password and relevant information
|
||||
await _apiService.SetPasswordAsync(request);
|
||||
await _stateService.SetKdfConfigurationAsync(kdfConfig);
|
||||
|
@ -201,7 +197,13 @@ namespace Bit.App.Pages
|
|||
await _cryptoService.SetMasterKeyAsync(newMasterKey);
|
||||
await _cryptoService.SetMasterKeyHashAsync(localMasterPasswordHash);
|
||||
await _cryptoService.SetMasterKeyEncryptedUserKeyAsync(newProtectedUserKey.EncryptedString);
|
||||
await _cryptoService.SetUserPrivateKeyAsync(newProtectedPrivateKey.EncryptedString);
|
||||
|
||||
// Set private key only for new JIT provisioned users in MP encryption orgs
|
||||
// Existing TDE users will have private key set on sync or on login
|
||||
if (keysRequest != null)
|
||||
{
|
||||
await _cryptoService.SetUserPrivateKeyAsync(keysRequest.EncryptedPrivateKey);
|
||||
}
|
||||
|
||||
if (ResetPasswordAutoEnroll)
|
||||
{
|
||||
|
@ -222,6 +224,9 @@ namespace Bit.App.Pages
|
|||
await _apiService.PutOrganizationUserResetPasswordEnrollmentAsync(OrgId, userId, resetRequest);
|
||||
}
|
||||
|
||||
await _stateService.SetForcePasswordResetReasonAsync(null);
|
||||
await _stateService.SetUserHasMasterPasswordAsync(true);
|
||||
await _syncService.FullSyncAsync(true);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
SetPasswordSuccessAction?.Invoke();
|
||||
}
|
||||
|
@ -236,6 +241,21 @@ namespace Bit.App.Pages
|
|||
}
|
||||
}
|
||||
|
||||
private async Task<KeysRequest> GetKeysForSetPasswordRequestAsync(UserKey newUserKey)
|
||||
{
|
||||
if (ForceSetPasswordReason == ForcePasswordResetReason.TdeUserWithoutPasswordHasPasswordResetPermission)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var (newPublicKey, newProtectedPrivateKey) = await _cryptoService.MakeKeyPairAsync(newUserKey);
|
||||
return new KeysRequest
|
||||
{
|
||||
PublicKey = newPublicKey,
|
||||
EncryptedPrivateKey = newProtectedPrivateKey.EncryptedString
|
||||
};
|
||||
}
|
||||
|
||||
public void TogglePassword()
|
||||
{
|
||||
ShowPassword = !ShowPassword;
|
||||
|
|
|
@ -10,6 +10,7 @@ using Bit.App.Utilities;
|
|||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
@ -62,7 +63,7 @@ namespace Bit.App.Pages
|
|||
|
||||
PageTitle = AppResources.TwoStepLogin;
|
||||
SubmitCommand = new Command(async () => await SubmitAsync());
|
||||
MoreCommand = new AsyncCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
MoreCommand = CreateDefaultAsyncRelayCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public string TotpInstruction
|
||||
|
@ -338,20 +339,18 @@ Device.RuntimePlatform == Device.iOS ? AppResources.YubiKeyInstructionIos :
|
|||
StartDeviceApprovalOptionsAction?.Invoke();
|
||||
return;
|
||||
}
|
||||
// If user doesn't have a MP, but has reset password permission, they must set a MP
|
||||
if (!decryptOptions.HasMasterPassword &&
|
||||
decryptOptions.TrustedDeviceOption.HasManageResetPasswordPermission)
|
||||
{
|
||||
StartSetPasswordAction?.Invoke();
|
||||
return;
|
||||
}
|
||||
// Update temp password only if the device is trusted and therefore has a decrypted User Key set
|
||||
if (result.ForcePasswordReset)
|
||||
{
|
||||
UpdateTempPasswordAction?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
// If user doesn't have a MP, but has reset password permission, they must set a MP
|
||||
if (!decryptOptions.HasMasterPassword &&
|
||||
decryptOptions.TrustedDeviceOption.HasManageResetPasswordPermission)
|
||||
{
|
||||
await _stateService.SetForcePasswordResetReasonAsync(ForcePasswordResetReason.TdeUserWithoutPasswordHasPasswordResetPermission);
|
||||
}
|
||||
// Device is trusted and has keys, so we can decrypt
|
||||
_syncService.FullSyncAsync(true).FireAndForget();
|
||||
await TwoFactorAuthSuccessAsync();
|
||||
|
|
|
@ -11,6 +11,7 @@ using Bit.Core.Utilities;
|
|||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -25,14 +26,14 @@ namespace Bit.App.Pages
|
|||
PageTitle = AppResources.UpdateMasterPassword;
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword);
|
||||
SubmitCommand = new AsyncCommand(SubmitAsync,
|
||||
SubmitCommand = CreateDefaultAsyncRelayCommand(SubmitAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
_userVerificationService = ServiceContainer.Resolve<IUserVerificationService>();
|
||||
}
|
||||
|
||||
public AsyncCommand SubmitCommand { get; }
|
||||
public AsyncRelayCommand SubmitCommand { get; }
|
||||
public Command TogglePasswordCommand { get; }
|
||||
public Command ToggleConfirmPasswordCommand { get; }
|
||||
public Action UpdateTempPasswordSuccessAction { get; set; }
|
||||
|
|
|
@ -39,8 +39,8 @@ namespace Bit.App.Pages
|
|||
PageTitle = AppResources.VerificationCode;
|
||||
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
MainActionCommand = new AsyncCommand(MainActionAsync, allowsMultipleExecutions: false);
|
||||
RequestOTPCommand = new AsyncCommand(RequestOTPAsync, allowsMultipleExecutions: false);
|
||||
MainActionCommand = CreateDefaultAsyncRelayCommand(MainActionAsync, allowsMultipleExecutions: false);
|
||||
RequestOTPCommand = CreateDefaultAsyncRelayCommand(RequestOTPAsync, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public bool ShowPassword
|
||||
|
|
|
@ -1,27 +1,13 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Controls;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Microsoft.Maui.Networking;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Bit.App.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public abstract class BaseViewModel : ExtendedViewModel
|
||||
{
|
||||
private string _pageTitle = string.Empty;
|
||||
private AvatarImageSource _avatar;
|
||||
private LazyResolve<IDeviceActionService> _deviceActionService = new LazyResolve<IDeviceActionService>();
|
||||
private LazyResolve<IPlatformUtilsService> _platformUtilsService = new LazyResolve<IPlatformUtilsService>();
|
||||
private LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
|
||||
|
||||
public string PageTitle
|
||||
{
|
||||
|
@ -37,29 +23,6 @@ namespace Bit.App.Pages
|
|||
|
||||
public ContentPage Page { get; set; }
|
||||
|
||||
protected void HandleException(Exception ex, string message = null)
|
||||
{
|
||||
if (ex is ApiException apiException && apiException.Error != null)
|
||||
{
|
||||
message = apiException.Error.GetSingleMessage();
|
||||
}
|
||||
|
||||
Microsoft.Maui.ApplicationModel.MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
await _deviceActionService.Value.HideLoadingAsync();
|
||||
await _platformUtilsService.Value.ShowDialogAsync(message ?? AppResources.GenericErrorMessage);
|
||||
}).FireAndForget();
|
||||
_logger.Value.Exception(ex);
|
||||
}
|
||||
|
||||
protected AsyncCommand CreateDefaultAsyncCommnad(Func<Task> execute, Func<bool> canExecute = null)
|
||||
{
|
||||
return new AsyncCommand(execute,
|
||||
canExecute,
|
||||
ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
protected async Task<bool> HasConnectivityAsync()
|
||||
{
|
||||
if (Connectivity.NetworkAccess == NetworkAccess.None)
|
||||
|
|
|
@ -89,11 +89,11 @@ namespace Bit.App.Pages
|
|||
};
|
||||
|
||||
UsernameTypePromptHelpCommand = new Command(UsernameTypePromptHelp);
|
||||
RegenerateCommand = new AsyncCommand(RegenerateAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
RegenerateUsernameCommand = new AsyncCommand(RegenerateUsernameAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
RegenerateCommand = CreateDefaultAsyncRelayCommand(RegenerateAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
RegenerateUsernameCommand = CreateDefaultAsyncRelayCommand(RegenerateUsernameAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
ToggleForwardedEmailHiddenValueCommand = new Command(() => ShowForwardedEmailApiSecret = !ShowForwardedEmailApiSecret);
|
||||
CopyCommand = new AsyncCommand(CopyAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
CloseCommand = new AsyncCommand(CloseAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyCommand = CreateDefaultAsyncRelayCommand(CopyAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
CloseCommand = CreateDefaultAsyncRelayCommand(CloseAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public List<GeneratorType> GeneratorTypeOptions { get; set; }
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -33,10 +32,10 @@ namespace Bit.App.Pages
|
|||
_onSelectionChangingAsync = onSelectionChangingAsync;
|
||||
_title = title;
|
||||
|
||||
SelectOptionCommand = new AsyncCommand(SelectOptionAsync, canExecuteSelectOptionCommand, onSelectOptionCommandException, allowsMultipleExecutions: false);
|
||||
SelectOptionCommand = CreateDefaultAsyncRelayCommand(SelectOptionAsync, canExecuteSelectOptionCommand, onSelectOptionCommandException, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public AsyncCommand SelectOptionCommand { get; }
|
||||
public AsyncRelayCommand SelectOptionCommand { get; }
|
||||
|
||||
public TKey SelectedKey => _selectedKey;
|
||||
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -29,32 +26,32 @@ namespace Bit.App.Pages
|
|||
var environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
var clipboardService = ServiceContainer.Resolve<IClipboardService>();
|
||||
|
||||
ToggleSubmitCrashLogsCommand = CreateDefaultAsyncCommnad(ToggleSubmitCrashLogsAsync);
|
||||
ToggleSubmitCrashLogsCommand = CreateDefaultAsyncRelayCommand(ToggleSubmitCrashLogsAsync, allowsMultipleExecutions: false);
|
||||
|
||||
GoToHelpCenterCommand = CreateDefaultAsyncCommnad(
|
||||
GoToHelpCenterCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.LearnMoreAboutHowToUseBitwardenOnTheHelpCenter,
|
||||
AppResources.ContinueToHelpCenter,
|
||||
ExternalLinksConstants.HELP_CENTER));
|
||||
ExternalLinksConstants.HELP_CENTER), allowsMultipleExecutions: false);
|
||||
|
||||
ContactBitwardenSupportCommand = CreateDefaultAsyncCommnad(
|
||||
ContactBitwardenSupportCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.ContactSupportDescriptionLong,
|
||||
AppResources.ContinueToContactSupport,
|
||||
ExternalLinksConstants.CONTACT_SUPPORT));
|
||||
ExternalLinksConstants.CONTACT_SUPPORT), allowsMultipleExecutions: false);
|
||||
|
||||
GoToWebVaultCommand = CreateDefaultAsyncCommnad(
|
||||
GoToWebVaultCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp,
|
||||
AppResources.ContinueToWebApp,
|
||||
environmentService.GetWebVaultUrl()));
|
||||
environmentService.GetWebVaultUrl()), allowsMultipleExecutions: false);
|
||||
|
||||
GoToLearnAboutOrgsCommand = CreateDefaultAsyncCommnad(
|
||||
GoToLearnAboutOrgsCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.LearnAboutOrganizationsDescriptionLong,
|
||||
string.Format(AppResources.ContinueToX, ExternalLinksConstants.BITWARDEN_WEBSITE),
|
||||
ExternalLinksConstants.HELP_ABOUT_ORGANIZATIONS));
|
||||
ExternalLinksConstants.HELP_ABOUT_ORGANIZATIONS), allowsMultipleExecutions: false);
|
||||
|
||||
RateTheAppCommand = CreateDefaultAsyncCommnad(RateAppAsync);
|
||||
RateTheAppCommand = CreateDefaultAsyncRelayCommand(RateAppAsync, allowsMultipleExecutions: false);
|
||||
|
||||
CopyAppInfoCommand = CreateDefaultAsyncCommnad(
|
||||
() => clipboardService.CopyTextAsync(AppInfo));
|
||||
CopyAppInfoCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => clipboardService.CopyTextAsync(AppInfo), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public bool ShouldSubmitCrashLogs
|
||||
|
@ -80,7 +77,7 @@ namespace Bit.App.Pages
|
|||
}
|
||||
}
|
||||
|
||||
public AsyncCommand ToggleSubmitCrashLogsCommand { get; }
|
||||
public AsyncRelayCommand ToggleSubmitCrashLogsCommand { get; }
|
||||
public ICommand GoToHelpCenterCommand { get; }
|
||||
public ICommand ContactBitwardenSupportCommand { get; }
|
||||
public ICommand GoToWebVaultCommand { get; }
|
||||
|
@ -97,7 +94,7 @@ namespace Bit.App.Pages
|
|||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
TriggerPropertyChanged(nameof(ShouldSubmitCrashLogs));
|
||||
ToggleSubmitCrashLogsCommand.RaiseCanExecuteChanged();
|
||||
ToggleSubmitCrashLogsCommand.NotifyCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -64,7 +58,7 @@ namespace Bit.App.Pages
|
|||
() => _inited,
|
||||
ex => HandleException(ex));
|
||||
|
||||
ToggleShowWebsiteIconsCommand = CreateDefaultAsyncCommnad(ToggleShowWebsiteIconsAsync, () => _inited);
|
||||
ToggleShowWebsiteIconsCommand = CreateDefaultAsyncRelayCommand(ToggleShowWebsiteIconsAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public PickerViewModel<string> LanguagePickerViewModel { get; }
|
||||
|
@ -87,7 +81,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public bool IsShowWebsiteIconsEnabled => ToggleShowWebsiteIconsCommand.CanExecute(null);
|
||||
|
||||
public AsyncCommand ToggleShowWebsiteIconsCommand { get; }
|
||||
public AsyncRelayCommand ToggleShowWebsiteIconsCommand { get; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
|
@ -102,10 +96,10 @@ namespace Bit.App.Pages
|
|||
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
ToggleShowWebsiteIconsCommand.RaiseCanExecuteChanged();
|
||||
LanguagePickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
ThemePickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
DefaultDarkThemePickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
ToggleShowWebsiteIconsCommand.NotifyCanExecuteChanged();
|
||||
LanguagePickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
ThemePickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
DefaultDarkThemePickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -16,8 +12,7 @@ namespace Bit.App.Pages
|
|||
private bool _useDrawOver;
|
||||
private bool _askToAddLogin;
|
||||
|
||||
public bool SupportsAndroidAutofillServices => // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
Device.RuntimePlatform == Device.Android && _deviceActionService.SupportsAutofillServices();
|
||||
public bool SupportsAndroidAutofillServices => DeviceInfo.Platform == DevicePlatform.Android && _deviceActionService.SupportsAutofillServices();
|
||||
|
||||
public bool UseAutofillServices
|
||||
{
|
||||
|
@ -45,8 +40,7 @@ Device.RuntimePlatform == Device.Android && _deviceActionService.SupportsAutofil
|
|||
}
|
||||
}
|
||||
|
||||
public bool ShowUseAccessibilityToggle => // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
Device.RuntimePlatform == Device.Android;
|
||||
public bool ShowUseAccessibilityToggle => DeviceInfo.Platform == DevicePlatform.Android;
|
||||
|
||||
public string UseAccessibilityDescription => _deviceActionService.GetAutofillAccessibilityDescription();
|
||||
|
||||
|
@ -90,21 +84,21 @@ Device.RuntimePlatform == Device.Android;
|
|||
}
|
||||
}
|
||||
|
||||
public AsyncCommand ToggleUseAutofillServicesCommand { get; private set; }
|
||||
public AsyncCommand ToggleUseInlineAutofillCommand { get; private set; }
|
||||
public AsyncCommand ToggleUseAccessibilityCommand { get; private set; }
|
||||
public AsyncCommand ToggleUseDrawOverCommand { get; private set; }
|
||||
public AsyncCommand ToggleAskToAddLoginCommand { get; private set; }
|
||||
public AsyncRelayCommand ToggleUseAutofillServicesCommand { get; private set; }
|
||||
public AsyncRelayCommand ToggleUseInlineAutofillCommand { get; private set; }
|
||||
public AsyncRelayCommand ToggleUseAccessibilityCommand { get; private set; }
|
||||
public AsyncRelayCommand ToggleUseDrawOverCommand { get; private set; }
|
||||
public AsyncRelayCommand ToggleAskToAddLoginCommand { get; private set; }
|
||||
public ICommand GoToBlockAutofillUrisCommand { get; private set; }
|
||||
|
||||
private void InitAndroidCommands()
|
||||
{
|
||||
ToggleUseAutofillServicesCommand = CreateDefaultAsyncCommnad(() => MainThread.InvokeOnMainThreadAsync(() => ToggleUseAutofillServices()), () => _inited);
|
||||
ToggleUseInlineAutofillCommand = CreateDefaultAsyncCommnad(() => MainThread.InvokeOnMainThreadAsync(() => ToggleUseInlineAutofillEnabledAsync()), () => _inited);
|
||||
ToggleUseAccessibilityCommand = CreateDefaultAsyncCommnad(ToggleUseAccessibilityAsync, () => _inited);
|
||||
ToggleUseDrawOverCommand = CreateDefaultAsyncCommnad(() => MainThread.InvokeOnMainThreadAsync(() => ToggleDrawOver()), () => _inited);
|
||||
ToggleAskToAddLoginCommand = CreateDefaultAsyncCommnad(ToggleAskToAddLoginAsync, () => _inited);
|
||||
GoToBlockAutofillUrisCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushAsync(new BlockAutofillUrisPage()));
|
||||
ToggleUseAutofillServicesCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(() => ToggleUseAutofillServices()), () => _inited, allowsMultipleExecutions: false);
|
||||
ToggleUseInlineAutofillCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(() => ToggleUseInlineAutofillEnabledAsync()), () => _inited, allowsMultipleExecutions: false);
|
||||
ToggleUseAccessibilityCommand = CreateDefaultAsyncRelayCommand(ToggleUseAccessibilityAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
ToggleUseDrawOverCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(() => ToggleDrawOver()), () => _inited, allowsMultipleExecutions: false);
|
||||
ToggleAskToAddLoginCommand = CreateDefaultAsyncRelayCommand(ToggleAskToAddLoginAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
GoToBlockAutofillUrisCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushAsync(new BlockAutofillUrisPage()), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
private async Task InitAndroidAutofillSettingsAsync()
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -36,7 +33,7 @@ namespace Bit.App.Pages
|
|||
() => _inited,
|
||||
ex => HandleException(ex));
|
||||
|
||||
ToggleCopyTotpAutomaticallyCommand = CreateDefaultAsyncCommnad(ToggleCopyTotpAutomaticallyAsync, () => _inited);
|
||||
ToggleCopyTotpAutomaticallyCommand = CreateDefaultAsyncRelayCommand(ToggleCopyTotpAutomaticallyAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
|
||||
InitAndroidCommands();
|
||||
InitIOSCommands();
|
||||
|
@ -56,7 +53,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public PickerViewModel<UriMatchType> DefaultUriMatchDetectionPickerViewModel { get; }
|
||||
|
||||
public AsyncCommand ToggleCopyTotpAutomaticallyCommand { get; private set; }
|
||||
public AsyncRelayCommand ToggleCopyTotpAutomaticallyCommand { get; private set; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
|
@ -72,11 +69,11 @@ namespace Bit.App.Pages
|
|||
{
|
||||
TriggerPropertyChanged(nameof(CopyTotpAutomatically));
|
||||
|
||||
ToggleUseAutofillServicesCommand.RaiseCanExecuteChanged();
|
||||
ToggleUseInlineAutofillCommand.RaiseCanExecuteChanged();
|
||||
ToggleUseAccessibilityCommand.RaiseCanExecuteChanged();
|
||||
ToggleUseDrawOverCommand.RaiseCanExecuteChanged();
|
||||
DefaultUriMatchDetectionPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
ToggleUseAutofillServicesCommand.NotifyCanExecuteChanged();
|
||||
ToggleUseInlineAutofillCommand.NotifyCanExecuteChanged();
|
||||
ToggleUseAccessibilityCommand.NotifyCanExecuteChanged();
|
||||
ToggleUseDrawOverCommand.NotifyCanExecuteChanged();
|
||||
DefaultUriMatchDetectionPickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,18 @@
|
|||
using System.Windows.Input;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class AutofillSettingsPageViewModel
|
||||
{
|
||||
public bool SupportsiOSAutofill => // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
Device.RuntimePlatform == Device.iOS && _deviceActionService.SupportsAutofillServices();
|
||||
public bool SupportsiOSAutofill => DeviceInfo.Platform == DevicePlatform.iOS && _deviceActionService.SupportsAutofillServices();
|
||||
|
||||
public ICommand GoToPasswordAutofillCommand { get; private set; }
|
||||
public ICommand GoToAppExtensionCommand { get; private set; }
|
||||
|
||||
private void InitIOSCommands()
|
||||
{
|
||||
GoToPasswordAutofillCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new AutofillPage())));
|
||||
GoToAppExtensionCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new ExtensionPage())));
|
||||
GoToPasswordAutofillCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new AutofillPage())), allowsMultipleExecutions: false);
|
||||
GoToAppExtensionCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new ExtensionPage())), allowsMultipleExecutions: false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,11 @@ namespace Bit.App.Pages
|
|||
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
|
||||
|
||||
AddUriCommand = new AsyncCommand(AddUriAsync,
|
||||
AddUriCommand = CreateDefaultAsyncRelayCommand(AddUriAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
EditUriCommand = new AsyncCommand<BlockAutofillUriItemViewModel>(EditUriAsync,
|
||||
EditUriCommand = CreateDefaultAsyncRelayCommand<BlockAutofillUriItemViewModel>(EditUriAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ using Microsoft.Maui.ApplicationModel;
|
|||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -34,11 +35,11 @@ namespace Bit.App.Pages
|
|||
PageTitle = AppResources.PendingLogInRequests;
|
||||
LoginRequests = new ObservableRangeCollection<PasswordlessLoginResponse>();
|
||||
|
||||
AnswerRequestCommand = new AsyncCommand<PasswordlessLoginResponse>(PasswordlessLoginAsync,
|
||||
AnswerRequestCommand = CreateDefaultAsyncRelayCommand<PasswordlessLoginResponse>(PasswordlessLoginAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
DeclineAllRequestsCommand = new AsyncCommand(DeclineAllRequestsAsync,
|
||||
DeclineAllRequestsCommand = CreateDefaultAsyncRelayCommand(DeclineAllRequestsAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
|
@ -47,9 +48,9 @@ namespace Bit.App.Pages
|
|||
|
||||
public ICommand RefreshCommand { get; }
|
||||
|
||||
public AsyncCommand<PasswordlessLoginResponse> AnswerRequestCommand { get; }
|
||||
public AsyncRelayCommand<PasswordlessLoginResponse> AnswerRequestCommand { get; }
|
||||
|
||||
public AsyncCommand DeclineAllRequestsCommand { get; }
|
||||
public AsyncRelayCommand DeclineAllRequestsCommand { get; }
|
||||
|
||||
public ObservableRangeCollection<PasswordlessLoginResponse> LoginRequests { get; }
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
Title="{u:I18n AllowScreenCapture}"
|
||||
IsToggled="{Binding IsScreenCaptureAllowed}"
|
||||
IsEnabled="{Binding CanToggleeScreenCaptureAllowed}"
|
||||
IsVisible="{OnPlatform Android=True, iOS=False}"
|
||||
AutomationId="AllowScreenCaptureSwitch"
|
||||
StyleClass="settings-item-view"
|
||||
HorizontalOptions="FillAndExpand" />
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
@ -43,19 +35,21 @@ namespace Bit.App.Pages
|
|||
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
|
||||
SyncCommand = CreateDefaultAsyncCommnad(SyncAsync, () => _inited);
|
||||
ToggleIsScreenCaptureAllowedCommand = CreateDefaultAsyncCommnad(ToggleIsScreenCaptureAllowedAsync, () => _inited);
|
||||
ToggleShouldConnectToWatchCommand = CreateDefaultAsyncCommnad(ToggleShouldConnectToWatchAsync, () => _inited);
|
||||
SyncCommand = CreateDefaultAsyncRelayCommand(SyncAsync, CanExecuteIfInited, allowsMultipleExecutions: false);
|
||||
ToggleIsScreenCaptureAllowedCommand = CreateDefaultAsyncRelayCommand(ToggleIsScreenCaptureAllowedAsync, CanExecuteIfInited, allowsMultipleExecutions: false);
|
||||
ToggleShouldConnectToWatchCommand = CreateDefaultAsyncRelayCommand(ToggleShouldConnectToWatchAsync, CanExecuteIfInited, allowsMultipleExecutions: false);
|
||||
|
||||
ClearClipboardPickerViewModel = new PickerViewModel<int>(
|
||||
_deviceActionService,
|
||||
_logger,
|
||||
OnClearClipboardChangingAsync,
|
||||
AppResources.ClearClipboard,
|
||||
() => _inited,
|
||||
CanExecuteIfInited,
|
||||
ex => HandleException(ex));
|
||||
}
|
||||
|
||||
private bool CanExecuteIfInited() => _inited;
|
||||
|
||||
public bool EnableSyncOnRefresh
|
||||
{
|
||||
get => _syncOnRefresh;
|
||||
|
@ -104,9 +98,9 @@ namespace Bit.App.Pages
|
|||
|
||||
public bool CanToggleShouldConnectToWatch => ToggleShouldConnectToWatchCommand.CanExecute(null);
|
||||
|
||||
public AsyncCommand SyncCommand { get; }
|
||||
public AsyncCommand ToggleIsScreenCaptureAllowedCommand { get; }
|
||||
public AsyncCommand ToggleShouldConnectToWatchCommand { get; }
|
||||
public AsyncRelayCommand SyncCommand { get; }
|
||||
public AsyncRelayCommand ToggleIsScreenCaptureAllowedCommand { get; }
|
||||
public AsyncRelayCommand ToggleShouldConnectToWatchCommand { get; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
|
@ -125,10 +119,10 @@ namespace Bit.App.Pages
|
|||
{
|
||||
TriggerPropertyChanged(nameof(IsScreenCaptureAllowed));
|
||||
TriggerPropertyChanged(nameof(ShouldConnectToWatch));
|
||||
SyncCommand.RaiseCanExecuteChanged();
|
||||
ClearClipboardPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
ToggleIsScreenCaptureAllowedCommand.RaiseCanExecuteChanged();
|
||||
ToggleShouldConnectToWatchCommand.RaiseCanExecuteChanged();
|
||||
SyncCommand.NotifyCanExecuteChanged();
|
||||
ClearClipboardPickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
ToggleIsScreenCaptureAllowedCommand.NotifyCanExecuteChanged();
|
||||
ToggleShouldConnectToWatchCommand.NotifyCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -142,8 +136,7 @@ namespace Bit.App.Pages
|
|||
[30] = AppResources.ThirtySeconds,
|
||||
[60] = AppResources.OneMinute
|
||||
};
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform != Device.iOS)
|
||||
if (DeviceInfo.Platform != DevicePlatform.iOS)
|
||||
{
|
||||
clearClipboardOptions.Add(120, AppResources.TwoMinutes);
|
||||
clearClipboardOptions.Add(300, AppResources.FiveMinutes);
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
<controls:CustomLabel
|
||||
Text="{u:I18n SessionTimeout}"
|
||||
StyleClass="settings-header" />
|
||||
|
||||
|
||||
<Frame
|
||||
IsVisible="{Binding ShowVaultTimeoutPolicyInfo}"
|
||||
Padding="10"
|
||||
|
@ -109,8 +109,10 @@
|
|||
|
||||
<controls:SettingChooserItemView
|
||||
Title="{u:I18n SessionTimeoutAction}"
|
||||
Subtitle="{Binding SetUpUnlockMethodLabel}"
|
||||
DisplayValue="{Binding VaultTimeoutActionPickerViewModel.SelectedValue}"
|
||||
ChooseCommand="{Binding VaultTimeoutActionPickerViewModel.SelectOptionCommand}"
|
||||
IsEnabled="{Binding IsVaultTimeoutActionLockAllowed}"
|
||||
AutomationId="VaultTimeoutActionChooser"
|
||||
StyleClass="settings-item-view"
|
||||
HorizontalOptions="FillAndExpand"/>
|
||||
|
@ -147,6 +149,7 @@
|
|||
|
||||
<controls:CustomLabel
|
||||
Text="{u:I18n LockNow}"
|
||||
IsVisible="{Binding IsVaultTimeoutActionLockAllowed}"
|
||||
StyleClass="settings-navigatable-label"
|
||||
AutomationId="LockNowLabel">
|
||||
<Label.GestureRecognizers>
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Pages.Accounts;
|
||||
using Bit.Core.Resources.Localization;
|
||||
|
@ -12,10 +8,7 @@ using Bit.Core.Abstractions;
|
|||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -77,19 +70,19 @@ namespace Bit.App.Pages
|
|||
_logger,
|
||||
OnVaultTimeoutActionChangingAsync,
|
||||
AppResources.SessionTimeoutAction,
|
||||
() => _inited && !HasVaultTimeoutActionPolicy,
|
||||
() => _inited && !HasVaultTimeoutActionPolicy && IsVaultTimeoutActionLockAllowed,
|
||||
ex => HandleException(ex));
|
||||
|
||||
ToggleUseThisDeviceToApproveLoginRequestsCommand = CreateDefaultAsyncCommnad(ToggleUseThisDeviceToApproveLoginRequestsAsync, () => _inited);
|
||||
GoToPendingLogInRequestsCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new LoginPasswordlessRequestsListPage())));
|
||||
ToggleCanUnlockWithBiometricsCommand = CreateDefaultAsyncCommnad(ToggleCanUnlockWithBiometricsAsync, () => _inited);
|
||||
ToggleCanUnlockWithPinCommand = CreateDefaultAsyncCommnad(ToggleCanUnlockWithPinAsync, () => _inited);
|
||||
ShowAccountFingerprintPhraseCommand = CreateDefaultAsyncCommnad(ShowAccountFingerprintPhraseAsync);
|
||||
GoToTwoStepLoginCommand = CreateDefaultAsyncCommnad(() => GoToWebVaultSettingsAsync(AppResources.TwoStepLoginDescriptionLong, AppResources.ContinueToWebApp));
|
||||
GoToChangeMasterPasswordCommand = CreateDefaultAsyncCommnad(() => GoToWebVaultSettingsAsync(AppResources.ChangeMasterPasswordDescriptionLong, AppResources.ContinueToWebApp));
|
||||
LockCommand = CreateDefaultAsyncCommnad(() => _vaultTimeoutService.LockAsync(true, true));
|
||||
LogOutCommand = CreateDefaultAsyncCommnad(LogOutAsync);
|
||||
DeleteAccountCommand = CreateDefaultAsyncCommnad(() => Page.Navigation.PushModalAsync(new NavigationPage(new DeleteAccountPage())));
|
||||
ToggleUseThisDeviceToApproveLoginRequestsCommand = CreateDefaultAsyncRelayCommand(ToggleUseThisDeviceToApproveLoginRequestsAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
GoToPendingLogInRequestsCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new LoginPasswordlessRequestsListPage())), allowsMultipleExecutions: false);
|
||||
ToggleCanUnlockWithBiometricsCommand = CreateDefaultAsyncRelayCommand(ToggleCanUnlockWithBiometricsAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
ToggleCanUnlockWithPinCommand = CreateDefaultAsyncRelayCommand(ToggleCanUnlockWithPinAsync, () => _inited, allowsMultipleExecutions: false);
|
||||
ShowAccountFingerprintPhraseCommand = CreateDefaultAsyncRelayCommand(ShowAccountFingerprintPhraseAsync, allowsMultipleExecutions: false);
|
||||
GoToTwoStepLoginCommand = CreateDefaultAsyncRelayCommand(() => GoToWebVaultSettingsAsync(AppResources.TwoStepLoginDescriptionLong, AppResources.ContinueToWebApp), allowsMultipleExecutions: false);
|
||||
GoToChangeMasterPasswordCommand = CreateDefaultAsyncRelayCommand(() => GoToWebVaultSettingsAsync(AppResources.ChangeMasterPasswordDescriptionLong, AppResources.ContinueToWebApp), allowsMultipleExecutions: false);
|
||||
LockCommand = CreateDefaultAsyncRelayCommand(() => _vaultTimeoutService.LockAsync(true, true), allowsMultipleExecutions: false);
|
||||
LogOutCommand = CreateDefaultAsyncRelayCommand(LogOutAsync, allowsMultipleExecutions: false);
|
||||
DeleteAccountCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new DeleteAccountPage())), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public bool UseThisDeviceToApproveLoginRequests
|
||||
|
@ -114,8 +107,7 @@ namespace Bit.App.Pages
|
|||
}
|
||||
|
||||
var biometricName = AppResources.Biometrics;
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
if (DeviceInfo.Platform == DevicePlatform.iOS)
|
||||
{
|
||||
biometricName = _deviceActionService.SupportsFaceBiometric()
|
||||
? AppResources.FaceID
|
||||
|
@ -131,6 +123,7 @@ namespace Bit.App.Pages
|
|||
get => _canUnlockWithBiometrics;
|
||||
set
|
||||
{
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
if (SetProperty(ref _canUnlockWithBiometrics, value))
|
||||
{
|
||||
((ICommand)ToggleCanUnlockWithBiometricsCommand).Execute(null);
|
||||
|
@ -143,6 +136,7 @@ namespace Bit.App.Pages
|
|||
get => _canUnlockWithPin;
|
||||
set
|
||||
{
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
if (SetProperty(ref _canUnlockWithPin, value))
|
||||
{
|
||||
((ICommand)ToggleCanUnlockWithPinCommand).Execute(null);
|
||||
|
@ -150,6 +144,10 @@ namespace Bit.App.Pages
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsVaultTimeoutActionLockAllowed => _hasMasterPassword || _canUnlockWithBiometrics || _canUnlockWithPin;
|
||||
|
||||
public string SetUpUnlockMethodLabel => IsVaultTimeoutActionLockAllowed ? null : AppResources.SetUpAnUnlockOptionToChangeYourVaultTimeoutAction;
|
||||
|
||||
public TimeSpan? CustomVaultTimeoutTime
|
||||
{
|
||||
get => _customVaultTimeoutTime;
|
||||
|
@ -166,6 +164,7 @@ namespace Bit.App.Pages
|
|||
MainThread.BeginInvokeOnMainThread(() => SetProperty(ref _customVaultTimeoutTime, oldValue));
|
||||
});
|
||||
}
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -205,22 +204,19 @@ namespace Bit.App.Pages
|
|||
|
||||
public bool ShowChangeMasterPassword { get; private set; }
|
||||
|
||||
private bool IsVaultTimeoutActionLockAllowed => _hasMasterPassword || _canUnlockWithBiometrics || _canUnlockWithPin;
|
||||
|
||||
private int? CurrentVaultTimeout => GetRawVaultTimeoutFrom(VaultTimeoutPickerViewModel.SelectedKey);
|
||||
|
||||
private bool IncludeLinksWithSubscriptionInfo => // TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
Device.RuntimePlatform != Device.iOS;
|
||||
private bool IncludeLinksWithSubscriptionInfo => DeviceInfo.Platform != DevicePlatform.iOS;
|
||||
|
||||
private bool HasVaultTimeoutActionPolicy => !string.IsNullOrEmpty(_vaultTimeoutActionPolicy);
|
||||
|
||||
public PickerViewModel<int> VaultTimeoutPickerViewModel { get; }
|
||||
public PickerViewModel<VaultTimeoutAction> VaultTimeoutActionPickerViewModel { get; }
|
||||
|
||||
public AsyncCommand ToggleUseThisDeviceToApproveLoginRequestsCommand { get; }
|
||||
public AsyncRelayCommand ToggleUseThisDeviceToApproveLoginRequestsCommand { get; }
|
||||
public ICommand GoToPendingLogInRequestsCommand { get; }
|
||||
public AsyncCommand ToggleCanUnlockWithBiometricsCommand { get; }
|
||||
public AsyncCommand ToggleCanUnlockWithPinCommand { get; }
|
||||
public AsyncRelayCommand ToggleCanUnlockWithBiometricsCommand { get; }
|
||||
public AsyncRelayCommand ToggleCanUnlockWithPinCommand { get; }
|
||||
public ICommand ShowAccountFingerprintPhraseCommand { get; }
|
||||
public ICommand GoToTwoStepLoginCommand { get; }
|
||||
public ICommand GoToChangeMasterPasswordCommand { get; }
|
||||
|
@ -256,11 +252,12 @@ Device.RuntimePlatform != Device.iOS;
|
|||
TriggerPropertyChanged(nameof(VaultTimeoutPolicyDescription));
|
||||
TriggerPropertyChanged(nameof(ShowChangeMasterPassword));
|
||||
TriggerUpdateCustomVaultTimeoutPicker();
|
||||
ToggleUseThisDeviceToApproveLoginRequestsCommand.RaiseCanExecuteChanged();
|
||||
ToggleCanUnlockWithBiometricsCommand.RaiseCanExecuteChanged();
|
||||
ToggleCanUnlockWithPinCommand.RaiseCanExecuteChanged();
|
||||
VaultTimeoutPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
VaultTimeoutActionPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged();
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
ToggleUseThisDeviceToApproveLoginRequestsCommand.NotifyCanExecuteChanged();
|
||||
ToggleCanUnlockWithBiometricsCommand.NotifyCanExecuteChanged();
|
||||
ToggleCanUnlockWithPinCommand.NotifyCanExecuteChanged();
|
||||
VaultTimeoutPickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
VaultTimeoutActionPickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -275,7 +272,7 @@ Device.RuntimePlatform != Device.iOS;
|
|||
_maximumVaultTimeoutPolicy = maximumVaultTimeoutPolicy?.GetInt(Policy.MINUTES_KEY);
|
||||
_vaultTimeoutActionPolicy = maximumVaultTimeoutPolicy?.GetString(Policy.ACTION_KEY);
|
||||
|
||||
MainThread.BeginInvokeOnMainThread(VaultTimeoutActionPickerViewModel.SelectOptionCommand.RaiseCanExecuteChanged);
|
||||
MainThread.BeginInvokeOnMainThread(VaultTimeoutActionPickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged);
|
||||
}
|
||||
|
||||
private async Task InitVaultTimeoutPickerAsync()
|
||||
|
@ -308,6 +305,7 @@ Device.RuntimePlatform != Device.iOS;
|
|||
{
|
||||
_customVaultTimeoutTime = TimeSpan.FromMinutes(vaultTimeout);
|
||||
}
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
}
|
||||
|
||||
private async Task InitVaultTimeoutActionPickerAsync()
|
||||
|
@ -327,6 +325,7 @@ Device.RuntimePlatform != Device.iOS;
|
|||
}
|
||||
|
||||
VaultTimeoutActionPickerViewModel.Init(options, timeoutAction, IsVaultTimeoutActionLockAllowed ? VaultTimeoutAction.Lock : VaultTimeoutAction.Logout);
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
}
|
||||
|
||||
private async Task ToggleUseThisDeviceToApproveLoginRequestsAsync()
|
||||
|
@ -363,15 +362,15 @@ Device.RuntimePlatform != Device.iOS;
|
|||
{
|
||||
if (!_canUnlockWithBiometrics)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(CanUnlockWithBiometrics)));
|
||||
await UpdateVaultTimeoutActionIfNeededAsync();
|
||||
await _biometricsService.SetCanUnlockWithBiometricsAsync(CanUnlockWithBiometrics);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Xamarin.Forms.Device.RuntimePlatform is no longer supported. Use Microsoft.Maui.Devices.DeviceInfo.Platform instead. For more details see https://learn.microsoft.com/en-us/dotnet/maui/migration/forms-projects#device-changes
|
||||
if (!_supportsBiometric
|
||||
||
|
||||
!await _platformUtilsService.AuthenticateBiometricAsync(null, Device.RuntimePlatform == Device.Android ? "." : null))
|
||||
!await _platformUtilsService.AuthenticateBiometricAsync(null, DeviceInfo.Platform == DevicePlatform.Android ? "." : null))
|
||||
{
|
||||
_canUnlockWithBiometrics = false;
|
||||
MainThread.BeginInvokeOnMainThread(() => TriggerPropertyChanged(nameof(CanUnlockWithBiometrics)));
|
||||
|
@ -379,11 +378,12 @@ Device.RuntimePlatform != Device.iOS;
|
|||
}
|
||||
|
||||
await _biometricsService.SetCanUnlockWithBiometricsAsync(CanUnlockWithBiometrics);
|
||||
await InitVaultTimeoutActionPickerAsync();
|
||||
}
|
||||
|
||||
public async Task ToggleCanUnlockWithPinAsync()
|
||||
{
|
||||
if (!CanUnlockWithPin)
|
||||
if (!_canUnlockWithPin)
|
||||
{
|
||||
await _vaultTimeoutService.ClearAsync();
|
||||
await UpdateVaultTimeoutActionIfNeededAsync();
|
||||
|
@ -407,10 +407,12 @@ Device.RuntimePlatform != Device.iOS;
|
|||
AppResources.No);
|
||||
|
||||
await _userPinService.SetupPinAsync(newPin, requireMasterPasswordOnRestart);
|
||||
await InitVaultTimeoutActionPickerAsync();
|
||||
}
|
||||
|
||||
private async Task UpdateVaultTimeoutActionIfNeededAsync()
|
||||
{
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
if (IsVaultTimeoutActionLockAllowed)
|
||||
{
|
||||
return;
|
||||
|
@ -471,6 +473,16 @@ Device.RuntimePlatform != Device.iOS;
|
|||
TriggerPropertyChanged(nameof(CustomVaultTimeoutTime));
|
||||
}
|
||||
|
||||
private void TriggerVaultTimeoutActionLockAllowedPropertyChanged()
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
TriggerPropertyChanged(nameof(IsVaultTimeoutActionLockAllowed));
|
||||
TriggerPropertyChanged(nameof(SetUpUnlockMethodLabel));
|
||||
VaultTimeoutActionPickerViewModel.SelectOptionCommand.NotifyCanExecuteChanged();
|
||||
});
|
||||
}
|
||||
|
||||
private int? GetRawVaultTimeoutFrom(int vaultTimeoutPickerKey)
|
||||
{
|
||||
if (vaultTimeoutPickerKey == NEVER_SESSION_TIMEOUT_VALUE)
|
||||
|
@ -505,7 +517,7 @@ Device.RuntimePlatform != Device.iOS;
|
|||
|
||||
await _vaultTimeoutService.SetVaultTimeoutOptionsAsync(CurrentVaultTimeout, timeoutActionKey);
|
||||
_messagingService.Send(AppHelpers.VAULT_TIMEOUT_ACTION_CHANGED_MESSAGE_COMMAND);
|
||||
|
||||
TriggerVaultTimeoutActionLockAllowedPropertyChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using Bit.App.Utilities;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -7,7 +8,7 @@ namespace Bit.App.Pages
|
|||
{
|
||||
public SettingsPageViewModel()
|
||||
{
|
||||
ExecuteSettingItemCommand = new AsyncCommand<SettingsPageListItem>(item => item.ExecuteAsync(),
|
||||
ExecuteSettingItemCommand = CreateDefaultAsyncRelayCommand<SettingsPageListItem>(item => item.ExecuteAsync(),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
|
@ -24,7 +25,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public List<SettingsPageListItem> SettingsItems { get; }
|
||||
|
||||
public AsyncCommand<SettingsPageListItem> ExecuteSettingItemCommand { get; }
|
||||
public AsyncRelayCommand<SettingsPageListItem> ExecuteSettingItemCommand { get; }
|
||||
|
||||
private async Task NavigateToAsync(Page page)
|
||||
{
|
||||
|
|
|
@ -22,15 +22,15 @@ namespace Bit.App.Pages
|
|||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
|
||||
GoToFoldersCommand = new AsyncCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new FoldersPage())),
|
||||
GoToFoldersCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new FoldersPage())),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
GoToExportVaultCommand = new AsyncCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new ExportVaultPage())),
|
||||
GoToExportVaultCommand = CreateDefaultAsyncRelayCommand(() => Page.Navigation.PushModalAsync(new NavigationPage(new ExportVaultPage())),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
GoToImportItemsCommand = new AsyncCommand(GoToImportItemsAsync,
|
||||
GoToImportItemsCommand = CreateDefaultAsyncRelayCommand(GoToImportItemsAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
using Bit.App.Effects;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Effects;
|
||||
using Bit.App.Models;
|
||||
using Bit.Core.Resources.Localization;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
|
@ -97,11 +101,38 @@ namespace Bit.App.Pages
|
|||
_messagingService.Send("convertAccountToKeyConnector");
|
||||
}
|
||||
|
||||
var forcePasswordResetReason = await _stateService.GetForcePasswordResetReasonAsync();
|
||||
await ForcePasswordResetIfNeededAsync();
|
||||
}
|
||||
|
||||
if (forcePasswordResetReason.HasValue)
|
||||
private async Task ForcePasswordResetIfNeededAsync()
|
||||
{
|
||||
var forcePasswordResetReason = await _stateService.GetForcePasswordResetReasonAsync();
|
||||
switch (forcePasswordResetReason)
|
||||
{
|
||||
_messagingService.Send(Constants.ForceUpdatePassword);
|
||||
case ForcePasswordResetReason.TdeUserWithoutPasswordHasPasswordResetPermission:
|
||||
// TDE users should only have one org
|
||||
var userOrgs = await _stateService.GetOrganizationsAsync();
|
||||
if (userOrgs != null && userOrgs.Any())
|
||||
{
|
||||
_messagingService.Send(Constants.ForceSetPassword, userOrgs.First().Value.Identifier);
|
||||
return;
|
||||
}
|
||||
_logger.Value.Error("TDE user needs to set password but has no organizations.");
|
||||
|
||||
var rememberedOrg = _stateService.GetRememberedOrgIdentifierAsync();
|
||||
if (rememberedOrg == null)
|
||||
{
|
||||
_logger.Value.Error("TDE user needs to set password but has no organizations or remembered org identifier.");
|
||||
return;
|
||||
}
|
||||
_messagingService.Send(Constants.ForceSetPassword, rememberedOrg);
|
||||
return;
|
||||
case ForcePasswordResetReason.AdminForcePasswordReset:
|
||||
case ForcePasswordResetReason.WeakMasterPasswordOnLogin:
|
||||
_messagingService.Send(Constants.ForceUpdatePassword);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace Bit.App.Pages
|
|||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
Attachments = new ExtendedObservableCollection<AttachmentView>();
|
||||
DeleteAttachmentCommand = new Command<AttachmentView>(DeleteAsync);
|
||||
SubmitAsyncCommand = new AsyncCommand(SubmitAsync, allowsMultipleExecutions: false);
|
||||
SubmitAsyncCommand = CreateDefaultAsyncRelayCommand(SubmitAsync, allowsMultipleExecutions: false);
|
||||
PageTitle = AppResources.Attachments;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ using Bit.Core.Exceptions;
|
|||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
|
@ -28,7 +29,7 @@ namespace Bit.App.Pages
|
|||
_auditService = ServiceContainer.Resolve<IAuditService>("auditService");
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
CheckPasswordCommand = new AsyncCommand(CheckPasswordAsync, allowsMultipleExecutions: false);
|
||||
CheckPasswordCommand = CreateDefaultAsyncRelayCommand(CheckPasswordAsync, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public CipherView Cipher
|
||||
|
@ -39,7 +40,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public string CreationDate => string.Format(AppResources.CreatedXY, Cipher?.CreationDate.ToShortDateString(), Cipher?.CreationDate.ToShortTimeString());
|
||||
|
||||
public AsyncCommand CheckPasswordCommand { get; }
|
||||
public AsyncRelayCommand CheckPasswordCommand { get; }
|
||||
|
||||
protected async Task CheckPasswordAsync()
|
||||
{
|
||||
|
|
|
@ -16,6 +16,7 @@ using Bit.Core.Utilities;
|
|||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
using Bit.App.Utilities;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
|
||||
#nullable enable
|
||||
|
||||
|
@ -99,8 +100,8 @@ namespace Bit.App.Pages
|
|||
UriOptionsCommand = new Command<LoginUriView>(UriOptions);
|
||||
FieldOptionsCommand = new Command<ICustomFieldItemViewModel>(FieldOptions);
|
||||
PasswordPromptHelpCommand = new Command(PasswordPromptHelp);
|
||||
CopyCommand = new AsyncCommand(CopyTotpClipboardAsync, onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
GenerateUsernameCommand = new AsyncCommand(GenerateUsernameAsync, onException: ex => OnGenerateUsernameException(ex), allowsMultipleExecutions: false);
|
||||
CopyCommand = CreateDefaultAsyncRelayCommand(CopyTotpClipboardAsync, onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
GenerateUsernameCommand = CreateDefaultAsyncRelayCommand(GenerateUsernameAsync, onException: ex => OnGenerateUsernameException(ex), allowsMultipleExecutions: false);
|
||||
Uris = new ExtendedObservableCollection<LoginUriView>();
|
||||
Fields = new ExtendedObservableCollection<ICustomFieldItemViewModel>();
|
||||
Collections = new ExtendedObservableCollection<CollectionViewModel>();
|
||||
|
@ -163,8 +164,8 @@ namespace Bit.App.Pages
|
|||
public Command UriOptionsCommand { get; set; }
|
||||
public Command FieldOptionsCommand { get; set; }
|
||||
public Command PasswordPromptHelpCommand { get; set; }
|
||||
public AsyncCommand CopyCommand { get; set; }
|
||||
public AsyncCommand GenerateUsernameCommand { get; set; }
|
||||
public AsyncRelayCommand CopyCommand { get; set; }
|
||||
public AsyncRelayCommand GenerateUsernameCommand { get; set; }
|
||||
public string CipherId { get; set; }
|
||||
public string OrganizationId { get; set; }
|
||||
public string FolderId { get; set; }
|
||||
|
|
|
@ -14,7 +14,7 @@ using Bit.Core.Enums;
|
|||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
|
@ -66,15 +66,15 @@ namespace Bit.App.Pages
|
|||
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
|
||||
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
|
||||
|
||||
CopyCommand = new AsyncCommand<string>((id) => CopyAsync(id, null), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyUriCommand = new AsyncCommand<LoginUriView>(uriView => CopyAsync("LoginUri", uriView.Uri), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyFieldCommand = new AsyncCommand<FieldView>(field => CopyAsync(field.Type == FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyCommand = CreateDefaultAsyncRelayCommand<string>((id) => CopyAsync(id, null), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyUriCommand = CreateDefaultAsyncRelayCommand<LoginUriView>(uriView => CopyAsync("LoginUri", uriView.Uri), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyFieldCommand = CreateDefaultAsyncRelayCommand<FieldView>(field => CopyAsync(field.Type == FieldType.Hidden ? "H_FieldValue" : "FieldValue", field.Value), onException: ex => _logger.Exception(ex), allowsMultipleExecutions: false);
|
||||
LaunchUriCommand = new Command<ILaunchableView>(LaunchUri);
|
||||
CloneCommand = new AsyncCommand(CloneAsync, onException: ex => HandleException(ex), allowsMultipleExecutions: false);
|
||||
CloneCommand = CreateDefaultAsyncRelayCommand(CloneAsync, onException: ex => HandleException(ex), allowsMultipleExecutions: false);
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
ToggleCardNumberCommand = new Command(ToggleCardNumber);
|
||||
ToggleCardCodeCommand = new Command(ToggleCardCode);
|
||||
DownloadAttachmentCommand = new AsyncCommand<AttachmentView>(DownloadAttachmentAsync, allowsMultipleExecutions: false);
|
||||
DownloadAttachmentCommand = CreateDefaultAsyncRelayCommand<AttachmentView>(DownloadAttachmentAsync, allowsMultipleExecutions: false);
|
||||
|
||||
PageTitle = AppResources.ViewItem;
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ namespace Bit.App.Pages
|
|||
public Command TogglePasswordCommand { get; set; }
|
||||
public Command ToggleCardNumberCommand { get; set; }
|
||||
public Command ToggleCardCodeCommand { get; set; }
|
||||
public AsyncCommand<AttachmentView> DownloadAttachmentCommand { get; set; }
|
||||
public AsyncRelayCommand<AttachmentView> DownloadAttachmentCommand { get; set; }
|
||||
public string CipherId { get; set; }
|
||||
protected override string[] AdditionalPropertiesToRaiseOnCipherChanged => new string[]
|
||||
{
|
||||
|
|
|
@ -45,13 +45,13 @@ namespace Bit.App.Pages
|
|||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
|
||||
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
|
||||
CipherOptionsCommand = new AsyncCommand<CipherView>(cipher => AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
|
||||
CipherOptionsCommand = CreateDefaultAsyncRelayCommand<CipherView>(cipher => AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
SelectCipherCommand = new AsyncCommand<IGroupingsPageListItem>(SelectCipherAsync,
|
||||
SelectCipherCommand = CreateDefaultAsyncRelayCommand<IGroupingsPageListItem>(SelectCipherAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
AddCipherCommand = new AsyncCommand(AddCipherAsync,
|
||||
AddCipherCommand = CreateDefaultAsyncRelayCommand(AddCipherAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
|
|
|
@ -52,10 +52,10 @@ namespace Bit.App.Pages
|
|||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
Ciphers = new ExtendedObservableCollection<CipherView>();
|
||||
CipherOptionsCommand = new AsyncCommand<CipherView>(cipher => Utilities.AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
|
||||
CipherOptionsCommand = CreateDefaultAsyncRelayCommand<CipherView>(cipher => Utilities.AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
AddCipherCommand = new AsyncCommand(AddCipherAsync,
|
||||
AddCipherCommand = CreateDefaultAsyncRelayCommand(AddCipherAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using Bit.App.Utilities;
|
|||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using Microsoft.Maui.ApplicationModel;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
@ -37,13 +37,13 @@ namespace Bit.App.Pages
|
|||
|
||||
Cipher = cipherView;
|
||||
WebsiteIconsEnabled = websiteIconsEnabled;
|
||||
CopyCommand = new AsyncCommand(CopyToClipboardAsync,
|
||||
CopyCommand = CreateDefaultAsyncRelayCommand(CopyToClipboardAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
_totpTickHelper = new TotpHelper(cipherView);
|
||||
}
|
||||
|
||||
public AsyncCommand CopyCommand { get; set; }
|
||||
public AsyncRelayCommand CopyCommand { get; set; }
|
||||
|
||||
public CipherView Cipher
|
||||
{
|
||||
|
|
|
@ -71,10 +71,10 @@ namespace Bit.App.Pages
|
|||
Refreshing = true;
|
||||
await LoadAsync();
|
||||
});
|
||||
CipherOptionsCommand = new AsyncCommand<CipherView>(cipher => AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
|
||||
CipherOptionsCommand = CreateDefaultAsyncRelayCommand<CipherView>(cipher => AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
|
||||
onException: ex => _logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
VaultFilterCommand = new AsyncCommand(VaultFilterOptionsAsync,
|
||||
VaultFilterCommand = CreateDefaultAsyncRelayCommand(VaultFilterOptionsAsync,
|
||||
onException: ex => _logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public ScanPageViewModel()
|
||||
{
|
||||
ToggleScanModeCommand = new AsyncCommand(ToggleScanMode, onException: HandleException);
|
||||
ToggleScanModeCommand = CreateDefaultAsyncRelayCommand(ToggleScanMode, onException: HandleException);
|
||||
StartCameraCommand = new Command(StartCamera);
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Bit.App.Pages
|
|||
OrganizationOptions = new List<KeyValuePair<string, string>>();
|
||||
PageTitle = AppResources.MoveToOrganization;
|
||||
|
||||
MoveCommand = new AsyncCommand(MoveAsync, onException: ex => HandleException(ex), allowsMultipleExecutions: false);
|
||||
MoveCommand = CreateDefaultAsyncRelayCommand(MoveAsync, onException: ex => HandleException(ex), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public string CipherId { get; set; }
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Bit.App.Pages
|
|||
|
||||
public VaultFilterViewModel()
|
||||
{
|
||||
VaultFilterCommand = new AsyncCommand(VaultFilterOptionsAsync,
|
||||
VaultFilterCommand = CreateDefaultAsyncRelayCommand(VaultFilterOptionsAsync,
|
||||
onException: ex => logger.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
|
|
@ -6227,6 +6227,15 @@ namespace Bit.Core.Resources.Localization {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Set up an unlock option to change your vault timeout action..
|
||||
/// </summary>
|
||||
public static string SetUpAnUnlockOptionToChangeYourVaultTimeoutAction {
|
||||
get {
|
||||
return ResourceManager.GetString("SetUpAnUnlockOptionToChangeYourVaultTimeoutAction", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Set up TOTP.
|
||||
/// </summary>
|
||||
|
@ -7766,6 +7775,24 @@ namespace Bit.Core.Resources.Localization {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Your organization permissions were updated, requiring you to set a master password..
|
||||
/// </summary>
|
||||
public static string YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Your organization requires you to set a master password..
|
||||
/// </summary>
|
||||
public static string YourOrganizationRequiresYouToSetAMasterPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("YourOrganizationRequiresYouToSetAMasterPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Your request has been sent to your admin..
|
||||
/// </summary>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ Wil u na die rekening omskakel?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2751,109 +2751,109 @@
|
|||
<value>جارٍ تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="Vault" xml:space="preserve">
|
||||
<value>Vault</value>
|
||||
<value>الخزنة</value>
|
||||
</data>
|
||||
<data name="Appearance" xml:space="preserve">
|
||||
<value>Appearance</value>
|
||||
<value>المظهر</value>
|
||||
</data>
|
||||
<data name="AccountSecurity" xml:space="preserve">
|
||||
<value>Account security</value>
|
||||
<value>أمان الحساب</value>
|
||||
</data>
|
||||
<data name="BitwardenHelpCenter" xml:space="preserve">
|
||||
<value>Bitwarden Help Center</value>
|
||||
<value>مركز المساعدة Bitwarden</value>
|
||||
</data>
|
||||
<data name="ContactBitwardenSupport" xml:space="preserve">
|
||||
<value>Contact Bitwarden support</value>
|
||||
<value>اتصل بالدعم Bitwarden</value>
|
||||
</data>
|
||||
<data name="CopyAppInformation" xml:space="preserve">
|
||||
<value>Copy app information</value>
|
||||
<value>نسخ معلومات التطبيق</value>
|
||||
</data>
|
||||
<data name="SyncNow" xml:space="preserve">
|
||||
<value>Sync now</value>
|
||||
<value>المزامنة الآن</value>
|
||||
</data>
|
||||
<data name="UnlockOptions" xml:space="preserve">
|
||||
<value>Unlock options</value>
|
||||
<value>خيارات فتح القفل</value>
|
||||
</data>
|
||||
<data name="SessionTimeout" xml:space="preserve">
|
||||
<value>Session timeout</value>
|
||||
<value>مهلة الجلسة</value>
|
||||
</data>
|
||||
<data name="SessionTimeoutAction" xml:space="preserve">
|
||||
<value>Session timeout action</value>
|
||||
<value>إجراء مهلة الجلسة</value>
|
||||
</data>
|
||||
<data name="AccountFingerprintPhrase" xml:space="preserve">
|
||||
<value>Account fingerprint phrase</value>
|
||||
<value>عبارة بصمة الحساب</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="OneHourAndOneMinute" xml:space="preserve">
|
||||
<value>One hour and one minute</value>
|
||||
<value>ساعة واحدة ودقيقة واحدة</value>
|
||||
</data>
|
||||
<data name="OneHourAndXMinute" xml:space="preserve">
|
||||
<value>One hour and {0} minutes</value>
|
||||
<value>ساعة واحدة و {0} دقيقة</value>
|
||||
</data>
|
||||
<data name="XHoursAndOneMinute" xml:space="preserve">
|
||||
<value>{0} hours and one minute</value>
|
||||
<value>{0} ساعات ودقيقة واحدة</value>
|
||||
</data>
|
||||
<data name="XHoursAndYMinutes" xml:space="preserve">
|
||||
<value>{0} hours and {1} minutes</value>
|
||||
<value>{0} ساعات و {1} دقيقة</value>
|
||||
</data>
|
||||
<data name="XHours" xml:space="preserve">
|
||||
<value>{0} hours</value>
|
||||
<value>{0} ساعات</value>
|
||||
</data>
|
||||
<data name="AutofillServicesExplanationLong" xml:space="preserve">
|
||||
<value>The Android Autofill Framework is used to assist in filling login information into other apps on your device.</value>
|
||||
<value>يتم استخدام إطار التعبئة التلقائية لأندرويد للمساعدة في ملء معلومات تسجيل الدخول في تطبيقات أخرى على جهازك.</value>
|
||||
</data>
|
||||
<data name="UseInlineAutofillExplanationLong" xml:space="preserve">
|
||||
<value>Use inline autofill if your selected keyboard supports it. Otherwise, use the default overlay.</value>
|
||||
<value>استخدم التعبئة التلقائية المضمنة إذا كانت لوحة المفاتيح المحددة تدعمها. وإلا استخدم التراكب الافتراضي.</value>
|
||||
</data>
|
||||
<data name="AdditionalOptions" xml:space="preserve">
|
||||
<value>Additional options</value>
|
||||
<value>خيارات إضافية</value>
|
||||
</data>
|
||||
<data name="ContinueToWebApp" xml:space="preserve">
|
||||
<value>Continue to web app?</value>
|
||||
<value>متابعة إلى تطبيق الويب؟</value>
|
||||
</data>
|
||||
<data name="ContinueToX" xml:space="preserve">
|
||||
<value>Continue to {0}?</value>
|
||||
<value>الإستمرار إلى {0}؟</value>
|
||||
<comment>The parameter is an URL, like bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="ContinueToHelpCenter" xml:space="preserve">
|
||||
<value>Continue to Help center?</value>
|
||||
<value>هل تريد المتابعة إلى مركز المساعدة؟</value>
|
||||
</data>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
<value>مواصلة الاتصال بالدعم؟</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
<value>هل تريد المتابعة إلى متجر التطبيقات؟</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
|
||||
<value>Make your account more secure by setting up two-step login in the Bitwarden web app.</value>
|
||||
<value>اجعل حسابك أكثر أمنا من خلال إعداد تسجيل الدخول بخطوتين في تطبيق Bitwarden على شبكة الإنترنت.</value>
|
||||
</data>
|
||||
<data name="ChangeMasterPasswordDescriptionLong" xml:space="preserve">
|
||||
<value>You can change your master password on the Bitwarden web app.</value>
|
||||
<value>يمكنك تغيير كلمة المرور الرئيسية الخاصة بك على تطبيق ويب Bitwarden.</value>
|
||||
</data>
|
||||
<data name="YouCanImportDataToYourVaultOnX" xml:space="preserve">
|
||||
<value>You can import data to your vault on {0}.</value>
|
||||
<value>يمكنك استيراد البيانات إلى خزانتك على {0}.</value>
|
||||
<comment>The parameter is an URL, like vault.bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="LearnMoreAboutHowToUseBitwardenOnTheHelpCenter" xml:space="preserve">
|
||||
<value>Learn more about how to use Bitwarden on the Help center.</value>
|
||||
<value>تعرف على المزيد حول كيفية استخدام Bitwarden في مركز المساعدة.</value>
|
||||
</data>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
<value>لا يمكن العثور على ما تبحث عنه؟ قم بالتواصل مع دعم Bitwarden على bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
<value>استكشف المزيد من الميزات لحساب Bitwarden الخاص بك على تطبيق الويب.</value>
|
||||
</data>
|
||||
<data name="LearnAboutOrganizationsDescriptionLong" xml:space="preserve">
|
||||
<value>Bitwarden allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website.</value>
|
||||
<value>يتيح لك Bitwarden مشاركة عناصر خزنتك مع الآخرين باستخدام حساب المؤسسة. تعرف على المزيد على موقع bitwarden.com على شبكة الإنترنت.</value>
|
||||
</data>
|
||||
<data name="RateAppDescriptionLong" xml:space="preserve">
|
||||
<value>Help others find out if Bitwarden is right for them. Visit the app store and leave a rating now.</value>
|
||||
<value>ساعد الآخرين في معرفة ما إذا كان Bitwarden مناسبا لهم. قم بزيارة متجر التطبيقات وترك التقييم الآن.</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescriptionLong" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when your device’s dark mode is in use</value>
|
||||
<value>اختر السمة المظلمة لاستخدامها عند استخدام الوضع المظلم لجهازك</value>
|
||||
</data>
|
||||
<data name="CreatedXY" xml:space="preserve">
|
||||
<value>Created {0}, {1}</value>
|
||||
<value>أنشئ {0}، {1}</value>
|
||||
<comment>To state the date/time in which the cipher was created: Created 03/21/2023, 09:25 AM. First parameter is the date and the second parameter is the time.</comment>
|
||||
</data>
|
||||
<data name="TooManyAttempts" xml:space="preserve">
|
||||
|
@ -2862,4 +2862,13 @@
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>تم تسجيل الخروج من الحساب.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2860,4 +2860,13 @@ Bu hesaba keçmək istəyirsiniz?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Hesabdan çıxış edildi.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Təşkilatınızın icazələri güncəlləndi və bir ana parol ayarlamağınızı tələb edir.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Təşkilatınız bir ana parol ayarlamağı tələb edir.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Anbar vaxt bitməsi əməliyyatınızı dəyişdirmək üçün bir kilid açma seçimi qurun.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ select Add TOTP to store the key safely</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Акаунтът е отписан.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Правата Ви в организацията бяха променени, необходимо е да зададете главна парола.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Организацията Ви изисква да зададете главна парола.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Задайте начин за отключване, за да може да промените действието при изтичане на времето за достъп до трезора.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2860,4 +2860,13 @@ Skeniranje će biti izvršeno automatski.</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ Voleu canviar a aquest compte?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>S'ha tancat la sessió del compte.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Els permisos de la vostra organització s'han actualitzat, cal que establiu una contrasenya mestra.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>La vostra organització requereix que establiu una contrasenya mestra.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Configura una opció de desbloqueig per canviar l'acció de temps d'espera de la caixa forta.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -375,7 +375,7 @@
|
|||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} bylo zkopírováno.</value>
|
||||
<value>{0}: zkopírováno</value>
|
||||
<comment>Confirmation message after successfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
|
@ -499,7 +499,7 @@
|
|||
<value>Pro spuštění rozšíření klepněte na ikonu Bitwardenu v menu.</value>
|
||||
</data>
|
||||
<data name="ExtensionTurnOn" xml:space="preserve">
|
||||
<value>Pro zapnutí Bitwardenu v prohlížeči Safari a dalších aplikacích klepněte na ikonu „Další“ v dolní části menu.</value>
|
||||
<value>Pro zapnutí Bitwardenu v prohlížeči Safari a dalších aplikacích klepněte na ikonu "Další“ v dolní části menu.</value>
|
||||
</data>
|
||||
<data name="Favorite" xml:space="preserve">
|
||||
<value>Oblíbené</value>
|
||||
|
@ -958,10 +958,10 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Vlastní prostředí</value>
|
||||
</data>
|
||||
<data name="CustomEnvironmentFooter" xml:space="preserve">
|
||||
<value>Pro pokročilé uživatele. Můžete zadat základní URL adresu každé služby zvlášť.</value>
|
||||
<value>Pro pokročilé uživatele. Můžete zadat základní URL každé služby zvlášť.</value>
|
||||
</data>
|
||||
<data name="EnvironmentSaved" xml:space="preserve">
|
||||
<value>URL adresy vlastního prostředí byly uloženy.</value>
|
||||
<value>URL vlastního prostředí byly uloženy.</value>
|
||||
</data>
|
||||
<data name="FormattedIncorrectly" xml:space="preserve">
|
||||
<value>{0} nemá správný formát.</value>
|
||||
|
@ -975,7 +975,7 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Vlastní hostované prostředí</value>
|
||||
</data>
|
||||
<data name="SelfHostedEnvironmentFooter" xml:space="preserve">
|
||||
<value>Zadejte základní URL adresu vlastní hostované aplikace Bitwarden.</value>
|
||||
<value>Zadejte základní URL vlastní hostované aplikace Bitwarden.</value>
|
||||
</data>
|
||||
<data name="ServerUrl" xml:space="preserve">
|
||||
<value>URL serveru</value>
|
||||
|
@ -1023,13 +1023,13 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Adresa 3</value>
|
||||
</data>
|
||||
<data name="April" xml:space="preserve">
|
||||
<value>Duben</value>
|
||||
<value>duben</value>
|
||||
</data>
|
||||
<data name="August" xml:space="preserve">
|
||||
<value>Srpen</value>
|
||||
<value>srpen</value>
|
||||
</data>
|
||||
<data name="Brand" xml:space="preserve">
|
||||
<value>Značka</value>
|
||||
<value>Vydavatel</value>
|
||||
</data>
|
||||
<data name="CardholderName" xml:space="preserve">
|
||||
<value>Jméno držitele karty</value>
|
||||
|
@ -1044,10 +1044,10 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Stát</value>
|
||||
</data>
|
||||
<data name="December" xml:space="preserve">
|
||||
<value>Prosinec</value>
|
||||
<value>prosinec</value>
|
||||
</data>
|
||||
<data name="Dr" xml:space="preserve">
|
||||
<value>MUDr.</value>
|
||||
<value>Dr.</value>
|
||||
</data>
|
||||
<data name="ExpirationMonth" xml:space="preserve">
|
||||
<value>Měsíc expirace</value>
|
||||
|
@ -1056,19 +1056,19 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Rok expirace</value>
|
||||
</data>
|
||||
<data name="February" xml:space="preserve">
|
||||
<value>Únor</value>
|
||||
<value>únor</value>
|
||||
</data>
|
||||
<data name="FirstName" xml:space="preserve">
|
||||
<value>Křestní jméno</value>
|
||||
</data>
|
||||
<data name="January" xml:space="preserve">
|
||||
<value>Leden</value>
|
||||
<value>leden</value>
|
||||
</data>
|
||||
<data name="July" xml:space="preserve">
|
||||
<value>Červenec</value>
|
||||
<value>červenec</value>
|
||||
</data>
|
||||
<data name="June" xml:space="preserve">
|
||||
<value>Červen</value>
|
||||
<value>červen</value>
|
||||
</data>
|
||||
<data name="LastName" xml:space="preserve">
|
||||
<value>Příjmení</value>
|
||||
|
@ -1080,10 +1080,10 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Číslo dokladu totožnosti</value>
|
||||
</data>
|
||||
<data name="March" xml:space="preserve">
|
||||
<value>Březen</value>
|
||||
<value>březen</value>
|
||||
</data>
|
||||
<data name="May" xml:space="preserve">
|
||||
<value>Květen</value>
|
||||
<value>květen</value>
|
||||
</data>
|
||||
<data name="MiddleName" xml:space="preserve">
|
||||
<value>Prostřední jméno</value>
|
||||
|
@ -1101,10 +1101,10 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Neutrální</value>
|
||||
</data>
|
||||
<data name="November" xml:space="preserve">
|
||||
<value>Listopad</value>
|
||||
<value>listopad</value>
|
||||
</data>
|
||||
<data name="October" xml:space="preserve">
|
||||
<value>Říjen</value>
|
||||
<value>říjen</value>
|
||||
</data>
|
||||
<data name="PassportNumber" xml:space="preserve">
|
||||
<value>Číslo cestovního pasu</value>
|
||||
|
@ -1113,10 +1113,10 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Telefon</value>
|
||||
</data>
|
||||
<data name="September" xml:space="preserve">
|
||||
<value>Září</value>
|
||||
<value>září</value>
|
||||
</data>
|
||||
<data name="SSN" xml:space="preserve">
|
||||
<value>Číslo sociálního pojištění</value>
|
||||
<value>Rodné číslo</value>
|
||||
</data>
|
||||
<data name="StateProvince" xml:space="preserve">
|
||||
<value>Kraj / Provincie</value>
|
||||
|
@ -1298,22 +1298,22 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Přistupujte k Vašemu trezoru přímo z Vaší klávesnice pro rychlejší automatické vyplnění hesel.</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn" xml:space="preserve">
|
||||
<value>Pokyny pro zapnutí automatického vyplňování hesel na vašem zařízení:</value>
|
||||
<value>Pokyny pro zapnutí automatického vyplňování hesel na Vašem zařízení:</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn1" xml:space="preserve">
|
||||
<value>1. Přejděte do aplikace "Nastavení" v iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Klepněte na „Hesla“ > „Volby hesla“</value>
|
||||
<value>2. Klepněte na "Hesla" > "Volby hesla"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Povolte „Automatické vyplnění hesel“</value>
|
||||
<value>3. Zapněte přepínač u položky "Automatické vyplnění hesel"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn4" xml:space="preserve">
|
||||
<value>4. Najděte sekci „Povolit vyplňování z“</value>
|
||||
<value>4. Najděte sekci "Povolit vyplňování z:"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn5" xml:space="preserve">
|
||||
<value>5. Zvolte „Bitwarden“</value>
|
||||
<value>5. Zvolte "Bitwarden"</value>
|
||||
</data>
|
||||
<data name="PasswordAutofill" xml:space="preserve">
|
||||
<value>Automatické vyplňování hesel</value>
|
||||
|
@ -1562,7 +1562,7 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Chcete po restartování aplikace vyžadovat hlavní heslo pro odemknutí trezoru?</value>
|
||||
</data>
|
||||
<data name="Black" xml:space="preserve">
|
||||
<value>Černá</value>
|
||||
<value>Černý</value>
|
||||
<comment>The color black</comment>
|
||||
</data>
|
||||
<data name="Nord" xml:space="preserve">
|
||||
|
@ -1570,7 +1570,7 @@ Načtení proběhne automaticky.</value>
|
|||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Tmavý – Solarized</value>
|
||||
<value>Tmavý (solární)</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
|
@ -1947,7 +1947,7 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Nové heslo</value>
|
||||
</data>
|
||||
<data name="PasswordInfo" xml:space="preserve">
|
||||
<value>Volitelně vyžadovat heslo pro přístup k tomuto Send.</value>
|
||||
<value>Volitelně bude vyžadovat heslo pro přístup k tomuto Send.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="RemovePassword" xml:space="preserve">
|
||||
|
@ -1967,7 +1967,7 @@ Načtení proběhne automaticky.</value>
|
|||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSend" xml:space="preserve">
|
||||
<value>Deaktivuje tento Send, díky čemuž k němu nebude moci nikdo přistoupit</value>
|
||||
<value>Deaktivovat tento Send (nikdo k němu nebude mít přístup)</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
|
@ -2299,13 +2299,13 @@ Načtení proběhne automaticky.</value>
|
|||
<value>Nastavení zámku na "Nikdy" ponechá Váš trezor k dispozici komukoli s přístupem k Vašemu zařízení. Používáte-li tuto možnost, měli byste zajistit, aby Vaše zařízení bylo náležitě chráněno.</value>
|
||||
</data>
|
||||
<data name="EnvironmentPageUrlsError" xml:space="preserve">
|
||||
<value>Jedna nebo více zadaných adres URL jsou neplatné. Zkontrolujte je a opakujte akci znovu.</value>
|
||||
<value>Jedna nebo více zadaných URL jsou neplatné. Zkontrolujte je a opakujte akci znovu.</value>
|
||||
</data>
|
||||
<data name="GenericErrorMessage" xml:space="preserve">
|
||||
<value>Nepodařilo se nám zpracovat Váš požadavek. Zkuste to znovu nebo nás kontaktujte.</value>
|
||||
</data>
|
||||
<data name="AllowScreenCapture" xml:space="preserve">
|
||||
<value>Povolit záznam obrazovky</value>
|
||||
<value>Zapnout záznam obrazovky</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Opravdu chcete zapnout záznam obrazovky?</value>
|
||||
|
@ -2544,7 +2544,7 @@ Chcete se přepnout na tento účet?</value>
|
|||
<value>Jazyk byl změněn na {0}. Pro zobrazení změn restartujte aplikaci.</value>
|
||||
</data>
|
||||
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
|
||||
<value>Změna jazyku vyžaduje restart aplikace</value>
|
||||
<value>Změna jazyka vyžaduje restart aplikace.</value>
|
||||
</data>
|
||||
<data name="DefaultSystem" xml:space="preserve">
|
||||
<value>Výchozí (Systémový)</value>
|
||||
|
@ -2860,4 +2860,13 @@ Chcete se přepnout na tento účet?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Účet byl odhlášen.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Oprávnění Vaší organizace byla aktualizována. To vyžaduje nastavení hlavního hesla.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Vaše organizace vyžaduje nastavení hlavního hesla.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Nastavte volbu odemknutí, abyste změnili časový limit Vašeho trezoru.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ Vil du skifte til denne konto?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Konto logget ud.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Organisationstilladelserne er blevet opdateret, og der kræves nu oprettelse af en hovedadgangskode.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Organisationen kræver, at der oprettes en hovedadgangskode.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Opsæt en oplåsningsmetode for at ændre Bokstimeouthandlingen.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -946,7 +946,7 @@ Das Scannen erfolgt automatisch.</value>
|
|||
<value>Du kannst diese Funktion nicht nutzen, solange du deinen Verschlüsselungsschlüssel nicht aktualisiert hast.</value>
|
||||
</data>
|
||||
<data name="EncryptionKeyMigrationRequiredDescriptionLong" xml:space="preserve">
|
||||
<value>Encryption key migration required. Please login through the web vault to update your encryption key.</value>
|
||||
<value>Verschlüsselungscode-Migration erforderlich. Bitte melde dich über den Web-Tresor an, um deinen Verschlüsselungscode zu aktualisieren.</value>
|
||||
</data>
|
||||
<data name="LearnMore" xml:space="preserve">
|
||||
<value>Mehr erfahren</value>
|
||||
|
@ -2860,4 +2860,13 @@ Möchtest du zu diesem Konto wechseln?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Konto abgemeldet.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Deine Organisationsberechtigungen wurden aktualisiert und verlangen, dass du ein Master-Passwort festlegen musst.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Deine Organisation verlangt, dass du ein Master-Passwort festlegen musst.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Richte eine Entsperroption ein, um deine Aktion bei Tresor-Timeout zu ändern.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -247,8 +247,7 @@
|
|||
<comment>Description message for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
|
||||
<value>28/5000
|
||||
Απαιτείται σύνδεση στο διαδίκτυο</value>
|
||||
<value>Απαιτείται σύνδεση στο διαδίκτυο</value>
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
|
@ -946,7 +945,7 @@
|
|||
<value>Δεν μπορείτε να χρησιμοποιήσετε αυτήν τη δυνατότητα μέχρι να ενημερώσετε το κλειδί κρυπτογράφησης.</value>
|
||||
</data>
|
||||
<data name="EncryptionKeyMigrationRequiredDescriptionLong" xml:space="preserve">
|
||||
<value>Encryption key migration required. Please login through the web vault to update your encryption key.</value>
|
||||
<value>Απαιτείται μεταφορά του κλειδιού κρυπτογράφησης. Παρακαλούμε συνδεθείτε μέσω του web vault για να ενημερώσετε το κλειδί κρυπτογράφησης.</value>
|
||||
</data>
|
||||
<data name="LearnMore" xml:space="preserve">
|
||||
<value>Μάθετε Περισσότερα</value>
|
||||
|
@ -2623,28 +2622,28 @@
|
|||
<value>Τρέχων κύριος κωδικός</value>
|
||||
</data>
|
||||
<data name="LoggedIn" xml:space="preserve">
|
||||
<value>Logged in!</value>
|
||||
<value>Έχετε συνδεθεί!</value>
|
||||
</data>
|
||||
<data name="ApproveWithMyOtherDevice" xml:space="preserve">
|
||||
<value>Approve with my other device</value>
|
||||
<value>Έγκριση μέσω άλλης συσκευής μου</value>
|
||||
</data>
|
||||
<data name="RequestAdminApproval" xml:space="preserve">
|
||||
<value>Request admin approval</value>
|
||||
<value>Αίτηση έγκρισης από διαχειριστή</value>
|
||||
</data>
|
||||
<data name="ApproveWithMasterPassword" xml:space="preserve">
|
||||
<value>Approve with master password</value>
|
||||
<value>Έγκριση με τον κύριο κωδικό πρόσβασης</value>
|
||||
</data>
|
||||
<data name="TurnOffUsingPublicDevice" xml:space="preserve">
|
||||
<value>Turn off using a public device</value>
|
||||
<value>Απενεργοποίηση με χρήση δημόσιας συσκευής</value>
|
||||
</data>
|
||||
<data name="RememberThisDevice" xml:space="preserve">
|
||||
<value>Remember this device</value>
|
||||
<value>Απομνημόνευση αυτής της συσκευής</value>
|
||||
</data>
|
||||
<data name="Passkey" xml:space="preserve">
|
||||
<value>Συνθηματικό</value>
|
||||
<value>Κλειδί πρόσβασης</value>
|
||||
</data>
|
||||
<data name="Passkeys" xml:space="preserve">
|
||||
<value>Συνθηματικά</value>
|
||||
<value>Κλειδιά πρόσβασης</value>
|
||||
</data>
|
||||
<data name="Application" xml:space="preserve">
|
||||
<value>Εφαρμογή</value>
|
||||
|
@ -2659,13 +2658,13 @@
|
|||
<value>Το κλειδί πρόσβασης δεν θα αντιγραφεί στο κλωνοποιημένο στοιχείο. Θέλετε να συνεχίσετε την κλωνοποίηση αυτού του στοιχείου;</value>
|
||||
</data>
|
||||
<data name="CopyApplication" xml:space="preserve">
|
||||
<value>Copy application</value>
|
||||
<value>Αντιγραφή εφαρμογής</value>
|
||||
</data>
|
||||
<data name="AvailableForTwoStepLogin" xml:space="preserve">
|
||||
<value>Διαθέσιμο για σύνδεση με δύο βήματα</value>
|
||||
</data>
|
||||
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
|
||||
<value>Master password re-prompt help</value>
|
||||
<value>Βοήθεια προτροπής κύριου κωδικού πρόσβασης</value>
|
||||
</data>
|
||||
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
|
||||
<value>Το ξεκλείδωμα μπορεί να αποτύχει λόγω ανεπαρκούς μνήμης. Μειώστε τις ρυθμίσεις μνήμης KDF ή ρυθμίστε το βιομετρικό ξεκλείδωμα για επίλυση.</value>
|
||||
|
@ -2677,188 +2676,197 @@
|
|||
<value>Μη έγκυρο API token</value>
|
||||
</data>
|
||||
<data name="AdminApprovalRequested" xml:space="preserve">
|
||||
<value>Admin approval requested</value>
|
||||
<value>Ζητήθηκε έγκριση διαχειριστή</value>
|
||||
</data>
|
||||
<data name="YourRequestHasBeenSentToYourAdmin" xml:space="preserve">
|
||||
<value>Your request has been sent to your admin.</value>
|
||||
<value>Το αίτημά σας έχει σταλεί στον διαχειριστή σας.</value>
|
||||
</data>
|
||||
<data name="YouWillBeNotifiedOnceApproved" xml:space="preserve">
|
||||
<value>You will be notified once approved. </value>
|
||||
<value>Θα ειδοποιηθείτε μόλις εγκριθεί. </value>
|
||||
</data>
|
||||
<data name="TroubleLoggingIn" xml:space="preserve">
|
||||
<value>Trouble logging in?</value>
|
||||
<value>Δεν μπορείτε να συνδεθείτε;</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Σύνδεση ως {0}</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutActionChangedToLogOut" xml:space="preserve">
|
||||
<value>Vault timeout action changed to log out</value>
|
||||
<value>Η ενέργεια στη λήξη χρόνου του vault άλλαξε σε αποσύνδεση</value>
|
||||
</data>
|
||||
<data name="BlockAutoFill" xml:space="preserve">
|
||||
<value>Block auto-fill</value>
|
||||
<value>Αποκλείστε την αυτόματη συμπλήρωση</value>
|
||||
</data>
|
||||
<data name="AutoFillWillNotBeOfferedForTheseURIs" xml:space="preserve">
|
||||
<value>Auto-fill will not be offered for these URIs.</value>
|
||||
<value>Η αυτόματη συμπλήρωση δε θα προσφέρεται για αυτά τα URI.</value>
|
||||
</data>
|
||||
<data name="NewBlockedURI" xml:space="preserve">
|
||||
<value>New blocked URI</value>
|
||||
<value>Νέο αποκλεισμένο URI</value>
|
||||
</data>
|
||||
<data name="URISaved" xml:space="preserve">
|
||||
<value>URI saved</value>
|
||||
<value>URI αποθηκεύτηκε</value>
|
||||
</data>
|
||||
<data name="InvalidFormatUseHttpsHttpOrAndroidApp" xml:space="preserve">
|
||||
<value>Invalid format. Use https://, http://, or androidapp://</value>
|
||||
<value>Μη έγκυρη μορφή. Χρησιμοποιήστε https://, http://, ή androidapp://</value>
|
||||
<comment>https://, http://, androidapp:// should not be translated</comment>
|
||||
</data>
|
||||
<data name="EditURI" xml:space="preserve">
|
||||
<value>Edit URI</value>
|
||||
<value>Επεξεργασία του URI</value>
|
||||
</data>
|
||||
<data name="EnterURI" xml:space="preserve">
|
||||
<value>Enter URI</value>
|
||||
<value>Καταχωρήστε URI</value>
|
||||
</data>
|
||||
<data name="FormatXSeparateMultipleURIsWithAComma" xml:space="preserve">
|
||||
<value>Format: {0}. Separate multiple URIs with a comma.</value>
|
||||
<value>Μορφή: {0}. Διαχωρίστε τα πολλαπλά URI με κόμμα.</value>
|
||||
</data>
|
||||
<data name="FormatX" xml:space="preserve">
|
||||
<value>Format: {0}</value>
|
||||
<value>Μορφή: {0}</value>
|
||||
</data>
|
||||
<data name="InvalidURI" xml:space="preserve">
|
||||
<value>Invalid URI</value>
|
||||
<value>Μη έγκυρο URI</value>
|
||||
</data>
|
||||
<data name="URIRemoved" xml:space="preserve">
|
||||
<value>URI removed</value>
|
||||
<value>Το URI αφαιρέθηκε</value>
|
||||
</data>
|
||||
<data name="ThereAreNoBlockedURIs" xml:space="preserve">
|
||||
<value>There are no blocked URIs</value>
|
||||
<value>Δεν υπάρχουν αποκλεισμένα URI</value>
|
||||
</data>
|
||||
<data name="TheURIXIsAlreadyBlocked" xml:space="preserve">
|
||||
<value>The URI {0} is already blocked</value>
|
||||
<value>Το URI {0} είναι ήδη αποκλεισμένο</value>
|
||||
</data>
|
||||
<data name="CannotEditMultipleURIsAtOnce" xml:space="preserve">
|
||||
<value>Cannot edit multiple URIs at once</value>
|
||||
<value>Αδυναμία επεξεργασίας πολλαπλών URI ταυτόχρονα</value>
|
||||
</data>
|
||||
<data name="LoginApproved" xml:space="preserve">
|
||||
<value>Login approved</value>
|
||||
<value>Η σύνδεση εγκρίθηκε</value>
|
||||
</data>
|
||||
<data name="LogInWithDeviceMustBeSetUpInTheSettingsOfTheBitwardenAppNeedAnotherOption" xml:space="preserve">
|
||||
<value>Log in with device must be set up in the settings of the Bitwarden app. Need another option?</value>
|
||||
<value>Η σύνδεση με χρήση συσκευής πρέπει να ρυθμιστεί στις ρυθμίσεις της εφαρμογής Bitwarden. Χρειάζεστε άλλη επιλογή;</value>
|
||||
</data>
|
||||
<data name="LogInWithDevice" xml:space="preserve">
|
||||
<value>Log in with device</value>
|
||||
<value>Σύνδεση με χρήση συσκευής</value>
|
||||
</data>
|
||||
<data name="LoggingInOn" xml:space="preserve">
|
||||
<value>Logging in on</value>
|
||||
<value>Σύνδεση στο</value>
|
||||
</data>
|
||||
<data name="Vault" xml:space="preserve">
|
||||
<value>Vault</value>
|
||||
</data>
|
||||
<data name="Appearance" xml:space="preserve">
|
||||
<value>Appearance</value>
|
||||
<value>Εμφάνιση</value>
|
||||
</data>
|
||||
<data name="AccountSecurity" xml:space="preserve">
|
||||
<value>Account security</value>
|
||||
<value>Ασφάλεια λογαριασμού</value>
|
||||
</data>
|
||||
<data name="BitwardenHelpCenter" xml:space="preserve">
|
||||
<value>Bitwarden Help Center</value>
|
||||
<value>Κέντρο Βοήθειας Bitwarden</value>
|
||||
</data>
|
||||
<data name="ContactBitwardenSupport" xml:space="preserve">
|
||||
<value>Contact Bitwarden support</value>
|
||||
<value>Επικοινωνία με την υποστήριξη του Bitwarden</value>
|
||||
</data>
|
||||
<data name="CopyAppInformation" xml:space="preserve">
|
||||
<value>Copy app information</value>
|
||||
<value>Αντιγραφή πληροφοριών εφαρμογής</value>
|
||||
</data>
|
||||
<data name="SyncNow" xml:space="preserve">
|
||||
<value>Sync now</value>
|
||||
<value>Συγχρονισμός τώρα</value>
|
||||
</data>
|
||||
<data name="UnlockOptions" xml:space="preserve">
|
||||
<value>Unlock options</value>
|
||||
<value>Επιλογές Κλειδώματος</value>
|
||||
</data>
|
||||
<data name="SessionTimeout" xml:space="preserve">
|
||||
<value>Session timeout</value>
|
||||
<value>Χρονικό όριο συνεδρίας</value>
|
||||
</data>
|
||||
<data name="SessionTimeoutAction" xml:space="preserve">
|
||||
<value>Session timeout action</value>
|
||||
<value>Ενέργεια στη λήξη χρόνου συνεδρίας</value>
|
||||
</data>
|
||||
<data name="AccountFingerprintPhrase" xml:space="preserve">
|
||||
<value>Account fingerprint phrase</value>
|
||||
<value>"Φράση αποτυπώματος" λογαριασμού</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="OneHourAndOneMinute" xml:space="preserve">
|
||||
<value>One hour and one minute</value>
|
||||
<value>Μία ώρα και ένα λεπτό</value>
|
||||
</data>
|
||||
<data name="OneHourAndXMinute" xml:space="preserve">
|
||||
<value>One hour and {0} minutes</value>
|
||||
<value>Μία ώρα και {0} λεπτά</value>
|
||||
</data>
|
||||
<data name="XHoursAndOneMinute" xml:space="preserve">
|
||||
<value>{0} hours and one minute</value>
|
||||
<value>{0} ώρες και ένα λεπτό</value>
|
||||
</data>
|
||||
<data name="XHoursAndYMinutes" xml:space="preserve">
|
||||
<value>{0} hours and {1} minutes</value>
|
||||
<value>{0} ώρες και {1} λεπτά</value>
|
||||
</data>
|
||||
<data name="XHours" xml:space="preserve">
|
||||
<value>{0} hours</value>
|
||||
<value>{0} ώρες</value>
|
||||
</data>
|
||||
<data name="AutofillServicesExplanationLong" xml:space="preserve">
|
||||
<value>The Android Autofill Framework is used to assist in filling login information into other apps on your device.</value>
|
||||
<value>Το Android Autofill Framework χρησιμοποιείται για να προσφέρει αυτόματη συμπλήρωση στοιχείων σύνδεσης σε άλλες εφαρμογές στη συσκευή σας.</value>
|
||||
</data>
|
||||
<data name="UseInlineAutofillExplanationLong" xml:space="preserve">
|
||||
<value>Use inline autofill if your selected keyboard supports it. Otherwise, use the default overlay.</value>
|
||||
<value>Χρησιμοποιήστε την ενσωματωμένη αυτόματη συμπλήρωση αν το πληκτρολόγιο σας την υποστηρίζει. Διαφορετικά, χρησιμοποιήστε την προεπιλεγμένη επικάλυψη.</value>
|
||||
</data>
|
||||
<data name="AdditionalOptions" xml:space="preserve">
|
||||
<value>Additional options</value>
|
||||
<value>Πρόσθετες επιλογές</value>
|
||||
</data>
|
||||
<data name="ContinueToWebApp" xml:space="preserve">
|
||||
<value>Continue to web app?</value>
|
||||
<value>Συνέχεια στην εφαρμογή διαδικτύου;</value>
|
||||
</data>
|
||||
<data name="ContinueToX" xml:space="preserve">
|
||||
<value>Continue to {0}?</value>
|
||||
<value>Συνέχεια στο {0};</value>
|
||||
<comment>The parameter is an URL, like bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="ContinueToHelpCenter" xml:space="preserve">
|
||||
<value>Continue to Help center?</value>
|
||||
<value>Συνέχεια στο κέντρο βοήθειας;</value>
|
||||
</data>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
<value>Συνέχεια στην επικοινωνία με την υποστήριξη;</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
<value>Συνέχεια στο κατάστημα εφαρμογών;</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
|
||||
<value>Make your account more secure by setting up two-step login in the Bitwarden web app.</value>
|
||||
<value>Κάντε τον λογαριασμό σας πιο ασφαλή με τη ρύθμιση δύο βημάτων σύνδεσης στην εφαρμογή διαδικτύου Bitwarden.</value>
|
||||
</data>
|
||||
<data name="ChangeMasterPasswordDescriptionLong" xml:space="preserve">
|
||||
<value>You can change your master password on the Bitwarden web app.</value>
|
||||
<value>Μπορείτε να αλλάξετε τον κύριο κωδικό πρόσβασης στην εφαρμογή διαδικτύου Bitwarden.</value>
|
||||
</data>
|
||||
<data name="YouCanImportDataToYourVaultOnX" xml:space="preserve">
|
||||
<value>You can import data to your vault on {0}.</value>
|
||||
<value>Μπορείτε να εισαγάγετε δεδομένα στο vault σας στο {0}.</value>
|
||||
<comment>The parameter is an URL, like vault.bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="LearnMoreAboutHowToUseBitwardenOnTheHelpCenter" xml:space="preserve">
|
||||
<value>Learn more about how to use Bitwarden on the Help center.</value>
|
||||
<value>Μάθετε περισσότερα για το πώς να χρησιμοποιήσετε το Bitwarden στο κέντρο βοήθειας.</value>
|
||||
</data>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
<value>Δεν μπορείτε να βρείτε αυτό που ψάχνετε; Επικοινωνήστε με την υποστήριξη Bitwarden στο bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
<value>Εξερευνήστε περισσότερες δυνατότητες του Bitwarden λογαριασμού σας, στην εφαρμογή διαδικτύου.</value>
|
||||
</data>
|
||||
<data name="LearnAboutOrganizationsDescriptionLong" xml:space="preserve">
|
||||
<value>Bitwarden allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website.</value>
|
||||
<value>Το Bitwarden σας επιτρέπει να μοιράζεστε τα στοιχεία του vault σας με άλλους, χρησιμοποιώντας έναν λογαριασμό οργανισμού. Μάθετε περισσότερα στην ιστοσελίδα bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="RateAppDescriptionLong" xml:space="preserve">
|
||||
<value>Help others find out if Bitwarden is right for them. Visit the app store and leave a rating now.</value>
|
||||
<value>Βοηθήστε άλλους να μάθουν αν το Bitwarden είναι κατάλληλο για αυτούς. Επισκεφθείτε το κατάστημα εφαρμογών και αφήστε τώρα μια βαθμολογία.</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescriptionLong" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when your device’s dark mode is in use</value>
|
||||
<value>Επιλέξτε να χρησιμοποιείται το σκούρο θέμα όταν η συσκευή σας βρίσκεται σε σκοτεινή λειτουργία</value>
|
||||
</data>
|
||||
<data name="CreatedXY" xml:space="preserve">
|
||||
<value>Created {0}, {1}</value>
|
||||
<value>Δημιουργήθηκε {0}, {1}</value>
|
||||
<comment>To state the date/time in which the cipher was created: Created 03/21/2023, 09:25 AM. First parameter is the date and the second parameter is the time.</comment>
|
||||
</data>
|
||||
<data name="TooManyAttempts" xml:space="preserve">
|
||||
<value>Too many attempts</value>
|
||||
<value>Πάρα πολλές προσπάθειες</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
<value>Ο λογαριασμός αποσυνδέθηκε.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Τα δικαιώματα του οργανισμού σας ενημερώθηκαν, απαιτώντας από εσάς να ορίσετε έναν κύριο κωδικό πρόσβασης.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Ο οργανισμός σας απαιτεί να ορίσετε έναν κύριο κωδικό πρόσβασης.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Ρυθμίστε μια επιλογή κλειδώματος για να αλλάξετε την ενέργεια στη λήξη χρόνου του vault σας.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2875,4 +2875,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ Soovid selle konto peale lülituda?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2860,4 +2860,13 @@ Kontu honetara aldatu nahi duzu?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>حساب از سیستم خارج شد.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Haluatko vaihtaa tähän tiliin?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Tili kirjattiin ulos.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Organisaatiosi käyttöoikeuksia muutettiin ja tämän seurauksena sinun on asetettava pääsalasana.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Organisaatiosi edellyttää, että asetat pääsalasanan.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Muuta holvisi aikakatkaisutoimintoa määrittämällä lukituksen avaustapa.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Gusto mo bang pumunta sa account na ito?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -455,7 +455,7 @@
|
|||
<value>Continuer</value>
|
||||
</data>
|
||||
<data name="CreateAccount" xml:space="preserve">
|
||||
<value>Créer un compte</value>
|
||||
<value>Créez un compte</value>
|
||||
</data>
|
||||
<data name="CreatingAccount" xml:space="preserve">
|
||||
<value>Création du compte...</value>
|
||||
|
@ -686,10 +686,10 @@
|
|||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="SyncingComplete" xml:space="preserve">
|
||||
<value>Synchronisation terminée</value>
|
||||
<value>Synchronisation achevée</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Échec de la synchronisation</value>
|
||||
<value>Synchronisation échouée</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Synchroniser le coffre maintenant</value>
|
||||
|
@ -778,7 +778,7 @@
|
|||
<value>Le moyen le plus simple d'ajouter de nouveaux identifiants à votre coffre est d'utiliser le service de saisie automatique Bitwarden. Pour en savoir davantage sur l'utilisation du service de saisie automatique Bitwarden, naviguez jusqu'à l'écran "Paramètres".</value>
|
||||
</data>
|
||||
<data name="Autofill" xml:space="preserve">
|
||||
<value>Saisir automatiquement</value>
|
||||
<value>Saisie automatique</value>
|
||||
</data>
|
||||
<data name="AutofillOrView" xml:space="preserve">
|
||||
<value>Voulez-vous saisir automatiquement ou afficher cet élément ?</value>
|
||||
|
@ -907,7 +907,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Copier le TOTP</value>
|
||||
</data>
|
||||
<data name="CopyTotpAutomaticallyDescription" xml:space="preserve">
|
||||
<value>Si un identifiant a une clé d'authentification, copier le code de vérification TOTP dans votre presse-papier quand vous remplissez automatiquement l'identifiant.</value>
|
||||
<value>Si un identifiant possède une clé d'authentification, copiez le code de vérification TOTP dans votre presse-papiers lorsque vous saisissez automatiquement l'identifiant.</value>
|
||||
</data>
|
||||
<data name="CopyTotpAutomatically" xml:space="preserve">
|
||||
<value>Copier TOTP automatiquement</value>
|
||||
|
@ -1134,7 +1134,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Expiration</value>
|
||||
</data>
|
||||
<data name="ShowWebsiteIcons" xml:space="preserve">
|
||||
<value>Afficher les icônes du site web</value>
|
||||
<value>Afficher les icônes des sites web</value>
|
||||
</data>
|
||||
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
|
||||
<value>Affichez une image reconnaissable à côté de chaque identifiant.</value>
|
||||
|
@ -1304,13 +1304,13 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>1. Allez dans l'application "Réglages" d'iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Appuyez sur "Mots de passe et comptes"</value>
|
||||
<value>2. Appuyez sur "Mots de passe"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Appuyez sur "Préremplir mots de passe"</value>
|
||||
<value>3. Appuyez sur "Options des mots de passe"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn4" xml:space="preserve">
|
||||
<value>4. Activez "Préremplir mots de passe"</value>
|
||||
<value>4. Activez "Remplir automatiquement les mots de passe et les clés d'identification"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn5" xml:space="preserve">
|
||||
<value>5. Sélectionnez "Bitwarden"</value>
|
||||
|
@ -1378,10 +1378,10 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Rechercher dans la collection</value>
|
||||
</data>
|
||||
<data name="SearchFileSends" xml:space="preserve">
|
||||
<value>Rechercher des fichiers Sends</value>
|
||||
<value>Rechercher des Send fichier</value>
|
||||
</data>
|
||||
<data name="SearchTextSends" xml:space="preserve">
|
||||
<value>Rechercher des textes Sends</value>
|
||||
<value>Rechercher des Sends texte</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Rechercher {0} :</value>
|
||||
|
@ -1400,7 +1400,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Divers</value>
|
||||
</data>
|
||||
<data name="Ownership" xml:space="preserve">
|
||||
<value>Propriété</value>
|
||||
<value>Propriétaire</value>
|
||||
</data>
|
||||
<data name="WhoOwnsThisItem" xml:space="preserve">
|
||||
<value>À qui appartient cet élément ?</value>
|
||||
|
@ -1431,7 +1431,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Aucune organisation à lister.</value>
|
||||
</data>
|
||||
<data name="MoveToOrgDesc" xml:space="preserve">
|
||||
<value>Choisissez une organisation vers laquelle vous souhaitez déplacer cet élément. Déplacer un élément vers une organisation transfère la propriété de l'élément à cette organisation. Vous ne serez plus le propriétaire direct de cet élément une fois qu'il aura été déplacé.</value>
|
||||
<value>Choisissez une organisation vers laquelle vous souhaitez déplacer cet élément. Le déplacement vers une organisation transfère le Propriétaire de l'élément à cette organisation. Vous ne serez plus le propriétaire direct de cet élément une fois qu'il aura été déplacé.</value>
|
||||
</data>
|
||||
<data name="NumberOfWords" xml:space="preserve">
|
||||
<value>Nombre de mots</value>
|
||||
|
@ -1526,7 +1526,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
|
||||
</data>
|
||||
<data name="ClearClipboardDescription" xml:space="preserve">
|
||||
<value>Effacer automatiquement de votre presse-papiers les valeurs copiées.</value>
|
||||
<value>Effacez automatiquement les valeurs copiées de votre presse-papiers.</value>
|
||||
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
|
||||
</data>
|
||||
<data name="DefaultUriMatchDetection" xml:space="preserve">
|
||||
|
@ -1750,7 +1750,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Autoriser la synchronisation au rafraîchissement</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
|
||||
<value>Synchronisation du coffre avec un geste vers le bas</value>
|
||||
<value>Synchronisez le coffre avec un geste vers le bas.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Portail de connexion unique d'entreprise</value>
|
||||
|
@ -1853,10 +1853,10 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Si cette option est activée, l'accessibilité affichera une popup pour améliorer le service de remplissage automatique pour les anciennes applications qui ne prennent pas en charge les outils de remplissage automatique d'Android.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
|
||||
<value>En raison d'une Politique d'Entreprise, il vous est interdit d'enregistrer des objets dans votre coffre personnel. Changez l'option Propriété pour une organisation et choisissez parmi les Collections disponibles.</value>
|
||||
<value>En raison d'une politique d'entreprise, il vous est interdit d'enregistrer des éléments dans votre coffre personnel. Changez l'option Propriétaire au profit d'une organisation et choisissez parmi les collections disponibles.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipPolicyInEffect" xml:space="preserve">
|
||||
<value>Une politique d'organisation affecte vos options de propriété.</value>
|
||||
<value>Une politique d'organisation affecte vos options de Propriétaire.</value>
|
||||
</data>
|
||||
<data name="Send" xml:space="preserve">
|
||||
<value>Send</value>
|
||||
|
@ -1968,7 +1968,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSend" xml:space="preserve">
|
||||
<value>Désactiver cet envoi pour que personne ne puisse y accéder.</value>
|
||||
<value>Désactiver ce Send pour que personne ne puisse y accéder</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
|
@ -1998,7 +1998,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AddSend" xml:space="preserve">
|
||||
<value>Ajouter un Send</value>
|
||||
<value>Nouveau Send</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AreYouSureDeleteSend" xml:space="preserve">
|
||||
|
@ -2006,7 +2006,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDeleted" xml:space="preserve">
|
||||
<value>Le Send a été supprimé.</value>
|
||||
<value>Send supprimé</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
|
@ -2014,7 +2014,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
<value>Nouveau Send créé.</value>
|
||||
<value>Send créé</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="OneDay" xml:space="preserve">
|
||||
|
@ -2036,7 +2036,7 @@ La numérisation se fera automatiquement.</value>
|
|||
<value>Personnalisé</value>
|
||||
</data>
|
||||
<data name="ShareOnSave" xml:space="preserve">
|
||||
<value>Partager ce Send lors de l'enregistrement.</value>
|
||||
<value>Partagez ce Send au moment de l'enregistrement</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDisabledWarning" xml:space="preserve">
|
||||
|
@ -2355,7 +2355,7 @@ sélectionnez Ajouter TOTP pour stocker la clé en toute sécurité</value>
|
|||
<value>Approuver les demandes de connexion</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Utiliser cet appareil pour approuver les demandes de connexion faites à partir d'autres appareils.</value>
|
||||
<value>Utiliser cet appareil pour approuver les demandes de connexion faites à partir d'autres appareils</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Autoriser les notifications</value>
|
||||
|
@ -2546,7 +2546,7 @@ Voulez-vous basculer vers ce compte ?</value>
|
|||
<value>La langue a été changée en {0}. Veuillez redémarrer l'application pour voir le changement</value>
|
||||
</data>
|
||||
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
|
||||
<value>Le changement de langue nécessite le redémarrage de l'application</value>
|
||||
<value>Le changement de la langue nécessite le redémarrage de l'application.</value>
|
||||
</data>
|
||||
<data name="DefaultSystem" xml:space="preserve">
|
||||
<value>Par défaut (système)</value>
|
||||
|
@ -2781,7 +2781,7 @@ Voulez-vous basculer vers ce compte ?</value>
|
|||
<value>Action après délai d'expiration de la session</value>
|
||||
</data>
|
||||
<data name="AccountFingerprintPhrase" xml:space="preserve">
|
||||
<value>La phrase d'empreinte du compte</value>
|
||||
<value>Phrase d'empreinte du compte</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="OneHourAndOneMinute" xml:space="preserve">
|
||||
|
@ -2862,4 +2862,13 @@ Voulez-vous basculer vers ce compte ?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Compte déconnecté.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Les autorisations de votre organisation ont été mises à jour, vous obligeant à définir un mot de passe principal.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Votre organisation vous demande de définir un mot de passe principal.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Configurez une méthode de déverrouillage pour modifier l'action après délai d'expiration de votre coffre.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2864,4 +2864,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2423,7 +2423,7 @@
|
|||
<comment>"Fastmail" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="ForwardEmail" xml:space="preserve">
|
||||
<value>ForwardEmail</value>
|
||||
<value>FowardEmail</value>
|
||||
<comment>"ForwardEmail" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="APIAccessToken" xml:space="preserve">
|
||||
|
@ -2748,106 +2748,106 @@
|
|||
<value>Prijava na</value>
|
||||
</data>
|
||||
<data name="Vault" xml:space="preserve">
|
||||
<value>Vault</value>
|
||||
<value>Trezor</value>
|
||||
</data>
|
||||
<data name="Appearance" xml:space="preserve">
|
||||
<value>Appearance</value>
|
||||
<value>Izgled</value>
|
||||
</data>
|
||||
<data name="AccountSecurity" xml:space="preserve">
|
||||
<value>Account security</value>
|
||||
<value>Sigurnost računa</value>
|
||||
</data>
|
||||
<data name="BitwardenHelpCenter" xml:space="preserve">
|
||||
<value>Bitwarden Help Center</value>
|
||||
<value>Bitwarden centar za pomoć</value>
|
||||
</data>
|
||||
<data name="ContactBitwardenSupport" xml:space="preserve">
|
||||
<value>Contact Bitwarden support</value>
|
||||
<value>Kontaktiraj Bitwarden pomoć</value>
|
||||
</data>
|
||||
<data name="CopyAppInformation" xml:space="preserve">
|
||||
<value>Copy app information</value>
|
||||
<value>Kopiraj podake o aplikaciji</value>
|
||||
</data>
|
||||
<data name="SyncNow" xml:space="preserve">
|
||||
<value>Sync now</value>
|
||||
<value>Sinkroniziraj</value>
|
||||
</data>
|
||||
<data name="UnlockOptions" xml:space="preserve">
|
||||
<value>Unlock options</value>
|
||||
<value>Otključaj mogućnosti</value>
|
||||
</data>
|
||||
<data name="SessionTimeout" xml:space="preserve">
|
||||
<value>Session timeout</value>
|
||||
<value>Istek sesije</value>
|
||||
</data>
|
||||
<data name="SessionTimeoutAction" xml:space="preserve">
|
||||
<value>Session timeout action</value>
|
||||
<value>Radnja kod isteka sesije</value>
|
||||
</data>
|
||||
<data name="AccountFingerprintPhrase" xml:space="preserve">
|
||||
<value>Account fingerprint phrase</value>
|
||||
<value>Jedinstvena fraza računa</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="OneHourAndOneMinute" xml:space="preserve">
|
||||
<value>One hour and one minute</value>
|
||||
<value>Jedan sat i jedna minuta</value>
|
||||
</data>
|
||||
<data name="OneHourAndXMinute" xml:space="preserve">
|
||||
<value>One hour and {0} minutes</value>
|
||||
<value>Jedan sat i {0} minuta</value>
|
||||
</data>
|
||||
<data name="XHoursAndOneMinute" xml:space="preserve">
|
||||
<value>{0} hours and one minute</value>
|
||||
<value>{0} sat/i i jedna minuta</value>
|
||||
</data>
|
||||
<data name="XHoursAndYMinutes" xml:space="preserve">
|
||||
<value>{0} hours and {1} minutes</value>
|
||||
<value>{0} sat/i {1} minuta</value>
|
||||
</data>
|
||||
<data name="XHours" xml:space="preserve">
|
||||
<value>{0} hours</value>
|
||||
<value>{0} sat/i</value>
|
||||
</data>
|
||||
<data name="AutofillServicesExplanationLong" xml:space="preserve">
|
||||
<value>The Android Autofill Framework is used to assist in filling login information into other apps on your device.</value>
|
||||
<value>Android Autofill Framework se koristi za pomoć pri ispunjavanju prijava, platnih kartica i identifikacijskih podataka u drugim aplikacijama na tvojem uređaju.</value>
|
||||
</data>
|
||||
<data name="UseInlineAutofillExplanationLong" xml:space="preserve">
|
||||
<value>Use inline autofill if your selected keyboard supports it. Otherwise, use the default overlay.</value>
|
||||
<value>Koristi izravnu auto-ispunu ako ga tvoja odabrana tipkovnica podržava. U suprotnom, koristit će se zadana usluga auto-ispune.</value>
|
||||
</data>
|
||||
<data name="AdditionalOptions" xml:space="preserve">
|
||||
<value>Additional options</value>
|
||||
<value>Dodatne mogućnosti</value>
|
||||
</data>
|
||||
<data name="ContinueToWebApp" xml:space="preserve">
|
||||
<value>Continue to web app?</value>
|
||||
<value>Nastavi na web aplikaciju?</value>
|
||||
</data>
|
||||
<data name="ContinueToX" xml:space="preserve">
|
||||
<value>Continue to {0}?</value>
|
||||
<value>Nastavi na {0}?</value>
|
||||
<comment>The parameter is an URL, like bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="ContinueToHelpCenter" xml:space="preserve">
|
||||
<value>Continue to Help center?</value>
|
||||
<value>Nastavi u centar za pomoć?</value>
|
||||
</data>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
<value>Kontaktiraj podršku?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
<value>Nastavi u trgovinu aplikacijama?</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginDescriptionLong" xml:space="preserve">
|
||||
<value>Make your account more secure by setting up two-step login in the Bitwarden web app.</value>
|
||||
<value>Učini svoj račun sigurnijim uključivanjem prijave dvofaktorskom autentifikacijom u Bitwarden web aplikaciji.</value>
|
||||
</data>
|
||||
<data name="ChangeMasterPasswordDescriptionLong" xml:space="preserve">
|
||||
<value>You can change your master password on the Bitwarden web app.</value>
|
||||
<value>Svoju lozinku možeš promijeniti u Bitwarden web aplikaciji.</value>
|
||||
</data>
|
||||
<data name="YouCanImportDataToYourVaultOnX" xml:space="preserve">
|
||||
<value>You can import data to your vault on {0}.</value>
|
||||
<value>Svoje podatke možeš uvesti u trezor na {0}.</value>
|
||||
<comment>The parameter is an URL, like vault.bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="LearnMoreAboutHowToUseBitwardenOnTheHelpCenter" xml:space="preserve">
|
||||
<value>Learn more about how to use Bitwarden on the Help center.</value>
|
||||
<value>Za pomoć oko korištenja Bitwardena posjeti centar za pomoć.</value>
|
||||
</data>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
<value>Ne možeš naći što te zanima? Kontaktiraj Bitwarden podršku na bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
<value>Pronađi viđe značajki svojeg Bitwarden računa u web aplikaciji.</value>
|
||||
</data>
|
||||
<data name="LearnAboutOrganizationsDescriptionLong" xml:space="preserve">
|
||||
<value>Bitwarden allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website.</value>
|
||||
<value>Bitwarden omogućuje dijeljenje trezora s drugima pomoću organizacijskog računa. Za više informacija posjeti bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="RateAppDescriptionLong" xml:space="preserve">
|
||||
<value>Help others find out if Bitwarden is right for them. Visit the app store and leave a rating now.</value>
|
||||
<value>Želiš preporučiti Bitwarden drugima? Posjeti app store i ostavi recenziju.</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescriptionLong" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when your device’s dark mode is in use</value>
|
||||
<value>Odaberi tamnu temu kada se tvoj uređaj nalazi u tamnom načinu rada</value>
|
||||
</data>
|
||||
<data name="CreatedXY" xml:space="preserve">
|
||||
<value>Stvoreno {0}, {1}</value>
|
||||
|
@ -2859,4 +2859,13 @@
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Račun odjavljen.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Moraš postaviti glavnu lozinku jer su dopuštenja tvoje organizacije ažurirana.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Tvoja organizacija zahtijeva da postaviš glavnu lozinku.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Za promjenu vremena isteka trezora, odredi način otključavanja.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2860,4 +2860,13 @@ Szeretnénk átváltani erre a fiókra?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>A fiók kijelentkezett.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>A szervezeti jogosultságok frissítésre kerültek, ezért be kell állítani egy mesterjelszót.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>A szervezet megköveteli egy mesterjelszó beállítását.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Állítsunk be egy feloldási módot a széf időkifutási műveletének módosításához.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2695,7 +2695,7 @@ Vuoi passare a questo account?</value>
|
|||
<value>Azione timeout cassaforte impostata su uscire</value>
|
||||
</data>
|
||||
<data name="BlockAutoFill" xml:space="preserve">
|
||||
<value>Bocca riempimento automatico</value>
|
||||
<value>Blocca riempimento automatico</value>
|
||||
</data>
|
||||
<data name="AutoFillWillNotBeOfferedForTheseURIs" xml:space="preserve">
|
||||
<value>Il riempimento automatico non sarà offerto per questi URI.</value>
|
||||
|
@ -2861,4 +2861,13 @@ Vuoi passare a questo account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account uscito.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Le autorizzazioni della tua organizzazione sono state aggiornate, obbligandoti a impostare una password principale.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>La tua organizzazione ti obbliga di impostare di una password principale.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Imposta un metodo di sblocco per modificare l'azione timeout cassaforte.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2861,4 +2861,13 @@
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>アカウントからログアウトしました。</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>組織の権限が更新され、マスターパスワードの設定が必要になりました。</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>あなたの組織では、マスターパスワードの設定が義務付けられています。</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>保管庫のタイムアウト動作を変更するには、ロック解除方法を設定してください。</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -2862,4 +2862,13 @@ Do you want to switch to this account?</value>
|
|||
<data name="AccountLoggedOutBiometricExceeded" xml:space="preserve">
|
||||
<value>Account logged out.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationPermissionsWereUpdatedRequeringYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization permissions were updated, requiring you to set a master password.</value>
|
||||
</data>
|
||||
<data name="YourOrganizationRequiresYouToSetAMasterPassword" xml:space="preserve">
|
||||
<value>Your organization requires you to set a master password.</value>
|
||||
</data>
|
||||
<data name="SetUpAnUnlockOptionToChangeYourVaultTimeoutAction" xml:space="preserve">
|
||||
<value>Set up an unlock option to change your vault timeout action.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue