mirror of
https://github.com/bitwarden/mobile
synced 2026-01-08 03:23:23 +00:00
Merge branch 'feature/maui-migration-passkeys' into PM-5731-create-c-web-authn-authenticator-to-support-maui-apps
This commit is contained in:
@@ -56,18 +56,20 @@
|
||||
<CodesignKey>iPhone Developer</CodesignKey>
|
||||
<CodesignEntitlements>Platforms\iOS\Entitlements.plist</CodesignEntitlements>
|
||||
<UseInterpreter>true</UseInterpreter>
|
||||
<!--TODO: add argon2id load when library is built with the corresponding architecture for iOS Simulator-->
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(RuntimeIdentifier)'=='Debug|net8.0-ios|iossimulator-x64'">
|
||||
<MtouchExtraArgs>$(Argon2IdLoadMtouchExtraArgs)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(RuntimeIdentifier)'=='Debug|net8.0-ios|ios-arm64'">
|
||||
<MtouchExtraArgs>-gcc_flags "-L$(ProjectDir)../../lib/ios -largon2 -force_load $(ProjectDir)../../lib/ios/libargon2.a"</MtouchExtraArgs>
|
||||
<MtouchExtraArgs>$(Argon2IdLoadMtouchExtraArgs)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net8.0-ios|AnyCPU'">
|
||||
<CreatePackage>false</CreatePackage>
|
||||
<CodesignProvision>Automatic:AppStore</CodesignProvision>
|
||||
<CodesignKey>iPhone Distribution</CodesignKey>
|
||||
<CodesignProvision>$(ReleaseCodesignProvision)</CodesignProvision>
|
||||
<CodesignKey>$(ReleaseCodesignKey)</CodesignKey>
|
||||
<CodesignEntitlements>Platforms\iOS\Entitlements.plist</CodesignEntitlements>
|
||||
<UseInterpreter>true</UseInterpreter>
|
||||
<MtouchExtraArgs>-gcc_flags "-L$(ProjectDir)../../lib/ios -largon2 -force_load $(ProjectDir)../../lib/ios/libargon2.a"</MtouchExtraArgs>
|
||||
<MtouchExtraArgs>$(Argon2IdLoadMtouchExtraArgs)</MtouchExtraArgs>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
|
||||
<!--This is needed for PCLCrypto to work correctly-->
|
||||
@@ -209,7 +211,7 @@
|
||||
</MauiImage>
|
||||
<MauiImage Include="Resources\yubikey.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">
|
||||
<ItemGroup Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios' AND '$(IncludeBitwardeniOSExtensions)' == 'True'">
|
||||
<ProjectReference Include="..\iOS.Autofill\iOS.Autofill.csproj">
|
||||
<IsAppExtension>true</IsAppExtension>
|
||||
<IsWatchApp>false</IsWatchApp>
|
||||
@@ -223,15 +225,15 @@
|
||||
<IsWatchApp>false</IsWatchApp>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)'=='net8.0-ios'">
|
||||
<WatchAppBuildPath Condition=" '$(Configuration)' == 'Debug' ">$(Home)/Library/Developer/Xcode/DerivedData/bitwarden-acgkbpwvmebfiofokotvoerzkqcl/Build/Products</WatchAppBuildPath>
|
||||
<WatchAppBuildPath Condition=" '$(Configuration)' != 'Debug' ">$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..'))/watchOS/bitwarden.xcarchive/Products/Applications/bitwarden.app/Watch</WatchAppBuildPath>
|
||||
<WatchAppBundle>Bitwarden.app</WatchAppBundle>
|
||||
<WatchAppConfiguration Condition="'$(RuntimeIdentifier)'!='ios-arm64'">watchsimulator</WatchAppConfiguration>
|
||||
<WatchAppConfiguration Condition="'$(RuntimeIdentifier)'=='ios-arm64'">watchos</WatchAppConfiguration>
|
||||
<WatchAppBundleFullPath Condition=" '$(Configuration)' == 'Debug' ">$(WatchAppBuildPath)/$(Configuration)-$(WatchAppConfiguration)/$(WatchAppBundle)</WatchAppBundleFullPath>
|
||||
<WatchAppBundleFullPath Condition=" '$(Configuration)' != 'Debug' ">$(WatchAppBuildPath)/$(WatchAppBundle)</WatchAppBundleFullPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)'=='net8.0-ios' AND '$(IncludeBitwardenWatchOSApp)' == 'True'">
|
||||
<WatchAppBuildPath Condition=" '$(Configuration)' == 'Debug' ">$(Home)/Library/Developer/Xcode/DerivedData/bitwarden-acgkbpwvmebfiofokotvoerzkqcl/Build/Products</WatchAppBuildPath>
|
||||
<WatchAppBuildPath Condition=" '$(Configuration)' != 'Debug' ">$([System.IO.Path]::GetFullPath('$(MSBuildProjectDirectory)\..'))/watchOS/bitwarden.xcarchive/Products/Applications/bitwarden.app/Watch</WatchAppBuildPath>
|
||||
<WatchAppBundle>Bitwarden.app</WatchAppBundle>
|
||||
<WatchAppConfiguration Condition="'$(RuntimeIdentifier)'!='ios-arm64'">watchsimulator</WatchAppConfiguration>
|
||||
<WatchAppConfiguration Condition="'$(RuntimeIdentifier)'=='ios-arm64'">watchos</WatchAppConfiguration>
|
||||
<WatchAppBundleFullPath Condition=" '$(Configuration)' == 'Debug' ">$(WatchAppBuildPath)/$(Configuration)-$(WatchAppConfiguration)/$(WatchAppBundle)</WatchAppBundleFullPath>
|
||||
<WatchAppBundleFullPath Condition=" '$(Configuration)' != 'Debug' ">$(WatchAppBuildPath)/$(WatchAppBundle)</WatchAppBundleFullPath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net8.0-ios' AND Exists('$(WatchAppBundleFullPath)') ">
|
||||
<_ResolvedWatchAppReferences Include="$(WatchAppBundleFullPath)" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2024.1.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2024.2.0" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using AndroidX.AppCompat.View.Menu;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Google.Android.Material.BottomNavigation;
|
||||
using Microsoft.Maui.Handlers;
|
||||
@@ -90,7 +91,17 @@ namespace Bit.App.Handlers
|
||||
if(e.Item is MenuItemImpl item)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Tab '{item.Title}' was reselected so we'll PopToRoot.");
|
||||
MainThread.BeginInvokeOnMainThread(async () => await _tabbedPage.CurrentPage.Navigation.PopToRootAsync());
|
||||
MainThread.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await _tabbedPage.CurrentPage.Navigation.PopToRootAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,8 @@ namespace Bit.Droid
|
||||
|
||||
//We need to get and set the Options before calling OnCreate as that will "trigger" CreateWindow on App.xaml.cs
|
||||
_appOptions = GetOptions();
|
||||
((Bit.App.App)Microsoft.Maui.Controls.Application.Current).SetOptions(_appOptions);
|
||||
//This does not replace existing Options in App.xaml.cs if it exists already. It only updates properties in Options related with Autofill/CreateSend/etc..
|
||||
((Bit.App.App)Microsoft.Maui.Controls.Application.Current).SetAndroidOptions(_appOptions);
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Bit.Droid
|
||||
var autofillHandler = new AutofillHandler(stateService, messagingService, clipboardService,
|
||||
platformUtilsService, new LazyResolve<IEventService>());
|
||||
var cryptoFunctionService = new PclCryptoFunctionService(cryptoPrimitiveService);
|
||||
var cryptoService = new CryptoService(stateService, cryptoFunctionService);
|
||||
var cryptoService = new CryptoService(stateService, cryptoFunctionService, logger);
|
||||
var biometricService = new BiometricService(stateService, cryptoService);
|
||||
var userPinService = new UserPinService(stateService, cryptoService);
|
||||
var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService, stateService);
|
||||
|
||||
@@ -15,6 +15,7 @@ using CoreNFC;
|
||||
using Foundation;
|
||||
using Microsoft.Maui.Platform;
|
||||
using UIKit;
|
||||
using UserNotifications;
|
||||
using WatchConnectivity;
|
||||
|
||||
namespace Bit.iOS
|
||||
@@ -41,73 +42,78 @@ namespace Bit.iOS
|
||||
private IStateService _stateService;
|
||||
private IEventService _eventService;
|
||||
|
||||
private LazyResolve<IDeepLinkContext> _deepLinkContext = new LazyResolve<IDeepLinkContext>();
|
||||
private readonly LazyResolve<IDeepLinkContext> _deepLinkContext = new LazyResolve<IDeepLinkContext>();
|
||||
|
||||
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
|
||||
{
|
||||
InitApp();
|
||||
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||
|
||||
ConnectToWatchIfNeededAsync().FireAndForget();
|
||||
|
||||
_broadcasterService.Subscribe(nameof(AppDelegate), async (message) =>
|
||||
try
|
||||
{
|
||||
try
|
||||
InitApp();
|
||||
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||
|
||||
ConnectToWatchIfNeededAsync().FireAndForget();
|
||||
|
||||
_broadcasterService.Subscribe(nameof(AppDelegate), async (message) =>
|
||||
{
|
||||
if (message.Command == "startEventTimer")
|
||||
try
|
||||
{
|
||||
StartEventTimer();
|
||||
}
|
||||
else if (message.Command == "stopEventTimer")
|
||||
{
|
||||
var task = StopEventTimerAsync();
|
||||
}
|
||||
else if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
if (message.Command == "startEventTimer")
|
||||
{
|
||||
iOSCoreHelpers.AppearanceAdjustments();
|
||||
});
|
||||
}
|
||||
else if (message.Command == "listenYubiKeyOTP")
|
||||
{
|
||||
iOSCoreHelpers.ListenYubiKey((bool)message.Data, _deviceActionService, _nfcSession, _nfcDelegate);
|
||||
}
|
||||
else if (message.Command == "unlocked")
|
||||
{
|
||||
var needsAutofillReplacement = await _storageService.GetAsync<bool?>(
|
||||
Core.Constants.AutofillNeedsIdentityReplacementKey);
|
||||
if (needsAutofillReplacement.GetValueOrDefault())
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
StartEventTimer();
|
||||
}
|
||||
}
|
||||
else if (message.Command == "showAppExtension")
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() => ShowAppExtension((ExtensionPageViewModel)message.Data));
|
||||
}
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
if (message.Data is Dictionary<string, object> data && data.ContainsKey("successfully"))
|
||||
else if (message.Command == "stopEventTimer")
|
||||
{
|
||||
var success = data["successfully"] as bool?;
|
||||
if (success.GetValueOrDefault() && _deviceActionService.SystemMajorVersion() >= 12)
|
||||
var task = StopEventTimerAsync();
|
||||
}
|
||||
else if (message.Command is ThemeManager.UPDATED_THEME_MESSAGE_KEY)
|
||||
{
|
||||
await MainThread.InvokeOnMainThreadAsync(() =>
|
||||
{
|
||||
iOSCoreHelpers.AppearanceAdjustments();
|
||||
});
|
||||
}
|
||||
else if (message.Command == "listenYubiKeyOTP" && message.Data is bool listen)
|
||||
{
|
||||
iOSCoreHelpers.ListenYubiKey(listen, _deviceActionService, _nfcSession, _nfcDelegate);
|
||||
}
|
||||
else if (message.Command == "unlocked")
|
||||
{
|
||||
var needsAutofillReplacement = await _storageService.GetAsync<bool?>(
|
||||
Core.Constants.AutofillNeedsIdentityReplacementKey);
|
||||
if (needsAutofillReplacement.GetValueOrDefault())
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (message.Command == "addedCipher" || message.Command == "editedCipher" ||
|
||||
message.Command == "restoredCipher")
|
||||
{
|
||||
if (_deviceActionService.SystemMajorVersion() >= 12)
|
||||
else if (message.Command == "showAppExtension")
|
||||
{
|
||||
await MainThread.InvokeOnMainThreadAsync(() => ShowAppExtension((ExtensionPageViewModel)message.Data));
|
||||
}
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
if (message.Data is Dictionary<string, object> data && data.TryGetValue("successfully", out var value))
|
||||
{
|
||||
var success = value as bool?;
|
||||
if (success.GetValueOrDefault() && _deviceActionService.SystemMajorVersion() >= 12)
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (message.Command == "addedCipher" || message.Command == "editedCipher" ||
|
||||
message.Command == "restoredCipher")
|
||||
{
|
||||
if (!UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (await ASHelpers.IdentitiesSupportIncrementalAsync())
|
||||
{
|
||||
var cipherId = message.Data as string;
|
||||
@@ -124,11 +130,13 @@ namespace Bit.iOS
|
||||
}
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
else if (message.Command == "deletedCipher" || message.Command == "softDeletedCipher")
|
||||
{
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
else if (message.Command == "deletedCipher" || message.Command == "softDeletedCipher")
|
||||
{
|
||||
if (!UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (await ASHelpers.IdentitiesSupportIncrementalAsync())
|
||||
{
|
||||
var identity = ASHelpers.ToPasswordCredentialIdentity(
|
||||
@@ -142,105 +150,145 @@ namespace Bit.iOS
|
||||
}
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
else if (message.Command == "logout")
|
||||
{
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
else if (message.Command == "logout" && UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
await ASCredentialIdentityStore.SharedStore.RemoveAllCredentialIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
else if ((message.Command == "softDeletedCipher" || message.Command == "restoredCipher")
|
||||
&& UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
else if (message.Command == AppHelpers.VAULT_TIMEOUT_ACTION_CHANGED_MESSAGE_COMMAND)
|
||||
{
|
||||
var timeoutAction = await _stateService.GetVaultTimeoutActionAsync();
|
||||
if (timeoutAction == VaultTimeoutAction.Logout && UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
await ASCredentialIdentityStore.SharedStore.RemoveAllCredentialIdentitiesAsync();
|
||||
}
|
||||
else
|
||||
else if ((message.Command == "softDeletedCipher" || message.Command == "restoredCipher")
|
||||
&& UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
else if (message.Command == AppHelpers.VAULT_TIMEOUT_ACTION_CHANGED_MESSAGE_COMMAND)
|
||||
{
|
||||
var timeoutAction = await _stateService.GetVaultTimeoutActionAsync();
|
||||
if (timeoutAction == VaultTimeoutAction.Logout)
|
||||
{
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(12, 0))
|
||||
{
|
||||
await ASCredentialIdentityStore.SharedStore.RemoveAllCredentialIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await ASHelpers.ReplaceAllIdentitiesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
|
||||
var finishedLaunching = base.FinishedLaunching(app, options);
|
||||
var finishedLaunching = base.FinishedLaunching(app, options);
|
||||
|
||||
ThemeManager.SetTheme(Microsoft.Maui.Controls.Application.Current.Resources);
|
||||
iOSCoreHelpers.AppearanceAdjustments();
|
||||
ThemeManager.SetTheme(Microsoft.Maui.Controls.Application.Current.Resources);
|
||||
iOSCoreHelpers.AppearanceAdjustments();
|
||||
|
||||
return finishedLaunching;
|
||||
return finishedLaunching;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResignActivation(UIApplication uiApplication)
|
||||
{
|
||||
if (UIApplication.SharedApplication.KeyWindow is null)
|
||||
try
|
||||
{
|
||||
if (UIApplication.SharedApplication.KeyWindow != null)
|
||||
{
|
||||
var view = new UIView(UIApplication.SharedApplication.KeyWindow.Frame)
|
||||
{
|
||||
Tag = SPLASH_VIEW_TAG
|
||||
};
|
||||
var backgroundView = new UIView(UIApplication.SharedApplication.KeyWindow.Frame)
|
||||
{
|
||||
BackgroundColor = ThemeManager.GetResourceColor("SplashBackgroundColor").ToPlatform()
|
||||
};
|
||||
var logo = new UIImage(!ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png");
|
||||
var frame = new CGRect(0, 0, 280, 100); //Setting image width to avoid it being larger and getting cropped on smaller devices. This harcoded size should be good even for very small devices.
|
||||
var imageView = new UIImageView(frame)
|
||||
{
|
||||
Image = logo,
|
||||
Center = new CGPoint(view.Center.X, view.Center.Y - 30),
|
||||
ContentMode = UIViewContentMode.ScaleAspectFit
|
||||
};
|
||||
view.AddSubview(backgroundView);
|
||||
view.AddSubview(imageView);
|
||||
UIApplication.SharedApplication.KeyWindow.AddSubview(view);
|
||||
UIApplication.SharedApplication.KeyWindow.BringSubviewToFront(view);
|
||||
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
|
||||
}
|
||||
base.OnResignActivation(uiApplication);
|
||||
return;
|
||||
}
|
||||
|
||||
var view = new UIView(UIApplication.SharedApplication.KeyWindow.Frame)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Tag = SPLASH_VIEW_TAG
|
||||
};
|
||||
var backgroundView = new UIView(UIApplication.SharedApplication.KeyWindow.Frame)
|
||||
{
|
||||
BackgroundColor = ThemeManager.GetResourceColor("SplashBackgroundColor").ToPlatform()
|
||||
};
|
||||
var logo = new UIImage(!ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png");
|
||||
var frame = new CGRect(0, 0, 280, 100); //Setting image width to avoid it being larger and getting cropped on smaller devices. This harcoded size should be good even for very small devices.
|
||||
var imageView = new UIImageView(frame)
|
||||
{
|
||||
Image = logo,
|
||||
Center = new CGPoint(view.Center.X, view.Center.Y - 30),
|
||||
ContentMode = UIViewContentMode.ScaleAspectFit
|
||||
};
|
||||
view.AddSubview(backgroundView);
|
||||
view.AddSubview(imageView);
|
||||
UIApplication.SharedApplication.KeyWindow.AddSubview(view);
|
||||
UIApplication.SharedApplication.KeyWindow.BringSubviewToFront(view);
|
||||
UIApplication.SharedApplication.KeyWindow.EndEditing(true);
|
||||
|
||||
base.OnResignActivation(uiApplication);
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DidEnterBackground(UIApplication uiApplication)
|
||||
{
|
||||
if (_stateService != null && _deviceActionService != null)
|
||||
try
|
||||
{
|
||||
_stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime());
|
||||
}
|
||||
if (_stateService != null && _deviceActionService != null)
|
||||
{
|
||||
_stateService.SetLastActiveTimeAsync(_deviceActionService.GetActiveTime());
|
||||
}
|
||||
|
||||
_messagingService?.Send("slept");
|
||||
base.DidEnterBackground(uiApplication);
|
||||
_messagingService?.Send("slept");
|
||||
base.DidEnterBackground(uiApplication);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnActivated(UIApplication uiApplication)
|
||||
public override async void OnActivated(UIApplication uiApplication)
|
||||
{
|
||||
base.OnActivated(uiApplication);
|
||||
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
|
||||
UIApplication.SharedApplication.KeyWindow?
|
||||
.ViewWithTag(SPLASH_VIEW_TAG)?
|
||||
.RemoveFromSuperview();
|
||||
try
|
||||
{
|
||||
base.OnActivated(uiApplication);
|
||||
|
||||
ThemeManager.UpdateThemeOnPagesAsync();
|
||||
if (UIDevice.CurrentDevice.CheckSystemVersion(17, 0))
|
||||
{
|
||||
await UNUserNotificationCenter.Current.SetBadgeCountAsync(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
UIApplication.SharedApplication.ApplicationIconBadgeNumber = 0;
|
||||
}
|
||||
|
||||
UIApplication.SharedApplication.KeyWindow?
|
||||
.ViewWithTag(SPLASH_VIEW_TAG)?
|
||||
.RemoveFromSuperview();
|
||||
|
||||
ThemeManager.UpdateThemeOnPagesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WillEnterForeground(UIApplication uiApplication)
|
||||
{
|
||||
_messagingService?.Send(AppHelpers.RESUMED_MESSAGE_COMMAND);
|
||||
base.WillEnterForeground(uiApplication);
|
||||
try
|
||||
{
|
||||
_messagingService?.Send(AppHelpers.RESUMED_MESSAGE_COMMAND);
|
||||
base.WillEnterForeground(uiApplication);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("application:openURL:sourceApplication:annotation:")]
|
||||
@@ -251,15 +299,30 @@ namespace Bit.iOS
|
||||
|
||||
public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
|
||||
{
|
||||
return _deepLinkContext.Value.OnNewUri(url) || base.OpenUrl(app, url, options);
|
||||
try
|
||||
{
|
||||
return _deepLinkContext.Value.OnNewUri(url) || base.OpenUrl(app, url, options);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ContinueUserActivity(UIApplication application, NSUserActivity userActivity,
|
||||
UIApplicationRestorationHandler completionHandler)
|
||||
{
|
||||
if (Microsoft.Maui.ApplicationModel.Platform.ContinueUserActivity(application, userActivity, completionHandler))
|
||||
try
|
||||
{
|
||||
return true;
|
||||
if (Microsoft.Maui.ApplicationModel.Platform.ContinueUserActivity(application, userActivity, completionHandler))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
return base.ContinueUserActivity(application, userActivity, completionHandler);
|
||||
}
|
||||
@@ -267,33 +330,68 @@ namespace Bit.iOS
|
||||
[Export("application:didFailToRegisterForRemoteNotificationsWithError:")]
|
||||
public void FailedToRegisterForRemoteNotifications(UIApplication application, NSError error)
|
||||
{
|
||||
_pushHandler?.OnErrorReceived(error);
|
||||
try
|
||||
{
|
||||
_pushHandler?.OnErrorReceived(error);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("application:didRegisterForRemoteNotificationsWithDeviceToken:")]
|
||||
public void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
|
||||
{
|
||||
_pushHandler?.OnRegisteredSuccess(deviceToken);
|
||||
try
|
||||
{
|
||||
_pushHandler?.OnRegisteredSuccess(deviceToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("application:didRegisterUserNotificationSettings:")]
|
||||
public void DidRegisterUserNotificationSettings(UIApplication application,
|
||||
UIUserNotificationSettings notificationSettings)
|
||||
{
|
||||
application.RegisterForRemoteNotifications();
|
||||
try
|
||||
{
|
||||
application.RegisterForRemoteNotifications();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("application:didReceiveRemoteNotification:fetchCompletionHandler:")]
|
||||
public void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo,
|
||||
Action<UIBackgroundFetchResult> completionHandler)
|
||||
{
|
||||
_pushHandler?.OnMessageReceived(userInfo);
|
||||
try
|
||||
{
|
||||
_pushHandler?.OnMessageReceived(userInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
[Export("application:didReceiveRemoteNotification:")]
|
||||
public void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
|
||||
{
|
||||
_pushHandler?.OnMessageReceived(userInfo);
|
||||
try
|
||||
{
|
||||
_pushHandler?.OnMessageReceived(userInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void InitApp()
|
||||
@@ -319,7 +417,7 @@ namespace Bit.iOS
|
||||
_nfcDelegate = new Core.NFCReaderDelegate((success, message) =>
|
||||
_messagingService.Send("gotYubiKeyOTP", message));
|
||||
|
||||
iOSCoreHelpers.Bootstrap(async () => await ApplyManagedSettingsAsync());
|
||||
iOSCoreHelpers.Bootstrap(ApplyManagedSettingsAsync);
|
||||
}
|
||||
|
||||
private void RegisterPush()
|
||||
@@ -364,31 +462,45 @@ namespace Bit.iOS
|
||||
_eventTimer = null;
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
_eventTimer = NSTimer.CreateScheduledTimer(60, true, timer =>
|
||||
try
|
||||
{
|
||||
var task = Task.Run(() => _eventService.UploadEventsAsync());
|
||||
});
|
||||
_eventTimer = NSTimer.CreateScheduledTimer(60, true, timer =>
|
||||
{
|
||||
_eventService?.UploadEventsAsync().FireAndForget();
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async Task StopEventTimerAsync()
|
||||
{
|
||||
_eventTimer?.Invalidate();
|
||||
_eventTimer?.Dispose();
|
||||
_eventTimer = null;
|
||||
if (_eventBackgroundTaskId > 0)
|
||||
try
|
||||
{
|
||||
_eventTimer?.Invalidate();
|
||||
_eventTimer?.Dispose();
|
||||
_eventTimer = null;
|
||||
if (_eventBackgroundTaskId > 0)
|
||||
{
|
||||
UIApplication.SharedApplication.EndBackgroundTask(_eventBackgroundTaskId);
|
||||
_eventBackgroundTaskId = 0;
|
||||
}
|
||||
_eventBackgroundTaskId = UIApplication.SharedApplication.BeginBackgroundTask(() =>
|
||||
{
|
||||
UIApplication.SharedApplication.EndBackgroundTask(_eventBackgroundTaskId);
|
||||
_eventBackgroundTaskId = 0;
|
||||
});
|
||||
await _eventService.UploadEventsAsync();
|
||||
UIApplication.SharedApplication.EndBackgroundTask(_eventBackgroundTaskId);
|
||||
_eventBackgroundTaskId = 0;
|
||||
}
|
||||
_eventBackgroundTaskId = UIApplication.SharedApplication.BeginBackgroundTask(() =>
|
||||
catch (Exception ex)
|
||||
{
|
||||
UIApplication.SharedApplication.EndBackgroundTask(_eventBackgroundTaskId);
|
||||
_eventBackgroundTaskId = 0;
|
||||
});
|
||||
await _eventService.UploadEventsAsync();
|
||||
UIApplication.SharedApplication.EndBackgroundTask(_eventBackgroundTaskId);
|
||||
_eventBackgroundTaskId = 0;
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ApplyManagedSettingsAsync()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.8bit.bitwarden</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2024.1.1</string>
|
||||
<string>2024.2.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CFBundleIconName</key>
|
||||
|
||||
@@ -63,5 +63,7 @@ namespace Bit.Core.Abstractions
|
||||
Task<UserKey> DecryptAndMigrateOldPinKeyAsync(bool masterPasswordOnRestart, string pin, string email, KdfConfig kdfConfig, EncString oldPinKey);
|
||||
Task<MasterKey> GetOrDeriveMasterKeyAsync(string password, string userId = null);
|
||||
Task UpdateMasterKeyAndUserKeyAsync(MasterKey masterKey);
|
||||
Task<string> HashAsync(string value, CryptoHashAlgorithm hashAlgorithm);
|
||||
Task<bool> ValidateUriChecksumAsync(EncString remoteUriChecksum, string rawUri, string orgId, SymmetricCryptoKey key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,14 +81,31 @@ namespace Bit.App
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.Current.Windows.OfType<ResumeWindow>().FirstOrDefault(w => w.IsActive);
|
||||
return Application.Current?.Windows.OfType<ResumeWindow>().FirstOrDefault(w => w.IsActive);
|
||||
}
|
||||
}
|
||||
|
||||
//Allows setting Options from MainActivity before base.OnCreate
|
||||
public void SetOptions(AppOptions appOptions)
|
||||
/// <summary>
|
||||
/// Allows setting Options from MainActivity before base.OnCreate
|
||||
/// Note 1: This is only be used by Android due to way it's Lifecycle works
|
||||
/// Note 2: This method does not replace existing Options in App.xaml.cs if it exists already.
|
||||
/// It only updates properties in Options related with Autofill/CreateSend/etc..
|
||||
/// </summary>
|
||||
/// <param name="appOptions">Options created in Android MainActivity.cs</param>
|
||||
public void SetAndroidOptions(AppOptions appOptions)
|
||||
{
|
||||
Options = appOptions ?? new AppOptions();
|
||||
if (Options == null)
|
||||
{
|
||||
Options = appOptions ?? new AppOptions();
|
||||
}
|
||||
else if(appOptions != null)
|
||||
{
|
||||
Options.Uri = appOptions.Uri;
|
||||
Options.MyVaultTile = appOptions.MyVaultTile;
|
||||
Options.GeneratorTile = appOptions.GeneratorTile;
|
||||
Options.FromAutofillFramework = appOptions.FromAutofillFramework;
|
||||
Options.CreateSend = appOptions.CreateSend;
|
||||
}
|
||||
}
|
||||
|
||||
protected override Window CreateWindow(IActivationState activationState)
|
||||
@@ -145,11 +162,14 @@ namespace Bit.App
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.Current.MainPage;
|
||||
return Application.Current?.MainPage;
|
||||
}
|
||||
set
|
||||
{
|
||||
Application.Current.MainPage = value;
|
||||
if (Application.Current != null)
|
||||
{
|
||||
Application.Current.MainPage = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -70,10 +70,11 @@ namespace Bit.Core
|
||||
public const int Argon2Parallelism = 4;
|
||||
public const int MasterPasswordMinimumChars = 12;
|
||||
public const int CipherKeyRandomBytesLength = 64;
|
||||
public const string CipherKeyEncryptionMinServerVersion = "2023.9.1";
|
||||
public const string CipherKeyEncryptionMinServerVersion = "2024.2.0";
|
||||
public const string DefaultFido2CredentialType = "public-key";
|
||||
public const string DefaultFido2CredentialAlgorithm = "ECDSA";
|
||||
public const string DefaultFido2CredentialCurve = "P-256";
|
||||
public const int LatestStateVersion = 7;
|
||||
|
||||
public static readonly string[] AndroidAllClearCipherCacheKeys =
|
||||
{
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
BackgroundColor="#22000000"
|
||||
Padding="0"
|
||||
IsVisible="False">
|
||||
<VerticalStackLayout
|
||||
<Grid
|
||||
x:Name="_accountListContainer"
|
||||
VerticalOptions="Fill"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
BackgroundColor="Transparent">
|
||||
HorizontalOptions="Fill"
|
||||
BackgroundColor="Transparent"
|
||||
RowDefinitions="Auto, *">
|
||||
<Frame
|
||||
Grid.Row="0"
|
||||
Padding="0"
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="Start">
|
||||
@@ -49,12 +51,13 @@
|
||||
</ListView>
|
||||
</Frame>
|
||||
<BoxView
|
||||
Grid.Row="1"
|
||||
BackgroundColor="Transparent"
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="FillAndExpand">
|
||||
VerticalOptions="Fill">
|
||||
<BoxView.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="FreeSpaceOverlay_Tapped" />
|
||||
</BoxView.GestureRecognizers>
|
||||
</BoxView>
|
||||
</VerticalStackLayout>
|
||||
</Grid>
|
||||
</ContentView>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<controls:ExtendedGrid xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
<controls:BaseCipherViewCell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Controls.AuthenticatorViewCell"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
@@ -13,33 +13,32 @@
|
||||
RowSpacing="0"
|
||||
Padding="0,10,0,0"
|
||||
RowDefinitions="*,*">
|
||||
<Grid.Resources>
|
||||
<controls:BaseCipherViewCell.Resources>
|
||||
<u:IconGlyphConverter x:Key="iconGlyphConverter" />
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
</Grid.Resources>
|
||||
|
||||
<controls:IconLabel
|
||||
Grid.Column="0"
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
StyleClass="list-icon, list-icon-platform"
|
||||
Grid.RowSpan="2"
|
||||
IsVisible="{Binding ShowIconImage, Converter={StaticResource inverseBool}}"
|
||||
Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}"
|
||||
AutomationProperties.IsInAccessibleTree="False" />
|
||||
</controls:BaseCipherViewCell.Resources>
|
||||
|
||||
<controls:CachedImage
|
||||
x:Name="_iconImage"
|
||||
Grid.Column="0"
|
||||
Grid.RowSpan="2"
|
||||
BitmapOptimizations="True"
|
||||
ErrorPlaceholder="login.png"
|
||||
LoadingPlaceholder="login.png"
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
WidthRequest="22"
|
||||
HeightRequest="22"
|
||||
Success="Icon_Success"
|
||||
Error="Icon_Error"
|
||||
AutomationProperties.IsInAccessibleTree="False" />
|
||||
|
||||
<controls:IconLabel
|
||||
x:Name="_iconPlaceholderImage"
|
||||
Grid.Column="0"
|
||||
Grid.RowSpan="2"
|
||||
IsVisible="{Binding ShowIconImage}"
|
||||
Source="{Binding IconImageSource, Mode=OneTime}"
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
StyleClass="list-icon, list-icon-platform"
|
||||
Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}"
|
||||
AutomationProperties.IsInAccessibleTree="False" />
|
||||
|
||||
<Label
|
||||
@@ -47,7 +46,7 @@
|
||||
Grid.Column="1"
|
||||
Grid.Row="0"
|
||||
VerticalTextAlignment="Center"
|
||||
VerticalOptions="Fill"
|
||||
VerticalOptions="End"
|
||||
StyleClass="list-title, list-title-platform"
|
||||
Text="{Binding Cipher.Name}" />
|
||||
|
||||
@@ -56,7 +55,7 @@
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
VerticalTextAlignment="Center"
|
||||
VerticalOptions="Fill"
|
||||
VerticalOptions="Start"
|
||||
StyleClass="list-subtitle, list-subtitle-platform"
|
||||
Text="{Binding Cipher.SubTitle}" />
|
||||
|
||||
@@ -66,11 +65,14 @@
|
||||
Grid.Column="2"
|
||||
Grid.RowSpan="2"
|
||||
HorizontalOptions="Fill"
|
||||
WidthRequest="50"
|
||||
HeightRequest="50"
|
||||
VerticalOptions="CenterAndExpand" />
|
||||
|
||||
<Label
|
||||
Text="{Binding TotpSec, Mode=OneWay}"
|
||||
Style="{DynamicResource textTotp}"
|
||||
BackgroundColor="Transparent"
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
Grid.RowSpan="2"
|
||||
@@ -121,4 +123,4 @@
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
SemanticProperties.Description="{u:I18n CopyTotp}" />
|
||||
</controls:ExtendedGrid>
|
||||
</controls:BaseCipherViewCell>
|
||||
@@ -1,10 +1,14 @@
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class AuthenticatorViewCell : ExtendedGrid
|
||||
public partial class AuthenticatorViewCell : BaseCipherViewCell
|
||||
{
|
||||
public AuthenticatorViewCell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override CachedImage Icon => _iconImage;
|
||||
|
||||
protected override IconLabel IconPlaceholder => _iconPlaceholderImage;
|
||||
}
|
||||
}
|
||||
|
||||
62
src/Core/Controls/Avatar/AvatarImageSource.cs
Normal file
62
src/Core/Controls/Avatar/AvatarImageSource.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class AvatarImageSource : StreamImageSource
|
||||
{
|
||||
private readonly string _text;
|
||||
private readonly string _id;
|
||||
private readonly string _color;
|
||||
private readonly AvatarInfo _avatarInfo;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj is AvatarImageSource avatar)
|
||||
{
|
||||
return avatar._id == _id && avatar._text == _text && avatar._color == _color;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode() => _id?.GetHashCode() ?? _text?.GetHashCode() ?? -1;
|
||||
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null, string color = null)
|
||||
{
|
||||
_id = userId;
|
||||
_text = name;
|
||||
if (string.IsNullOrWhiteSpace(_text))
|
||||
{
|
||||
_text = email;
|
||||
}
|
||||
_color = color;
|
||||
|
||||
//Workaround: [MAUI-Migration] There is currently a bug in MAUI where the actual size of the image is used instead of the size it should occupy in the Toolbar.
|
||||
//This causes some issues with the position of the icon. As a workaround we make the icon smaller until this is fixed.
|
||||
//Github issues: https://github.com/dotnet/maui/issues/12359 and https://github.com/dotnet/maui/pull/17120
|
||||
_avatarInfo = new AvatarInfo(userId, name, email, color, DeviceInfo.Platform == DevicePlatform.iOS ? 20 : 50);
|
||||
}
|
||||
|
||||
public override Func<CancellationToken, Task<Stream>> Stream => GetStreamAsync;
|
||||
|
||||
private Task<Stream> GetStreamAsync(CancellationToken userToken = new CancellationToken())
|
||||
{
|
||||
var result = Draw();
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
private Stream Draw()
|
||||
{
|
||||
using (var img = SKAvatarImageHelper.Draw(_avatarInfo))
|
||||
{
|
||||
var data = img.Encode(SKEncodedImageFormat.Png, 100);
|
||||
return data?.AsStream(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/Core/Controls/Avatar/AvatarInfo.cs
Normal file
63
src/Core/Controls/Avatar/AvatarInfo.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
#nullable enable
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public struct AvatarInfo
|
||||
{
|
||||
private const string DEFAULT_BACKGROUND_COLOR = "#33ffffff";
|
||||
|
||||
public AvatarInfo(string? userId = null, string? name = null, string? email = null, string? color = null, int size = 50)
|
||||
{
|
||||
Size = size;
|
||||
var text = string.IsNullOrWhiteSpace(name) ? email : name;
|
||||
|
||||
string? upperCaseText = null;
|
||||
|
||||
if (string.IsNullOrEmpty(text))
|
||||
{
|
||||
CharsToDraw = "..";
|
||||
}
|
||||
else if (text.Length > 1)
|
||||
{
|
||||
upperCaseText = text.ToUpper();
|
||||
CharsToDraw = GetFirstLetters(upperCaseText, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharsToDraw = upperCaseText = text.ToUpper();
|
||||
}
|
||||
|
||||
BackgroundColor = color ?? CoreHelpers.StringToColor(userId ?? upperCaseText, DEFAULT_BACKGROUND_COLOR);
|
||||
TextColor = CoreHelpers.TextColorFromBgColor(BackgroundColor);
|
||||
}
|
||||
|
||||
public string CharsToDraw { get; }
|
||||
public string BackgroundColor { get; }
|
||||
public string TextColor { get; }
|
||||
public int Size { get; }
|
||||
|
||||
private static string GetFirstLetters(string data, int charCount)
|
||||
{
|
||||
var sanitizedData = data.Trim();
|
||||
var parts = sanitizedData.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (parts.Length > 1 && charCount <= 2)
|
||||
{
|
||||
var text = string.Empty;
|
||||
for (var i = 0; i < charCount; i++)
|
||||
{
|
||||
text += parts[i][0];
|
||||
}
|
||||
return text;
|
||||
}
|
||||
if (sanitizedData.Length > 2)
|
||||
{
|
||||
return sanitizedData.Substring(0, 2);
|
||||
}
|
||||
return sanitizedData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
63
src/Core/Controls/Avatar/SKAvatarImageHelper.cs
Normal file
63
src/Core/Controls/Avatar/SKAvatarImageHelper.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public static class SKAvatarImageHelper
|
||||
{
|
||||
public static SKImage Draw(AvatarInfo avatarInfo)
|
||||
{
|
||||
using (var bitmap = new SKBitmap(avatarInfo.Size * 2,
|
||||
avatarInfo.Size * 2,
|
||||
SKImageInfo.PlatformColorType,
|
||||
SKAlphaType.Premul))
|
||||
{
|
||||
using (var canvas = new SKCanvas(bitmap))
|
||||
{
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
using (var paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(avatarInfo.BackgroundColor)
|
||||
})
|
||||
{
|
||||
var midX = canvas.LocalClipBounds.Size.ToSizeI().Width / 2;
|
||||
var midY = canvas.LocalClipBounds.Size.ToSizeI().Height / 2;
|
||||
var radius = midX - midX / 5;
|
||||
|
||||
using (var circlePaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(avatarInfo.BackgroundColor)
|
||||
})
|
||||
{
|
||||
canvas.DrawCircle(midX, midY, radius, circlePaint);
|
||||
|
||||
var typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Normal);
|
||||
var textSize = midX / 1.3f;
|
||||
using (var textPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
Color = SKColor.Parse(avatarInfo.TextColor),
|
||||
TextSize = textSize,
|
||||
TextAlign = SKTextAlign.Center,
|
||||
Typeface = typeface
|
||||
})
|
||||
{
|
||||
var rect = new SKRect();
|
||||
textPaint.MeasureText(avatarInfo.CharsToDraw, ref rect);
|
||||
canvas.DrawText(avatarInfo.CharsToDraw, midX, midY + rect.Height / 2, textPaint);
|
||||
|
||||
return SKImage.FromBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
using Bit.Core.Utilities;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class AvatarImageSource : StreamImageSource
|
||||
{
|
||||
private readonly string _text;
|
||||
private readonly string _id;
|
||||
private readonly string _color;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj is AvatarImageSource avatar)
|
||||
{
|
||||
return avatar._id == _id && avatar._text == _text && avatar._color == _color;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode() => _id?.GetHashCode() ?? _text?.GetHashCode() ?? -1;
|
||||
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null, string color = null)
|
||||
{
|
||||
_id = userId;
|
||||
_text = name;
|
||||
if (string.IsNullOrWhiteSpace(_text))
|
||||
{
|
||||
_text = email;
|
||||
}
|
||||
_color = color;
|
||||
}
|
||||
|
||||
public override Func<CancellationToken, Task<Stream>> Stream => GetStreamAsync;
|
||||
|
||||
private Task<Stream> GetStreamAsync(CancellationToken userToken = new CancellationToken())
|
||||
{
|
||||
var result = Draw();
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
private Stream Draw()
|
||||
{
|
||||
string chars;
|
||||
string upperCaseText = null;
|
||||
|
||||
if (string.IsNullOrEmpty(_text))
|
||||
{
|
||||
chars = "..";
|
||||
}
|
||||
else if (_text?.Length > 1)
|
||||
{
|
||||
upperCaseText = _text.ToUpper();
|
||||
chars = GetFirstLetters(upperCaseText, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
chars = upperCaseText = _text.ToUpper();
|
||||
}
|
||||
|
||||
var bgColor = _color ?? CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var textColor = CoreHelpers.TextColorFromBgColor(bgColor);
|
||||
var size = 50;
|
||||
|
||||
//Workaround: [MAUI-Migration] There is currently a bug in MAUI where the actual size of the image is used instead of the size it should occupy in the Toolbar.
|
||||
//This causes some issues with the position of the icon. As a workaround we make the icon smaller until this is fixed.
|
||||
//Github issues: https://github.com/dotnet/maui/issues/12359 and https://github.com/dotnet/maui/pull/17120
|
||||
if (DeviceInfo.Platform == DevicePlatform.iOS)
|
||||
{
|
||||
size = 20;
|
||||
}
|
||||
|
||||
using (var bitmap = new SKBitmap(size * 2,
|
||||
size * 2,
|
||||
SKImageInfo.PlatformColorType,
|
||||
SKAlphaType.Premul))
|
||||
{
|
||||
using (var canvas = new SKCanvas(bitmap))
|
||||
{
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
using (var paint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(bgColor)
|
||||
})
|
||||
{
|
||||
var midX = canvas.LocalClipBounds.Size.ToSizeI().Width / 2;
|
||||
var midY = canvas.LocalClipBounds.Size.ToSizeI().Height / 2;
|
||||
var radius = midX - midX / 5;
|
||||
|
||||
using (var circlePaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(bgColor)
|
||||
})
|
||||
{
|
||||
canvas.DrawCircle(midX, midY, radius, circlePaint);
|
||||
|
||||
var typeface = SKTypeface.FromFamilyName("Arial", SKFontStyle.Normal);
|
||||
var textSize = midX / 1.3f;
|
||||
using (var textPaint = new SKPaint
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
Color = SKColor.Parse(textColor),
|
||||
TextSize = textSize,
|
||||
TextAlign = SKTextAlign.Center,
|
||||
Typeface = typeface
|
||||
})
|
||||
{
|
||||
var rect = new SKRect();
|
||||
textPaint.MeasureText(chars, ref rect);
|
||||
canvas.DrawText(chars, midX, midY + rect.Height / 2, textPaint);
|
||||
|
||||
using (var img = SKImage.FromBitmap(bitmap))
|
||||
{
|
||||
var data = img.Encode(SKEncodedImageFormat.Png, 100);
|
||||
return data?.AsStream(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetFirstLetters(string data, int charCount)
|
||||
{
|
||||
var sanitizedData = data.Trim();
|
||||
var parts = sanitizedData.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (parts.Length > 1 && charCount <= 2)
|
||||
{
|
||||
var text = string.Empty;
|
||||
for (var i = 0; i < charCount; i++)
|
||||
{
|
||||
text += parts[i][0];
|
||||
}
|
||||
return text;
|
||||
}
|
||||
if (sanitizedData.Length > 2)
|
||||
{
|
||||
return sanitizedData.Substring(0, 2);
|
||||
}
|
||||
return sanitizedData;
|
||||
}
|
||||
|
||||
private Color StringToColor(string str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return Color.FromArgb("#33ffffff");
|
||||
}
|
||||
var hash = 0;
|
||||
for (var i = 0; i < str.Length; i++)
|
||||
{
|
||||
hash = str[i] + ((hash << 5) - hash);
|
||||
}
|
||||
var color = "#FF";
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var value = (hash >> (i * 8)) & 0xff;
|
||||
var base16 = "00" + Convert.ToString(value, 16);
|
||||
color += base16.Substring(base16.Length - 2);
|
||||
}
|
||||
return Color.FromArgb(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
src/Core/Controls/CipherViewCell/BaseCipherViewCell.cs
Normal file
103
src/Core/Controls/CipherViewCell/BaseCipherViewCell.cs
Normal file
@@ -0,0 +1,103 @@
|
||||
using Bit.App.Pages;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public abstract class BaseCipherViewCell : ExtendedGrid
|
||||
{
|
||||
protected virtual CachedImage Icon { get; }
|
||||
|
||||
protected virtual IconLabel IconPlaceholder { get; }
|
||||
|
||||
// HACK: PM-5896 Fix for Background Crash on iOS
|
||||
// While loading the cipher icon and the user sent the app to background
|
||||
// the app was crashing sometimes when the "LoadingPlaceholder" or "ErrorPlaceholder"
|
||||
// were being accessed, thus locked, and as soon the app got suspended by the OS
|
||||
// the app would crash because there can't be any lock files by the app when it gets suspended.
|
||||
// So, the approach has changed to reuse the IconLabel default icon to use it for these placeholders
|
||||
// as well. In order to do that both icon controls change their visibility dynamically here reacting to
|
||||
// CachedImage events and binding context changes.
|
||||
|
||||
protected override void OnBindingContextChanged()
|
||||
{
|
||||
Icon.Source = null;
|
||||
if (BindingContext is CipherItemViewModel cipherItemVM)
|
||||
{
|
||||
Icon.Source = cipherItemVM.IconImageSource;
|
||||
if (!cipherItemVM.IconImageSuccesfullyLoaded)
|
||||
{
|
||||
UpdateIconImages(cipherItemVM.ShowIconImage);
|
||||
}
|
||||
}
|
||||
|
||||
base.OnBindingContextChanged();
|
||||
}
|
||||
|
||||
private void UpdateIconImages(bool showIcon)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
if (!showIcon)
|
||||
{
|
||||
Icon.IsVisible = false;
|
||||
IconPlaceholder.IsVisible = true;
|
||||
return;
|
||||
}
|
||||
|
||||
IconPlaceholder.IsVisible = Icon.IsLoading;
|
||||
});
|
||||
}
|
||||
|
||||
public void Icon_Success(object sender, FFImageLoading.Maui.CachedImageEvents.SuccessEventArgs e)
|
||||
{
|
||||
if (BindingContext is CipherItemViewModel cipherItemVM)
|
||||
{
|
||||
cipherItemVM.IconImageSuccesfullyLoaded = true;
|
||||
}
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
Icon.IsVisible = true;
|
||||
IconPlaceholder.IsVisible = false;
|
||||
});
|
||||
}
|
||||
|
||||
public void Icon_Error(object sender, FFImageLoading.Maui.CachedImageEvents.ErrorEventArgs e)
|
||||
{
|
||||
if (BindingContext is CipherItemViewModel cipherItemVM)
|
||||
{
|
||||
cipherItemVM.IconImageSuccesfullyLoaded = false;
|
||||
}
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
Icon.IsVisible = false;
|
||||
IconPlaceholder.IsVisible = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public class StubBaseCipherViewCellSoLinkerDoesntRemoveMethods : BaseCipherViewCell
|
||||
{
|
||||
protected override CachedImage Icon => new CachedImage();
|
||||
protected override IconLabel IconPlaceholder => new IconLabel();
|
||||
|
||||
public static void CallThisSoLinkerDoesntRemoveMethods()
|
||||
{
|
||||
var stub = new StubBaseCipherViewCellSoLinkerDoesntRemoveMethods();
|
||||
|
||||
try
|
||||
{
|
||||
stub.Icon_Success(stub, new FFImageLoading.Maui.CachedImageEvents.SuccessEventArgs(new FFImageLoading.Work.ImageInformation(), FFImageLoading.Work.LoadingResult.Disk));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
stub.Icon_Error(stub, new FFImageLoading.Maui.CachedImageEvents.ErrorEventArgs(new InvalidOperationException("stub")));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<controls:ExtendedGrid xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
<controls:BaseCipherViewCell xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Controls.CipherViewCell"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
@@ -29,34 +29,32 @@
|
||||
<ColumnDefinition Width="60" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<controls:IconLabel
|
||||
Grid.Column="0"
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
StyleClass="list-icon, list-icon-platform"
|
||||
IsVisible="{Binding ShowIconImage, Converter={StaticResource inverseBool}}"
|
||||
Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}"
|
||||
ShouldUpdateFontSizeDynamicallyForAccesibility="True"
|
||||
AutomationProperties.IsInAccessibleTree="False"
|
||||
AutomationId="CipherTypeIcon" />
|
||||
|
||||
<controls:CachedImage
|
||||
x:Name="_iconImage"
|
||||
Grid.Column="0"
|
||||
BitmapOptimizations="True"
|
||||
ErrorPlaceholder="login.png"
|
||||
LoadingPlaceholder="login.png"
|
||||
HorizontalOptions="CenterAndExpand"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Margin="9"
|
||||
WidthRequest="22"
|
||||
HeightRequest="22"
|
||||
Aspect="AspectFit"
|
||||
IsVisible="{Binding ShowIconImage}"
|
||||
Source="{Binding IconImageSource, Mode=OneTime}"
|
||||
Success="Icon_Success"
|
||||
Error="Icon_Error"
|
||||
AutomationProperties.IsInAccessibleTree="False"
|
||||
AutomationId="CipherWebsiteIcon" />
|
||||
|
||||
<controls:IconLabel
|
||||
x:Name="_iconPlaceholderImage"
|
||||
Grid.Column="0"
|
||||
HorizontalOptions="Center"
|
||||
VerticalOptions="Center"
|
||||
StyleClass="list-icon, list-icon-platform"
|
||||
Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}"
|
||||
ShouldUpdateFontSizeDynamicallyForAccesibility="True"
|
||||
AutomationProperties.IsInAccessibleTree="False"
|
||||
AutomationId="CipherTypeIcon" />
|
||||
|
||||
<Grid RowSpacing="0" ColumnSpacing="0" Grid.Row="0" Grid.Column="1" VerticalOptions="Center" Padding="0, 7">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
@@ -121,4 +119,4 @@
|
||||
SemanticProperties.Description="{u:I18n Options}"
|
||||
AutomationId="CipherOptionsButton" />
|
||||
|
||||
</controls:ExtendedGrid>
|
||||
</controls:BaseCipherViewCell>
|
||||
@@ -5,7 +5,7 @@ using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class CipherViewCell : ExtendedGrid
|
||||
public partial class CipherViewCell : BaseCipherViewCell
|
||||
{
|
||||
private const int ICON_COLUMN_DEFAULT_WIDTH = 40;
|
||||
private const int ICON_IMAGE_DEFAULT_WIDTH = 22;
|
||||
@@ -23,6 +23,10 @@ namespace Bit.App.Controls
|
||||
_iconImage.HeightRequest = ICON_IMAGE_DEFAULT_WIDTH * fontScale;
|
||||
}
|
||||
|
||||
protected override CachedImage Icon => _iconImage;
|
||||
|
||||
protected override IconLabel IconPlaceholder => _iconPlaceholderImage;
|
||||
|
||||
public ICommand ButtonCommand
|
||||
{
|
||||
get => GetValue(ButtonCommandProperty) as ICommand;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<ContentView
|
||||
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
@@ -17,7 +17,7 @@
|
||||
LineBreakMode="TailTruncation" />
|
||||
|
||||
<controls:IconLabel
|
||||
Text="{Binding Source={x:Static core:BitwardenIcons.ShareSquare}}"
|
||||
Text="{Binding Source={x:Static core:BitwardenIcons.ExternalLink}}"
|
||||
TextColor="{DynamicResource TextColor}"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="Center"
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
<Folder Include="Resources\Localization\" />
|
||||
<Folder Include="Utilities\Fido2\" />
|
||||
<Folder Include="Controls\Picker\" />
|
||||
<Folder Include="Controls\Avatar\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<MauiImage Include="Resources\Images\dotnet_bot.svg">
|
||||
@@ -109,5 +110,6 @@
|
||||
<ItemGroup>
|
||||
<None Remove="Utilities\Fido2\" />
|
||||
<None Remove="Controls\Picker\" />
|
||||
<None Remove="Controls\Avatar\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -6,7 +6,7 @@
|
||||
public const string HELP_ABOUT_ORGANIZATIONS = "https://bitwarden.com/help/about-organizations/";
|
||||
public const string HELP_FINGERPRINT_PHRASE = "https://bitwarden.com/help/fingerprint-phrase/";
|
||||
|
||||
public const string CONTACT_SUPPORT = "https://bitwarden.com/contact/";
|
||||
public const string PRIVACY_POLICY = "https://bitwarden.com/privacy/";
|
||||
|
||||
/// <summary>
|
||||
/// Link to go to settings website. Requires to pass website URL as parameter.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Camera.MAUI;
|
||||
using Bit.App.Controls;
|
||||
using Camera.MAUI;
|
||||
using CommunityToolkit.Maui;
|
||||
#if !UT
|
||||
using FFImageLoading.Maui;
|
||||
@@ -62,6 +63,13 @@ public static class MauiProgram
|
||||
builder.Logging.AddDebug();
|
||||
#endif
|
||||
|
||||
ExplicitlyPreventThingsGetRemovedBecauseOfLinker();
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static void ExplicitlyPreventThingsGetRemovedBecauseOfLinker()
|
||||
{
|
||||
StubBaseCipherViewCellSoLinkerDoesntRemoveMethods.CallThisSoLinkerDoesntRemoveMethods();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@ namespace Bit.Core.Models.Api
|
||||
{
|
||||
public string Uri { get; set; }
|
||||
public UriMatchType? Match { get; set; }
|
||||
public string UriChecksum { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,11 @@ namespace Bit.Core.Models.Data
|
||||
{
|
||||
Uri = data.Uri;
|
||||
Match = data.Match;
|
||||
UriChecksum = data.UriChecksum;
|
||||
}
|
||||
|
||||
public string Uri { get; set; }
|
||||
public UriMatchType? Match { get; set; }
|
||||
public string UriChecksum { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace Bit.Core.Models.Domain
|
||||
switch (Type)
|
||||
{
|
||||
case Enums.CipherType.Login:
|
||||
model.Login = await Login.DecryptAsync(OrganizationId, model.Key);
|
||||
model.Login = await Login.DecryptAsync(OrganizationId, Key == null, model.Key);
|
||||
break;
|
||||
case Enums.CipherType.SecureNote:
|
||||
model.SecureNote = await SecureNote.DecryptAsync(OrganizationId, model.Key);
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Models.Domain
|
||||
{
|
||||
@@ -31,7 +33,7 @@ namespace Bit.Core.Models.Domain
|
||||
public EncString Totp { get; set; }
|
||||
public List<Fido2Credential> Fido2Credentials { get; set; }
|
||||
|
||||
public async Task<LoginView> DecryptAsync(string orgId, SymmetricCryptoKey key = null)
|
||||
public async Task<LoginView> DecryptAsync(string orgId, bool bypassUriChecksumValidation, SymmetricCryptoKey key = null)
|
||||
{
|
||||
var view = await DecryptObjAsync(new LoginView(this), this, new HashSet<string>
|
||||
{
|
||||
@@ -41,10 +43,15 @@ namespace Bit.Core.Models.Domain
|
||||
}, orgId, key);
|
||||
if (Uris != null)
|
||||
{
|
||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>();
|
||||
view.Uris = new List<LoginUriView>();
|
||||
foreach (var uri in Uris)
|
||||
{
|
||||
view.Uris.Add(await uri.DecryptAsync(orgId, key));
|
||||
var loginUriView = await uri.DecryptAsync(orgId, key);
|
||||
if (bypassUriChecksumValidation || await cryptoService.ValidateUriChecksumAsync(uri.UriChecksum, loginUriView.Uri, orgId, key))
|
||||
{
|
||||
view.Uris.Add(loginUriView);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Fido2Credentials != null)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
@@ -10,7 +11,8 @@ namespace Bit.Core.Models.Domain
|
||||
{
|
||||
private HashSet<string> _map = new HashSet<string>
|
||||
{
|
||||
"Uri"
|
||||
nameof(Uri),
|
||||
nameof(UriChecksum)
|
||||
};
|
||||
|
||||
public LoginUri() { }
|
||||
@@ -23,10 +25,11 @@ namespace Bit.Core.Models.Domain
|
||||
|
||||
public EncString Uri { get; set; }
|
||||
public UriMatchType? Match { get; set; }
|
||||
public EncString UriChecksum { get; set; }
|
||||
|
||||
public Task<LoginUriView> DecryptAsync(string orgId, SymmetricCryptoKey key = null)
|
||||
{
|
||||
return DecryptObjAsync(new LoginUriView(this), this, _map, orgId, key);
|
||||
return DecryptObjAsync(new LoginUriView(this), this, _map.Where(m => m != nameof(UriChecksum)).ToHashSet<string>(), orgId, key);
|
||||
}
|
||||
|
||||
public LoginUriData ToLoginUriData()
|
||||
|
||||
@@ -17,10 +17,12 @@ namespace Bit.Core.Models.Export
|
||||
{
|
||||
Match = obj.Match;
|
||||
Uri = obj.Uri?.EncryptedString;
|
||||
UriChecksum = obj.UriChecksum?.EncryptedString;
|
||||
}
|
||||
|
||||
public UriMatchType? Match { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public string UriChecksum { get; set; }
|
||||
|
||||
public static LoginUriView ToView(LoginUri req, LoginUriView view = null)
|
||||
{
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Bit.Core.Models.Request
|
||||
Login = new LoginApi
|
||||
{
|
||||
Uris = cipher.Login.Uris?.Select(
|
||||
u => new LoginUriApi { Match = u.Match, Uri = u.Uri?.EncryptedString }).ToList(),
|
||||
u => new LoginUriApi { Match = u.Match, Uri = u.Uri?.EncryptedString, UriChecksum = u.UriChecksum?.EncryptedString }).ToList(),
|
||||
Username = cipher.Login.Username?.EncryptedString,
|
||||
Password = cipher.Login.Password?.EncryptedString,
|
||||
PasswordRevisionDate = cipher.Login.PasswordRevisionDate,
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
Text="{Binding BaseUrl}"
|
||||
Keyboard="Url"
|
||||
Placeholder="ex. https://bitwarden.company.com"
|
||||
StyleClass="box-value"
|
||||
StyleClass="box-value, no-keyboard-auto-help"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding SubmitCommand}"
|
||||
AutomationId="ServerUrlEntry"/>
|
||||
@@ -59,7 +59,7 @@
|
||||
x:Name="_webVaultEntry"
|
||||
Text="{Binding WebVaultUrl}"
|
||||
Keyboard="Url"
|
||||
StyleClass="box-value"
|
||||
StyleClass="box-value, no-keyboard-auto-help"
|
||||
AutomationId="WebVaultUrlEntry"/>
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box-row">
|
||||
@@ -70,7 +70,7 @@
|
||||
x:Name="_apiEntry"
|
||||
Text="{Binding ApiUrl}"
|
||||
Keyboard="Url"
|
||||
StyleClass="box-value"
|
||||
StyleClass="box-value, no-keyboard-auto-help"
|
||||
AutomationId="ApiUrlEntry"/>
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box-row">
|
||||
@@ -81,7 +81,7 @@
|
||||
x:Name="_identityEntry"
|
||||
Text="{Binding IdentityUrl}"
|
||||
Keyboard="Url"
|
||||
StyleClass="box-value"
|
||||
StyleClass="box-value, no-keyboard-auto-help"
|
||||
AutomationId="IdentityUrlEntry"/>
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box-row">
|
||||
@@ -92,7 +92,7 @@
|
||||
x:Name="_iconsEntry"
|
||||
Text="{Binding IconsUrl}"
|
||||
Keyboard="Url"
|
||||
StyleClass="box-value"
|
||||
StyleClass="box-value, no-keyboard-auto-help"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding SubmitCommand}"
|
||||
AutomationId="IconsUrlEntry"/>
|
||||
|
||||
@@ -50,11 +50,10 @@
|
||||
x:Name="_email"
|
||||
Text="{Binding Email}"
|
||||
Keyboard="Email"
|
||||
StyleClass="box-value"
|
||||
StyleClass="box-value, no-keyboard-auto-help"
|
||||
ReturnType="Go"
|
||||
ReturnCommand="{Binding ContinueCommand}"
|
||||
AutomationId="EmailAddressEntry"
|
||||
>
|
||||
AutomationId="EmailAddressEntry">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Disabled">
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task StartEnvironmentAsync()
|
||||
{
|
||||
await _accountListOverlay.HideAsync();
|
||||
await _accountListOverlay.HideAsync();
|
||||
var page = new EnvironmentPage();
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (message.Command == Constants.ClearSensitiveFields)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(_vm.ResetPinPasswordFields);
|
||||
MainThread.BeginInvokeOnMainThread(() => _vm?.ResetPinPasswordFields());
|
||||
}
|
||||
});
|
||||
if (_appeared)
|
||||
|
||||
@@ -245,9 +245,9 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task SubmitAsync()
|
||||
{
|
||||
ShowPassword = false;
|
||||
try
|
||||
{
|
||||
ShowPassword = false;
|
||||
var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile));
|
||||
if (PinEnabled)
|
||||
{
|
||||
@@ -257,12 +257,15 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await UnlockWithMasterPasswordAsync(kdfConfig);
|
||||
}
|
||||
|
||||
}
|
||||
catch (LegacyUserException)
|
||||
{
|
||||
await HandleLegacyUserAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UnlockWithPinAsync(KdfConfig kdfConfig)
|
||||
|
||||
@@ -3,6 +3,7 @@ using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -74,7 +75,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (message.Command == Constants.ClearSensitiveFields)
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(_vm.ResetPasswordField);
|
||||
MainThread.BeginInvokeOnMainThread(() => _vm?.ResetPasswordField());
|
||||
}
|
||||
});
|
||||
_mainContent.Content = _mainLayout;
|
||||
@@ -188,12 +189,20 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task LogInSuccessAsync()
|
||||
{
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
try
|
||||
{
|
||||
return;
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
throw;
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -48,12 +49,20 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task LogInSuccessAsync()
|
||||
{
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
try
|
||||
{
|
||||
return;
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
throw;
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_requestTimeCts?.Cancel();
|
||||
_requestTimeCts?.Dispose();
|
||||
_requestTimeCts = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -89,16 +90,30 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task StartTwoFactorAsync()
|
||||
{
|
||||
RestoreAppOptionsFromCopy();
|
||||
var page = new TwoFactorPage(true, _appOptions, _vm.OrgIdentifier);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
try
|
||||
{
|
||||
RestoreAppOptionsFromCopy();
|
||||
var page = new TwoFactorPage(true, _appOptions, _vm.OrgIdentifier);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartSetPasswordAsync()
|
||||
{
|
||||
RestoreAppOptionsFromCopy();
|
||||
var page = new SetPasswordPage(_appOptions, _vm.OrgIdentifier);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
try
|
||||
{
|
||||
RestoreAppOptionsFromCopy();
|
||||
var page = new SetPasswordPage(_appOptions, _vm.OrgIdentifier);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
@@ -115,16 +130,23 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task SsoAuthSuccessAsync()
|
||||
{
|
||||
RestoreAppOptionsFromCopy();
|
||||
await AppHelpers.ClearPreviousPage();
|
||||
try
|
||||
{
|
||||
RestoreAppOptionsFromCopy();
|
||||
await AppHelpers.ClearPreviousPage();
|
||||
|
||||
if (await _vaultTimeoutService.IsLockedAsync())
|
||||
{
|
||||
App.MainPage = new NavigationPage(new LockPage(_appOptions));
|
||||
if (await _vaultTimeoutService.IsLockedAsync())
|
||||
{
|
||||
App.MainPage = new NavigationPage(new LockPage(_appOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
App.MainPage = new TabsPage(_appOptions, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception ex)
|
||||
{
|
||||
App.MainPage = new TabsPage(_appOptions, null);
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Services;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -64,12 +65,19 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task SetPasswordSuccessAsync()
|
||||
{
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
try
|
||||
{
|
||||
return;
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
App.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,12 +133,12 @@
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<StackLayout Spacing="0" Padding="0" IsVisible="{Binding DuoMethod, Mode=OneWay}"
|
||||
VerticalOptions="FillAndExpand">
|
||||
VerticalOptions="StartAndExpand">
|
||||
<controls:HybridWebView
|
||||
x:Name="_duoWebView"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="FillAndExpand"
|
||||
MinimumHeightRequest="400" />
|
||||
HeightRequest="{Binding DuoWebViewHeight, Mode=OneWay}" />
|
||||
<StackLayout StyleClass="box" VerticalOptions="End">
|
||||
<StackLayout StyleClass="box-row, box-row-switch">
|
||||
<Label
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -63,11 +64,11 @@ namespace Bit.App.Pages
|
||||
if (_vm.YubikeyMethod && !string.IsNullOrWhiteSpace(token) &&
|
||||
token.Length == 44 && !token.Contains(" "))
|
||||
{
|
||||
MainThread.BeginInvokeOnMainThread(async () =>
|
||||
MainThread.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
_vm.Token = token;
|
||||
await _vm.SubmitAsync();
|
||||
});
|
||||
_vm.SubmitCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
else if (message.Command == "resumeYubiKey")
|
||||
@@ -124,12 +125,9 @@ namespace Bit.App.Pages
|
||||
return base.OnBackButtonPressed();
|
||||
}
|
||||
|
||||
private async void Continue_Clicked(object sender, EventArgs e)
|
||||
private void Continue_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
await _vm.SubmitAsync();
|
||||
}
|
||||
_vm.SubmitCommand.Execute(null);
|
||||
}
|
||||
|
||||
private async void Methods_Clicked(object sender, EventArgs e)
|
||||
@@ -158,17 +156,24 @@ namespace Bit.App.Pages
|
||||
|
||||
private async void TryAgain_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
try
|
||||
{
|
||||
if (_vm.Fido2Method)
|
||||
if (DoOnce())
|
||||
{
|
||||
await _vm.Fido2AuthenticateAsync();
|
||||
}
|
||||
else if (_vm.YubikeyMethod)
|
||||
{
|
||||
_messagingService.Send("listenYubiKeyOTP", true);
|
||||
if (_vm.Fido2Method)
|
||||
{
|
||||
await _vm.Fido2AuthenticateAsync();
|
||||
}
|
||||
else if (_vm.YubikeyMethod)
|
||||
{
|
||||
_messagingService.Send("listenYubiKeyOTP", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartSetPasswordAsync()
|
||||
|
||||
@@ -1,25 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Resources.Localization;
|
||||
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.Resources.Localization;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using Microsoft.Maui.Authentication;
|
||||
using Microsoft.Maui.Controls;
|
||||
using Microsoft.Maui;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class TwoFactorPageViewModel : CaptchaProtectedViewModel
|
||||
@@ -43,6 +34,7 @@ namespace Bit.App.Pages
|
||||
private string _webVaultUrl = "https://vault.bitwarden.com";
|
||||
private bool _enableContinue = false;
|
||||
private bool _showContinue = true;
|
||||
private double _duoWebViewHeight;
|
||||
|
||||
public TwoFactorPageViewModel()
|
||||
{
|
||||
@@ -62,7 +54,7 @@ namespace Bit.App.Pages
|
||||
_deviceTrustCryptoService = ServiceContainer.Resolve<IDeviceTrustCryptoService>();
|
||||
|
||||
PageTitle = AppResources.TwoStepLogin;
|
||||
SubmitCommand = new Command(async () => await SubmitAsync());
|
||||
SubmitCommand = CreateDefaultAsyncRelayCommand(() => MainThread.InvokeOnMainThreadAsync(async () => await SubmitAsync()), allowsMultipleExecutions: false);
|
||||
MoreCommand = CreateDefaultAsyncRelayCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
@@ -72,6 +64,12 @@ namespace Bit.App.Pages
|
||||
set => SetProperty(ref _totpInstruction, value);
|
||||
}
|
||||
|
||||
public double DuoWebViewHeight
|
||||
{
|
||||
get => _duoWebViewHeight;
|
||||
set => SetProperty(ref _duoWebViewHeight, value);
|
||||
}
|
||||
|
||||
public bool Remember { get; set; }
|
||||
|
||||
public bool AuthingWithSso { get; set; }
|
||||
@@ -91,8 +89,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public bool TotpMethod => AuthenticatorMethod || EmailMethod;
|
||||
|
||||
public bool ShowTryAgain => (YubikeyMethod && // 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) || Fido2Method;
|
||||
public bool ShowTryAgain => (YubikeyMethod && DeviceInfo.Platform == DevicePlatform.iOS) || Fido2Method;
|
||||
|
||||
public bool ShowContinue
|
||||
{
|
||||
@@ -106,9 +103,11 @@ Device.RuntimePlatform == Device.iOS) || Fido2Method;
|
||||
set => SetProperty(ref _enableContinue, value);
|
||||
}
|
||||
|
||||
public string YubikeyInstruction => // 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 ? AppResources.YubiKeyInstructionIos :
|
||||
AppResources.YubiKeyInstruction;
|
||||
#if IOS
|
||||
public string YubikeyInstruction => AppResources.YubiKeyInstructionIos;
|
||||
#else
|
||||
public string YubikeyInstruction => AppResources.YubiKeyInstruction;
|
||||
#endif
|
||||
|
||||
public TwoFactorProviderType? SelectedProviderType
|
||||
{
|
||||
@@ -124,7 +123,7 @@ Device.RuntimePlatform == Device.iOS ? AppResources.YubiKeyInstructionIos :
|
||||
nameof(ShowTryAgain),
|
||||
});
|
||||
}
|
||||
public Command SubmitCommand { get; }
|
||||
public ICommand SubmitCommand { get; }
|
||||
public ICommand MoreCommand { get; }
|
||||
public Action TwoFactorAuthSuccessAction { get; set; }
|
||||
public Action LockAction { get; set; }
|
||||
@@ -180,13 +179,14 @@ Device.RuntimePlatform == Device.iOS ? AppResources.YubiKeyInstructionIos :
|
||||
break;
|
||||
case TwoFactorProviderType.Duo:
|
||||
case TwoFactorProviderType.OrganizationDuo:
|
||||
SetDuoWebViewHeight();
|
||||
var host = WebUtility.UrlEncode(providerData["Host"] as string);
|
||||
var req = WebUtility.UrlEncode(providerData["Signature"] as string);
|
||||
page.DuoWebView.Uri = $"{_webVaultUrl}/duo-connector.html?host={host}&request={req}";
|
||||
page.DuoWebView.RegisterAction(sig =>
|
||||
{
|
||||
Token = sig;
|
||||
Device.BeginInvokeOnMainThread(async () => await SubmitAsync());
|
||||
SubmitCommand.Execute(null);
|
||||
});
|
||||
break;
|
||||
case TwoFactorProviderType.Email:
|
||||
@@ -211,70 +211,84 @@ Device.RuntimePlatform == Device.iOS ? AppResources.YubiKeyInstructionIos :
|
||||
ShowContinue = !(SelectedProviderType == null || DuoMethod || Fido2Method);
|
||||
}
|
||||
|
||||
public void SetDuoWebViewHeight()
|
||||
{
|
||||
var screenHeight = DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density;
|
||||
DuoWebViewHeight = screenHeight > 0 ? (screenHeight / 8) * 6 : 400;
|
||||
}
|
||||
|
||||
public async Task Fido2AuthenticateAsync(Dictionary<string, object> providerData = null)
|
||||
{
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Validating);
|
||||
|
||||
if (providerData == null)
|
||||
{
|
||||
providerData = _authService.TwoFactorProvidersData[TwoFactorProviderType.Fido2WebAuthn];
|
||||
}
|
||||
|
||||
var callbackUri = "bitwarden://webauthn-callback";
|
||||
var data = AppHelpers.EncodeDataParameter(new
|
||||
{
|
||||
callbackUri = callbackUri,
|
||||
data = JsonConvert.SerializeObject(providerData),
|
||||
headerText = AppResources.Fido2Title,
|
||||
btnText = AppResources.Fido2AuthenticateWebAuthn,
|
||||
btnReturnText = AppResources.Fido2ReturnToApp,
|
||||
});
|
||||
|
||||
var url = _webVaultUrl + "/webauthn-mobile-connector.html?" + "data=" + data +
|
||||
"&parent=" + Uri.EscapeDataString(callbackUri) + "&v=2";
|
||||
|
||||
WebAuthenticatorResult authResult = null;
|
||||
try
|
||||
{
|
||||
var options = new WebAuthenticatorOptions
|
||||
{
|
||||
Url = new Uri(url),
|
||||
CallbackUrl = new Uri(callbackUri),
|
||||
PrefersEphemeralWebBrowserSession = true,
|
||||
};
|
||||
authResult = await WebAuthenticator.AuthenticateAsync(options);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
// user canceled
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
return;
|
||||
}
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Validating);
|
||||
|
||||
string response = null;
|
||||
if (authResult != null && authResult.Properties.TryGetValue("data", out var resultData))
|
||||
{
|
||||
response = Uri.UnescapeDataString(resultData);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(response))
|
||||
{
|
||||
Token = response;
|
||||
await SubmitAsync(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
if (authResult != null && authResult.Properties.TryGetValue("error", out var resultError))
|
||||
if (providerData == null)
|
||||
{
|
||||
var message = AppResources.Fido2CheckBrowser + "\n\n" + resultError;
|
||||
await _platformUtilsService.ShowDialogAsync(message, AppResources.AnErrorHasOccurred,
|
||||
AppResources.Ok);
|
||||
providerData = _authService.TwoFactorProvidersData[TwoFactorProviderType.Fido2WebAuthn];
|
||||
}
|
||||
|
||||
var callbackUri = "bitwarden://webauthn-callback";
|
||||
var data = AppHelpers.EncodeDataParameter(new
|
||||
{
|
||||
callbackUri = callbackUri,
|
||||
data = JsonConvert.SerializeObject(providerData),
|
||||
headerText = AppResources.Fido2Title,
|
||||
btnText = AppResources.Fido2AuthenticateWebAuthn,
|
||||
btnReturnText = AppResources.Fido2ReturnToApp,
|
||||
});
|
||||
|
||||
var url = _webVaultUrl + "/webauthn-mobile-connector.html?" + "data=" + data +
|
||||
"&parent=" + Uri.EscapeDataString(callbackUri) + "&v=2";
|
||||
|
||||
WebAuthenticatorResult authResult = null;
|
||||
try
|
||||
{
|
||||
var options = new WebAuthenticatorOptions
|
||||
{
|
||||
Url = new Uri(url),
|
||||
CallbackUrl = new Uri(callbackUri),
|
||||
PrefersEphemeralWebBrowserSession = true,
|
||||
};
|
||||
authResult = await WebAuthenticator.AuthenticateAsync(options);
|
||||
}
|
||||
catch (TaskCanceledException)
|
||||
{
|
||||
// user canceled
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
string response = null;
|
||||
if (authResult != null && authResult.Properties.TryGetValue("data", out var resultData))
|
||||
{
|
||||
response = Uri.UnescapeDataString(resultData);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(response))
|
||||
{
|
||||
Token = response;
|
||||
await SubmitAsync(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.Fido2CheckBrowser,
|
||||
AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
if (authResult != null && authResult.Properties.TryGetValue("error", out var resultError))
|
||||
{
|
||||
var message = AppResources.Fido2CheckBrowser + "\n\n" + resultError;
|
||||
await _platformUtilsService.ShowDialogAsync(message, AppResources.AnErrorHasOccurred,
|
||||
AppResources.Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.Fido2CheckBrowser,
|
||||
AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,8 +170,15 @@ namespace Bit.App.Pages
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(ShowModalAnimationDelay);
|
||||
MainThread.BeginInvokeOnMainThread(() => input.Focus());
|
||||
try
|
||||
{
|
||||
await Task.Delay(ShowModalAnimationDelay);
|
||||
MainThread.BeginInvokeOnMainThread(() => input.Focus());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Value.Exception(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
<BoxView StyleClass="box-row-separator" />
|
||||
|
||||
<controls:ExternalLinkItemView
|
||||
Title="{u:I18n ContactBitwardenSupport}"
|
||||
GoToLinkCommand="{Binding ContactBitwardenSupportCommand}"
|
||||
Title="{u:I18n PrivacyPolicy}"
|
||||
GoToLinkCommand="{Binding GoToPrivacyPolicyCommand}"
|
||||
StyleClass="settings-external-link-item"
|
||||
HorizontalOptions="FillAndExpand" />
|
||||
<BoxView StyleClass="box-row-separator" />
|
||||
|
||||
@@ -33,10 +33,10 @@ namespace Bit.App.Pages
|
||||
AppResources.ContinueToHelpCenter,
|
||||
ExternalLinksConstants.HELP_CENTER), allowsMultipleExecutions: false);
|
||||
|
||||
ContactBitwardenSupportCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.ContactSupportDescriptionLong,
|
||||
AppResources.ContinueToContactSupport,
|
||||
ExternalLinksConstants.CONTACT_SUPPORT), allowsMultipleExecutions: false);
|
||||
GoToPrivacyPolicyCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.PrivacyPolicyDescriptionLong,
|
||||
AppResources.ContinueToPrivacyPolicy,
|
||||
ExternalLinksConstants.PRIVACY_POLICY), allowsMultipleExecutions: false);
|
||||
|
||||
GoToWebVaultCommand = CreateDefaultAsyncRelayCommand(
|
||||
() => LaunchUriAsync(AppResources.ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp,
|
||||
@@ -80,7 +80,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public AsyncRelayCommand ToggleSubmitCrashLogsCommand { get; }
|
||||
public ICommand GoToHelpCenterCommand { get; }
|
||||
public ICommand ContactBitwardenSupportCommand { get; }
|
||||
public ICommand GoToPrivacyPolicyCommand { get; }
|
||||
public ICommand GoToWebVaultCommand { get; }
|
||||
public ICommand GoToLearnAboutOrgsCommand { get; }
|
||||
public ICommand RateTheAppCommand { get; }
|
||||
|
||||
@@ -93,6 +93,7 @@
|
||||
<controls:CustomLabel
|
||||
StyleClass="box-label-regular"
|
||||
Text="{u:I18n NoPendingRequests}"
|
||||
IsVisible="{Binding HasLoginRequests, Converter={StaticResource inverseBool}}"
|
||||
FontAttributes="{OnPlatform iOS=Bold}"
|
||||
FontWeight="500"
|
||||
HorizontalTextAlignment="Center"
|
||||
|
||||
@@ -38,5 +38,11 @@ namespace Bit.App.Pages
|
||||
return _iconImageSource;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Flag that indicates if FFImageLoading has successfully finished loading the image.
|
||||
/// This is useful to check when the cell is being reused.
|
||||
/// </summary>
|
||||
public bool IconImageSuccesfullyLoaded { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
Camera="{Binding Camera}"
|
||||
AutoStartPreview="{Binding AutoStartPreview}"
|
||||
NumCamerasDetected="{Binding NumCameras, Mode=OneWayToSource}"
|
||||
WidthRequest="{OnPlatform Android=150}"
|
||||
HeightRequest="{OnPlatform Android=150}"
|
||||
Scale="{OnPlatform Android=4}"
|
||||
Grid.Column="0"
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="3" />
|
||||
|
||||
@@ -1723,6 +1723,15 @@ namespace Bit.Core.Resources.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Continue to privacy policy?.
|
||||
/// </summary>
|
||||
public static string ContinueToPrivacyPolicy {
|
||||
get {
|
||||
return ResourceManager.GetString("ContinueToPrivacyPolicy", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Continue to web app?.
|
||||
/// </summary>
|
||||
@@ -5525,6 +5534,15 @@ namespace Bit.Core.Resources.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Check out our privacy policy on bitwarden.com..
|
||||
/// </summary>
|
||||
public static string PrivacyPolicyDescriptionLong {
|
||||
get {
|
||||
return ResourceManager.GetString("PrivacyPolicyDescriptionLong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bitwarden keeps your vault automatically synced by using push notifications. For the best possible experience, please select "Allow" on the following prompt when asked to allow push notifications..
|
||||
/// </summary>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Wil u na die rekening omskakel?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Wil u na die rekening omskakel?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>مواصلة الاتصال بالدعم؟</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>هل تريد المتابعة إلى متجر التطبيقات؟</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>لا يمكن العثور على ما تبحث عنه؟ قم بالتواصل مع دعم Bitwarden على bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>استكشف المزيد من الميزات لحساب Bitwarden الخاص بك على تطبيق الويب.</value>
|
||||
</data>
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
<comment>The button text that allows a user to copy the login's password to their clipboard.</comment>
|
||||
</data>
|
||||
<data name="CopyUsername" xml:space="preserve">
|
||||
<value>İstifadəçi adını kopyalayın</value>
|
||||
<value>İstifadəçi adını kopyala</value>
|
||||
<comment>The button text that allows a user to copy the login's username to their clipboard.</comment>
|
||||
</data>
|
||||
<data name="Credits" xml:space="preserve">
|
||||
@@ -176,7 +176,7 @@
|
||||
<comment>Confirmation alert message when deleteing something.</comment>
|
||||
</data>
|
||||
<data name="Edit" xml:space="preserve">
|
||||
<value>Redaktə edin</value>
|
||||
<value>Düzəliş et</value>
|
||||
</data>
|
||||
<data name="EditFolder" xml:space="preserve">
|
||||
<value>Qovluğa düzəliş et</value>
|
||||
@@ -349,7 +349,7 @@
|
||||
<value>Göndər</value>
|
||||
</data>
|
||||
<data name="Sync" xml:space="preserve">
|
||||
<value>Eyniləşdirmə</value>
|
||||
<value>Sinxr</value>
|
||||
<comment>The title for the sync page.</comment>
|
||||
</data>
|
||||
<data name="ThankYou" xml:space="preserve">
|
||||
@@ -416,7 +416,7 @@
|
||||
<value>Tətbiq uzantısı</value>
|
||||
</data>
|
||||
<data name="AutofillAccessibilityDescription" xml:space="preserve">
|
||||
<value>Tətbiq və veb saytda giriş məlumatlarının avto-doldurulması üçün Bitwarden əlçatımlılıq xidmətini istifadə edin.</value>
|
||||
<value>Tətbiqlərdə və vebdə giriş məlumatlarının avto-doldurulması üçün Bitwarden əlçatımlılıq xidmətini istifadə edin.</value>
|
||||
</data>
|
||||
<data name="AutofillService" xml:space="preserve">
|
||||
<value>Avto-doldurma xidməti</value>
|
||||
@@ -465,7 +465,7 @@
|
||||
<value>Elementə düzəliş et</value>
|
||||
</data>
|
||||
<data name="EnableAutomaticSyncing" xml:space="preserve">
|
||||
<value>Avto-eyniləşdirməni fəallaşdır</value>
|
||||
<value>Avto-sinxr icazə ver</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>Ana parol məsləhətini alacağınız hesabınızın e-poçt ünvanını daxil edin.</value>
|
||||
@@ -523,7 +523,7 @@
|
||||
<value>Digər parol idarəetmə tətbiqlərindəki elementləri cəld və toplu formada daxilə köçürün.</value>
|
||||
</data>
|
||||
<data name="LastSync" xml:space="preserve">
|
||||
<value>Son eyniləşdirmə:</value>
|
||||
<value>Son sinxr:</value>
|
||||
</data>
|
||||
<data name="Length" xml:space="preserve">
|
||||
<value>Uzunluq</value>
|
||||
@@ -641,7 +641,7 @@
|
||||
<value>Hazırkı parolun üzərinə yazmaq istədiyinizə əminsiniz?</value>
|
||||
</data>
|
||||
<data name="PushNotificationAlert" xml:space="preserve">
|
||||
<value>Bitwarden, ani bildirişləri istifadə edərək anbarınızı avtomatik eyniləşdirir. Mümkün olan ən yaxşı təcrübəni təqdim etmək üçün, sizdən ani bildirişləri fəallaşdırmağı soruşanda növbəti ekranda "İcazə ver"i seçin.</value>
|
||||
<value>Bitwarden, ani bildirişləri istifadə edərək anbarınızın avtomatik sinxronlaşdırılmasını təmin edir. Mümkün olan ən yaxşı təcrübəni təqdim etmək üçün, sizdən ani bildirişləri fəallaşdırmağı soruşduqda növbəti ekranda "İcazə ver"i seçin.</value>
|
||||
<comment>Push notifications for apple products</comment>
|
||||
</data>
|
||||
<data name="RateTheApp" xml:space="preserve">
|
||||
@@ -682,17 +682,17 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="Syncing" xml:space="preserve">
|
||||
<value>Eyniləşdirilir...</value>
|
||||
<value>Sinxronlaşdırılır...</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="SyncingComplete" xml:space="preserve">
|
||||
<value>Eyniləşdirmə tamamlandı.</value>
|
||||
<value>Sinxr tamamlandı</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Uğursuz eyniləşdirmə.</value>
|
||||
<value>Sinxr uğursuz oldu</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Anbarı indi eyniləşdir</value>
|
||||
<value>Anbarı indi sinxronlaşdır</value>
|
||||
</data>
|
||||
<data name="TouchID" xml:space="preserve">
|
||||
<value>Touch ID</value>
|
||||
@@ -745,7 +745,7 @@
|
||||
<comment>This is used for the autofill service. ex. "There are no items in your vault for twitter.com".</comment>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOverlay" xml:space="preserve">
|
||||
<value>Bir giriş sahəsi seçəndə və Bitwarden avto-doldurma örtüyünü görəndə, avto-doldurma xidmətini başlatmaq üçün ona toxuna bilərsiniz.</value>
|
||||
<value>Bir giriş xanası seçdikdə və Bitwarden avto-doldurma örtüyünü gördükdə, avto-doldurma xidmətini başlatmaq üçün buna toxuna bilərsiniz.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceNotificationContent" xml:space="preserve">
|
||||
<value>Anbarınızdakı bir elementi avto-doldurmaq üçün bu bildirişə toxunun.</value>
|
||||
@@ -1167,10 +1167,10 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Avto-doldurma əlçatımlılıq xidməti</value>
|
||||
</data>
|
||||
<data name="AutofillServiceDescription" xml:space="preserve">
|
||||
<value>Bitwarden avto-doldurma xidməti, giriş məlumatlarının, kredit kartlarının və kimlik məlumatlarının cihazınızdakı digər tətbiqlərdə doldurmasına kömək etməsi üçün Android avto-doldurma sistemini istifadə edir.</value>
|
||||
<value>Bitwarden avto-doldurma xidməti, giriş məlumatlarının cihazınızdakı digər tətbiqlərdə doldurmasına kömək etməsi üçün Android Avto-doldurma Çərçivəsini istifadə edir.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Digər tətbiqlərdəki giriş məlumatlarının, kredit kartlarının və kimlik məlumatlarının doldurulması üçün Bitwarden avto-doldurma xidmətini istifadə edin.</value>
|
||||
<value>Giriş məlumatlarını digər tətbiqlərdə doldurmaq üçün Bitwarden avto-doldurma xidmətini istifadə edin.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
|
||||
<value>Avto-doldurma ayarlarını aç</value>
|
||||
@@ -1289,7 +1289,7 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Avto-doldurmanı istifadə edə bilmək üçün Bitwarden tətbiqində giriş etməlisiniz.</value>
|
||||
</data>
|
||||
<data name="AutofillSetup" xml:space="preserve">
|
||||
<value>Tətbiqlərdə və veb saytlarda giriş edərkən giriş etmə məlumatlarınıza klaviaturadan asanlıqla müraciət edə bilərsiniz.</value>
|
||||
<value>Tətbiqlərdə və veb saytlarda giriş edərkən giriş məlumatlarınıza klaviaturadan asanlıqla müraciət edə bilərsiniz.</value>
|
||||
</data>
|
||||
<data name="AutofillSetup2" xml:space="preserve">
|
||||
<value>İstifadə etməyi düşünmürsünüzsə, digər Avto-doldurma tətbiqlərini Ayarlarda sıradan çıxartmağı tövsiyə edirik.</value>
|
||||
@@ -1369,10 +1369,10 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Növlər</value>
|
||||
</data>
|
||||
<data name="NoPasswordsToList" xml:space="preserve">
|
||||
<value>Siyahılanacaq parol yoxdur.</value>
|
||||
<value>Sadalanacaq parol yoxdur.</value>
|
||||
</data>
|
||||
<data name="NoItemsToList" xml:space="preserve">
|
||||
<value>Siyahılanacaq heç bir element yoxdur.</value>
|
||||
<value>Sadalanacaq heç bir element yoxdur.</value>
|
||||
</data>
|
||||
<data name="SearchCollection" xml:space="preserve">
|
||||
<value>Kolleksiya axtar</value>
|
||||
@@ -1406,7 +1406,7 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Bu elementin sahibi kimdir?</value>
|
||||
</data>
|
||||
<data name="NoCollectionsToList" xml:space="preserve">
|
||||
<value>Siyahılanacaq heç bir kolleksiya yoxdur.</value>
|
||||
<value>Sadalanacaq heç bir kolleksiya yoxdur.</value>
|
||||
</data>
|
||||
<data name="MovedItemToOrg" xml:space="preserve">
|
||||
<value>{0}, {1} ünvanına daşındı.</value>
|
||||
@@ -1428,7 +1428,7 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Təşkilata daşı</value>
|
||||
</data>
|
||||
<data name="NoOrgsToList" xml:space="preserve">
|
||||
<value>Siyahılanacaq heç bir təşkilat yoxdur.</value>
|
||||
<value>Sadalanacaq heç bir təşkilat yoxdur.</value>
|
||||
</data>
|
||||
<data name="MoveToOrgDesc" xml:space="preserve">
|
||||
<value>Bu elementi daşımaq istədiyiniz təşkilatı seçin. Bir təşkilata daşımaq, elementin sahibliyini də həmin təşkilata daşıyacaq. Daşıdıqdan sonra bu elementə birbaşa sahibliyiniz olmayacaq.</value>
|
||||
@@ -1451,7 +1451,7 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<comment>Short for "Password Generator"</comment>
|
||||
</data>
|
||||
<data name="NoFoldersToList" xml:space="preserve">
|
||||
<value>Siyahılanacaq heç bir qovluq yoxdur.</value>
|
||||
<value>Sadalanacaq heç bir qovluq yoxdur.</value>
|
||||
</data>
|
||||
<data name="FingerprintPhrase" xml:space="preserve">
|
||||
<value>Barmaq izi ifadəsi</value>
|
||||
@@ -1747,10 +1747,10 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Ana parolun doğrulanması gözlənildiyi üçün bu hesab üzrə avto-doldurma biometrik kilid açma sıradan çıxarıldı.</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefresh" xml:space="preserve">
|
||||
<value>Təzələmə əsnasında eyniləşdirməni fəallaşdır</value>
|
||||
<value>Təzələmə zamanı sinxr icazə ver</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
|
||||
<value>Barmağınızla aşağı çəkəndə anbarı eyniləşdir</value>
|
||||
<value>Barmağınızla aşağı çəkdikdə anbarı sinxronlaşdır.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Müəssisə üçün tək daxil olma</value>
|
||||
@@ -1828,10 +1828,10 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Əlçatımlılığı istifadə et</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription" xml:space="preserve">
|
||||
<value>Saytda və tətbiqlərdə giriş məlumatlarınızın avto-doldurulması üçün Bitwarden əlçatımlılıq xidmətini istifadə edə bilərsiniz. Fəal olanda, giriş məlumatlarını daxil edərkən açılan pəncərə görünəcək.</value>
|
||||
<value>Saytda və vebdə giriş məlumatlarınızı avto-doldurmaq üçün Bitwarden Əlçatımlılıq Xidmətini istifadə edin. Qurulanda, giriş xanalarını seçərkən açılan pəncərə göstərəcəyik.</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription2" xml:space="preserve">
|
||||
<value>Saytda və tətbiqlərdə giriş məlumatlarınızın avto-doldurulması üçün Bitwarden əlçatımlılıq xidmətini istifadə edə bilərsiniz. ("Üzərində göstər" seçiminin fəal olması lazımdır)</value>
|
||||
<value>Saytda və vebdə giriş məlumatlarınızı avto-doldurmaq üçün Bitwarden Əlçatımlılıq Xidmətini istifadə edin. ("Üzərində göstər" seçimi açıq olmalıdır)</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription3" xml:space="preserve">
|
||||
<value>Avto-doldurma cəld əməliyyat qutusunu istifadə etmək üçün Bitwarden əlçatımlılıq xidmətini istifadə edin və/və ya "Üzərində göstər"i (əgər fəaldırsa) istifadə edərək açılan bir pəncərə göstərə bilərsiniz.</value>
|
||||
@@ -1843,13 +1843,13 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>"Üzərində göstər"i istifadə edin</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription" xml:space="preserve">
|
||||
<value>Fəal olsa, giriş məlumatları daxil ediləndə Bitwarden əlçatımlılıq xidmətinə açılan pəncərə görüntüləməsinə icazə verilər.</value>
|
||||
<value>Giriş xanalarını seçdikdə Bitwarden Əlçatımlılıq Xidmətinin açılan pəncərə göstərməsinə icazə verir.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription2" xml:space="preserve">
|
||||
<value>Fəal olsa, giriş məlumatlarının avto-doldurmasına köməkçi olması üçün giriş sahələri seçiləndə Bitwarden əlçatımlılıq xidməti açılan bir pəncərə görüntüləyəcək.</value>
|
||||
<value>İşə salındıqda Bitwarden Əlçatımlılıq Xidməti, giriş məlumatlarınızın avto-doldurmasına kömək etmək üçün giriş xanaları seçildikdə açılan pəncərə göstərəcək.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription3" xml:space="preserve">
|
||||
<value>Fəal olsa, əlçatımlılıq, Android-in avto-doldurma sistemini dəstəkləməyən köhnə tətbiqlər üçün Avto-doldurma xidmətini təqlid etməsi üçün açılan bir pəncərə göstərəcək.</value>
|
||||
<value>Fəal olsa, əlçatımlılıq, Android Avto-doldurma Çərçivəsini dəstəkləməyən köhnə tətbiqlərdə Avto-doldurma Xidmətini təqlid etməsi üçün açılan bir pəncərə göstərəcək.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
|
||||
<value>Müəssisə Siyasətinə görə, elementləri şəxsi anbarınızda saxlamağınız məhdudlaşdırılıb. Sahiblik seçimini təşkilat olaraq dəyişdirin və mövcud kolleksiyalar arasından seçim edin.</value>
|
||||
@@ -2464,7 +2464,7 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Əlçatımlılıq Xidməti açıqlaması</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden, tətbiqlərdə və veb saytlarda giriş sahələrini axtarmaq üçün Əlçatımlılıq Xidmətini istifadə edir, daha sonra tətbiq və ya sayt üçün uyuşma tapdıqda istifadəçi adı və parolun daxil edilməsi üçün müvafiq sahə kimliklərini yaradır. Xidmət tərəfindən bizə təqdim edilən məlumatların heç birini saxlamırıq, kimlik məlumatlarının daxil edilməsindən kənar ekrandakı hər hansısa elementə nəzarət etməyə cəhd etmirik.</value>
|
||||
<value>Bitwarden, tətbiqlərdə və veb saytlarda giriş xanalarını axtarmaq üçün Əlçatımlılıq Xidmətini istifadə edir, daha sonra tətbiq və ya sayt üçün uyuşma tapdıqda istifadəçi adı və parolun daxil edilməsi üçün müvafiq sahə kimliklərini yaradır. Xidmət tərəfindən bizə təqdim edilən məlumatların heç birini saxlamırıq, kimlik məlumatlarının daxil edilməsindən kənar ekrandakı hər hansısa elementə nəzarət etməyə cəhd etmirik.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Qəbul et</value>
|
||||
@@ -2801,7 +2801,7 @@ Bu hesaba keçmək istəyirsiniz?</value>
|
||||
<value>Android Avto-doldurma Çərçivəsi, giriş məlumatlarını cihazınızdakı digər tətbiqlərə doldurmağa kömək etmək üçün istifadə olunur.</value>
|
||||
</data>
|
||||
<data name="UseInlineAutofillExplanationLong" xml:space="preserve">
|
||||
<value>Seçdiyiniz klaviatura dəstəkləyirsə sətir daxili avto-doldurmani istifadə edin. Əks halda, ilkin örtük istifadə edin.</value>
|
||||
<value>Seçdiyiniz klaviatura dəstəkləyirsə sətir daxili avto-doldurmanı istifadə edin. Əks halda, ilkin örtük istifadə edin.</value>
|
||||
</data>
|
||||
<data name="AdditionalOptions" xml:space="preserve">
|
||||
<value>Əlavə seçimlər</value>
|
||||
@@ -2819,6 +2819,9 @@ Bu hesaba keçmək istəyirsiniz?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Dəstək komandası ilə əlaqə qurmağa davam edilsin?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Gizlilik Siyasətinə davam edirsiniz?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Tətbiq mağazası ilə davam edilsin?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Bu hesaba keçmək istəyirsiniz?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Axtardığınızı tapa bilmirsiniz? bitwarden.com üzərindən Bitwarden dəstəyinə müraciət edin.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>bitwarden.com saytında gizlilik siyasətimizi nəzərdən keçirin.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Veb tətbiqində Bitwarden hesabınızın daha çox özəlliyini kəşf edin.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Продължаване към връзка с поддръжката?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Продължаване към Политиката за поверителност?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Продължаване към магазина за приложения?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Не намирате това, което търсите? Свържете се с поддръжката на Битуорден на bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Прегледайте нашата Политика за поверителност на bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Разгледайте още от възможностите на регистрацията си в Битуорден в уеб приложението.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@ Skeniranje će biti izvršeno automatski.</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Skeniranje će biti izvršeno automatski.</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Voleu canviar a aquest compte?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Voleu continuar per contactar amb l'assistència?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Voleu continuar amb la política de privadesa?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Voleu continuar cap a l'app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Voleu canviar a aquest compte?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>No trobeu el que esteu buscant? Poseu-vos en contacte amb l'assistència de Bitwarden a bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Consulteu la nostra política de privadesa a bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Exploreu més característiques del vostre compte Bitwarden a l'aplicació web.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@ Chcete se přepnout na tento účet?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Pokračovat v kontaktování podpory?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Pokračovat na Zásady ochrany osobních údajů?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Pokračovat do obchodu s aplikacemi?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Chcete se přepnout na tento účet?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Nenašli jste to, co jste hledali? Na bitwarden.com získejte podporu.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Podívejte se na naše Zásady ochrany osobních údajů na bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Prozkoumejte další funkce Vašeho účtu Bitwarden ve webové aplikaci.</value>
|
||||
</data>
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
<comment>App name. Shouldn't ever change.</comment>
|
||||
</data>
|
||||
<data name="Cancel" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
<value>Yn ôl</value>
|
||||
<comment>Cancel an operation.</comment>
|
||||
</data>
|
||||
<data name="Copy" xml:space="preserve">
|
||||
@@ -152,11 +152,11 @@
|
||||
<comment>Copy some value to your clipboard.</comment>
|
||||
</data>
|
||||
<data name="CopyPassword" xml:space="preserve">
|
||||
<value>Copy password</value>
|
||||
<value>Copïo'r cyfrinair</value>
|
||||
<comment>The button text that allows a user to copy the login's password to their clipboard.</comment>
|
||||
</data>
|
||||
<data name="CopyUsername" xml:space="preserve">
|
||||
<value>Copy username</value>
|
||||
<value>Copïo'r enw defnyddiwr</value>
|
||||
<comment>The button text that allows a user to copy the login's username to their clipboard.</comment>
|
||||
</data>
|
||||
<data name="Credits" xml:space="preserve">
|
||||
@@ -265,7 +265,7 @@
|
||||
<comment>The login button text (verb).</comment>
|
||||
</data>
|
||||
<data name="LogInNoun" xml:space="preserve">
|
||||
<value>Login</value>
|
||||
<value>Mewngofnodi</value>
|
||||
<comment>Title for login page. (noun)</comment>
|
||||
</data>
|
||||
<data name="LogOut" xml:space="preserve">
|
||||
@@ -282,7 +282,7 @@
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account already added</value>
|
||||
<value>Wedi'i ychwanegu eisoes</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
@@ -308,7 +308,7 @@
|
||||
<comment>Label for an entity name.</comment>
|
||||
</data>
|
||||
<data name="No" xml:space="preserve">
|
||||
<value>No</value>
|
||||
<value>Na</value>
|
||||
</data>
|
||||
<data name="Notes" xml:space="preserve">
|
||||
<value>Nodiadau</value>
|
||||
@@ -327,7 +327,7 @@
|
||||
<comment>Button text for a save operation (verb).</comment>
|
||||
</data>
|
||||
<data name="Move" xml:space="preserve">
|
||||
<value>Move</value>
|
||||
<value>Symud</value>
|
||||
</data>
|
||||
<data name="Saving" xml:space="preserve">
|
||||
<value>Yn cadw...</value>
|
||||
@@ -391,7 +391,7 @@
|
||||
<value>Fersiwn</value>
|
||||
</data>
|
||||
<data name="View" xml:space="preserve">
|
||||
<value>View</value>
|
||||
<value>Gweld</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsite" xml:space="preserve">
|
||||
<value>Visit our website</value>
|
||||
@@ -401,7 +401,7 @@
|
||||
<comment>Label for a website.</comment>
|
||||
</data>
|
||||
<data name="Yes" xml:space="preserve">
|
||||
<value>Yes</value>
|
||||
<value>Ydw</value>
|
||||
</data>
|
||||
<data name="Account" xml:space="preserve">
|
||||
<value>Cyfrif</value>
|
||||
@@ -455,7 +455,7 @@
|
||||
<value>Parhau</value>
|
||||
</data>
|
||||
<data name="CreateAccount" xml:space="preserve">
|
||||
<value>Creu cyfrif</value>
|
||||
<value>Crëwch gyfrif</value>
|
||||
</data>
|
||||
<data name="CreatingAccount" xml:space="preserve">
|
||||
<value>Wrthi'n creu cyfrif...</value>
|
||||
@@ -484,13 +484,13 @@
|
||||
<comment>Safari is the name of apple's web browser</comment>
|
||||
</data>
|
||||
<data name="ExtensionInstantAccess" xml:space="preserve">
|
||||
<value>Get instant access to your passwords!</value>
|
||||
<value>Mynnwch fynediad i'ch cyfrineiriau ar unwaith!</value>
|
||||
</data>
|
||||
<data name="ExtensionReady" xml:space="preserve">
|
||||
<value>Rydych chi'n barod i fewngofnodi!</value>
|
||||
</data>
|
||||
<data name="ExtensionSetup" xml:space="preserve">
|
||||
<value>Your logins are now easily accessible from Safari, Chrome, and other supported apps.</value>
|
||||
<value>Mae eich manylion mewngofnodi bellach yn hawdd i'w canfod o Safari, Chrome, ac apiau eraill.</value>
|
||||
</data>
|
||||
<data name="ExtensionSetup2" xml:space="preserve">
|
||||
<value>In Safari and Chrome, find Bitwarden using the share icon (hint: scroll to the right on the bottom row of the share menu).</value>
|
||||
@@ -502,7 +502,7 @@
|
||||
<value>To turn on Bitwarden in Safari and other apps, tap the "more" icon on the bottom row of the menu.</value>
|
||||
</data>
|
||||
<data name="Favorite" xml:space="preserve">
|
||||
<value>Favorite</value>
|
||||
<value>Ffefryn</value>
|
||||
</data>
|
||||
<data name="Fingerprint" xml:space="preserve">
|
||||
<value>Ôl bys</value>
|
||||
@@ -511,7 +511,7 @@
|
||||
<value>Cynhyrchu cyfrinair</value>
|
||||
</data>
|
||||
<data name="GetPasswordHint" xml:space="preserve">
|
||||
<value>Get your master password hint</value>
|
||||
<value>Anfon awgrym o'ch prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="ImportItems" xml:space="preserve">
|
||||
<value>Mewnforio eitemau</value>
|
||||
@@ -572,27 +572,27 @@
|
||||
<value>The master password is the password you use to access your vault. It is very important that you do not forget your master password. There is no way to recover the password in the event that you forget it.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHint" xml:space="preserve">
|
||||
<value>Master password hint (optional)</value>
|
||||
<value>Awgrym o'ch prif gyfrinair (dewisol)</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHintDescription" xml:space="preserve">
|
||||
<value>Gall awgrym o'ch prif gyfrinair eich helpu i'w gofio os ydych chi'n ei anghofio.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
|
||||
<value>Master password must be at least {0} characters long.</value>
|
||||
<value>Rhaid i'ch prif gyfrinair gynnwys o leiaf {0} nod.</value>
|
||||
</data>
|
||||
<data name="MinNumbers" xml:space="preserve">
|
||||
<value>Isafswm rhifau</value>
|
||||
<comment>Minimum numeric characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MinSpecial" xml:space="preserve">
|
||||
<value>Isafswm arbennig</value>
|
||||
<value>Isafswm nodau arbennig</value>
|
||||
<comment>Minimum special characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MoreSettings" xml:space="preserve">
|
||||
<value>Mwy o osodiadau</value>
|
||||
</data>
|
||||
<data name="MustLogInMainApp" xml:space="preserve">
|
||||
<value>You must log into the main Bitwarden app before you can use the extension.</value>
|
||||
<value>Rhaid i chi fewngofnodi i brif ap Bitwarden cyn defnyddio'r estyniad.</value>
|
||||
</data>
|
||||
<data name="Never" xml:space="preserve">
|
||||
<value>byth</value>
|
||||
@@ -610,7 +610,7 @@
|
||||
<value>There are no items in your vault for this website/app. Tap to add one.</value>
|
||||
</data>
|
||||
<data name="NoUsernamePasswordConfigured" xml:space="preserve">
|
||||
<value>This login does not have a username or password configured.</value>
|
||||
<value>Does dim enw defnyddiwr na chyfrinair i'r manylyn mewngofnodi hwn.</value>
|
||||
</data>
|
||||
<data name="OkGotIt" xml:space="preserve">
|
||||
<value>Iawn, deall!</value>
|
||||
@@ -623,7 +623,7 @@
|
||||
<value>Dewisiadau</value>
|
||||
</data>
|
||||
<data name="Other" xml:space="preserve">
|
||||
<value>Other</value>
|
||||
<value>Gosodiadau eraill</value>
|
||||
</data>
|
||||
<data name="PasswordGenerated" xml:space="preserve">
|
||||
<value>Password generated</value>
|
||||
@@ -632,7 +632,7 @@
|
||||
<value>Cynhyrchydd cyfrineiriau</value>
|
||||
</data>
|
||||
<data name="PasswordHint" xml:space="preserve">
|
||||
<value>Password hint</value>
|
||||
<value>Awgrym o'r cyfrinair</value>
|
||||
</data>
|
||||
<data name="PasswordHintAlert" xml:space="preserve">
|
||||
<value>Rydym ni wedi anfon ebost atoch gydag awgrym ar gyfer eich prif gyfrinair.</value>
|
||||
@@ -654,7 +654,7 @@
|
||||
<value>Ailgynhyrchu cyfrinair</value>
|
||||
</data>
|
||||
<data name="RetypeMasterPassword" xml:space="preserve">
|
||||
<value>Re-type master password</value>
|
||||
<value>Aildeipio'r prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="SearchVault" xml:space="preserve">
|
||||
<value>Chwilio'r gell</value>
|
||||
@@ -672,7 +672,7 @@
|
||||
<value>Rhowch god PIN 4 nod i'w ddefnyddio i ddatgloi'r ap.</value>
|
||||
</data>
|
||||
<data name="ItemInformation" xml:space="preserve">
|
||||
<value>Item information</value>
|
||||
<value>Gwybodaeth am yr eitem</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Eitem wedi'i chadw</value>
|
||||
@@ -699,7 +699,7 @@
|
||||
<comment>What Apple calls their fingerprint reader.</comment>
|
||||
</data>
|
||||
<data name="TwoStepLogin" xml:space="preserve">
|
||||
<value>Two-step login</value>
|
||||
<value>Mewngofnodi dau agm</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Datgloi â {0}</value>
|
||||
@@ -715,7 +715,7 @@
|
||||
<value>Verification code</value>
|
||||
</data>
|
||||
<data name="ViewItem" xml:space="preserve">
|
||||
<value>View item</value>
|
||||
<value>Gweld yr eitem</value>
|
||||
</data>
|
||||
<data name="WebVault" xml:space="preserve">
|
||||
<value>Cell we Bitwarden</value>
|
||||
@@ -837,10 +837,10 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="TwoStepLoginOptions" xml:space="preserve">
|
||||
<value>Two-step login options</value>
|
||||
<value>Dewisiadau mewngofnodi dau gam</value>
|
||||
</data>
|
||||
<data name="UseAnotherTwoStepMethod" xml:space="preserve">
|
||||
<value>Use another two-step login method</value>
|
||||
<value>Defnyddio dull mewngofnodi dau gam arall</value>
|
||||
</data>
|
||||
<data name="VerificationEmailNotSent" xml:space="preserve">
|
||||
<value>Could not send verification email. Try again.</value>
|
||||
@@ -1005,10 +1005,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Cerdyn</value>
|
||||
</data>
|
||||
<data name="TypeIdentity" xml:space="preserve">
|
||||
<value>Hunaniaeth</value>
|
||||
<value>Eitem hunaniaeth</value>
|
||||
</data>
|
||||
<data name="TypeLogin" xml:space="preserve">
|
||||
<value>Login</value>
|
||||
<value>Manylyn mewngofnodi</value>
|
||||
</data>
|
||||
<data name="TypeSecureNote" xml:space="preserve">
|
||||
<value>Nodyn diogel</value>
|
||||
@@ -1083,10 +1083,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Mawrth</value>
|
||||
</data>
|
||||
<data name="May" xml:space="preserve">
|
||||
<value>May</value>
|
||||
<value>Mai</value>
|
||||
</data>
|
||||
<data name="MiddleName" xml:space="preserve">
|
||||
<value>Middle name</value>
|
||||
<value>Enw canol</value>
|
||||
</data>
|
||||
<data name="Mr" xml:space="preserve">
|
||||
<value>Mr</value>
|
||||
@@ -1104,13 +1104,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Tachwedd</value>
|
||||
</data>
|
||||
<data name="October" xml:space="preserve">
|
||||
<value>October</value>
|
||||
<value>Hydref</value>
|
||||
</data>
|
||||
<data name="PassportNumber" xml:space="preserve">
|
||||
<value>Rhif pasbort</value>
|
||||
</data>
|
||||
<data name="Phone" xml:space="preserve">
|
||||
<value>Phone</value>
|
||||
<value>Ffôn</value>
|
||||
</data>
|
||||
<data name="September" xml:space="preserve">
|
||||
<value>Medi</value>
|
||||
@@ -1137,7 +1137,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Dangos eiconau gwefannau</value>
|
||||
</data>
|
||||
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
|
||||
<value>Show a recognizable image next to each login.</value>
|
||||
<value>Dangos delwedd adnabyddadwy wrth ymyl pob eitem.</value>
|
||||
</data>
|
||||
<data name="IconsUrl" xml:space="preserve">
|
||||
<value>Icons server URL</value>
|
||||
@@ -1158,10 +1158,10 @@ Scanning will happen automatically.</value>
|
||||
<value>There are no items in this collection.</value>
|
||||
</data>
|
||||
<data name="NoItemsFolder" xml:space="preserve">
|
||||
<value>There are no items in this folder.</value>
|
||||
<value>Does dim eitemau yn y ffolder hon.</value>
|
||||
</data>
|
||||
<data name="NoItemsTrash" xml:space="preserve">
|
||||
<value>There are no items in the trash.</value>
|
||||
<value>Does dim eitemau yn y bin sbwriel.</value>
|
||||
</data>
|
||||
<data name="AutofillAccessibilityService" xml:space="preserve">
|
||||
<value>Auto-fill Accessibility Service</value>
|
||||
@@ -1266,7 +1266,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Hold your Yubikey near the top of the device.</value>
|
||||
</data>
|
||||
<data name="TryAgain" xml:space="preserve">
|
||||
<value>Try again</value>
|
||||
<value>Ceisio eto</value>
|
||||
</data>
|
||||
<data name="YubiKeyInstructionIos" xml:space="preserve">
|
||||
<value>To continue, hold your YubiKey NEO against the back of the device.</value>
|
||||
@@ -1351,10 +1351,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Gwirio a ydy'r cyfrinair wedi'i ddatgelu.</value>
|
||||
</data>
|
||||
<data name="PasswordExposed" xml:space="preserve">
|
||||
<value>Mae'r cyfrinair hwn wedi cael ei ddatgelu {0} o weithiau mewn achosion o dorri data. Dylech chi ei newid.</value>
|
||||
<value>Mae'r cyfrinair hwn wedi cael ei ddatgelu {0} o weithiau mewn achosion o ddatgelu data. Dylech chi ei newid.</value>
|
||||
</data>
|
||||
<data name="PasswordSafe" xml:space="preserve">
|
||||
<value>This password was not found in any known data breaches. It should be safe to use.</value>
|
||||
<value>Chafodd y cyfrinair hwn mo'i ganfod mewn unrhyw achos hysbys o ddatgelu data. Dylai fod yn iawn i'w ddefnyddio.</value>
|
||||
</data>
|
||||
<data name="IdentityName" xml:space="preserve">
|
||||
<value>Identity name</value>
|
||||
@@ -1366,13 +1366,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Password history</value>
|
||||
</data>
|
||||
<data name="Types" xml:space="preserve">
|
||||
<value>Types</value>
|
||||
<value>Mathau</value>
|
||||
</data>
|
||||
<data name="NoPasswordsToList" xml:space="preserve">
|
||||
<value>No passwords to list.</value>
|
||||
<value>Dim cyfrineiriau i'w rhestru.</value>
|
||||
</data>
|
||||
<data name="NoItemsToList" xml:space="preserve">
|
||||
<value>There are no items to list.</value>
|
||||
<value>Does dim eitemau i'w rhestu.</value>
|
||||
</data>
|
||||
<data name="SearchCollection" xml:space="preserve">
|
||||
<value>Search collection</value>
|
||||
@@ -1384,7 +1384,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Search text Sends</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Search {0}</value>
|
||||
<value>Chwilio {0}</value>
|
||||
<comment>ex: Search Logins</comment>
|
||||
</data>
|
||||
<data name="Type" xml:space="preserve">
|
||||
@@ -1451,7 +1451,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>Short for "Password Generator"</comment>
|
||||
</data>
|
||||
<data name="NoFoldersToList" xml:space="preserve">
|
||||
<value>There are no folders to list.</value>
|
||||
<value>Does dim ffolderi i'w rhestru.</value>
|
||||
</data>
|
||||
<data name="FingerprintPhrase" xml:space="preserve">
|
||||
<value>Fingerprint phrase</value>
|
||||
@@ -1522,11 +1522,11 @@ Scanning will happen automatically.</value>
|
||||
<value>ar ôl 2 funud</value>
|
||||
</data>
|
||||
<data name="ClearClipboard" xml:space="preserve">
|
||||
<value>Clear clipboard</value>
|
||||
<value>Clirio'r clipfwrdd</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>Automatically clear copied values from your clipboard.</value>
|
||||
<value>Clirio eitemau a gopïwyd o'ch clipfwrdd yn awtomatig.</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">
|
||||
@@ -1541,7 +1541,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>Color theme</comment>
|
||||
</data>
|
||||
<data name="ThemeDescription" xml:space="preserve">
|
||||
<value>Change the application's color theme.</value>
|
||||
<value>Newid thema liwiau'r ap.</value>
|
||||
</data>
|
||||
<data name="ThemeDefault" xml:space="preserve">
|
||||
<value>Rhagosodiad (system)</value>
|
||||
@@ -1550,13 +1550,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Default dark theme</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Copy note</value>
|
||||
<value>Copïo'r nodyn</value>
|
||||
</data>
|
||||
<data name="Exit" xml:space="preserve">
|
||||
<value>Exit</value>
|
||||
<value>Gadael</value>
|
||||
</data>
|
||||
<data name="ExitConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to exit Bitwarden?</value>
|
||||
<value>Ydych chi'n siŵr eich bod am adael Bitwarden?</value>
|
||||
</data>
|
||||
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
|
||||
<value>Do you want to require unlocking with your master password when the application is restarted?</value>
|
||||
@@ -1599,7 +1599,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Cynnwys rhif</value>
|
||||
</data>
|
||||
<data name="Download" xml:space="preserve">
|
||||
<value>Download</value>
|
||||
<value>Lawrlwytho</value>
|
||||
</data>
|
||||
<data name="Shared" xml:space="preserve">
|
||||
<value>Shared</value>
|
||||
@@ -1614,10 +1614,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Biometric verification</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Biometrics</value>
|
||||
<value>biometreg</value>
|
||||
</data>
|
||||
<data name="UseBiometricsToUnlock" xml:space="preserve">
|
||||
<value>Use biometrics to unlock</value>
|
||||
<value>Defnyddio biometreg i ddatgloi</value>
|
||||
</data>
|
||||
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden needs attention - See "Auto-fill Accessibility Service" from Bitwarden settings</value>
|
||||
@@ -1641,7 +1641,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Granted</value>
|
||||
</data>
|
||||
<data name="FileFormat" xml:space="preserve">
|
||||
<value>File format</value>
|
||||
<value>Fformat y ffeil</value>
|
||||
</data>
|
||||
<data name="ExportVaultMasterPasswordDescription" xml:space="preserve">
|
||||
<value>Rhowch eich prif gyfrinair i allforio data eich cell.</value>
|
||||
@@ -1692,7 +1692,7 @@ Scanning will happen automatically.</value>
|
||||
<value>There was a problem saving this attachment. If the problem persists, you can save it from the web vault.</value>
|
||||
</data>
|
||||
<data name="SaveAttachmentSuccess" xml:space="preserve">
|
||||
<value>Attachment saved successfully</value>
|
||||
<value>Cadwyd yr atodiad yn llwyddiannus</value>
|
||||
</data>
|
||||
<data name="AutofillTileAccessibilityRequired" xml:space="preserve">
|
||||
<value>Please turn on "Auto-fill Accessibility Service" from Bitwarden Settings to use the Auto-fill tile.</value>
|
||||
@@ -1701,11 +1701,11 @@ Scanning will happen automatically.</value>
|
||||
<value>No password fields detected</value>
|
||||
</data>
|
||||
<data name="SoftDeleting" xml:space="preserve">
|
||||
<value>Sending to trash...</value>
|
||||
<value>Yn anfon i'r bin sbwriel...</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemSoftDeleted" xml:space="preserve">
|
||||
<value>Item has been sent to trash.</value>
|
||||
<value>Anfonwyd yr eitem i'r bin sbwriel.</value>
|
||||
<comment>Confirmation message after successfully soft-deleting a login</comment>
|
||||
</data>
|
||||
<data name="Restore" xml:space="preserve">
|
||||
@@ -1713,7 +1713,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>Restores an entity (verb).</comment>
|
||||
</data>
|
||||
<data name="Restoring" xml:space="preserve">
|
||||
<value>Restoring...</value>
|
||||
<value>Yn adfer...</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
@@ -1721,15 +1721,15 @@ Scanning will happen automatically.</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
<value>Trash</value>
|
||||
<value>Bin sbwriel</value>
|
||||
<comment>(noun) Location of deleted items which have not yet been permanently deleted</comment>
|
||||
</data>
|
||||
<data name="SearchTrash" xml:space="preserve">
|
||||
<value>Search trash</value>
|
||||
<value>Chwilio drwy'r bin sbwriel</value>
|
||||
<comment>(action prompt) Label for the search text field when viewing the trash folder</comment>
|
||||
</data>
|
||||
<data name="DoYouReallyWantToPermanentlyDeleteCipher" xml:space="preserve">
|
||||
<value>Do you really want to permanently delete? This cannot be undone.</value>
|
||||
<value>Ydych chi wir eisiau dileu'r eitem hon? Allwch chi ddim dadwneud hyn.</value>
|
||||
<comment>Confirmation alert message when permanently deleteing a cipher.</comment>
|
||||
</data>
|
||||
<data name="DoYouReallyWantToRestoreCipher" xml:space="preserve">
|
||||
@@ -1737,7 +1737,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>Confirmation alert message when restoring a soft-deleted cipher.</comment>
|
||||
</data>
|
||||
<data name="DoYouReallyWantToSoftDeleteCipher" xml:space="preserve">
|
||||
<value>Do you really want to send to the trash?</value>
|
||||
<value>Ydych chi wir eisiau anfon yr eitem hon i'r bin sbwriel?</value>
|
||||
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
|
||||
</data>
|
||||
<data name="AccountBiometricInvalidated" xml:space="preserve">
|
||||
@@ -1747,10 +1747,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefresh" xml:space="preserve">
|
||||
<value>Allow sync on refresh</value>
|
||||
<value>Caniatáu cysoni wrth adnewyddu</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
<value>Cysoni'r gell drwy dynnu i lawr.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise single sign-on</value>
|
||||
@@ -1765,7 +1765,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Currently unable to login with SSO</value>
|
||||
</data>
|
||||
<data name="SetMasterPassword" xml:space="preserve">
|
||||
<value>Set master password</value>
|
||||
<value>Gosod prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="SetMasterPasswordSummary" xml:space="preserve">
|
||||
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
|
||||
@@ -1798,7 +1798,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
|
||||
</data>
|
||||
<data name="Loading" xml:space="preserve">
|
||||
<value>Loading</value>
|
||||
<value>Llwytho</value>
|
||||
</data>
|
||||
<data name="AcceptPolicies" xml:space="preserve">
|
||||
<value>By activating this switch you agree to the following:
|
||||
@@ -1808,16 +1808,16 @@ Scanning will happen automatically.</value>
|
||||
<value>Terms of Service and Privacy Policy have not been acknowledged.</value>
|
||||
</data>
|
||||
<data name="TermsOfService" xml:space="preserve">
|
||||
<value>Terms of Service</value>
|
||||
<value>Telerau gwasanaeth</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicy" xml:space="preserve">
|
||||
<value>Privacy Policy</value>
|
||||
<value>Polisi preifatrwydd</value>
|
||||
</data>
|
||||
<data name="AccessibilityDrawOverPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden needs attention - Turn on "Draw-Over" in "Auto-fill Services" from Bitwarden Settings</value>
|
||||
</data>
|
||||
<data name="AutofillServices" xml:space="preserve">
|
||||
<value>Auto-fill services</value>
|
||||
<value>Gwasanaethau llenwi awtomatig</value>
|
||||
</data>
|
||||
<data name="InlineAutofill" xml:space="preserve">
|
||||
<value>Use inline autofill</value>
|
||||
@@ -2044,11 +2044,11 @@ Scanning will happen automatically.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AboutSend" xml:space="preserve">
|
||||
<value>About Send</value>
|
||||
<value>Ynghylch 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="HideEmail" xml:space="preserve">
|
||||
<value>Hide my email address from recipients</value>
|
||||
<value>Cuddio fy nghyfeiriad ebost rhag derbynwyr</value>
|
||||
</data>
|
||||
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||
<value>One or more organization policies are affecting your Send options.</value>
|
||||
@@ -2063,7 +2063,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="PasswordPrompt" xml:space="preserve">
|
||||
<value>Master password re-prompt</value>
|
||||
<value>Ailofyn am y prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="PasswordConfirmation" xml:space="preserve">
|
||||
<value>Master password confirmation</value>
|
||||
@@ -2078,16 +2078,16 @@ Scanning will happen automatically.</value>
|
||||
<value>Captcha failed. Please try again.</value>
|
||||
</data>
|
||||
<data name="UpdatedMasterPassword" xml:space="preserve">
|
||||
<value>Updated master password</value>
|
||||
<value>Diweddarwyd y prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPassword" xml:space="preserve">
|
||||
<value>Update master password</value>
|
||||
<value>Diweddaru'r prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Updating password</value>
|
||||
<value>Yn diweddaru'r cyfrinair</value>
|
||||
</data>
|
||||
<data name="UpdatePasswordError" xml:space="preserve">
|
||||
<value>Currently unable to update password</value>
|
||||
@@ -2105,7 +2105,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Leave organization</value>
|
||||
</data>
|
||||
<data name="LeaveOrganizationName" xml:space="preserve">
|
||||
<value>Leave {0}?</value>
|
||||
<value>Gadael {0}?</value>
|
||||
</data>
|
||||
<data name="Fido2Title" xml:space="preserve">
|
||||
<value>FIDO2 WebAuthn</value>
|
||||
@@ -2120,7 +2120,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Authenticate WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2ReturnToApp" xml:space="preserve">
|
||||
<value>Return to app</value>
|
||||
<value>Dychwelyd i'r ap</value>
|
||||
</data>
|
||||
<data name="Fido2CheckBrowser" xml:space="preserve">
|
||||
<value>Please make sure your default browser supports WebAuthn and try again.</value>
|
||||
@@ -2144,7 +2144,7 @@ Scanning will happen automatically.</value>
|
||||
<value>One or more organization policies prevents your from exporting your individual vault.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add account</value>
|
||||
<value>Ychwanegu cyfrif</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
@@ -2168,19 +2168,19 @@ Scanning will happen automatically.</value>
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete account</value>
|
||||
<value>Dileu eich cyfrif</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccountIsPermanent" xml:space="preserve">
|
||||
<value>Deleting your account is permanent</value>
|
||||
</data>
|
||||
<data name="DeleteAccountExplanation" xml:space="preserve">
|
||||
<value>Your account and all vault data will be erased and unrecoverable. Are you sure you want to continue?</value>
|
||||
<value>Caiff eich cyfrif a holl ddata'ch cell eu dileu mewn ffordd anadferadwy. Ydych chi'n siŵr yr hoffech chi barhau?</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccount" xml:space="preserve">
|
||||
<value>Deleting your account</value>
|
||||
</data>
|
||||
<data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve">
|
||||
<value>Your account has been permanently deleted</value>
|
||||
<value>Mae eich cyfrif wedi cael ei ddileu'n barhaol</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Invalid verification code</value>
|
||||
@@ -2249,7 +2249,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Password is not visible, tap to show.</value>
|
||||
</data>
|
||||
<data name="FilterByVault" xml:space="preserve">
|
||||
<value>Filter items by vault</value>
|
||||
<value>Hidlo eitemau yn ôl cell</value>
|
||||
</data>
|
||||
<data name="AllVaults" xml:space="preserve">
|
||||
<value>Pob cell</value>
|
||||
@@ -2307,7 +2307,7 @@ select Add TOTP to store the key safely</value>
|
||||
<value>We were unable to process your request. Please try again or contact us.</value>
|
||||
</data>
|
||||
<data name="AllowScreenCapture" xml:space="preserve">
|
||||
<value>Allow screen capture</value>
|
||||
<value>Caniatáu sgrinluniau</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Are you sure you want to turn on screen capture?</value>
|
||||
@@ -2316,46 +2316,46 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Login requested</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Are you trying to log in?</value>
|
||||
<value>Ydych chi'n ceisio mewngofnodi?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Login attempt by {0} on {1}</value>
|
||||
<value>Cais mewngofnodi gan {0} ar {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Device type</value>
|
||||
<value>Math o ddyfais</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>Cyfeiriad IP</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Time</value>
|
||||
<value>Amser</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
<value>Gerllaw</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirm login</value>
|
||||
<value>Cadarnhau'r mewngofnodi</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Deny login</value>
|
||||
<value>Gwrthod y mewngofnodi</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Just now</value>
|
||||
<value>Ychydig yn ôl</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minutes ago</value>
|
||||
<value>{0} o funudau yn ôl</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Login confirmed</value>
|
||||
<value>Cadarnhawyd y mewngofnodi</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Login denied</value>
|
||||
<value>Gwrthodwyd y mewngofnodi</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Approve login requests</value>
|
||||
<value>Cymeradwyo ceisiadau mewngofnodi</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use this device to approve login requests made from other devices</value>
|
||||
<value>Defnyddio'r ddyfais hon i gymeradwyo ceisiadau mewngofnodi gan ddyfeisiau eraill</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Caniatáu hysbysiadau</value>
|
||||
@@ -2373,16 +2373,16 @@ select Add TOTP to store the key safely</value>
|
||||
<value>All notifications</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password type</value>
|
||||
<value>Math o gyfrinair</value>
|
||||
</data>
|
||||
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
|
||||
<value>What would you like to generate?</value>
|
||||
<value>Beth hoffech chi ei gynhyrchu?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Math o enw defnyddiwr</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus addressed email</value>
|
||||
<value>Is-gyfeiriad ebost</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all email</value>
|
||||
@@ -2391,13 +2391,13 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Forwarded email alias</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Random word</value>
|
||||
<value>Gair ar hap</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>Email (required)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Domain name (required)</value>
|
||||
<value>Enw parth (gofynnol)</value>
|
||||
</data>
|
||||
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
|
||||
<value>API key (required)</value>
|
||||
@@ -2442,13 +2442,13 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Math o ebost</value>
|
||||
</data>
|
||||
<data name="WebsiteRequired" xml:space="preserve">
|
||||
<value>Website (required)</value>
|
||||
<value>Gwefan (gofynnol)</value>
|
||||
</data>
|
||||
<data name="UnknownXErrorMessage" xml:space="preserve">
|
||||
<value>Unknown {0} error occurred.</value>
|
||||
<value>Bu gwall anhysbys {0}.</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmailDescription" xml:space="preserve">
|
||||
<value>Use your email provider's subaddress capabilities</value>
|
||||
<value>Defnyddio galluoedd is-gyfeirio darparwr eich cyfeiriad ebost ('plus addressing')</value>
|
||||
</data>
|
||||
<data name="CatchAllEmailDescription" xml:space="preserve">
|
||||
<value>Use your domain's configured catch-all inbox.</value>
|
||||
@@ -2457,7 +2457,7 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Generate an email alias with an external forwarding service.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
<value>Hap</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
@@ -2469,10 +2469,10 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accept</value>
|
||||
<value>Derbyn</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Decline</value>
|
||||
<value>Gwrthod</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
@@ -2483,22 +2483,22 @@ select Add TOTP to store the key safely</value>
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Ydych chi'n newydd?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Anfon awgrym o'ch prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="LoggingInAsXOnY" xml:space="preserve">
|
||||
<value>Logging in as {0} on {1}</value>
|
||||
<value>Yn mewngofnodi fel {0} ar {1}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Nid chi?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
<value>Mewngofnodi â'ch prif gyfrinair</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log in with device</value>
|
||||
<value>Mewngofnodi â dyfais</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Login initiated</value>
|
||||
@@ -2513,13 +2513,13 @@ Do you want to switch to this account?</value>
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
<value>Angen opsiwn arall?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
<value>Dyw'r cais hwn ddim yn ddilys bellach</value>
|
||||
</data>
|
||||
<data name="PendingLogInRequests" xml:space="preserve">
|
||||
<value>Pending login requests</value>
|
||||
@@ -2540,13 +2540,13 @@ Do you want to switch to this account?</value>
|
||||
<value>Enable camera permission to use the scanner</value>
|
||||
</data>
|
||||
<data name="Language" xml:space="preserve">
|
||||
<value>Language</value>
|
||||
<value>Iaith</value>
|
||||
</data>
|
||||
<data name="LanguageChangeXDescription" xml:space="preserve">
|
||||
<value>The language has been changed to {0}. Please restart the app to see the change</value>
|
||||
<value>Cafodd yr iaith ei newid i {0}. Ailgychwynnwch yr ap i weld newidiadau</value>
|
||||
</data>
|
||||
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
|
||||
<value>Language change requires app restart</value>
|
||||
<value>Bydd angen ailgychwyn yr ap</value>
|
||||
</data>
|
||||
<data name="DefaultSystem" xml:space="preserve">
|
||||
<value>Default (System)</value>
|
||||
@@ -2573,7 +2573,7 @@ Do you want to switch to this account?</value>
|
||||
<value>Cryf</value>
|
||||
</data>
|
||||
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
|
||||
<value>Check known data breaches for this password</value>
|
||||
<value>Chwilio am achosion o ddatgelu data sy'n cynnwys y cyfrinair hwn</value>
|
||||
</data>
|
||||
<data name="ExposedMasterPassword" xml:space="preserve">
|
||||
<value>Prif gyfrinair wedi'i ddatgelu</value>
|
||||
@@ -2609,7 +2609,7 @@ Do you want to switch to this account?</value>
|
||||
<value>UE</value>
|
||||
</data>
|
||||
<data name="SelfHosted" xml:space="preserve">
|
||||
<value>Hunangynhaliol</value>
|
||||
<value>Gweinydd hunangynhaliol</value>
|
||||
</data>
|
||||
<data name="DataRegion" xml:space="preserve">
|
||||
<value>Lleoliad y data</value>
|
||||
@@ -2639,7 +2639,7 @@ Do you want to switch to this account?</value>
|
||||
<value>Turn off using a public device</value>
|
||||
</data>
|
||||
<data name="RememberThisDevice" xml:space="preserve">
|
||||
<value>Remember this device</value>
|
||||
<value>Cofio'r ddyfais hon</value>
|
||||
</data>
|
||||
<data name="Passkey" xml:space="preserve">
|
||||
<value>Passkey</value>
|
||||
@@ -2690,7 +2690,7 @@ Do you want to switch to this account?</value>
|
||||
<value>Trouble logging in?</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Yn mewngofnodi fel {0}</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutActionChangedToLogOut" xml:space="preserve">
|
||||
<value>Vault timeout action changed to log out</value>
|
||||
@@ -2745,19 +2745,19 @@ Do you want to switch to this account?</value>
|
||||
<value>Log in with device must be set up in the settings of the Bitwarden app. Need another option?</value>
|
||||
</data>
|
||||
<data name="LogInWithDevice" xml:space="preserve">
|
||||
<value>Log in with device</value>
|
||||
<value>Mewngofnodi â dyfais</value>
|
||||
</data>
|
||||
<data name="LoggingInOn" xml:space="preserve">
|
||||
<value>Logging in on</value>
|
||||
<value>Mewngofnodi ar</value>
|
||||
</data>
|
||||
<data name="Vault" xml:space="preserve">
|
||||
<value>Vault</value>
|
||||
<value>Cell</value>
|
||||
</data>
|
||||
<data name="Appearance" xml:space="preserve">
|
||||
<value>Appearance</value>
|
||||
<value>Golwg</value>
|
||||
</data>
|
||||
<data name="AccountSecurity" xml:space="preserve">
|
||||
<value>Account security</value>
|
||||
<value>Diogelwch eich cyfrif</value>
|
||||
</data>
|
||||
<data name="BitwardenHelpCenter" xml:space="preserve">
|
||||
<value>Bitwarden Help Center</value>
|
||||
@@ -2769,10 +2769,10 @@ Do you want to switch to this account?</value>
|
||||
<value>Copy app information</value>
|
||||
</data>
|
||||
<data name="SyncNow" xml:space="preserve">
|
||||
<value>Sync now</value>
|
||||
<value>Cysoni nawr</value>
|
||||
</data>
|
||||
<data name="UnlockOptions" xml:space="preserve">
|
||||
<value>Unlock options</value>
|
||||
<value>Dewisiadau datgloi</value>
|
||||
</data>
|
||||
<data name="SessionTimeout" xml:space="preserve">
|
||||
<value>Session timeout</value>
|
||||
@@ -2806,10 +2806,10 @@ Do you want to switch to this account?</value>
|
||||
<value>Use inline autofill if your selected keyboard supports it. Otherwise, use the default overlay.</value>
|
||||
</data>
|
||||
<data name="AdditionalOptions" xml:space="preserve">
|
||||
<value>Additional options</value>
|
||||
<value>Dewisiadau ychwanegol</value>
|
||||
</data>
|
||||
<data name="ContinueToWebApp" xml:space="preserve">
|
||||
<value>Continue to web app?</value>
|
||||
<value>Parhau i'r ap gwe?</value>
|
||||
</data>
|
||||
<data name="ContinueToX" xml:space="preserve">
|
||||
<value>Continue to {0}?</value>
|
||||
@@ -2821,11 +2821,14 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</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>Gallwch wneud eich cyfrif yn fwy diogel drwy alluogi mewngofnodi dau gam yn ap gwe Bitwarden.</value>
|
||||
</data>
|
||||
<data name="ChangeMasterPasswordDescriptionLong" xml:space="preserve">
|
||||
<value>You can change your master password on the Bitwarden web app.</value>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Vil du skifte til denne konto?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Fortsæt med at kontakte support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Fortsæt til Fortrolighedspolitik?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Fortsæt til app-butik?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Vil du skifte til denne konto?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Kan ikke finde det, der søges efter? Kontakt Bitwarden-supporten via bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Tjek vores Fortrolighedspolitik på bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Tjek flere funktioner ud i Bitwarden-kontoen på web-appen.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@ Möchtest du zu diesem Konto wechseln?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Weiter, um den Support zu kontaktieren?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Weiter zur Datenschutzerklärung?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Weiter zum App Store?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Möchtest du zu diesem Konto wechseln?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Du findest nicht, was du suchst? Kontaktiere den Bitwarden Support auf bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Lies unsere Datenschutzerklärung auf bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Entdecke mehr Funktionen deines Bitwarden-Kontos in der Web-App.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Συνέχεια στην επικοινωνία με την υποστήριξη;</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Συνέχεια στο κατάστημα εφαρμογών;</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Δεν μπορείτε να βρείτε αυτό που ψάχνετε; Επικοινωνήστε με την υποστήριξη Bitwarden στο bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Εξερευνήστε περισσότερες δυνατότητες του Bitwarden λογαριασμού σας, στην εφαρμογή διαδικτύου.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2834,6 +2834,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2853,6 +2856,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2822,6 +2822,9 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>¿Continuar con el servicio de asistencia?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>¿Continuar a la App Store?</value>
|
||||
</data>
|
||||
@@ -2841,6 +2844,9 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>¿No encuentras lo que estás buscando? Contacta con el soporte de Bitwarden en bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explora más características de tu cuenta de Bitwarden en la aplicación web.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Soovid selle konto peale lülituda?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Soovid selle konto peale lülituda?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@ Kontu honetara aldatu nahi duzu?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Kontu honetara aldatu nahi duzu?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>میخواهید با پشتیبانی تماس بگیرید؟</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>به فروشگاه برنامه ادامه میدهید؟</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>چیزی را که به دنبالش هستید پیدا نمیکنید؟ با پشتیبانی Bitwarden در bitwarden.com تماس بگیرید.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>ویژگیهای بیشتر حساب Bitwarden خود را در برنامه وب کاوش کنید.</value>
|
||||
</data>
|
||||
|
||||
@@ -560,7 +560,7 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="LoginOrCreateNewAccount" xml:space="preserve">
|
||||
<value>Kirjaudu tai luo uusi tili käyttääksesi salattua holviasi.</value>
|
||||
<value>Käytä salattua holviasi kirjautumalla sisään tai tai luo uusi tili.</value>
|
||||
</data>
|
||||
<data name="Manage" xml:space="preserve">
|
||||
<value>Hallinta</value>
|
||||
@@ -2821,6 +2821,9 @@ Haluatko vaihtaa tähän tiliin?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Siirrytäänkö asiakaspalveluun?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Jatketaanko tietosuojakäytäntöön?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Avataanko sovelluskauppa?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Haluatko vaihtaa tähän tiliin?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Etkö löydä etsimääsi? Tavoitat Bitwardenin asiakaspalvelun osoitteesta bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Tutustu tietosuojakäytäntöömme osoitteessa bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Tutustu Bitwarden-tilisi muihin omimaisuuksiin verkkosovelluksessa.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Gusto mo bang pumunta sa account na ito?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Gusto mo bang pumunta sa account na ito?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Voulez-vous basculer vers ce compte ?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continuer vers le contact du support ?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Poursuivre vers la politique de confidentialité ?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continuer vers la boutique des applications ?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Voulez-vous basculer vers ce compte ?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Vous ne trouvez pas ce que vous cherchez ? Contactez le support de Bitwarden sur bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Consultez notre politique de confidentialité sur bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explorez plus de fonctionnalités de votre compte Bitwarden sur l'application Web.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2823,6 +2823,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2842,6 +2845,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2818,6 +2818,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Kontaktiraj podršku?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Nastavi u trgovinu aplikacijama?</value>
|
||||
</data>
|
||||
@@ -2837,6 +2840,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Ne možeš naći što te zanima? Kontaktiraj Bitwarden podršku na bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Pronađi viđe značajki svojeg Bitwarden računa u web aplikaciji.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@ Szeretnénk átváltani erre a fiókra?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Tovább az ügyfélszolgálathoz?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Tovább az adatvédelmi szabályzathoz?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Tovább az alkalmazásboltba?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Szeretnénk átváltani erre a fiókra?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Nem találjuk, amit keresünk? Lépjünk kapcsolatba a Bitwarden ügyfélszolgálatával a bitwarden.com oldalon.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Az adatvédelmi szabályzat megtekintése a bitwarden.com webhelyen.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Fedezzük fel a Bitwarden-fiók további funkcióit a webalkalmazásban.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Vuoi passare a questo account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continua per contattare l'assistenza?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continuare alla privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continuare sull'App Store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Vuoi passare a questo account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Non riesci a trovare quello che stai cercando? Contatta il supporto Bitwarden su bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Consulta la nostra privacy policy su bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Esplora altre funzionalità del tuo account Bitwarden sul sito web.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>サポートに連絡しますか?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>プライバシーポリシーを確認しますか?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>アプリストアに進みますか?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>お探しのものが見つかりませんか? bitwarden.com で Bitwarden のサポートにご連絡ください。</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>bitwarden.com でプライバシーポリシーをご覧ください。</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Bitwarden アカウントの機能をウェブアプリでご確認ください。</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Ar norite pereiti prie šios paskyros?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Ar norite pereiti prie šios paskyros?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Vai pārslēgties uz šo kontu?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Pāriet uz sazināšanos ar atbalstu?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Pāriet uz privātuma nosacījumiem?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Pāriet uz lietotņu veikalu?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Vai pārslēgties uz šo kontu?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Meklējamais nav atrodams? Ir iespēja sazināties ar Bitwarden atbalstu bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Mūsu privātuma nosacījumi ir pārskatāmi bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Vairāk sava Bitwarden konta iespēju var izpētīt tīmekļa vietnē.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Vil du bytte til denne kontoen?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Vil du bytte til denne kontoen?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2212,7 +2212,7 @@ Het scannen gebeurt automatisch.</value>
|
||||
<value>Er is een fout opgetreden tijdens het verzenden van een verificatiecode naar je e-mail. Probeer het opnieuw</value>
|
||||
</data>
|
||||
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
|
||||
<value>Voer de verificatiecode in die we naar je e-mail is gestuurd</value>
|
||||
<value>Voer de verificatiecode in die naar je e-mail is gestuurd</value>
|
||||
</data>
|
||||
<data name="SubmitCrashLogs" xml:space="preserve">
|
||||
<value>Crashes rapporteren</value>
|
||||
@@ -2820,6 +2820,9 @@ Wilt u naar dit account wisselen?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Doorgaan met het contact opnemen met support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Doorgaan naar privacybeleid?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Doorgaan naar de app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Wilt u naar dit account wisselen?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Kan je niet vinden wat je zoekt? Neem contact op met Bitwarden-ondersteuning via bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Bekijk ons privacybeleid op bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Ontdek meer functies van je Bitwarden-account in de webapp.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Fortset til personvernerklæringa?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Sjekk ut personvernerklæringa vår på bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Czy chcesz przełączyć się na to konto?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Kontynuować kontakt z pomocą techniczną?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Kontynuować do polityki prywatności?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Kontynuować do sklepu aplikacji?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Czy chcesz przełączyć się na to konto?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Nie możesz znaleźć tego, czego szukasz? Skontaktuj się z pomocą na bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Sprawdź naszą politykę prywatności na bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Odkryj więcej funkcji swojego konta Bitwarden w aplikacji internetowej.</value>
|
||||
</data>
|
||||
|
||||
@@ -2821,6 +2821,9 @@ Você deseja mudar para esta conta?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continuar e contatar o suporte?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continuar para a loja de apps?</value>
|
||||
</data>
|
||||
@@ -2840,6 +2843,9 @@ Você deseja mudar para esta conta?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2819,6 +2819,9 @@ Deseja mudar para esta conta?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continuar a contactar o apoio ao cliente?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continuar para a política de privacidade?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continuar para a loja de aplicações?</value>
|
||||
</data>
|
||||
@@ -2838,6 +2841,9 @@ Deseja mudar para esta conta?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Não consegue encontrar o que está a procurar? Entre em contacto com o suporte da Bitwarden em bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Consulte a nossa política de privacidade em bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore mais funcionalidades da sua conta Bitwarden na aplicação web.</value>
|
||||
</data>
|
||||
|
||||
@@ -2830,6 +2830,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2849,6 +2852,9 @@ Do you want to switch to this account?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
@@ -2820,6 +2820,9 @@ Doriți să comutați la acest cont?</value>
|
||||
<data name="ContinueToContactSupport" xml:space="preserve">
|
||||
<value>Continue to contact support?</value>
|
||||
</data>
|
||||
<data name="ContinueToPrivacyPolicy" xml:space="preserve">
|
||||
<value>Continue to privacy policy?</value>
|
||||
</data>
|
||||
<data name="ContinueToAppStore" xml:space="preserve">
|
||||
<value>Continue to app store?</value>
|
||||
</data>
|
||||
@@ -2839,6 +2842,9 @@ Doriți să comutați la acest cont?</value>
|
||||
<data name="ContactSupportDescriptionLong" xml:space="preserve">
|
||||
<value>Can’t find what you are looking for? Reach out to Bitwarden support on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicyDescriptionLong" xml:space="preserve">
|
||||
<value>Check out our privacy policy on bitwarden.com.</value>
|
||||
</data>
|
||||
<data name="ExploreMoreFeaturesOfYourBitwardenAccountOnTheWebApp" xml:space="preserve">
|
||||
<value>Explore more features of your Bitwarden account on the web app.</value>
|
||||
</data>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user