diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d11fb4dd5..d9594668b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,5 +1,6 @@ --- name: Release +run-name: Release ${{ inputs.release_type }} on: workflow_dispatch: @@ -57,6 +58,7 @@ jobs: echo "::set-output name=branch-name::$BRANCH_NAME" - name: Create GitHub deployment + if: ${{ github.event.inputs.release_type != 'Dry Run' }} uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48 id: deployment with: @@ -75,7 +77,7 @@ jobs: workflow_conclusion: success branch: ${{ steps.branch.outputs.branch-name }} - - name: Download all artifacts + - name: Dry Run - Download all artifacts if: ${{ github.event.inputs.release_type == 'Dry Run' }} uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10 with: @@ -102,7 +104,7 @@ jobs: draft: true - name: Update deployment status to Success - if: ${{ success() }} + if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }} uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86 with: token: '${{ secrets.GITHUB_TOKEN }}' @@ -110,7 +112,7 @@ jobs: deployment-id: ${{ steps.deployment.outputs.deployment_id }} - name: Update deployment status to Failure - if: ${{ failure() }} + if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }} uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86 with: token: '${{ secrets.GITHUB_TOKEN }}' @@ -136,7 +138,7 @@ jobs: branch: ${{ needs.release.outputs.branch-name }} name: ${{ BASE_PKG_NAME }}-fdroid.apk - - name: Download F-Droid .apk artifact + - name: Dry Run - Download F-Droid .apk artifact if: ${{ github.event.inputs.release_type == 'Dry Run' }} uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10 with: diff --git a/src/App/Abstractions/IAccountsManager.cs b/src/App/Abstractions/IAccountsManager.cs index 37acbc1db..532b75958 100644 --- a/src/App/Abstractions/IAccountsManager.cs +++ b/src/App/Abstractions/IAccountsManager.cs @@ -9,5 +9,6 @@ namespace Bit.App.Abstractions void Init(Func getOptionsFunc, IAccountsManagerHost accountsManagerHost); Task NavigateOnAccountChangeAsync(bool? isAuthed = null); Task LogOutAsync(string userId, bool userInitiated, bool expired); + Task PromptToSwitchToExistingAccountAsync(string userId); } } diff --git a/src/App/App.csproj b/src/App/App.csproj index c60580e2d..8dbcc000f 100644 --- a/src/App/App.csproj +++ b/src/App/App.csproj @@ -125,6 +125,9 @@ LoginPasswordlessPage.xaml + + LoginPasswordlessRequestPage.xaml + diff --git a/src/App/App.xaml.cs b/src/App/App.xaml.cs index 5239a278c..4d44dc01c 100644 --- a/src/App/App.xaml.cs +++ b/src/App/App.xaml.cs @@ -145,7 +145,9 @@ namespace Bit.App new NavigationPage(new RemoveMasterPasswordPage())); }); } - else if (message.Command == Constants.PasswordlessLoginRequestKey || message.Command == "unlocked" || message.Command == AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED) + else if (message.Command == Constants.PasswordlessLoginRequestKey + || message.Command == "unlocked" + || message.Command == AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED) { lock (_processingLoginRequestLock) { @@ -202,11 +204,11 @@ namespace Bit.App FingerprintPhrase = loginRequestData.RequestFingerprint, RequestDate = loginRequestData.CreationDate, DeviceType = loginRequestData.RequestDeviceType, - Origin = loginRequestData.Origin, + Origin = loginRequestData.Origin }); await _stateService.SetPasswordlessLoginNotificationAsync(null); _pushNotificationService.DismissLocalNotification(Constants.PasswordlessNotificationId); - if (loginRequestData.CreationDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes) > DateTime.UtcNow) + if (!loginRequestData.IsExpired) { await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page))); } @@ -221,13 +223,20 @@ namespace Bit.App } var notificationUserEmail = await _stateService.GetEmailAsync(notification.UserId); - await Device.InvokeOnMainThreadAsync(async () => + Device.BeginInvokeOnMainThread(async () => { - var result = await _deviceActionService.DisplayAlertAsync(AppResources.LogInRequested, string.Format(AppResources.LoginAttemptFromXDoYouWantToSwitchToThisAccount, notificationUserEmail), AppResources.Cancel, AppResources.Ok); - if (result == AppResources.Ok) + try { - await _stateService.SetActiveUserAsync(notification.UserId); - _messagingService.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT); + var result = await _deviceActionService.DisplayAlertAsync(AppResources.LogInRequested, string.Format(AppResources.LoginAttemptFromXDoYouWantToSwitchToThisAccount, notificationUserEmail), AppResources.Cancel, AppResources.Ok); + if (result == AppResources.Ok) + { + await _stateService.SetActiveUserAsync(notification.UserId); + _messagingService.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT); + } + } + catch (Exception ex) + { + LoggerHelper.LogEvenIfCantBeResolved(ex); } }); return true; @@ -450,7 +459,14 @@ namespace Bit.App switch (navTarget) { case NavigationTarget.HomeLogin: - Current.MainPage = new NavigationPage(new HomePage(Options)); + if (navParams is HomeNavigationParams homeParams) + { + Current.MainPage = new NavigationPage(new HomePage(Options, homeParams.ShouldCheckRememberEmail)); + } + else + { + Current.MainPage = new NavigationPage(new HomePage(Options)); + } break; case NavigationTarget.Login: if (navParams is LoginNavigationParams loginParams) diff --git a/src/App/Controls/IconLabelButton/IconLabelButton.xaml b/src/App/Controls/IconLabelButton/IconLabelButton.xaml index 5b88dcd91..73af0751e 100644 --- a/src/App/Controls/IconLabelButton/IconLabelButton.xaml +++ b/src/App/Controls/IconLabelButton/IconLabelButton.xaml @@ -8,6 +8,7 @@ Padding="1" StyleClass="btn-icon-secondary" BackgroundColor="{Binding IconLabelBorderColor, Source={x:Reference _iconLabelButton}}" + BorderColor="Transparent" HasShadow="False"> @@ -17,6 +18,7 @@ Padding="0" CornerRadius="{Binding CornerRadius, Source={x:Reference _iconLabelButton}}" BackgroundColor="{Binding IconLabelBackgroundColor, Source={x:Reference _iconLabelButton}}" + BorderColor="Transparent" IsClippedToBounds="True" HasShadow="False"> ("broadcasterService"); _appOptions = appOptions; InitializeComponent(); _vm = BindingContext as HomeViewModel; _vm.Page = this; - _vm.CheckHasRememberedEmail = checkRememberedEmail; + _vm.ShouldCheckRememberEmail = shouldCheckRememberEmail; _vm.ShowCancelButton = _appOptions?.IosExtension ?? false; _vm.StartLoginAction = async () => await StartLoginAsync(); _vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync()); @@ -59,7 +59,7 @@ namespace Bit.App.Pages if (!_appOptions?.HideAccountSwitcher ?? false) { - _vm.AvatarImageSource = await GetAvatarImageSourceAsync(); + _vm.AvatarImageSource = await GetAvatarImageSourceAsync(false); } _broadcasterService.Subscribe(nameof(HomePage), (message) => { diff --git a/src/App/Pages/Accounts/HomePageViewModel.cs b/src/App/Pages/Accounts/HomePageViewModel.cs index 1b014c2d2..26a4c334e 100644 --- a/src/App/Pages/Accounts/HomePageViewModel.cs +++ b/src/App/Pages/Accounts/HomePageViewModel.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Bit.App.Abstractions; using Bit.App.Controls; using Bit.App.Resources; using Bit.App.Utilities; @@ -24,13 +25,17 @@ namespace Bit.App.Pages private bool _canLogin; private IPlatformUtilsService _platformUtilsService; private ILogger _logger; + private IEnvironmentService _environmentService; + private IAccountsManager _accountManager; public HomeViewModel() { - _stateService = ServiceContainer.Resolve("stateService"); - _messagingService = ServiceContainer.Resolve("messagingService"); + _stateService = ServiceContainer.Resolve(); + _messagingService = ServiceContainer.Resolve(); _platformUtilsService = ServiceContainer.Resolve(); - _logger = ServiceContainer.Resolve("logger"); + _logger = ServiceContainer.Resolve(); + _environmentService = ServiceContainer.Resolve(); + _accountManager = ServiceContainer.Resolve(); PageTitle = AppResources.Bitwarden; @@ -68,7 +73,7 @@ namespace Bit.App.Pages public bool CanContinue => !string.IsNullOrEmpty(Email); - public bool CheckHasRememberedEmail { get; set; } + public bool ShouldCheckRememberEmail { get; set; } public FormattedString CreateAccountText { @@ -107,11 +112,11 @@ namespace Bit.App.Pages public void CheckNavigateLoginStep() { - if (CheckHasRememberedEmail && RememberEmail) + if (ShouldCheckRememberEmail && RememberEmail) { StartLoginAction(); } - CheckHasRememberedEmail = false; + ShouldCheckRememberEmail = false; } public async Task ContinueToLoginStepAsync() @@ -132,6 +137,16 @@ namespace Bit.App.Pages return; } await _stateService.SetRememberedEmailAsync(RememberEmail ? Email : null); + var userId = await _stateService.GetUserIdAsync(Email); + if (!string.IsNullOrWhiteSpace(userId)) + { + var userEnvUrls = await _stateService.GetEnvironmentUrlsAsync(userId); + if (userEnvUrls?.Base == _environmentService.BaseUrl) + { + await _accountManager.PromptToSwitchToExistingAccountAsync(userId); + return; + } + } StartLoginAction(); } catch (Exception ex) diff --git a/src/App/Pages/Accounts/LoginPage.xaml b/src/App/Pages/Accounts/LoginPage.xaml index 11ea61e99..aa23b782b 100644 --- a/src/App/Pages/Accounts/LoginPage.xaml +++ b/src/App/Pages/Accounts/LoginPage.xaml @@ -110,8 +110,8 @@ VerticalOptions="CenterAndExpand" Icon="{Binding Source={x:Static core:BitwardenIcons.Device}}" Label="{u:I18n LogInWithAnotherDevice}" - ButtonCommand="{Binding LogInCommand}" - IsVisible="False"/> + ButtonCommand="{Binding LogInWithDeviceCommand}" + IsVisible="{Binding IsKnownDevice}"/> Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync()); _vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync()); + _vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget(); _vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync()); - _vm.UpdateTempPasswordAction = - () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync()); + _vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync()); _vm.CloseAction = async () => { await _accountListOverlay.HideAsync(); @@ -53,11 +54,6 @@ namespace Bit.App.Pages ToolbarItems.Add(_getPasswordHint); } - if (Device.RuntimePlatform == Device.Android && !_vm.IsEmailEnabled) - { - ToolbarItems.Add(_removeAccount); - } - if (_appOptions?.IosExtension ?? false) { _vm.ShowCancelButton = true; @@ -77,16 +73,20 @@ namespace Bit.App.Pages _mainContent.Content = _mainLayout; _accountAvatar?.OnAppearing(); + await _vm.InitAsync(); if (!_appOptions?.HideAccountSwitcher ?? false) { - _vm.AvatarImageSource = await GetAvatarImageSourceAsync(); + _vm.AvatarImageSource = await GetAvatarImageSourceAsync(_vm.EmailIsInSavedAccounts); } - await _vm.InitAsync(); if (!_inputFocused) { RequestFocus(_masterPassword); _inputFocused = true; } + if (Device.RuntimePlatform == Device.Android && !_vm.CanRemoveAccount) + { + ToolbarItems.Add(_removeAccount); + } } protected override bool OnBackButtonPressed() @@ -122,6 +122,12 @@ namespace Bit.App.Pages } } + private async Task StartLoginWithDeviceAsync() + { + var page = new LoginPasswordlessRequestPage(_vm.Email, _appOptions); + await Navigation.PushModalAsync(new NavigationPage(page)); + } + private async Task StartSsoLoginAsync() { var page = new LoginSsoPage(_appOptions); diff --git a/src/App/Pages/Accounts/LoginPageViewModel.cs b/src/App/Pages/Accounts/LoginPageViewModel.cs index 9377daae5..40d928c78 100644 --- a/src/App/Pages/Accounts/LoginPageViewModel.cs +++ b/src/App/Pages/Accounts/LoginPageViewModel.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using Bit.App.Abstractions; @@ -6,9 +8,11 @@ using Bit.App.Controls; using Bit.App.Models; using Bit.App.Resources; using Bit.App.Utilities; +using Bit.App.Utilities.AccountManagement; using Bit.Core; using Bit.Core.Abstractions; using Bit.Core.Exceptions; +using Bit.Core.Models.View; using Bit.Core.Services; using Bit.Core.Utilities; using Xamarin.CommunityToolkit.ObjectModel; @@ -29,6 +33,7 @@ namespace Bit.App.Pages private readonly ILogger _logger; private readonly IApiService _apiService; private readonly IAppIdService _appIdService; + private readonly IAccountsManager _accountManager; private bool _showPassword; private bool _showCancelButton; private string _email; @@ -49,11 +54,13 @@ namespace Bit.App.Pages _logger = ServiceContainer.Resolve("logger"); _apiService = ServiceContainer.Resolve(); _appIdService = ServiceContainer.Resolve(); + _accountManager = ServiceContainer.Resolve(); PageTitle = AppResources.Bitwarden; TogglePasswordCommand = new Command(TogglePassword); LogInCommand = new Command(async () => await LogInAsync()); MoreCommand = new AsyncCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false); + LogInWithDeviceCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithDeviceAction), onException: _logger.Exception, allowsMultipleExecutions: false); AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger) { @@ -107,22 +114,25 @@ namespace Bit.App.Pages set => SetProperty(ref _isKnownDevice, value); } - public bool IsIosExtension { get; set; } - public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; } - public Command LogInCommand { get; } public Command TogglePasswordCommand { get; } public ICommand MoreCommand { get; internal set; } + public ICommand LogInWithDeviceCommand { get; } public string ShowPasswordIcon => ShowPassword ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye; public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow; public string LoggingInAsText => string.Format(AppResources.LoggingInAsX, Email); + public bool IsIosExtension { get; set; } + public bool CanRemoveAccount { get; set; } public Action StartTwoFactorAction { get; set; } public Action LogInSuccessAction { get; set; } + public Action LogInWithDeviceAction { get; set; } public Action UpdateTempPasswordAction { get; set; } public Action StartSsoLoginAction { get; set; } public Action CloseAction { get; set; } + public bool EmailIsInSavedAccounts => _stateService.AccountViews != null && _stateService.AccountViews.Any(e => e.Email == Email); + protected override II18nService i18nService => _i18nService; protected override IEnvironmentService environmentService => _environmentService; protected override IDeviceActionService deviceActionService => _deviceActionService; @@ -130,14 +140,23 @@ namespace Bit.App.Pages public async Task InitAsync() { - await _deviceActionService.ShowLoadingAsync(AppResources.Loading); - if (string.IsNullOrWhiteSpace(Email)) + try { - Email = await _stateService.GetRememberedEmailAsync(); + await _deviceActionService.ShowLoadingAsync(AppResources.Loading); + await AccountSwitchingOverlayViewModel.RefreshAccountViewsAsync(); + if (string.IsNullOrWhiteSpace(Email)) + { + Email = await _stateService.GetRememberedEmailAsync(); + } + var deviceIdentifier = await _appIdService.GetAppIdAsync(); + IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier); + CanRemoveAccount = await _stateService.GetActiveUserEmailAsync() != Email; + await _deviceActionService.HideLoadingAsync(); + } + catch (Exception ex) + { + HandleException(ex); } - var deviceIdentifier = await _appIdService.GetAppIdAsync(); - IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier); - await _deviceActionService.HideLoadingAsync(); } public async Task LogInAsync(bool showLoading = true, bool checkForExistingAccount = false) @@ -180,7 +199,7 @@ namespace Bit.App.Pages var userEnvUrls = await _stateService.GetEnvironmentUrlsAsync(userId); if (userEnvUrls?.Base == _environmentService.BaseUrl) { - await PromptToSwitchToExistingAccountAsync(userId); + await _accountManager.PromptToSwitchToExistingAccountAsync(userId); return; } } @@ -237,7 +256,7 @@ namespace Bit.App.Pages private async Task MoreAsync() { - var buttons = IsEmailEnabled + var buttons = IsEmailEnabled || CanRemoveAccount ? new[] { AppResources.GetPasswordHint } : new[] { AppResources.GetPasswordHint, AppResources.RemoveAccount }; var selection = await _deviceActionService.DisplayActionSheetAsync(AppResources.Options, AppResources.Cancel, null, buttons); @@ -287,16 +306,14 @@ namespace Bit.App.Pages } } - private async Task PromptToSwitchToExistingAccountAsync(string userId) + private void HandleException(Exception ex) { - var switchToAccount = await _platformUtilsService.ShowDialogAsync( - AppResources.SwitchToAlreadyAddedAccountConfirmation, - AppResources.AccountAlreadyAdded, AppResources.Yes, AppResources.Cancel); - if (switchToAccount) + Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () => { - await _stateService.SetActiveUserAsync(userId); - _messagingService.Send("switchedAccount"); - } + await _deviceActionService.HideLoadingAsync(); + await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage); + }).FireAndForget(); + _logger.Exception(ex); } } } diff --git a/src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml b/src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml new file mode 100644 index 000000000..d6ea864f0 --- /dev/null +++ b/src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + diff --git a/src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs b/src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs new file mode 100644 index 000000000..383161c7c --- /dev/null +++ b/src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Bit.App.Models; +using Bit.App.Utilities; +using Xamarin.Forms; + +namespace Bit.App.Pages +{ + public partial class LoginPasswordlessRequestPage : BaseContentPage + { + private LoginPasswordlessRequestViewModel _vm; + private readonly AppOptions _appOptions; + + public LoginPasswordlessRequestPage(string email, AppOptions appOptions = null) + { + InitializeComponent(); + _appOptions = appOptions; + _vm = BindingContext as LoginPasswordlessRequestViewModel; + _vm.Page = this; + _vm.Email = email; + _vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync()); + _vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync()); + _vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync()); + _vm.CloseAction = () => { Navigation.PopModalAsync(); }; + + _vm.CreatePasswordlessLoginCommand.Execute(null); + } + + protected override void OnAppearing() + { + base.OnAppearing(); + _vm.StartCheckLoginRequestStatus(); + } + + protected override void OnDisappearing() + { + base.OnDisappearing(); + _vm.StopCheckLoginRequestStatus(); + } + + private async Task StartTwoFactorAsync() + { + var page = new TwoFactorPage(false, _appOptions); + await Navigation.PushModalAsync(new NavigationPage(page)); + } + + private async Task LogInSuccessAsync() + { + if (AppHelpers.SetAlternateMainPage(_appOptions)) + { + return; + } + var previousPage = await AppHelpers.ClearPreviousPage(); + Application.Current.MainPage = new TabsPage(_appOptions, previousPage); + } + + private async Task UpdateTempPasswordAsync() + { + var page = new UpdateTempPasswordPage(); + await Navigation.PushModalAsync(new NavigationPage(page)); + } + } +} + diff --git a/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs b/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs new file mode 100644 index 000000000..df8fce7dd --- /dev/null +++ b/src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Input; +using Bit.App.Abstractions; +using Bit.App.Resources; +using Bit.App.Utilities; +using Bit.Core; +using Bit.Core.Abstractions; +using Bit.Core.Enums; +using Bit.Core.Models.Domain; +using Bit.Core.Services; +using Bit.Core.Utilities; +using Xamarin.CommunityToolkit.ObjectModel; +using Xamarin.Essentials; +using Xamarin.Forms; + +namespace Bit.App.Pages +{ + public class LoginPasswordlessRequestViewModel : CaptchaProtectedViewModel + { + private const int REQUEST_TIME_UPDATE_PERIOD_IN_SECONDS = 4; + + private IDeviceActionService _deviceActionService; + private IAuthService _authService; + private ISyncService _syncService; + private II18nService _i18nService; + private IStateService _stateService; + private IPlatformUtilsService _platformUtilsService; + private IEnvironmentService _environmentService; + private ILogger _logger; + + protected override II18nService i18nService => _i18nService; + protected override IEnvironmentService environmentService => _environmentService; + protected override IDeviceActionService deviceActionService => _deviceActionService; + protected override IPlatformUtilsService platformUtilsService => _platformUtilsService; + + private CancellationTokenSource _checkLoginRequestStatusCts; + private Task _checkLoginRequestStatusTask; + private string _fingerprintPhrase; + private string _email; + private string _requestId; + private string _requestAccessCode; + // Item1 publicKey, Item2 privateKey + private Tuple _requestKeyPair; + + public LoginPasswordlessRequestViewModel() + { + _deviceActionService = ServiceContainer.Resolve(); + _platformUtilsService = ServiceContainer.Resolve(); + _environmentService = ServiceContainer.Resolve(); + _authService = ServiceContainer.Resolve(); + _syncService = ServiceContainer.Resolve(); + _i18nService = ServiceContainer.Resolve(); + _stateService = ServiceContainer.Resolve(); + _logger = ServiceContainer.Resolve(); + + PageTitle = AppResources.LogInWithAnotherDevice; + + CreatePasswordlessLoginCommand = new AsyncCommand(CreatePasswordlessLoginAsync, + onException: ex => HandleException(ex), + allowsMultipleExecutions: false); + + CloseCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(CloseAction), + onException: _logger.Exception, + allowsMultipleExecutions: false); + } + + public Action StartTwoFactorAction { get; set; } + public Action LogInSuccessAction { get; set; } + public Action UpdateTempPasswordAction { get; set; } + public Action CloseAction { get; set; } + + public ICommand CreatePasswordlessLoginCommand { get; } + public ICommand CloseCommand { get; } + + public string FingerprintPhrase + { + get => _fingerprintPhrase; + set => SetProperty(ref _fingerprintPhrase, value); + } + + public string Email + { + get => _email; + set => SetProperty(ref _email, value); + } + + public void StartCheckLoginRequestStatus() + { + try + { + _checkLoginRequestStatusCts?.Cancel(); + _checkLoginRequestStatusCts = new CancellationTokenSource(); + _checkLoginRequestStatusTask = new TimerTask(_logger, CheckLoginRequestStatus, _checkLoginRequestStatusCts).RunPeriodic(TimeSpan.FromSeconds(REQUEST_TIME_UPDATE_PERIOD_IN_SECONDS)); + } + catch (Exception ex) + { + _logger.Exception(ex); + } + } + + public void StopCheckLoginRequestStatus() + { + try + { + _checkLoginRequestStatusCts?.Cancel(); + _checkLoginRequestStatusCts?.Dispose(); + _checkLoginRequestStatusCts = null; + } + catch (Exception ex) + { + _logger.Exception(ex); + } + } + + private async Task CheckLoginRequestStatus() + { + if (string.IsNullOrEmpty(_requestId) || string.IsNullOrEmpty(_requestAccessCode)) + { + return; + } + + try + { + var response = await _authService.GetPasswordlessLoginResponseAsync(_requestId, _requestAccessCode); + + if (response.RequestApproved == null || !response.RequestApproved.Value) + { + return; + } + + StopCheckLoginRequestStatus(); + + var authResult = await _authService.LogInPasswordlessAsync(Email, _requestAccessCode, _requestId, _requestKeyPair.Item2, response.Key, response.MasterPasswordHash); + await AppHelpers.ResetInvalidUnlockAttemptsAsync(); + + if (await HandleCaptchaAsync(authResult.CaptchaSiteKey, authResult.CaptchaNeeded, CheckLoginRequestStatus)) + { + return; + } + + if (authResult.TwoFactor) + { + StartTwoFactorAction?.Invoke(); + } + else if (authResult.ForcePasswordReset) + { + UpdateTempPasswordAction?.Invoke(); + } + else + { + _syncService.FullSyncAsync(true).FireAndForget(); + LogInSuccessAction?.Invoke(); + } + } + catch (Exception ex) + { + StartCheckLoginRequestStatus(); + HandleException(ex); + } + } + + private async Task CreatePasswordlessLoginAsync() + { + await Device.InvokeOnMainThreadAsync(() => _deviceActionService.ShowLoadingAsync(AppResources.Loading)); + + var response = await _authService.PasswordlessCreateLoginRequestAsync(_email); + if (response != null) + { + FingerprintPhrase = response.RequestFingerprint; + _requestId = response.Id; + _requestAccessCode = response.RequestAccessCode; + _requestKeyPair = response.RequestKeyPair; + } + + await _deviceActionService.HideLoadingAsync(); + } + + private void HandleException(Exception ex) + { + Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () => + { + await _deviceActionService.HideLoadingAsync(); + await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage); + }).FireAndForget(); + _logger.Exception(ex); + } + } +} + diff --git a/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs b/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs index 1ca09b540..ced68d7b7 100644 --- a/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs +++ b/src/App/Pages/Accounts/LoginPasswordlessViewModel.cs @@ -100,7 +100,7 @@ namespace Bit.App.Pages private async Task UpdateRequestTime() { TriggerPropertyChanged(nameof(TimeOfRequestText)); - if (DateTime.UtcNow > LoginRequest?.RequestDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes)) + if (LoginRequest?.IsExpired ?? false) { StopRequestTimeUpdater(); await _platformUtilsService.ShowDialogAsync(AppResources.LoginRequestHasAlreadyExpired); @@ -110,13 +110,21 @@ namespace Bit.App.Pages private async Task PasswordlessLoginAsync(bool approveRequest) { - if (LoginRequest.RequestDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes) <= DateTime.UtcNow) + if (LoginRequest.IsExpired) { await _platformUtilsService.ShowDialogAsync(AppResources.LoginRequestHasAlreadyExpired); await Page.Navigation.PopModalAsync(); return; } + var loginRequestData = await _authService.GetPasswordlessLoginRequestByIdAsync(LoginRequest.Id); + if (loginRequestData.RequestApproved.HasValue && loginRequestData.ResponseDate.HasValue) + { + await _platformUtilsService.ShowDialogAsync(AppResources.ThisRequestIsNoLongerValid); + await Page.Navigation.PopModalAsync(); + return; + } + await _deviceActionService.ShowLoadingAsync(AppResources.Loading); await _authService.PasswordlessLoginAsync(LoginRequest.Id, LoginRequest.PubKey, approveRequest); await _deviceActionService.HideLoadingAsync(); @@ -171,5 +179,7 @@ namespace Bit.App.Pages public string DeviceType { get; set; } public string IpAddress { get; set; } + + public bool IsExpired => RequestDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes) < DateTime.UtcNow; } } diff --git a/src/App/Pages/CaptchaProtectedViewModel.cs b/src/App/Pages/CaptchaProtectedViewModel.cs index 042d1423c..2f9969080 100644 --- a/src/App/Pages/CaptchaProtectedViewModel.cs +++ b/src/App/Pages/CaptchaProtectedViewModel.cs @@ -16,6 +16,22 @@ namespace Bit.App.Pages protected abstract IPlatformUtilsService platformUtilsService { get; } protected string _captchaToken = null; + protected async Task HandleCaptchaAsync(string captchaSiteKey, bool needsCaptcha, Func onSuccess) + { + if (!needsCaptcha) + { + _captchaToken = null; + return false; + } + + if (await HandleCaptchaAsync(captchaSiteKey)) + { + await onSuccess(); + _captchaToken = null; + } + return true; + } + protected async Task HandleCaptchaAsync(string CaptchaSiteKey) { var callbackUri = "bitwarden://captcha-callback"; diff --git a/src/App/Pages/Settings/SyncPageViewModel.cs b/src/App/Pages/Settings/SyncPageViewModel.cs index 7aade221b..a98e12617 100644 --- a/src/App/Pages/Settings/SyncPageViewModel.cs +++ b/src/App/Pages/Settings/SyncPageViewModel.cs @@ -90,6 +90,7 @@ namespace Bit.App.Pages try { await _deviceActionService.ShowLoadingAsync(AppResources.Syncing); + await _syncService.SyncPasswordlessLoginRequestsAsync(); var success = await _syncService.FullSyncAsync(true); await _deviceActionService.HideLoadingAsync(); if (success) diff --git a/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs b/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs index 45014b262..36b7d71da 100644 --- a/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs +++ b/src/App/Pages/Vault/GroupingsPage/GroupingsPageViewModel.cs @@ -189,6 +189,7 @@ namespace Bit.App.Pages if (await _stateService.GetSyncOnRefreshAsync() && Refreshing && !SyncRefreshing) { SyncRefreshing = true; + await _syncService.SyncPasswordlessLoginRequestsAsync(); await _syncService.FullSyncAsync(false); return; } diff --git a/src/App/Resources/AppResources.Designer.cs b/src/App/Resources/AppResources.Designer.cs index a98953e55..ff83de8a7 100644 --- a/src/App/Resources/AppResources.Designer.cs +++ b/src/App/Resources/AppResources.Designer.cs @@ -481,6 +481,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to A notification has been sent to your device.. + /// + public static string ANotificationHasBeenSentToYourDevice { + get { + return ResourceManager.GetString("ANotificationHasBeenSentToYourDevice", resourceCulture); + } + } + /// /// Looks up a localized string similar to API access token. /// @@ -3480,6 +3489,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Log in initiated. + /// + public static string LogInInitiated { + get { + return ResourceManager.GetString("LogInInitiated", resourceCulture); + } + } + /// /// Looks up a localized string similar to Login. /// @@ -3966,6 +3984,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Need another option?. + /// + public static string NeedAnotherOption { + get { + return ResourceManager.GetString("NeedAnotherOption", resourceCulture); + } + } + /// /// Looks up a localized string similar to Never. /// @@ -4705,6 +4732,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.. + /// + public static string PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice { + get { + return ResourceManager.GetString("PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice", resourceCulture); + } + } + /// /// Looks up a localized string similar to Plus addressed email. /// @@ -5003,6 +5039,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to Resend notification. + /// + public static string ResendNotification { + get { + return ResourceManager.GetString("ResendNotification", resourceCulture); + } + } + /// /// Looks up a localized string similar to This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password.. /// @@ -5831,6 +5876,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to This request is no longer valid. + /// + public static string ThisRequestIsNoLongerValid { + get { + return ResourceManager.GetString("ThisRequestIsNoLongerValid", resourceCulture); + } + } + /// /// Looks up a localized string similar to 3 days. /// @@ -6542,6 +6596,15 @@ namespace Bit.App.Resources { } } + /// + /// Looks up a localized string similar to View all log in options. + /// + public static string ViewAllLoginOptions { + get { + return ResourceManager.GetString("ViewAllLoginOptions", resourceCulture); + } + } + /// /// Looks up a localized string similar to View item. /// diff --git a/src/App/Resources/AppResources.af.resx b/src/App/Resources/AppResources.af.resx index 8ef6bb473..4a2cea9c8 100644 --- a/src/App/Resources/AppResources.af.resx +++ b/src/App/Resources/AppResources.af.resx @@ -2472,4 +2472,43 @@ kies u Voeg TOTP toe om die sleutel veilig te bewaar {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.ar.resx b/src/App/Resources/AppResources.ar.resx index 5bbf39b9f..9b6f10574 100644 --- a/src/App/Resources/AppResources.ar.resx +++ b/src/App/Resources/AppResources.ar.resx @@ -2473,4 +2473,43 @@ {0} هل تريد التبديل إلى هذا الحساب؟ + + جديد هنا؟ + + + احصل على تلميح كلمة المرور الرئيسية + + + تسجيل الدخول كـ {0} + + + ليس أنت؟ + + + تسجيل الدخول باستخدام كلمة المرور الرئيسية + + + تسجيل الدخول باستخدام جهاز آخر + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.az.resx b/src/App/Resources/AppResources.az.resx index 2e830fb5a..51cb85386 100644 --- a/src/App/Resources/AppResources.az.resx +++ b/src/App/Resources/AppResources.az.resx @@ -2471,4 +2471,43 @@ Skan prosesi avtomatik baş tutacaq. {0} Bu hesaba keçmək istəyirsiniz? + + Burada yenisiniz? + + + Ana parol üçün məsləhət alın + + + {0} olaraq giriş edilir + + + Siz deyilsiniz? + + + Ana parolla giriş et + + + Başqa cihazla giriş et + + + Giriş etmə başladıldı + + + Cihazınıza bir bildiriş göndərildi. + + + Zəhmət olmasa anbarınızın kilidinin açıq olduğuna və Barmaq izi ifadəsinin digər cihazda uyğun gəldiyinə əmin olun. + + + Bildirişi təkrar göndər + + + Başqa bir seçimə ehtiyacınız var? + + + Bütün giriş etmə seçimlərinə bax + + + Bu tələb artıq yararsızdır + diff --git a/src/App/Resources/AppResources.be.resx b/src/App/Resources/AppResources.be.resx index c07f83b83..e1d650a1f 100644 --- a/src/App/Resources/AppResources.be.resx +++ b/src/App/Resources/AppResources.be.resx @@ -349,7 +349,7 @@ Адправіць - Сінхранізавана + Сінхранізаваць The title for the sync page. @@ -1622,7 +1622,7 @@ Біяметрычныя праверка - Біяметрыяй + біяметрыяй Выкарыстоўваць біяметрычныя даныя для разблакіроўкі @@ -2472,4 +2472,43 @@ {0} Вы сапраўды хочаце перайсці на гэты ўліковы запіс? + + Упершыню тут? + + + Атрымаць падказку да асноўнага пароля + + + Увайсці як {0} + + + Не вы? + + + Увайсці з асноўным паролем + + + Увайсці з іншай прылады + + + Ініцыяваны ўваход + + + Апавяшчэнне было адпраўлена на вашу прыладу. + + + Пераканайцеся, што ваша сховішча разблакіравана, а фраза адбітка пальца супадае з іншай прыладай. + + + Адправіць апавяшчэнне паўторна + + + Неабходны іншы варыянт? + + + Паглядзець усе варыянты ўваходу + + + Гэты запыт больш не дзейнічае + diff --git a/src/App/Resources/AppResources.bg.resx b/src/App/Resources/AppResources.bg.resx index 13f76e732..09b53472a 100644 --- a/src/App/Resources/AppResources.bg.resx +++ b/src/App/Resources/AppResources.bg.resx @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Искате ли да превключите към тази регистрация? + + За пръв път ли сте тук? + + + Получете подсказване за главната парола + + + Вписване като {0} + + + Това не сте Вие? + + + Вписване с главната парола + + + Вписване с друго устройство + + + Вписването е стартирано + + + Към устройството Ви е изпратено известие. + + + Уверете се, че трезорът Ви е отключен и че Уникалната фраза съвпада с другото устройство. + + + Повторно изпращане на известието + + + Предпочитате друг вариант? + + + Вижте всички възможности за вписване + + + Тази зявка вече не е приложима + diff --git a/src/App/Resources/AppResources.bn.resx b/src/App/Resources/AppResources.bn.resx index 389853b34..cd0586d38 100644 --- a/src/App/Resources/AppResources.bn.resx +++ b/src/App/Resources/AppResources.bn.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.bs.resx b/src/App/Resources/AppResources.bs.resx index 4ba289645..27ee4e83c 100644 --- a/src/App/Resources/AppResources.bs.resx +++ b/src/App/Resources/AppResources.bs.resx @@ -2472,4 +2472,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.ca.resx b/src/App/Resources/AppResources.ca.resx index df1bc3087..e05da0313 100644 --- a/src/App/Resources/AppResources.ca.resx +++ b/src/App/Resources/AppResources.ca.resx @@ -2472,4 +2472,43 @@ seleccioneu Afegeix TOTP per emmagatzemar la clau de manera segura {0} Voleu canviar a aquest compte? + + Nou per ací? + + + Obteniu la pista de la contrasenya mestra + + + Connectat com {0} + + + No sou vosaltres? + + + Inicia sessió amb la contrasenya mestra + + + Inicia sessió amb un altre dispositiu + + + S'ha iniciat la sessió + + + S'ha enviat una notificació al vostre dispositiu. + + + Assegureu-vos que la vostra caixa forta estiga desbloquejada i que la frase d'empremta digital coincidisca amb l'altre dispositiu. + + + Torna a enviar la notificació + + + Necessiteu una altra opció? + + + Veure totes les opcions d'inici de sessió + + + Aquesta sol·licitud ja no és vàlida + diff --git a/src/App/Resources/AppResources.cs.resx b/src/App/Resources/AppResources.cs.resx index 3185dbb1d..e073ed871 100644 --- a/src/App/Resources/AppResources.cs.resx +++ b/src/App/Resources/AppResources.cs.resx @@ -1457,11 +1457,11 @@ Načtení proběhne automaticky. Nejsou k dispozici žádné složky k zobrazení. - Fráze otisku prstu + Fráze otisku účtu A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing. - Fráze otisku prstu vašeho účtu + Fráze otisku vašeho účtu A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing. @@ -2468,8 +2468,47 @@ select Add TOTP to store the key safely Požadavek na přihlášení již vypršel. - Login attempt from: + Pokus o přihlášení z: {0} -Do you want to switch to this account? +Chcete se přepnout na tento účet? + + + Jste tu noví? + + + Získat nápovědu pro hlavní heslo + + + Přihlášování jako {0} + + + Nejste to vy? + + + Přihlásit se pomocí hlavního hesla + + + Přihlásit se pomocí jiného zařízení + + + Přihlášení zahájeno + + + Na vaše zařízení bylo odesláno oznámení. + + + Ujistěte se, že je váš trezor odemčen a fráze otisku prstu se shodují s druhým zařízením. + + + Odeslat oznámení znovu + + + Potřebujete jinou možnost? + + + Zobrazit všechny možnosti přihlášení + + + Tento požadavek již není platný diff --git a/src/App/Resources/AppResources.da.resx b/src/App/Resources/AppResources.da.resx index 866cd7997..9f4cbb8aa 100644 --- a/src/App/Resources/AppResources.da.resx +++ b/src/App/Resources/AppResources.da.resx @@ -2472,4 +2472,43 @@ vælg Tilføj TOTP for at gemme nøglen sikkert {0} Vil du skifte til denne konto? + + Ny her? + + + Få hovedadgangskodetip + + + Logger ind som {0} + + + Ikke dig? + + + Log ind med hovedadgangskoden + + + Log ind med en anden enhed + + + Indlogning påbegyndt + + + En notifikation er sendt til din enhed. + + + Sørg for, at din boks er oplåst, samt at Fingeraftrykssætningen på den anden enhed matcher. + + + Gensend notifikation + + + Behov for en anden mulighed? + + + Vis alle indlogningsmuligheder + + + Anmodningen er ikke længere gyldig + diff --git a/src/App/Resources/AppResources.de.resx b/src/App/Resources/AppResources.de.resx index 93ea6cc5f..caa432eab 100644 --- a/src/App/Resources/AppResources.de.resx +++ b/src/App/Resources/AppResources.de.resx @@ -229,7 +229,7 @@ Ordner - Ordner wurde aktualisiert + Ordner aktualisiert Webseite besuchen @@ -342,7 +342,7 @@ Reveal a hidden value (password). - Eintrag wurde gelöscht + Eintrag gelöscht Confirmation message after successfully deleting a login. @@ -416,7 +416,7 @@ Neuer Eintrag - App Erweiterung + App-Erweiterung Verwende den Bitwarden Dienst in den Bedienungshilfen, um deine Zugangsdaten in Apps und im Web automatisch ausfüllen zu lassen. @@ -428,7 +428,7 @@ Mehrdeutige Zeichen vermeiden - Bitwarden App Erweiterung + Bitwarden App-Erweiterung Die einfachste Möglichkeit, neue Anmeldedaten zu Ihrem Tresor hinzuzufügen, ist die Bitwarden App Erweiterung. Erfahren Sie mehr über die Bitwarden App Erweiterung, indem Sie zu dem "Einstellungen"-Bildschirm navigieren. @@ -477,13 +477,13 @@ Gebe die E-Mail Adresse deines Kontos ein, um den Hinweis für dein Master-Passwort zu erhalten. - App Erweiterung wieder aktivieren + App-Erweiterung wieder aktivieren Fast geschafft! - App Erweiterung aktivieren + App-Erweiterung aktivieren In Safari findest du Bitwarden unter dem Teilen-Symbol (Hinweis: scrolle auf der untersten Zeile des Menüs nach rechts). @@ -647,7 +647,7 @@ Bist du sicher, dass du das aktuelle Passwort überschreiben möchtest? - Bitwarden aktualisiert deinen Tresor mit Pushbenachrichtigungen. Für die bestmögliche Benutzererfahrung tippe im folgenden Dialogfenster auf "Ok", um Pushbenachrichtigungen zu aktivieren. + Bitwarden aktualisiert deinen Tresor mit Push-Benachrichtigungen. Für die bestmögliche Benutzererfahrung tippe im folgenden Dialogfenster auf "Ok", um Push-Benachrichtigungen zu aktivieren. Push notifications for apple products @@ -705,10 +705,10 @@ What Apple calls their fingerprint reader. - Zwei-Faktor Authentifizierung + Zwei-Faktor-Authentifizierung - Mit der Zwei-Faktor Authentifizierung wird dein Account zusätzlich abgesichert, da jede Anmeldung durch einen Sicherheitscode, eine Authentifizierungs-App, SMS, einen Anruf oder eine E-Mail verifiziert werden muss. Die Zwei-Faktor Authentifizierung kann im Bitwarden.com Web-Tresor aktiviert werden. Möchtest du die Seite jetzt öffnen? + Mit der Zwei-Faktor-Authentifizierung wird dein Account zusätzlich abgesichert, da jede Anmeldung durch einen Sicherheitscode, eine Authentifizierungs-App, SMS, einen Anruf oder eine E-Mail verifiziert werden muss. Die Zwei-Faktor-Authentifizierung kann im Web-Tresor unter bitwarden.com aktiviert werden. Möchtest du die Seite jetzt öffnen? Mit {0} entsperren @@ -831,7 +831,7 @@ For 2FA whenever there are no available providers on this device. - Dieses Konto hat eine aktive Zwei-Faktor Authentifizierung, allerdings wird keiner der konfigurierten Zwei-Faktor Anbieter von diesem Gerät unterstützt. Bitte nutzen Sie ein unterstütztes Gerät und / oder fügen Sie zusätzliche Anbieter hinzu, die von mehr Geräten unterstützt werden (wie eine Authentifizierungs-App). + Dieses Konto hat eine aktive Zwei-Faktor-Authentifizierung, allerdings wird keiner der konfigurierten Zwei-Faktor-Anbieter von diesem Gerät unterstützt. Bitte nutzen Sie ein unterstütztes Gerät und / oder fügen Sie zusätzliche Anbieter hinzu, die von mehr Geräten unterstützt werden (wie eine Authentifizierungs-App). Wiederherstellungscode @@ -1726,7 +1726,7 @@ Das Scannen erfolgt automatisch. Message shown when interacting with the server - Eintrag wurde wiederhergestellt + Eintrag wiederhergestellt Confirmation message after successfully restoring a soft-deleted item @@ -2471,4 +2471,43 @@ Das Scannen erfolgt automatisch. {0} Möchtest du zu diesem Konto wechseln? + + Neu hier? + + + Hinweis zum Master-Passwort erhalten + + + Anmelden als {0} + + + Nicht du? + + + Mit Master-Passwort anmelden + + + Mit einem anderen Gerät anmelden + + + Anmeldung initiiert + + + Eine Benachrichtigung wurde an dein Gerät gesendet. + + + Bitte stelle sicher, dass dein Tresor entsperrt ist und die Fingerabdruck-Phrase mit dem anderen Gerät übereinstimmt. + + + Benachrichtigung erneut senden + + + Brauchst du eine andere Option? + + + Alle Anmelde-Optionen anzeigen + + + Diese Anfrage ist nicht mehr gültig + diff --git a/src/App/Resources/AppResources.el.resx b/src/App/Resources/AppResources.el.resx index 76c0ae963..19829fa6f 100644 --- a/src/App/Resources/AppResources.el.resx +++ b/src/App/Resources/AppResources.el.resx @@ -2472,4 +2472,43 @@ {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.en-GB.resx b/src/App/Resources/AppResources.en-GB.resx index cde8d35af..daec9c158 100644 --- a/src/App/Resources/AppResources.en-GB.resx +++ b/src/App/Resources/AppResources.en-GB.resx @@ -2481,4 +2481,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + Are you new here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log in with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.en-IN.resx b/src/App/Resources/AppResources.en-IN.resx index de06fc353..48e77c749 100644 --- a/src/App/Resources/AppResources.en-IN.resx +++ b/src/App/Resources/AppResources.en-IN.resx @@ -2486,4 +2486,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.es.resx b/src/App/Resources/AppResources.es.resx index d22b36960..926da5df4 100644 --- a/src/App/Resources/AppResources.es.resx +++ b/src/App/Resources/AppResources.es.resx @@ -2473,4 +2473,43 @@ seleccione Agregar TOTP para almacenar la clave de forma segura {0} ¿Desea cambiar a esta cuenta? + + ¿Nuevo por aquí? + + + Obtener pista de contraseña maestra + + + Iniciando sesión como {0} + + + ¿No eres tú? + + + Iniciar sesión con contraseña maestra + + + Iniciar sesión con otro dispositivo + + + Inicio de sesión en proceso + + + Se ha enviado una notificación a tu dispositivo. + + + Por favor, asegúrese de que su bóveda está desbloqueada y la frase de huella dactilar coincide en el otro dispositivo. + + + Enviar nueva notificación + + + ¿Necesitas otra opción? + + + Ver todas las opciones de inicio de sesión + + + Esta solicitud ya no es válida + diff --git a/src/App/Resources/AppResources.et.resx b/src/App/Resources/AppResources.et.resx index b49c39e14..a1be8786b 100644 --- a/src/App/Resources/AppResources.et.resx +++ b/src/App/Resources/AppResources.et.resx @@ -2472,4 +2472,43 @@ Skaneerimine toimub automaatselt. {0} Soovid selle konto peale lülituda? + + Oled siin uus? + + + Tuleta ülemparooli vihjega meelde + + + Sisselogimas kui {0} + + + Pole sina? + + + Logi sisse ülemparooliga + + + Logi sisse läbi teise seadme + + + Sisselogimine on käivitatud + + + Sinu seadmesse saadeti teavitus. + + + Veendu, et hoidla on lahti lukustatud ja sõrmejälje fraasid seadmete vahel ühtivad. + + + Saada märguanne uuesti + + + Soovid teist valikut kasutada? + + + Vaata kõiki valikuid + + + See päring ei ole enam kehtiv + diff --git a/src/App/Resources/AppResources.eu.resx b/src/App/Resources/AppResources.eu.resx index 2e92cc922..301c2aa36 100644 --- a/src/App/Resources/AppResources.eu.resx +++ b/src/App/Resources/AppResources.eu.resx @@ -1575,7 +1575,7 @@ 'Nord' is the name of a specific color scheme. It should not be translated. - Solarized Dark + Solarized iluna 'Solarized Dark' is the name of a specific color scheme. It should not be translated. @@ -2464,11 +2464,50 @@ Baztertu - Login request has already expired. + Sarbide eskaera iraungi da. - Login attempt from: + Saio hasiera saiakera hemendik: {0} -Do you want to switch to this account? +Kontu honetara aldatu nahi duzu? + + + Berria hemendik? + + + Jaso pasahitz nagusiaren pista + + + {0} bezala hasi saioa + + + Ez zara zu? + + + Hasi saioa pasahitz nagusiarekin + + + Hasi saioa beste gailu batekin + + + Saioa hastea martxan da + + + Jakinarazpen bat bidali da zure gailura. + + + Mesedez, ziurtatu kutxa gotorra desblokeatuta dagoela eta hatz-marka digitalaren esaldia bat datorrela beste gailuarekin. + + + Berbidali jakinarazpena + + + Beste aukerarik behar al duzu? + + + Ikusi erregistro guztiak ezarpenetan + + + This request is no longer valid diff --git a/src/App/Resources/AppResources.fa.resx b/src/App/Resources/AppResources.fa.resx index adf3ee99a..bd52c1cd5 100644 --- a/src/App/Resources/AppResources.fa.resx +++ b/src/App/Resources/AppResources.fa.resx @@ -1576,7 +1576,7 @@ 'Nord' is the name of a specific color scheme. It should not be translated. - Solarized Dark + تاریک خورشیدی 'Solarized Dark' is the name of a specific color scheme. It should not be translated. @@ -2473,4 +2473,43 @@ {0} آیا می خواهید به این حساب تغییر دهید؟ + + اینجا جدیده؟ + + + دریافت راهنمای گذرواژه اصلی + + + در حال ورود به عنوان {0} + + + شما نیستید؟ + + + با کلمه عبور اصلی وارد شوید + + + با دستگاه دیگری وارد شوید + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.fi.resx b/src/App/Resources/AppResources.fi.resx index 2874335be..063b55d0b 100644 --- a/src/App/Resources/AppResources.fi.resx +++ b/src/App/Resources/AppResources.fi.resx @@ -1762,7 +1762,7 @@ Koodi luetaan automaattisesti. Synkronoidaan holvi alasveto-eleellä. - Kertakirjautuminen (SSO) + Yrityksen kertakirjautuminen (SSO) Kirjaudu sisään käyttäen organisaatiosi kertakirjautumista (SSO). Syötä organisaatiosi tunniste aloittaaksesi. @@ -1810,7 +1810,8 @@ Koodi luetaan automaattisesti. Ladataan - Aktivoimalla tämän valinnan hyväksyt seuraavat: + Valitsemalla tämän hyväksyt seuraavat: + Palveluehtoja ja tietosuojakäytäntöä ei ole vahvistettu. @@ -2324,7 +2325,7 @@ turvallisesti valitsemalla "Lisää TOTP" Yritätkö kirjautua sisään? - {0} yrittää kirjautua laitteella {1} + Kirjautumisyritys tunnuksella {0} laitteella {1} Laitteen tyyppi @@ -2472,4 +2473,43 @@ turvallisesti valitsemalla "Lisää TOTP" {0} Haluatko vaihtaa tähän tiliin? + + Oletko uusi täällä? + + + Pyydä pääsalasanan vihjettä + + + Kirjaudutaan tunnuksella {0} + + + Etkö se ollut sinä? + + + Kirjaudu pääsalasanalla + + + Kirjaudu toisella laitteella + + + Kirjautuminen aloitettu + + + Laitteellesi on lähetetty ilmoitus. + + + Varmista, että holvisi on avattu ja tunnistelauseke täsmää toisella laitteella. + + + Lähetä ilmoitus uudelleen + + + Tarvitsetko toisen vaihtoehdon? + + + Näytä kaikki kirjautumisvaihtoehdot + + + Pyyntö ei ole enää voimassa. + diff --git a/src/App/Resources/AppResources.fil.resx b/src/App/Resources/AppResources.fil.resx index 617b12c1d..047cb60af 100644 --- a/src/App/Resources/AppResources.fil.resx +++ b/src/App/Resources/AppResources.fil.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.fr.resx b/src/App/Resources/AppResources.fr.resx index e6f2fbc43..4d10cf361 100644 --- a/src/App/Resources/AppResources.fr.resx +++ b/src/App/Resources/AppResources.fr.resx @@ -2472,4 +2472,43 @@ sélectionnez Ajouter TOTP pour stocker la clé en toute sécurité {0} Voulez-vous basculer vers ce compte ? + + Vous êtes nouveau ici ? + + + Obtenir l'indice du mot de passe maître + + + Connecté en tant que {0} + + + Ce n'est pas vous ? + + + Connectez-vous avec le mot de passe maître + + + Connectez-vous avec un autre appareil + + + Connexion initiée + + + Une notification a été envoyée à votre appareil. + + + Veuillez vous assurer que votre coffre est déverrouillé et que l'empreinte digitale est identique sur l'autre appareil. + + + Renvoyer la notification + + + Besoin d'une autre option ? + + + Voir toutes les options de connexion + + + Cette demande n'est plus valide + diff --git a/src/App/Resources/AppResources.he.resx b/src/App/Resources/AppResources.he.resx index e565d0da0..c1fe0e1f1 100644 --- a/src/App/Resources/AppResources.he.resx +++ b/src/App/Resources/AppResources.he.resx @@ -2475,4 +2475,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.hi.resx b/src/App/Resources/AppResources.hi.resx index e54b61e9c..edfe1e6fc 100644 --- a/src/App/Resources/AppResources.hi.resx +++ b/src/App/Resources/AppResources.hi.resx @@ -1763,7 +1763,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2474,4 +2474,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.hr.resx b/src/App/Resources/AppResources.hr.resx index 6c5f285f2..5c4571f9a 100644 --- a/src/App/Resources/AppResources.hr.resx +++ b/src/App/Resources/AppResources.hr.resx @@ -229,7 +229,7 @@ Mape - Mapa ažurirana. + Mapa ažurirana Idi na web stranicu @@ -282,7 +282,7 @@ Sigurno želiš ukoniti ovaj račun? - Račun je već dodan + Račun već postoji Želiš li se sada prebaciti na njega? @@ -300,7 +300,7 @@ The title for the vault page. - Authenticator + Autentikator Authenticator TOTP feature @@ -342,7 +342,7 @@ Reveal a hidden value (password). - Stavka izbrisana. + Stavka izbrisana Confirmation message after successfully deleting a login. @@ -375,7 +375,7 @@ Validation message for when a form field is left blank and is required to be entered. - {0} kopirano. + {0} kopirano Confirmation message after suceessfully copying a value to the clipboard. @@ -591,7 +591,7 @@ Minimum numeric characters for password generator settings - Najmanje specijalnih + Najmanje posebnih Minimum special characters for password generator settings @@ -604,7 +604,7 @@ Nikad - Stvorena nova stavka. + Stavka dodana U tvom trezoru nema favorita. @@ -632,7 +632,7 @@ Ostalo - Lozinka generirana. + Lozinka generirana Generator lozinki @@ -647,7 +647,7 @@ Sigurno želiš prebrisati trenutnu lozinku? - bitwarden automatski sinkronizira vaš trezor pomoću push obavijesti. Za najbolji mogući doživljaj, molimo odaberite "Ok" u sljedećem upitu kada se zatraži da omogućite push obavijesti. + Obzirom Bitwarden automatski sinkronizira tvoj trezor pomoću push obavijesti, za najbolje moguće iskustvo, u sljedećem upitu odobri Bitwardenu slanje push obavijesti. Push notifications for apple products @@ -657,7 +657,7 @@ Razmotri da nam pomogneš dobrom recenzijom! - Obnovi lozinku + Ponovno generiraj lozinku Ponovno upiši glavnu lozinku @@ -681,7 +681,7 @@ Informacije o stavci - Stavka ažurirana. + Stavka spremljena Slanje... @@ -705,10 +705,10 @@ What Apple calls their fingerprint reader. - Prijava u dva koraka + Prijava dvostrukom autentifikacijom - Prijava u dva koraka čini tvoj račun još sigurnijim tako što će zahtijevati da potvrdiš prijavu putem drugog uređaja kao što je sigurnosni ključ, autentifikatorske aplikacije, SMS-om, pozivom ili e-poštom. Prijavu u dva koraka možeš omogućiti na web trezoru. Želiš li sada posjetiti bitwarden.com? + Prijava dvostrukom autentifikacijom čini tvoj račun još sigurnijim tako što će zahtijevati potvrdu prijave putem drugog uređaja kao što su sigurnosni ključ, autentifikatorske aplikacije, SMS-om, pozivom ili e-poštom. Prijavu dvostrukom autentifikacijom možeš omogućiti na web trezoru. Želiš li sada posjetiti bitwarden.com? Otključaj s {0} @@ -775,10 +775,10 @@ Omogućeno - Off + Isklj. - On + Uklj. Status @@ -831,7 +831,7 @@ For 2FA whenever there are no available providers on this device. - Ovaj račun ima omogućenu prijavu u dva koraka, međutim ovaj uređaj ne podržava niti jednog konfiguriranog pružatelja prijave u dva koraka. Koristi podržani uređaj i/ili dodaj dodatne pružatelje prijave u dva koraka, bolje podržane na svim uređajima (npr. autentifikatorska aplikacija). + Ovaj račun ima omogućenu prijavu dvostrukom autentifikacijom, međutim ovaj uređaj ne podržava niti jednog konfiguriranog pružatelja prijave dvostrukom autentifikacijom. Koristi podržani uređaj i/ili dodaj dodatne pružatelje prijave dvostrukom autentifikacijom, bolje podržane na svim uređajima (npr. autentifikatorska aplikacija). Kôd za oporavak @@ -846,17 +846,17 @@ For 2FA - Mogućnosti prijave u dva koraka + Mogućnosti prijave dvostrukom autentifikacijom - Koristiti drugi način prijave u dva koraka + Koristiti drugi način prijave dvostrukom autentifikacijom Nije moguće slanje kontrolnog koda e-poštom. Pokušaj ponovno. For 2FA - E-pošta za potvrdu poslana. + E-pošta za potvrdu poslana For 2FA @@ -900,8 +900,7 @@ Nije moguće očitati ključ za provjeru autentičnosti. - Point your camera at the QR Code. -Scanning will happen automatically. + Za automatsko očitavanje, uperite kameru u QR kôd. Skeniraj QR kôd @@ -916,10 +915,10 @@ Scanning will happen automatically. Kopiraj TOTP - If a login has an authenticator key, copy the TOTP verification code to your clip-board when you auto-fill the login. + Ako se za prijavu koristi dvostruka autentifikacija, TOTP kontrolni kôd se automatski kopira u međuspremnik nakon auto-ispune korisničkog imena i lozinke. - Copy TOTP automatically + Automatski kopiraj TOTP Za korištenje ove značajke potrebno je premium članstvo. @@ -978,7 +977,7 @@ Scanning will happen automatically. "Identity" refers to an identity server. See more context here https://en.wikipedia.org/wiki/Identity_management - Vlastito hosting okruženje + Vlastito poslužiteljsko okruženje Navedi osnovni URL svoje lokalno smještene Bitwarden instalacije. @@ -1119,7 +1118,7 @@ Scanning will happen automatically. rujan - Broj socijalnog osiguranja + Broj zdravstvenog osiguranja Država / Pokrajina @@ -1137,10 +1136,10 @@ Scanning will happen automatically. Istek - Show website icons + Prikaži ikone mrežnih mjesta - Show a recognizable image next to each login. + Prikaži prepoznatljivu sliku pored svake prijave. URL poslužitelja ikona @@ -1173,7 +1172,7 @@ Scanning will happen automatically. Usluga Bitwarden auto-ispune koristi Android Autofill Framework za pomoć pri ispunjavanju prijava, platnih kartica i identifikacijskih podataka u drugim aplikacijama na tvojem uređaju. - Upotrijebite uslugu pristupačnosti usluge bitwarden da biste automatski ispunili prijave. + Koristi uslugu Bitwarden auto-ispune za ispunjavanje prijava, platnih kartica i identifikacijskih podataka u drugim aplikacijama. Otvori postavke auto-ispune @@ -1286,7 +1285,7 @@ Scanning will happen automatically. ex. Date this item was updated - Automatsko popunjavanje aktivirano! + Automatsko popunjavanje uključeno! Prije korištenja automatskog popunjavanja, moraš se prijaviti u glavnu Bitwarden aplikaciju. @@ -1381,10 +1380,10 @@ Scanning will happen automatically. Pretraživanje zbirke - Pretraži datoteke za slanje + Pretraži datotečne Sendove - Pretraži tekstove za slanje + Pretraži tekstualne Sendove Pretraži {0} @@ -1550,13 +1549,13 @@ Scanning will happen automatically. Zadana (sustav) - Default dark theme + Zadana tamna tema - Choose the dark theme to use when using Default (System) theme while your device's dark mode is in use. + Odaberi korištenje tamnne teme kada ju uređaj zadano koristi. - Kopiraj bilješke + Kopiraj bilješku Izlaz @@ -1580,19 +1579,19 @@ Scanning will happen automatically. 'Solarized Dark' is the name of a specific color scheme. It should not be translated. - Auto-fill blocked URIs + Auto-ispuna blokiranih URI-ja - Auto-fill will not be offered for blocked URIs. Separate multiple URIs with a comma. For example: "https://twitter.com, androidapp://com.twitter.android". + Auto-ispuna neće biti ponuđena za blokirane URI-je. Odvoji višestruke URI-je zarezom. Npr. „https://twitter.com, androidapp://com.twitter.android” - Ask to add login + Upitaj za dodavanje prijave - Ask to add an item if one isn't found in your vault. + Upitaj za dodavanje, ako se stavka već ne nalazi u trezoru. - Kod ponovnog pokretanja + Pri ponovnom pokretanju Auto-ispuna olakšava siguran pristup tvom Bitwarden trezoru iz drugih aplikacija i na web stranicama. Izgleda da nije omogućena usluga auto-ispune za Bitwarden. Omogući uslugu auto-ispune u Bitwarden postavkama. @@ -1659,7 +1658,7 @@ Scanning will happen automatically. Slanje verifikacijskog kôda e-poštom - Kôd poslan + Kôd poslan! Potvrdite lozinku za nastavak. @@ -1726,7 +1725,7 @@ Scanning will happen automatically. Message shown when interacting with the server - Stavka je vraćena. + Stavka vraćena Confirmation message after successfully restoring a soft-deleted item @@ -1828,10 +1827,10 @@ Scanning will happen automatically. Usluge auto-ispune - Koristi izravno automatsko popunjavanje + Koristi izravnu auto-ispunu - Korisiti izravno automatsko popunjavanje ako ga tvoj odabrani IME (tipkovnica) podržava. Ako postavke ne podržavaju (ili je ova opcija isključena) biti će korištena zadana usluga automatskog popunjavanja. + Korisiti izravnu auto-ispunu ako ga tvoj odabrani IME (tipkovnica) podržava. Ako postavke ne podržavaju (ili je ova opcija isključena) biti će korištena zadana usluga auto-ispune. Koristi pristupačnost @@ -1852,13 +1851,13 @@ Scanning will happen automatically. Koristi preklapanje - Kada je uključeno, omogućuje usluzi Bitwarden pristupačnosti prikaz iskočnog okvira prilikom odabira polja za prijavu. + Omogućuje usluzi Bitwarden pristupačnosti prikaz iskočnog okvira prilikom odabira polja za prijavu. Ako je uključena, usluga Bitwarden pristupačnosti prikazati će iskočni okvir prilikom odabira polja za prijavu kao pomoć pri auto-ispuni. - Ako je uključeno, pristupačnost će prikazati iskočni okvir kao pomoć usluzi automatskog popunjavanja za starije aplikacije koje ne podržavaju Android strukturu auotmatskog popunjavanja. + Ako je uključeno, pristupačnost će prikazati iskočni okvir kao pomoć usluzi auto-ispune za starije aplikacije koje ne podržavaju Android strukturu automatskog popunjavanja. Pravila tvrtke onemogućuju spremanje stavki u osobni trezor. Promijeni vlasništvo stavke na tvrtku i odaberi dostupnu Zbirku. @@ -1976,7 +1975,7 @@ Scanning will happen automatically. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Onemogući ovaj Send da mu nitko ne može pristupiti. + Onemogući ovaj Send da mu nitko ne može pristupiti 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2006,7 +2005,7 @@ Scanning will happen automatically. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Dodaj Send + Novi Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2014,15 +2013,15 @@ Scanning will happen automatically. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Send izbrisan. + Send izbrisan 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Send ažuriran. + Send ažuriran 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Stvoren novi Send + Novi Send stvoren 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2063,7 +2062,7 @@ Scanning will happen automatically. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Kod besplatnog računa moguće je dijeljenje samo teksta. Za slanje datoteka potrebno je Premium članstvo. + Kod besplatnog računa moguće je dijeljenje samo teksta. Za slanje datoteka potrebno je premium članstvo. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2140,7 +2139,7 @@ Scanning will happen automatically. Pravilo tvoje organizacije utječe na istek trezora. Najveće dozvoljeno vrijeme isteka je {0}:{1} h. - Vrijeme isteka premašuje ograničenje koju je postavila tvoja organizacija. + Vrijeme isteka premašuje ograničenje koje je postavila tvoja organizacija. Jedno ili više pravila organizacija onemogućuje izvoz osobnog trezora. @@ -2158,10 +2157,10 @@ Scanning will happen automatically. Odjavljen - Prebačen na sljedeći dostupni račun + Sljedeći dostupni račun je aktivan - Račun je zaključan + Račun zaključan Račun uspješno odjavljen @@ -2188,7 +2187,7 @@ Scanning will happen automatically. Nevažeći kôd za provjeru - Zatražite jednokratnu lozinku + Zatraži jednokratnu lozinku Pošalji kôd @@ -2197,7 +2196,7 @@ Scanning will happen automatically. Šaljem - Kopiraj Send link nakon spremanja + Nakon spremanja, kopiraj Send poveznicu Šaljem kod @@ -2209,34 +2208,34 @@ Scanning will happen automatically. Ponovno pošalji kod - Kod za potvrdu je poslan na vaš e-mail. + Kôd za potvrdu je poslan na vašu adresu e-pošte - Došlo je do pogreške prilikom slanja kontrolnog koda na vaš email. Molim te pokušaj ponovno + Došlo je do pogreške prilikom slanja verifikacijskog koda. Molimo pokušaj ponovno - Unesite kontrolni kod koji vam je poslan na email + Unesite kôd za potvrdu primljen e-poštom - Pošaljite dnevnik pogrešaka + Slanje zapisnika rušenja - Pomozite Bitwardenu poboljšati stabilnost aplikacije šaljući izvješća o rušenju. + Pomozi Bitwardenu poboljšati stabilnost aplikacije šaljući zapisnike o rušenju. - Opcije su proširene, dodirnite za sažimanje. + Opcije su proširene, dodirni za sažimanje. - Opcije su sažete, dodirnite za proširenje. + Opcije su sažete, dodirni za proširenje. - Velika slova (A-Z) + Velika slova (A - Z) - Mala slova (a-z) + Mala slova (a - z) - Brojevi (0-9) + Brojevi (0 - 9) Posebni znakovi (!@#$%^&*) @@ -2269,146 +2268,145 @@ Scanning will happen automatically. TOTP - Verification codes + Kodovi za provjeru - Premium subscription required + Potrebna Premium pretplata - Cannot add authenticator key? + Nije moguće dodati ključ za provjeru autentičnosti? - Scan QR Code + Očitaj QR kôd - Cannot scan QR Code? + Nije moguće očitati QR kôd? - Authenticator key + Ključ za provjeru autentičnosti - Enter key manually + Ručno unesi ključ - Add TOTP + Dodaj TOTP - Set up TOTP + Namjesti TOTP - Once the key is successfully entered, -select Add TOTP to store the key safely + Jednom kada je ključ uspješno unesen, odaberi „Dodaj TOTP” za sigurno spremanje ključa - Setting your lock options to “Never” keeps your vault available to anyone with access to your device. If you use this option, you should ensure that you keep your device properly protected. + Postavljanje zaključavanja na „Nikad” čini tvoj trezor dostupnim svima koji imaju pristupom tvom uređaju. Ako koristiš ovu mogućnost, pobrini se da je uređaj dostatno zaštićen. - One or more of the URLs entered are invalid. Please revise it and try to save again. + Jedan ili više unesenih URL-ova nije ispravn. Molimo provjeri uneseni URL. - We were unable to process your request. Please try again or contact us. + Trenutno ne možemo obraditi tvoj zahtjev. Pokušaj ponovno ili nas kontaktiraj. - Allow screen capture + Dozvoli snimanje zaslona - Are you sure you want to turn on screen capture? + Sigurno želiš uključiti snimanje zaslona? - Login requested + Zatražena je prijava - Are you trying to log in? + Pokušavaš li se prijaviti? - Login attempt by {0} on {1} + Pokušaj prijave {0} na {1} - Device type + Vrsta uređaja - IP address + IP adresa - Time + Vrijeme - Near + Blizu - Confirm login + Potvrdi prijavu - Deny login + Odbij prijavu - Just now + Upravo - {0} minutes ago + prije {0} minute/a - Login confirmed + Prijava potvrđena - Login denied + Prijava odbijena - Approve login requests + Odobri pokušaje prijave - Use this device to approve login requests made from other devices. + Koristi ovaj uređaj za odobrenje zahtjeva za prijavu na drugim uređajima. - Allow notifications + Dozvoli obavijesti - Receive push notifications for new login requests + Primanje push obavijesti o novim zahtjevima za prijavu - No thanks + Ne hvala - Confirm login attempt for {0} + Potvrdi pokušaj prijave za {0} - All notifications + Sve obavijesti - Password type + Tip lozinke - What would you like to generate? + Što želiš generirati? - Username type + Tip korisničkog imena - Plus addressed email + Plus adresa e-pošte - Catch-all email + Dohvati sve (catch-all) e-pošta - Forwarded email alias + Proslijeđeni pseudonim e-pošte - Random word + Nasumična riječ - Email (required) + Adresa e-pošte (obavezno) - Domain name (required) + Naziv domene (obavezno) - API key (required) + API ključ (obavezno) - Service + Usluga AnonAddy @@ -2423,53 +2421,92 @@ select Add TOTP to store the key safely "SimpleLogin" is the product name and should not be translated. - API access token + Token za API pristup - Are you sure you want to overwrite the current username? + Sigurno želiš prebrisati trenutno korisničko ime? - Generate username + Generiraj korisničko ime - Email Type + Vrsta e-pošte - Website (required) + web stranica (obavezno) - Unknown {0} error occurred. + Došlo je do nepoznate {0} greške. - Use your email provider's subaddress capabilities + Koristi mogućnosti podadresiranja svog davatelja e-pošte - Use your domain's configured catch-all inbox. + Koristi konfigurirani catch-all sandučić svoje domene. - Generate an email alias with an external forwarding service. + Generiraj pseudonim e-pošte s vanjskom uslugom prosljeđivanja. - Random + Nasumično - Accessibility Service Disclosure + Odobrenje servisa pristupačnosti - 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. + Bitwarden koristi servis pristupačnosti za pretragu polja za prijavu u aplikacijama i na web stranicama, te potom određuje ID polja za unos korisničkog imena i lozinke kada su pronađeni odgovarajući podaci. Ne spremamo podatke koje servis daje, niti pokušavamo upravljati bilo kojim elementima na zaslonu osim tekstualnog unosa vjerodajnica. - Accept + Prihvati - Decline + Odbij - Login request has already expired. + Zahtjev za prijavu je već istekao. - Login attempt from: + Zahtjev za prijavu od: {0} -Do you want to switch to this account? +Želiš li se prebaciti na ovaj račun? + + + New around here? + + + Slanje podsjetnika glavne lozinke + + + Prijava kao {0} + + + Nisi ti? + + + Prijava glavnom lozinkom + + + Prijava drugim uređajem + + + Prijava pokrenuta + + + Obavijest je poslana na tvoj uređaj. + + + Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem. + + + Ponovno pošalji obavijest + + + Trebaš drugu opciju? + + + Pogledaj sve mogućnosti prijave + + + This request is no longer valid diff --git a/src/App/Resources/AppResources.hu.resx b/src/App/Resources/AppResources.hu.resx index 1b43e48d3..a34b3e714 100644 --- a/src/App/Resources/AppResources.hu.resx +++ b/src/App/Resources/AppResources.hu.resx @@ -1761,7 +1761,7 @@ A széf szinkronizálása lehúzó művelettel. - Vállalati önálló bejelentkezés + Vállalati egyszeri bejelentkezés Gyors bejelentkezés a szervezeti önálló bejelentkező portálba. A kezdéshez meg kell adni a szervezeti azonosítót. @@ -2471,4 +2471,43 @@ TOTP hozzáadása a kulcs biztonságos tárolásához lehetőséget. {0} Szeretnénk átváltani erre a fiókra? + + Új felhasználó vagyunk? + + + Mesterjelszó emlékeztető kérése + + + Bejelentkezve mint {0} + + + Ez tévedés? + + + Bejelentkezés mesterjelszóval + + + Bejelentkezés más eszközzel + + + A bejelentkezés elindításra került. + + + A rendszer értesítést küldött az eszközre. + + + Ellenőrizzük, hogy a széf feloldásra került és az Ujjlenyomat kifejezés egyezik a másik eszközön levővel. + + + Értesítés újraküldése + + + Másik opció szükséges? + + + Összes bejelentkezési opció megtekintése + + + A kérés már nem érvényes. + diff --git a/src/App/Resources/AppResources.id.resx b/src/App/Resources/AppResources.id.resx index d3bdb4d38..07ae516c3 100644 --- a/src/App/Resources/AppResources.id.resx +++ b/src/App/Resources/AppResources.id.resx @@ -2472,4 +2472,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.it.resx b/src/App/Resources/AppResources.it.resx index 4287f5e4f..d9dc07efa 100644 --- a/src/App/Resources/AppResources.it.resx +++ b/src/App/Resources/AppResources.it.resx @@ -1575,7 +1575,7 @@ 'Nord' is the name of a specific color scheme. It should not be translated. - Solarized Dark + Solarizzato scuro 'Solarized Dark' is the name of a specific color scheme. It should not be translated. @@ -2468,8 +2468,47 @@ seleziona Aggiungi TOTP per salvare la chiave in modo sicuro La richiesta di accesso è già scaduta. - Login attempt from: + Tentativo di accesso da: {0} -Do you want to switch to this account? +Vuoi passare a questo account? + + + Nuovo da queste parti? + + + Ottieni l'indizio della password principale + + + Accesso come {0} + + + Non sei tu? + + + Accedi con la password principale + + + Accedi con un altro dispositivo + + + Login avviato + + + Una notifica è stata inviata al tuo dispositivo. + + + Assicurati che la tua cassaforte sia sbloccata e che la "frase impronta" corrisponda sull'altro dispositivo. + + + Invia nuova notifica + + + Hai bisogno di un'altra opzione? + + + Visualizza tutte le opzioni di accesso + + + La richiesta non è più valida diff --git a/src/App/Resources/AppResources.ja.resx b/src/App/Resources/AppResources.ja.resx index b257c15a3..358974688 100644 --- a/src/App/Resources/AppResources.ja.resx +++ b/src/App/Resources/AppResources.ja.resx @@ -2472,4 +2472,43 @@ {0} このアカウントに切り替えますか? + + 初めてですか? + + + マスターパスワードのヒントを取得する + + + {0} としてログイン + + + あなたではないですか? + + + マスターパスワードでログイン + + + 別のデバイスでログイン + + + ログイン開始 + + + デバイスに通知を送信しました。 + + + 保管庫がロックされていることと、パスフレーズが他のデバイスと一致していることを確認してください。 + + + 通知を再送信する + + + 別の選択肢が必要ですか? + + + すべてのログインオプションを表示 + + + このリクエストは無効になりました + diff --git a/src/App/Resources/AppResources.ka.resx b/src/App/Resources/AppResources.ka.resx index 617b12c1d..047cb60af 100644 --- a/src/App/Resources/AppResources.ka.resx +++ b/src/App/Resources/AppResources.ka.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.kn.resx b/src/App/Resources/AppResources.kn.resx index 1c2d4c2ce..c23d4b1a2 100644 --- a/src/App/Resources/AppResources.kn.resx +++ b/src/App/Resources/AppResources.kn.resx @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.ko.resx b/src/App/Resources/AppResources.ko.resx index d6a184b7b..572b95870 100644 --- a/src/App/Resources/AppResources.ko.resx +++ b/src/App/Resources/AppResources.ko.resx @@ -2472,4 +2472,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.lt.resx b/src/App/Resources/AppResources.lt.resx index 617b12c1d..047cb60af 100644 --- a/src/App/Resources/AppResources.lt.resx +++ b/src/App/Resources/AppResources.lt.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.lv.resx b/src/App/Resources/AppResources.lv.resx index 90c81486a..8ffc20732 100644 --- a/src/App/Resources/AppResources.lv.resx +++ b/src/App/Resources/AppResources.lv.resx @@ -2472,4 +2472,43 @@ jāizvēlas "Pievienot TOTP", lai droši glabātu atslēgu. {0} Vai pārslēgties uz šo kontu? + + Jauns šeit? + + + Saņemt galvenās paroles norādi + + + Pierakstās kā {0} + + + Tas neesi Tu? + + + Pierakstīties ar galveno paroli + + + Pierakstīties ar citu ierīci + + + Uzsākta pierakstīšanās + + + Uz ierīci ir nosūtīts paziņojums. + + + Jāpārliecinās, ka glabātava ir atslēgta un atpazīšanas vārdkopa ir tāda pati arī citā ierīcē. + + + Atkārtoti nosūtīt paziņojumu + + + Nepieciešama cita iespēja? + + + Apskatīt visas pierakstīšanās iespējas + + + Šis pieprasījums vairs nav derīgs + diff --git a/src/App/Resources/AppResources.ml.resx b/src/App/Resources/AppResources.ml.resx index 6902aeb75..3c2b8e0c2 100644 --- a/src/App/Resources/AppResources.ml.resx +++ b/src/App/Resources/AppResources.ml.resx @@ -2472,4 +2472,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.nb.resx b/src/App/Resources/AppResources.nb.resx index 1e3cf11c0..d5e26b66f 100644 --- a/src/App/Resources/AppResources.nb.resx +++ b/src/App/Resources/AppResources.nb.resx @@ -1576,7 +1576,7 @@ Skanning skjer automatisk. 'Nord' is the name of a specific color scheme. It should not be translated. - Solarized Dark + Solarisert mørk 'Solarized Dark' is the name of a specific color scheme. It should not be translated. @@ -2469,8 +2469,47 @@ velg Legg til TOTP for å lagre nøkkelen sikkert Innloggingsforespørselen har allerede utløpt. - Login attempt from: + Innloggingsforsøk: {0} -Do you want to switch to this account? +Vil du bytte til denne kontoen? + + + Nytt rundt her? + + + Få et hint om superpassordet + + + Logger inn som {0} + + + Ikke du? + + + Logg inn med hovedpassord + + + Logg inn med en annen enhet + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid diff --git a/src/App/Resources/AppResources.nl.resx b/src/App/Resources/AppResources.nl.resx index 8bc4a521c..a40d14b13 100644 --- a/src/App/Resources/AppResources.nl.resx +++ b/src/App/Resources/AppResources.nl.resx @@ -2472,4 +2472,43 @@ kies je TOTP toevoegen om de sleutel veilig op te slaan {0} Wilt u naar dit account wisselen? + + Nieuw hier? + + + Hoofdwachtwoordhint krijgen + + + Inloggen als {0} + + + Ben jij dit niet? + + + Inloggen met je hoofdwachtwoord + + + Inloggen met een ander apparaat + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + Dit verzoek is niet langer geldig + diff --git a/src/App/Resources/AppResources.nn.resx b/src/App/Resources/AppResources.nn.resx index 9e5808b3e..a45c21290 100644 --- a/src/App/Resources/AppResources.nn.resx +++ b/src/App/Resources/AppResources.nn.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.pl.resx b/src/App/Resources/AppResources.pl.resx index b69d37088..6ed279caa 100644 --- a/src/App/Resources/AppResources.pl.resx +++ b/src/App/Resources/AppResources.pl.resx @@ -2472,4 +2472,43 @@ wybierz Dodaj TOTP, aby bezpiecznie przechowywać klucz {0} Czy chcesz przełączyć się na to konto? + + Jesteś tu nowy(a)? + + + Uzyskaj podpowiedź hasła głównego + + + Logowanie jako {0} + + + To nie Ty? + + + Logowanie hasłem głównym + + + Logowanie innym urządzeniem + + + Logowanie rozpoczęte + + + Powiadomienie zostało wysłane na urządzenie. + + + Upewnij się, że sejf jest odblokowany, a unikalny identyfikator konta pasuje do drugiego urządzenia. + + + Wyślij ponownie powiadomienie + + + Potrzebujesz innego sposobu? + + + Zobacz wszystkie sposoby logowania + + + Ta prośba nie jest już ważna + diff --git a/src/App/Resources/AppResources.pt-BR.resx b/src/App/Resources/AppResources.pt-BR.resx index 516efb61e..b121acd19 100644 --- a/src/App/Resources/AppResources.pt-BR.resx +++ b/src/App/Resources/AppResources.pt-BR.resx @@ -1576,7 +1576,7 @@ A leitura será feita automaticamente. 'Nord' is the name of a specific color scheme. It should not be translated. - Solarized Dark + Escuro Solarizado 'Solarized Dark' is the name of a specific color scheme. It should not be translated. @@ -2473,4 +2473,43 @@ selecione Adicionar TOTP para armazenar a chave de forma segura {0} Você deseja mudar para esta conta? + + Novo por aqui? + + + Obter dica da senha mestra + + + Entrando como {0} + + + Não é você? + + + Entrar com a senha mestra + + + Entrar com outro dispositivo + + + Login iniciado + + + Uma notificação foi enviada para seu dispositivo. + + + Por favor, certifique-se de que o seu cofre esteja desbloqueado e a frase de identificação corresponda ao outro dispositivo. + + + Reenviar notificação + + + Precisa de outra opção? + + + Ver todas as opções de login + + + Este pedido não é mais válido + diff --git a/src/App/Resources/AppResources.pt-PT.resx b/src/App/Resources/AppResources.pt-PT.resx index 30d3cf726..9011a2136 100644 --- a/src/App/Resources/AppResources.pt-PT.resx +++ b/src/App/Resources/AppResources.pt-PT.resx @@ -2472,4 +2472,43 @@ select Add TOTP to store the key safely {0} Deseja mudar para esta conta? + + Novo por aqui? + + + Obter dica da palavra-passe mestra + + + A iniciar sessão como {0} + + + Utilizador incorreto? + + + Iniciar sessão com a palavra-passe mestra + + + Iniciar sessão com outro dispositivo + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + Este pedido já não é válido + diff --git a/src/App/Resources/AppResources.resx b/src/App/Resources/AppResources.resx index 03f1c7aba..3a651bb62 100644 --- a/src/App/Resources/AppResources.resx +++ b/src/App/Resources/AppResources.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2486,9 +2486,30 @@ Do you want to switch to this account? Not you? - Log In with master password + Log in with master password Log In with another device + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.ro.resx b/src/App/Resources/AppResources.ro.resx index 8634645f8..423c3b768 100644 --- a/src/App/Resources/AppResources.ro.resx +++ b/src/App/Resources/AppResources.ro.resx @@ -2472,4 +2472,43 @@ selectați „Adăugare TOTP” pentru a stoca cheia în siguranță {0} Doriți să comutați la acest cont? + + Sunteți nou pe aici? + + + Obțineți indiciul parolei principale + + + Autentificare ca {0} + + + Nu sunteți dvs.? + + + Autentificați-vă cu parola principală + + + Autentificați-vă cu un alt dispozitiv + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.ru.resx b/src/App/Resources/AppResources.ru.resx index bc28186d0..ba1a87918 100644 --- a/src/App/Resources/AppResources.ru.resx +++ b/src/App/Resources/AppResources.ru.resx @@ -705,10 +705,10 @@ What Apple calls their fingerprint reader. - Двухфакторная аутентификация + Двухэтапная аутентификация - Двухэтапная аутентификация повышает защиту вашего аккаунта, требуя подтверждения входа на другом устройстве, например, с помощью ключа безопасности, приложения-аутентификатора, SMS, телефонного звонка или email. Двухфакторная аутентификация включается на bitwarden.com. Перейти на сайт сейчас? + Двухэтапная аутентификация делает аккаунт более защищенным, поскольку требуется подтверждение входа при помощи другого устройства, например, ключа безопасности, приложения-аутентификатора, SMS, телефонного звонка или электронной почты. Двухэтапная аутентификация включается на bitwarden.com. Перейти на сайт сейчас? Разблокировка {0} @@ -831,7 +831,7 @@ For 2FA whenever there are no available providers on this device. - Для этой учетной записи включена двухфакторная аутентификация, однако ни один из настроенных вариантов аутентификации не поддерживается на этом устройстве. Используйте поддерживаемое устройство и/или добавьте другие варианты, которые поддерживаются на большинстве устройств (например, приложение-аутентификатор). + У этой учетной записи включена двухэтапная аутентификация, однако ни один из настроенных вариантов не поддерживается на этом устройстве. Используйте поддерживаемое устройство и/или добавьте другие варианты, которые поддерживаются на большинстве устройств (например, приложение-аутентификатор). Код восстановления @@ -846,10 +846,10 @@ For 2FA - Настройки двухфакторной аутентификации + Настройки двухэтапной аутентификации - Использовать другой метод двухфакторной аутентификации + Использовать другой метод двухэтапной аутентификации Не удалось отправить письмо подтверждения. Повторить. @@ -919,7 +919,7 @@ Если к вашему логину прикреплен ключ аутентификации, то код подтверждения TOTP будет скопирован при автозаполнении логина. - Копировать TOTP автоматически + Скопировать TOTP автоматически Для использования этой функции требуется Премиум. @@ -1471,7 +1471,7 @@ Экспортировать хранилище - Заблокировать сейчас + Заблокировать PIN-код @@ -1614,10 +1614,10 @@ Общие - Изменить видимость + Вкл/выкл видимость - Истек срок действия вашей сессии. + Истек срок действия вашего сеанса. Биометрическая верификация. @@ -1635,7 +1635,7 @@ 3. На экране настроек приложений Android для Bitwarden перейдите в раздел "Отображение поверх других приложений" (в разделе "Дополнительно") и коснитесь переключателя, чтобы включить поддержку наложения. - Разрешения + Разрешение Открыть настройки разрешения наложения @@ -1762,7 +1762,7 @@ Синхронизация хранилища жестом смахивания вниз. - Единая корпоративная авторизация (SSO) + Единая корпоративная авторизация Авторизуйтесь при помощи единого корпоративного портала. Чтобы начать, введите идентификатор вашей организации. @@ -2092,7 +2092,7 @@ Обновить мастер-пароль - Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить мастер-пароль сейчас. В результате текущая сессия будет завершена, потребуется повторный вход. Активные сессии на других устройствах могут оставаться активными в течение одного часа. + Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить мастер-пароль сейчас. В результате текущий сеанс будет завершен, потребуется повторный вход. Активные сеансы на других устройствах могут оставаться активными в течение одного часа. Обновление пароля @@ -2472,4 +2472,43 @@ {0} Хотите переключиться на этот аккаунт? + + Вы здесь впервые? + + + Получить подсказку к мастер-паролю + + + Войти как {0} + + + Не вы? + + + Войти с мастер-паролем + + + Войти с другого устройства + + + Вход инициирован + + + На ваше устройство отправлено уведомление. + + + Убедитесь, что ваше хранилище разблокировано, а фраза отпечатка соответствует другому устройству. + + + Отправить уведомление повторно + + + Нужен другой вариант? + + + Посмотреть все варианты авторизации + + + Этот запрос больше не действителен + diff --git a/src/App/Resources/AppResources.si.resx b/src/App/Resources/AppResources.si.resx index 8ff3d2b94..b2736fddd 100644 --- a/src/App/Resources/AppResources.si.resx +++ b/src/App/Resources/AppResources.si.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.sk.resx b/src/App/Resources/AppResources.sk.resx index 4d2847199..482e56886 100644 --- a/src/App/Resources/AppResources.sk.resx +++ b/src/App/Resources/AppResources.sk.resx @@ -1762,7 +1762,7 @@ Skenovanie prebehne automaticky. Synchronizácia trezora potiahnutím nadol - Prihlásenie cez prihlasovací formulár spoločnosti (SSO) + Jednotné prihlásenie pre podniky (SSO) Prihláste sa prostredníctvom prihlasovacieho portálu (SSO) vašej organizácie. Najskôr zadajte identifikátor vašej organizácie. @@ -2472,4 +2472,43 @@ Pridať TOTP, aby ste kľúč bezpečne uložili {0} Chcete prepnúť na toto konto? + + Ste tu nový? + + + Získať nápoveď pre hlavné heslo + + + Prihlasujete sa ako {0} + + + Nie ste to vy? + + + Prihlásenie pomocou hlavného hesla + + + Prihlásenie pomocou iného zariadenia + + + Iniciované prihlásenie + + + Do vášho zariadenia bolo odoslané upozornenie. + + + Skontrolujte, či je trezor odomknutý, a či sa fráza odtlačku prsta zhoduje na druhom zariadení. + + + Znova odoslať upozornenie + + + Potrebujete inú možnosť? + + + Zobraziť všetky možnosti prihlásenia + + + Táto požiadavka už nie je platná + diff --git a/src/App/Resources/AppResources.sl.resx b/src/App/Resources/AppResources.sl.resx index 4c8b45efc..e9ca2fade 100644 --- a/src/App/Resources/AppResources.sl.resx +++ b/src/App/Resources/AppResources.sl.resx @@ -1762,7 +1762,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.sr.resx b/src/App/Resources/AppResources.sr.resx index a738cbb4e..3ceb76c18 100644 --- a/src/App/Resources/AppResources.sr.resx +++ b/src/App/Resources/AppResources.sr.resx @@ -1576,7 +1576,7 @@ 'Nord' is the name of a specific color scheme. It should not be translated. - Solarized Dark + Solarized црно 'Solarized Dark' is the name of a specific color scheme. It should not be translated. @@ -2395,7 +2395,7 @@ „Ухвати све“ е-порука - Forwarded email alias + Прослеђен псеудоним е-поште Случајна реч @@ -2443,10 +2443,10 @@ Непозната {0} грешка. - Use your email provider's subaddress capabilities + Користите могућности подадресе вашег добављача е-поште - Use your domain's configured catch-all inbox. + Користите подешено catch-all пријемно сандуче вашег домена. Генеришите псеудоним е-поште помоћу екстерне услуге прослеђивања. @@ -2455,10 +2455,10 @@ Случајно - Accessibility Service Disclosure + Откривање услуге приступачности - 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. + Битварден користи услугу приступачности да тражи поља за пријаву у апликацијама и веб локацијама, а затим успоставља одговарајуће ИД-ове поља за уношење корисничког имена и лозинке када се пронађе подударање за апликацију или сајт. Не чувамо ниједну информацију коју нам пружа услуга, нити покушавамо да контролишемо било које елементе на екрану осим уноса текста акредитива. Прихвати @@ -2474,4 +2474,43 @@ {0} Да ли желите да пређете на овај налог? + + Нов овде? + + + Добити савет за Главну Лозинку + + + Пријављивање као {0} + + + Не ти? + + + Пријавите се са главном лозинком + + + Пријавите се са другим уређајем + + + Пријава је покренута + + + Обавештење је послато на ваш уређај. + + + Уверите се да је ваш сеф откључан и да се фраза отиска прста подудара на другом уређају. + + + Поново послати обавештење + + + Треба Вам друга опције? + + + Погледајте сав извештај у опције + + + Овај захтев више не важи + diff --git a/src/App/Resources/AppResources.sv.resx b/src/App/Resources/AppResources.sv.resx index 2cfbc5df2..6fd82b5d6 100644 --- a/src/App/Resources/AppResources.sv.resx +++ b/src/App/Resources/AppResources.sv.resx @@ -229,7 +229,7 @@ Mappar - Mapp sparad + Mappen uppdaterades Gå till webbplats @@ -279,7 +279,7 @@ Ta bort konto - Vill du ta bort kontot? + Är du säker på att du vill ta bort detta konto? Kontot har redan lagts till @@ -428,7 +428,7 @@ Undvik tvetydiga tecken - Bitwarden Apptillägg + Bitwarden apptillägg Det enklaste sättet att lägga till nya inloggningar i ditt valv är genom apptillägget. Läs mer om Bitwardens apptillägg genom att navigera till fliken "Inställningar". @@ -657,7 +657,7 @@ Överväg gärna att hjälpa oss genom att ge oss en bra recension! - Skapa nytt lösenord + Återskapa lösenord Ange huvudlösenordet igen @@ -681,7 +681,7 @@ Objektinformation - Objekt har sparats + Objektet uppdaterades Skickar... @@ -708,7 +708,7 @@ Tvåfaktorsautentisering - Tvåstegsverifiering gör ditt konto säkrare genom att kräva att du verifierar din inloggning med en annan enhet, t.ex. en säkerhetsnyckel, autentiseringsapp, SMS, telefonsamtal eller e-post. Tvåstegsverifiering kan aktiveras i Bitwarden.com webbvalv. Vill du besöka webbplatsen nu? + Tvåstegsverifiering gör ditt konto säkrare genom att kräva att du verifierar din inloggning med en annan enhet, t.ex. en säkerhetsnyckel, autentiseringsapp, SMS, telefonsamtal eller e-post. Tvåstegsverifiering kan aktiveras i Bitwardens webbvalv. Vill du besöka webbplatsen nu? Lås upp med {0} @@ -857,7 +857,7 @@ Vänligen använd en enhet som stöds och/eller lägg till fler metoder som har For 2FA - E-postmeddelande för bekräftelse har skickats + Verifieringsmeddelande har skickats For 2FA @@ -901,7 +901,7 @@ Vänligen använd en enhet som stöds och/eller lägg till fler metoder som har Kan inte läsa autentiseringsnyckeln. - Peka kameran på QR-koden. + Rikta kameran mot QR-koden. Skanningen sker automatiskt. @@ -1382,10 +1382,10 @@ Skanningen sker automatiskt. Sök i samling - Sök i Sends filer + Sök bland Sends-filer - Sök i Sends textmeddelanden + Sök bland Sends-textmeddelanden Sök {0} @@ -1584,7 +1584,7 @@ Skanningen sker automatiskt. Fyll automatiskt i blockerade URI:er - Automatisk fyllning kommer inte att erbjudas för blockerade URI:er. Separera flera URI:er med kommatecken. Till exempel: "https://twitter.com, androidapp://com.twitter.android". + Automatisk ifyllnad kommer inte att erbjudas för blockerade URI:er. Separera flera URI:er med kommatecken. Till exempel: "https://twitter.com, androidapp://com.twitter.android". Be om att lägga till inloggning @@ -1894,7 +1894,7 @@ Skanningen sker automatiskt. Texten du vill skicka. - Dölj först texten när denna Send öppnas + Dölj texten som standard när denna Send öppnas 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1935,7 +1935,7 @@ Skanningen sker automatiskt. Utgångstid - Om angiven kommer åtkomst till denna Skicka att upphöra på angivet datum och tid. + Om angiven kommer åtkomst till denna Send att upphöra på angivet datum och tid. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1945,7 +1945,7 @@ Skanningen sker automatiskt. Maximalt antal åtkomster - Om angivet kommer användare inte längre kunna komma åt denna Skicka när det maximala antalet åtkomster har uppnåtts. + Om angivet kommer användare inte längre kunna komma åt denna Send när det maximala antalet åtkomster har uppnåtts. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1958,7 +1958,7 @@ Skanningen sker automatiskt. Nytt lösenord - Kräv eventuellt lösenord av användare för att komma åt detta Skicka. + Kräv valfritt ett lösenord för att användare ska komma åt denna Send. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1978,7 +1978,7 @@ Skanningen sker automatiskt. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Inaktivera detta Skicka så att ingen kan komma åt den + Inaktivera denna Send så att ingen kan komma åt den 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -1996,11 +1996,11 @@ Skanningen sker automatiskt. Dela länk - Send link + Send-länk 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Search Sends + Sök bland Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2008,7 +2008,7 @@ Skanningen sker automatiskt. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Lägg till Send + Skapa ny Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2050,7 +2050,7 @@ Skanningen sker automatiskt. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - På grund av företagspolicy kan du bara ta bort en befintlig Skickning. + På grund av en företagspolicy kan du bara radera en befintlig Send. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2121,7 +2121,7 @@ Skanningen sker automatiskt. FIDO2 WebAuthn - För att fortsätta, ha din FIDO2 WebAuthn aktiverad säkerhetsnyckel redo, följ sedan instruktionerna efter att du klickat på "Authenticate WebAuthn" på nästa skärm. + För att fortsätta, ha din FIDO2 WebAuthn-kompatibla säkerhetsnyckel redo, följ sedan instruktionerna efter att du klickat på "Autentisera WebAuthn" på nästa skärm. Autentisering med FIDO2 WebAuthn, du kan autentisera med en extern säkerhetsnyckel. @@ -2166,10 +2166,10 @@ Skanningen sker automatiskt. Kontot är låst - Framgångsrikt utloggad + Kontot har loggats ut - Lyckades ta bort konto + Kontot har tagits bort Radera konto @@ -2193,7 +2193,7 @@ Skanningen sker automatiskt. Begär engångslösenord - Skicka kod + Send-kod Skickar @@ -2220,7 +2220,7 @@ Skanningen sker automatiskt. Ange verifieringskoden som skickades till din e-postadress - Skicka in fellogg + Skicka in kraschloggar Hjälp Bitwarden att förbättra appens stabilitet genom att skicka in kraschrapporter. @@ -2271,7 +2271,7 @@ Skanningen sker automatiskt. TOTP - Bekräftelsekoder + Verifieringskoder Premium-prenumeration krävs @@ -2305,7 +2305,7 @@ välj Lägg till TOTP för att lagra nyckeln på ett säkert sätt - Ställa in dina låsalternativ till “Never” håller ditt valv tillgängligt för alla med tillgång till din enhet. Om du använder det här alternativet bör du se till att du håller din enhet ordentligt skyddad. + Att ställa in låsalternativ till “Aldrig” håller ditt valv tillgängligt för alla med tillgång till din enhet. Om du använder det här alternativet bör du se till att du håller din enhet ordentligt skyddad. En eller flera av de angivna webbadresserna är ogiltiga. Vänligen ändra det och försök att spara igen. @@ -2395,7 +2395,7 @@ välj Lägg till TOTP för att lagra nyckeln på ett säkert sätt E-post med catch-all - Vidarebefordrad e-postalias + Vidarebefordrat e-postalias Slumpmässigt ord @@ -2458,10 +2458,10 @@ välj Lägg till TOTP för att lagra nyckeln på ett säkert sätt Delgivning av tillgänglighetstjänst - Bitwarden använder tillgänglighetstjänsten för att söka efter inloggningsfält i appar och på webbplatser. Därefter fastställs lämpliga fältidentifierare för att mata in användarnamn och lösenord när en träff för appen eller webbplatsen hittas. Vi lagrar inte någon av de uppgifter som hittas av tjänsten, Vi gör inte heller några försök att kontrollera några element på skärmen bortom textinmatning av identitetshandlingarna. + Bitwarden använder tillgänglighetstjänsten för att söka efter inloggningsfält i appar och på webbplatser. Därefter fastställs lämpliga fältidentifierare för att mata in användarnamn och lösenord när en träff för appen eller webbplatsen hittas. Vi lagrar inte några av de uppgifter som hittas av tjänsten, vi gör inte heller några försök att kontrollera några element på skärmen bortom textinmatning av identitetshandlingarna. - Godkänn + Acceptera Neka @@ -2474,4 +2474,43 @@ välj Lägg till TOTP för att lagra nyckeln på ett säkert sätt {0} Vill du byta till detta konto? + + Är du ny här? + + + Hämta huvudlösenordsledtråd + + + Loggar in som {0} + + + Är det inte du? + + + Logga in med huvudlösenord + + + Logga in med en annan enhet + + + Inloggning påbörjad + + + En avisering har skickats till din enhet. + + + Se till att ditt valv är upplåst och att fingeravtrycksfrasen matchar på den andra enheten. + + + Skicka avisering igen + + + Behöver du fler alternativ? + + + Visa alla inloggningsalternativ + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.ta.resx b/src/App/Resources/AppResources.ta.resx index 057e00c3a..d68deef35 100644 --- a/src/App/Resources/AppResources.ta.resx +++ b/src/App/Resources/AppResources.ta.resx @@ -2473,4 +2473,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.th.resx b/src/App/Resources/AppResources.th.resx index a7b7b3911..778efe983 100644 --- a/src/App/Resources/AppResources.th.resx +++ b/src/App/Resources/AppResources.th.resx @@ -1769,7 +1769,7 @@ Scanning will happen automatically. Syncing vault with pull down gesture. - Enterprise Single Sign-On + Enterprise single sign-on Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin. @@ -2480,4 +2480,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.tr.resx b/src/App/Resources/AppResources.tr.resx index 67433d76c..fb1f1a4b2 100644 --- a/src/App/Resources/AppResources.tr.resx +++ b/src/App/Resources/AppResources.tr.resx @@ -152,11 +152,11 @@ Copy some value to your clipboard. - Parolayı Kopyala + Parolayı kopyala The button text that allows a user to copy the login's password to their clipboard. - Kullanıcı Adını Kopyala + Kullanıcı adını kopyala The button text that allows a user to copy the login's username to their clipboard. @@ -229,7 +229,7 @@ Klasörler - Klasör güncellendi. + Klasör kaydedildi Web sitesine git @@ -247,7 +247,7 @@ Description message for the alert when internet connection is required to continue. - İnternet Bağlantısı Gerekiyor + İnternet bağlantısı gerekli Title for the alert when internet connection is required to continue. @@ -342,7 +342,7 @@ Reveal a hidden value (password). - Kayıt silindi. + Kayıt silindi Confirmation message after successfully deleting a login. @@ -375,11 +375,11 @@ Validation message for when a form field is left blank and is required to be entered. - {0} kopyalandı. + {0} kopyalandı Confirmation message after suceessfully copying a value to the clipboard. - Parmak İzini Doğrula + Parmak izini doğrula Ana parolayı doğrula @@ -428,7 +428,7 @@ Okurken karışabilecek karakterleri kullanma - Bitwarden Uygulama Uzantısı + Bitwarden uygulama uzantısı Kasanıza yeni hesaplar eklemenin en kolay yolu Bitwarden uygulama uzantısıdır. Bitwarden uygulama uzantısı hakkında daha fazla bilgi almak için "Ayarlar" ekranına bakabilirsiniz. @@ -604,7 +604,7 @@ Asla - Yeni kayıt oluşturuldu. + Kayıt eklendi Kasanızda hiç favoriniz yok. @@ -632,10 +632,10 @@ Diğer - Parola oluşturuldu. + Parola oluşturuldu - Parola Oluşturucu + Parola üretici Parola ipucu @@ -663,7 +663,7 @@ Ana parolayı tekrar yazın - Kasada Ara + Kasada ara Güvenlik @@ -681,7 +681,7 @@ Hesap Bilgileri - Hesap güncellendi. + Kayıt kaydedildi Gönderiliyor... @@ -692,10 +692,10 @@ Message shown when interacting with the server - Eşitleme tamamlandı. + Eşitleme tamamlandı - Eşitleme başarısız oldu. + Eşitleme başarısız oldu Kasayı şimdi eşitle @@ -708,7 +708,7 @@ İki aşamalı giriş - İki aşamalı giriş, hesabınıza girererken işlemi bir güvenlik anahtarı, şifrematik uygulaması, SMS, telefon araması veya e-posta gibi ek bir yöntemle doğrulamanızı isteyerek hesabınızın güvenliğini artırır. İki aşamalı giriş özelliğini bitwarden.com web kasası üzerinden etkinleştirebilirsiniz. Şimdi siteye gitmek ister misiniz? + İki aşamalı giriş, hesabınıza girererken işlemi bir güvenlik anahtarı, şifrematik uygulaması, SMS, telefon araması veya e-posta gibi ek bir yöntemle doğrulamanızı isteyerek hesabınızın güvenliğini artırır. İki aşamalı giriş özelliğini bitwarden.com web kasası üzerinden ayarlayabilirsiniz. Şimdi siteye gitmek ister misiniz? Kilidi {0} ile aç @@ -856,14 +856,14 @@ For 2FA - Doğrulama e-postası gönderildi. + Doğrulama e-postası gönderildi For 2FA Devam etmek için YubiKey NEO anahtarınızı cihazınızın arkasına doğru tutun veya YubiKey'i cihazınızın USB portuna takıp düğmesine dokunun. - YubiKey Güvenlik Anahtarı + YubiKey güvenlik anahtarı "YubiKey" is the product name and should not be translated. @@ -1143,7 +1143,7 @@ Kod otomatik olarak taranacaktır. Hesapların yanında tanıdık görseller göster. - Sunucu URL simgeleri + Simge sunucusu URL'si Bitwarden ile otomatik doldur @@ -1213,7 +1213,7 @@ Kod otomatik olarak taranacaktır. Metin - Yeni Özel Alan + Yeni özel alan Ne tür bir özel alan eklemek istiyorsunuz? @@ -1252,11 +1252,11 @@ Kod otomatik olarak taranacaktır. URI eşleşme tespiti - Eşleşme Tespiti + Eşleşme tespiti URI match detection for auto-fill. - Evet, Kaydet + Evet ve kaydet Otomatik doldur ve kaydet @@ -1278,7 +1278,7 @@ Kod otomatik olarak taranacaktır. Erişilebilirlik hizmeti, standart otomatik doldurma hizmetini desteklemeyen uygulamalarda işe yarayabilir. - Parola Güncellendi + Parola güncellendi ex. Date this password was updated @@ -1337,10 +1337,10 @@ Kod otomatik olarak taranacaktır. Hesaplar - Güvenli Notlar + Güvenli notlar - Tüm Öğeler + Tüm kayıtlar URl'ler @@ -1480,7 +1480,7 @@ Kod otomatik olarak taranacaktır. Kilidi aç - Kasanı Aç + Kasa kilidini aç 30 dakika @@ -1556,7 +1556,7 @@ Kod otomatik olarak taranacaktır. Varsayılan (sistem) temayı kullanırken cihazınızın koyu modu açıldığında koyu temaya geçmek için bunu seçin. - Notları kopyala + Notu kopyala Çıkış @@ -1595,7 +1595,7 @@ Kod otomatik olarak taranacaktır. Uygulama yeniden başlatılınca - Otomatik doldurma, web sitelerinden ve uygulamalardan Bitwarden kasanıza güvenle erişmenizi kolaylaştırır. Bitwarden otomatik doldurma hizmetini henüz etkinleştirmemişsiniz. "Ayarlar" ekranından otomatik doldurmayı etkinleştirin. + Otomatik doldurma, web sitelerinden ve uygulamalardan Bitwarden kasanıza güvenle erişmenizi kolaylaştırır. Bitwarden otomatik doldurma hizmetini henüz ayarlamamışsınız. "Ayarlar" ekranından otomatik doldurmayı ayarlayın. Tema değişiklikleriniz uygulama yeniden başlatılınca uygulanacaktır. @@ -1632,7 +1632,7 @@ Kod otomatik olarak taranacaktır. Bitwarden'la ilgilenmeniz gerekiyor: Bitwarden ayarlarından "Otomatik doldurma erişilebilirlik hizmeti"ne bakın - 3. Android'in uygulama ayarları bölümünde Bitwarden'ı bulun ve "diğer uygulamaların üstünde göster" ayarını açın. ("Gelişmiş" altında olabilir.) + 3. Android'in uygulama ayarları bölümünde Bitwarden'ı bulun ve "Diğer uygulamaların üzerinde görüntüle" ayarını ("Gelişmiş" altında) açın. İzin @@ -1726,7 +1726,7 @@ Kod otomatik olarak taranacaktır. Message shown when interacting with the server - Kayıt geri yüklendi. + Kayıt geri yüklendi Confirmation message after successfully restoring a soft-deleted item @@ -1756,7 +1756,7 @@ Kod otomatik olarak taranacaktır. Otomatik doldurma için biyometrik kilit açma devre dışı. Ana parolanın doğrulanması bekleniyor. - Yenileme sırasında eşitlemeyi etkinleştir + Yenileme sırasında eşitlemeye izin ver Parmağımla aşağı çektiğimde kasayı eşitle. @@ -1774,7 +1774,7 @@ Kod otomatik olarak taranacaktır. Şu anda SSO ile giriş yapılamıyor - Ana Parola Belirleyin + Ana parolayı belirle SSO ile girişinizi tamamlamak için lütfen kasanıza erişirken kullanacağınız ana parolayı belirleyin. @@ -1831,7 +1831,7 @@ Kod otomatik olarak taranacaktır. Satır içi otomatik doldurmayı kullan - Seçtiğiniz IME (klavye) destekliyorsa satır içi otomatik doldurmayı kullanabilirsiniz. Yapılandırmanız desteklenmiyorsa (veya bu seçenek devre dışıysa) varsayılan otomatik doldurma kutusu kullanılacaktır. + Seçtiğiniz IME (klavye) destekliyorsa satır içi otomatik doldurmayı kullanabilirsiniz. Yapılandırmanız desteklenmiyorsa (veya bu seçenek kapalıysa) varsayılan otomatik doldurma kutusu kullanılacaktır. Erişilebilirliği kullan @@ -1840,13 +1840,13 @@ Kod otomatik olarak taranacaktır. Uygulamalarda ve web'de hesap bilgilerinizi otomatik olarak doldurmak için Bitwarden erişilebilirlik hizmetini kullanabilirsiniz. Bu özelliği açarsanız giriş alanlarını seçtiğinizde bir açılır pencere karşınıza çıkacaktır. - Uygulamalarda ve web'de hesap bilgilerinizi otomatik olarak doldurmak için Bitwarden erişilebilirlik hizmetini kullanın. ("Üstünde gösterme"nin açılması gerekir.) + Uygulamalarda ve web'de hesap bilgilerinizi otomatik olarak doldurmak için Bitwarden erişilebilirlik hizmetini kullanın. ("Üstünde gösterme"nin de açılması gerekir.) Bitwarden erişilebilirlik hizmetini açarak otomatik doldurma hızlı eylem kutusunu kullanabilir ve/veya üstünde gösterme yöntemiyle (bu özellliği açarsanız) açılır pencere açabilirisiniz. - Otomatik doldurma hızlı eylem kutusunu kullanmak veya üstünde gösterme yöntemiyle (etkinleştirildiyse) otomatik doldurma hizmetini taklit etmek için gereklidir. + Otomatik doldurma hızlı eylem kutusunu kullanmak veya üstünde gösterme yöntemiyle (açıldıysa) otomatik doldurma hizmetini taklit etmek için gereklidir. Üstünde göstermeyi kullan @@ -1855,13 +1855,13 @@ Kod otomatik olarak taranacaktır. Bu seçeneği açarsanız, giriş formları seçildiğinde Bitwarden erişilebilirlik hizmeti bir açılır pencere görüntüleyebilir. - Bu seçeneği açarsanız, giriş formları seçildiğinde Bitwarden Erişilebilirlik Hizmeti formu otomatik doldurmanızı sağlamak için bir pencere açabilir. + Bu seçeneği açarsanız, giriş formları seçildiğinde Bitwarden Erişilebilirlik Hizmeti formu otomatik doldurmanızı sağlamak için bir pencere açar. Bu seçeneği açarsanız, Android'in otomatik doldurma özelliğini desteklemeyen eski uygulamalarda bu özelliği taklit eden bir pencere açılacaktır. - Kurumsal ilkeler nedeniyle kişisel kasanıza hesap kaydetmeniz kısıtlanmış. Sahip seçeneğini bir kuruluş olarak değiştirin ve mevcut koleksiyonlar arasından seçim yapın. + Bir kuruluş ilkesi nedeniyle kişisel kasanıza hesap kaydetmeniz kısıtlanmış. Sahip seçeneğini bir kuruluş olarak değiştirin ve mevcut koleksiyonlar arasından seçim yapın. Bir kuruluş ilkesi sahiplik seçeneklerinizi etkiliyor. @@ -2006,7 +2006,7 @@ Kod otomatik olarak taranacaktır. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Send ekle + Yeni Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2014,15 +2014,15 @@ Kod otomatik olarak taranacaktır. 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Send silindi. + Send silindi 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Send güncellendi. + Send kaydedildi 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - Yeni Send oluşturuldu. + Send oluşturuldu 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2185,7 +2185,7 @@ Kod otomatik olarak taranacaktır. Hesabınız kalıcı olarak silinmiştir - Doğrulama kodu geçersiz. + Doğrulama kodu geçersiz Tek kullanımlık parola iste @@ -2302,7 +2302,7 @@ Kod otomatik olarak taranacaktır. - Kilit seçeneklerinizi "Hiçbir zaman" olarak ayarlamak, kasanızın cihazınıza erişimi olan herkesin kullanımına açık olmasını sağlar. Bu seçeneği kullanırsanız, cihazınızı uygun şekilde koruduğunuzdan emin olmalısınız. + Kilit seçeneklerinizi "Asla" olarak ayarlarsanız cihazınıza erişebilen herkes kasanıza da erişebilir. Bu seçeneği kullanırsanız cihazınızı uygun şekilde koruduğunuzdan emin olmalısınız. Girilen adreslerden biri veya birkaçı geçersiz. Lütfen düzeltip yeniden kaydetmeyi deneyin. @@ -2314,7 +2314,7 @@ Kod otomatik olarak taranacaktır. Ekran kaydına izin ver - Ekran kaydını etkinleştirmek istediğinizden emin misiniz? + Ekran kaydını açmak istediğinizden emin misiniz? Giriş istendi @@ -2323,7 +2323,7 @@ Kod otomatik olarak taranacaktır. Giriş yapmaya mı çalışıyorsunuz? - Login attempt by {0} on {1} + {0} - {1} giriş denemesi Cihaz türü @@ -2452,23 +2452,62 @@ Kod otomatik olarak taranacaktır. Rastgele - Accessibility Service Disclosure + Erişilebilirlik Hizmeti Beyanı - 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. + Bitwarden; uygulamalarda ve web sitelerinde giriş alanlarını bulmak ve eşleşme bulunduğunda kullanıcı adı ve parolayı doldurmak için erişilebilirlik hizmetini kullanır. Hizmetin bize sunduğu hiçbir bilgiyi saklamayız ve hesap bilgilerinin girilmesi dışında ekrandaki öğeleri değiştirmek için herhangi bir girişimde bulunmayız. - Accept + Kabul et - Decline + Reddet Giriş isteğinin süresi doldu. - Login attempt from: + Giriş denemesi yapan hesap: {0} -Do you want to switch to this account? +Bu hesaba geçmek ister misiniz? + + + Buralarda yeni misiniz? + + + Ana parola ipucunu al + + + {0} olarak giriş yapılıyor + + + Siz değil misiniz? + + + Ana parola ile giriş yap + + + Başka bir cihazla giriş yap + + + Giriş başlatıldı + + + Cihazınıza bir bildirim gönderildi. + + + Lütfen kasanızın kilidinin açık olduğundan ve parmak izi ifadesinin diğer cihazla eşleştiğinden emin olun. + + + Bildirimi yeniden gönder + + + Başka bir seçeneğe mi ihtiyacınız var? + + + Tüm giriş seçeneklerini gör + + + Bu istek artık geçerli değil diff --git a/src/App/Resources/AppResources.uk.resx b/src/App/Resources/AppResources.uk.resx index 69d66004d..a628c3826 100644 --- a/src/App/Resources/AppResources.uk.resx +++ b/src/App/Resources/AppResources.uk.resx @@ -708,7 +708,7 @@ Двоетапна перевірка - Двоетапна перевірка робить ваш обліковий запис більш захищеним, вимагаючи підтвердження входу з використанням іншого пристрою, наприклад, за допомогою коду безпеки, програми авторизації, SMS, телефонного виклику, або е-пошти. Ви можете увімкнути двоетапну перевірку в сховищі на bitwarden.com. Хочете перейти на вебсайт зараз? + Двоетапна перевірка дає змогу надійніше захистити ваш обліковий запис, вимагаючи підтвердження входу з використанням іншого пристрою, наприклад, за допомогою коду безпеки, програми авторизації, SMS, телефонного виклику, або е-пошти. Ви можете налаштувати двоетапну перевірку в сховищі на bitwarden.com. Хочете перейти на вебсайт зараз? Розблокування з {0} @@ -2472,4 +2472,43 @@ {0} Хочете перемкнутися на цей обліковий запис? + + Виконуєте вхід вперше? + + + Отримати підказку для головного пароля + + + Вхід у систему як {0} + + + Не ви? + + + Увійти з головним паролем + + + Увійти з іншого пристрою + + + Ініційовано вхід + + + Сповіщення було надіслано на ваш пристрій. + + + Переконайтеся, що ваше сховище розблоковане, а фраза відбитка збігається з іншим пристроєм. + + + Надіслати сповіщення ще раз + + + Потрібен інший варіант? + + + Переглянути всі варіанти входу + + + Цей запит більше недійсний + diff --git a/src/App/Resources/AppResources.vi.resx b/src/App/Resources/AppResources.vi.resx index 5ff69e818..4130ec1d7 100644 --- a/src/App/Resources/AppResources.vi.resx +++ b/src/App/Resources/AppResources.vi.resx @@ -2472,4 +2472,43 @@ select Add TOTP to store the key safely {0} Do you want to switch to this account? + + New around here? + + + Get master password hint + + + Logging in as {0} + + + Not you? + + + Log in with master password + + + Log In with another device + + + Log in initiated + + + A notification has been sent to your device. + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + Resend notification + + + Need another option? + + + View all log in options + + + This request is no longer valid + diff --git a/src/App/Resources/AppResources.zh-Hans.resx b/src/App/Resources/AppResources.zh-Hans.resx index 906a5ffa0..d88190462 100644 --- a/src/App/Resources/AppResources.zh-Hans.resx +++ b/src/App/Resources/AppResources.zh-Hans.resx @@ -1152,7 +1152,7 @@ 密码库已锁定 - 转到密码库 + 转到我的密码库 集合 @@ -2472,4 +2472,43 @@ {0} 您想要切换到此账户吗? + + 新建在这里? + + + 获取主密码提示 + + + 正登录为 {0} + + + 不是你? + + + 使用主密码登录 + + + 使用其他设备登录 + + + 登录已发起 + + + 通知已发送到您的设备。 + + + 请确保您的密码库已解锁,并且指纹短语与其他设备上的相匹配。 + + + 重新发送通知 + + + 需要其他选项吗? + + + 查看所有登录选项 + + + 请求已失效 + diff --git a/src/App/Resources/AppResources.zh-Hant.resx b/src/App/Resources/AppResources.zh-Hant.resx index 706529593..0cd3efdbc 100644 --- a/src/App/Resources/AppResources.zh-Hant.resx +++ b/src/App/Resources/AppResources.zh-Hant.resx @@ -296,7 +296,7 @@ Text to define that there are more options things to see. - 密碼庫 + 我的密碼庫 The title for the vault page. @@ -425,7 +425,7 @@ 自動填入服務 - 避免使用易混淆的字元 + 避免易混淆的字元 Bitwarden App 延伸功能 @@ -461,7 +461,7 @@ 繼續 - 新增帳戶 + 建立帳戶 正在建立帳戶... @@ -681,7 +681,7 @@ 項目資訊 - 已更新項目。 + 項目已儲存 正在送出... @@ -827,7 +827,7 @@ For 2FA - 無法登入 + 登入無法使用 For 2FA whenever there are no available providers on this device. @@ -937,7 +937,7 @@ 檔案 - 未選擇檔案 + 未選擇任何檔案 沒有附件。 @@ -1143,7 +1143,7 @@ 在每個登入資料旁顯示一個可辨識的圖片。 - 圖標伺服器 URL + 圖示伺服器 URL 使用 Bitwarden 自動填入 @@ -1152,7 +1152,7 @@ 密碼庫已鎖定 - 前往密碼庫 + 前往我的密碼庫 集合 @@ -1614,7 +1614,7 @@ 共用 - 切換顯示 + 切換可見性 您的登入階段已逾期。 @@ -1726,7 +1726,7 @@ Message shown when interacting with the server - 已還原項目。 + 項目已還原 Confirmation message after successfully restoring a soft-deleted item @@ -1762,7 +1762,7 @@ 使用下拉手勢同步密碼庫。 - 企業單一登入 + 企業單一登入(SSO) 若要使用組織的單一登入入口快速登入。請先輸入您的組織識別碼。 @@ -2006,7 +2006,7 @@ 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. - 新增 Send + 建立新 Send 'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated. @@ -2472,4 +2472,43 @@ {0} 您想要切換至這個帳戶嗎? + + New around here? + + + 獲取主密碼提示 + + + 正登入為 {0} + + + 不是您嗎? + + + 使用主密碼登入 + + + 使用其他裝置登入 + + + 登入已發起 + + + 通知已傳送至您的裝置。 + + + Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device. + + + 重新傳送通知 + + + Need another option? + + + 檢視所有登入選項 + + + 此請求已失效 + diff --git a/src/App/Services/PushNotificationListenerService.cs b/src/App/Services/PushNotificationListenerService.cs index 26e5fe176..80adee2e1 100644 --- a/src/App/Services/PushNotificationListenerService.cs +++ b/src/App/Services/PushNotificationListenerService.cs @@ -228,7 +228,8 @@ namespace Bit.App.Services if (data is PasswordlessNotificationData passwordlessNotificationData) { var notificationUserId = await _stateService.Value.GetUserIdAsync(passwordlessNotificationData.UserEmail); - if (notificationUserId != null) + var notificationSaved = await _stateService.Value.GetPasswordlessLoginNotificationAsync(); + if (notificationUserId != null && notificationSaved != null) { await _stateService.Value.SetActiveUserAsync(notificationUserId); _messagingService.Value.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT); diff --git a/src/App/Utilities/AccountManagement/AccountsManager.cs b/src/App/Utilities/AccountManagement/AccountsManager.cs index bf64901c9..b804823f2 100644 --- a/src/App/Utilities/AccountManagement/AccountsManager.cs +++ b/src/App/Utilities/AccountManagement/AccountsManager.cs @@ -7,6 +7,7 @@ using Bit.Core.Abstractions; using Bit.Core.Enums; using Bit.Core.Models.Domain; using Bit.Core.Utilities; +using Xamarin.Essentials; using Xamarin.Forms; namespace Bit.App.Utilities.AccountManagement @@ -103,11 +104,12 @@ namespace Bit.App.Utilities.AccountManagement // var orgIdentifier = await _stateService.GetOrgIdentifierAsync(); var email = await _stateService.GetEmailAsync(); - _accountsManagerHost.Navigate(NavigationTarget.Login, new LoginNavigationParams(email)); + await _stateService.SetRememberedEmailAsync(email); + _accountsManagerHost.Navigate(NavigationTarget.HomeLogin, new HomeNavigationParams(true)); } else { - _accountsManagerHost.Navigate(NavigationTarget.HomeLogin); + _accountsManagerHost.Navigate(NavigationTarget.HomeLogin, new HomeNavigationParams(false)); } } } @@ -183,7 +185,7 @@ namespace Bit.App.Utilities.AccountManagement await Device.InvokeOnMainThreadAsync(() => { Options.HideAccountSwitcher = false; - _accountsManagerHost.Navigate(NavigationTarget.HomeLogin); + _accountsManagerHost.Navigate(NavigationTarget.HomeLogin, new HomeNavigationParams(false)); }); } @@ -218,5 +220,17 @@ namespace Bit.App.Utilities.AccountManagement _messagingService.Send(AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED); }); } + + public async Task PromptToSwitchToExistingAccountAsync(string userId) + { + var switchToAccount = await _platformUtilsService.ShowDialogAsync( + AppResources.SwitchToAlreadyAddedAccountConfirmation, + AppResources.AccountAlreadyAdded, AppResources.Yes, AppResources.Cancel); + if (switchToAccount) + { + await _stateService.SetActiveUserAsync(userId); + _messagingService.Send("switchedAccount"); + } + } } } diff --git a/src/App/Utilities/AccountManagement/HomeNavigationParams.cs b/src/App/Utilities/AccountManagement/HomeNavigationParams.cs new file mode 100644 index 000000000..9bda9f227 --- /dev/null +++ b/src/App/Utilities/AccountManagement/HomeNavigationParams.cs @@ -0,0 +1,14 @@ +using Bit.App.Abstractions; + +namespace Bit.App.Utilities.AccountManagement +{ + public class HomeNavigationParams : INavigationParams + { + public HomeNavigationParams(bool shouldCheckRememberEmail) + { + ShouldCheckRememberEmail = shouldCheckRememberEmail; + } + + public bool ShouldCheckRememberEmail { get; } + } +} diff --git a/src/Core/Abstractions/IApiService.cs b/src/Core/Abstractions/IApiService.cs index 208d17c0c..adbbef1a1 100644 --- a/src/Core/Abstractions/IApiService.cs +++ b/src/Core/Abstractions/IApiService.cs @@ -83,8 +83,11 @@ namespace Bit.Core.Abstractions Task PutSendAsync(string id, SendRequest request); Task PutSendRemovePasswordAsync(string id); Task DeleteSendAsync(string id); + Task> GetAuthRequestAsync(); Task GetAuthRequestAsync(string id); + Task GetAuthResponseAsync(string id, string accessCode); Task PutAuthRequestAsync(string id, string key, string masterPasswordHash, string deviceIdentifier, bool requestApproved); + Task PostCreateRequestAsync(PasswordlessCreateLoginRequest passwordlessCreateLoginRequest); Task GetUsernameFromAsync(ForwardedEmailServiceType service, UsernameGeneratorConfig config); Task GetKnownDeviceAsync(string email, string deviceIdentifier); } diff --git a/src/Core/Abstractions/IAuthService.cs b/src/Core/Abstractions/IAuthService.cs index e151daabd..e1c947a9d 100644 --- a/src/Core/Abstractions/IAuthService.cs +++ b/src/Core/Abstractions/IAuthService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Bit.Core.Enums; using Bit.Core.Models.Domain; +using Bit.Core.Models.Request; using Bit.Core.Models.Response; namespace Bit.Core.Abstractions @@ -26,9 +27,13 @@ namespace Bit.Core.Abstractions Task LogInSsoAsync(string code, string codeVerifier, string redirectUrl, string orgId); Task LogInCompleteAsync(string email, string masterPassword, TwoFactorProviderType twoFactorProvider, string twoFactorToken, bool? remember = null); Task LogInTwoFactorAsync(TwoFactorProviderType twoFactorProvider, string twoFactorToken, string captchaToken, bool? remember = null); + Task LogInPasswordlessAsync(string email, string accessCode, string authRequestId, byte[] decryptionKey, string userKeyCiphered, string localHashedPasswordCiphered); + Task> GetPasswordlessLoginRequestsAsync(); Task GetPasswordlessLoginRequestByIdAsync(string id); + Task GetPasswordlessLoginResponseAsync(string id, string accessCode); Task PasswordlessLoginAsync(string id, string pubKey, bool requestApproved); + Task PasswordlessCreateLoginRequestAsync(string email); void LogOut(Action callback); void Init(); diff --git a/src/Core/Abstractions/ICryptoService.cs b/src/Core/Abstractions/ICryptoService.cs index c06b5b272..b628f3ac1 100644 --- a/src/Core/Abstractions/ICryptoService.cs +++ b/src/Core/Abstractions/ICryptoService.cs @@ -46,6 +46,7 @@ namespace Bit.Core.Abstractions Task RandomNumberAsync(int min, int max); Task> RemakeEncKeyAsync(SymmetricCryptoKey key); Task RsaEncryptAsync(byte[] data, byte[] publicKey = null); + Task RsaDecryptAsync(string encValue, byte[] privateKey = null); Task SetEncKeyAsync(string encKey); Task SetEncPrivateKeyAsync(string encPrivateKey); Task SetKeyAsync(SymmetricCryptoKey key); diff --git a/src/Core/Abstractions/IStateService.cs b/src/Core/Abstractions/IStateService.cs index 529f379ba..63a020403 100644 --- a/src/Core/Abstractions/IStateService.cs +++ b/src/Core/Abstractions/IStateService.cs @@ -13,6 +13,7 @@ namespace Bit.Core.Abstractions { List AccountViews { get; } Task GetActiveUserIdAsync(); + Task GetActiveUserEmailAsync(); Task IsActiveAccountAsync(string userId = null); Task SetActiveUserAsync(string userId); Task CheckExtensionActiveUserAndSwitchIfNeededAsync(); diff --git a/src/Core/Abstractions/ISyncService.cs b/src/Core/Abstractions/ISyncService.cs index 7cfe707e6..aeb0205b1 100644 --- a/src/Core/Abstractions/ISyncService.cs +++ b/src/Core/Abstractions/ISyncService.cs @@ -14,5 +14,7 @@ namespace Bit.Core.Abstractions Task SyncDeleteFolderAsync(SyncFolderNotification notification); Task SyncUpsertCipherAsync(SyncCipherNotification notification, bool isEdit); Task SyncUpsertFolderAsync(SyncFolderNotification notification, bool isEdit); + // Passwordless code will be moved to an independent service in future techdept + Task SyncPasswordlessLoginRequestsAsync(); } } diff --git a/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs b/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs new file mode 100644 index 000000000..aeaff5f1f --- /dev/null +++ b/src/Core/Models/Request/PasswordlessCreateLoginRequest.cs @@ -0,0 +1,34 @@ +using System; +namespace Bit.Core.Models.Request +{ + public class PasswordlessCreateLoginRequest + { + public PasswordlessCreateLoginRequest(string email, string publicKey, string deviceIdentifier, string accessCode, AuthRequestType? type, string fingerprintPhrase) + { + Email = email ?? throw new ArgumentNullException(nameof(email)); + PublicKey = publicKey ?? throw new ArgumentNullException(nameof(publicKey)); + DeviceIdentifier = deviceIdentifier ?? throw new ArgumentNullException(nameof(deviceIdentifier)); + AccessCode = accessCode ?? throw new ArgumentNullException(nameof(accessCode)); + Type = type; + FingerprintPhrase = fingerprintPhrase ?? throw new ArgumentNullException(nameof(fingerprintPhrase)); + } + + public string Email { get; set; } + + public string PublicKey { get; set; } + + public string DeviceIdentifier { get; set; } + + public string AccessCode { get; set; } + + public AuthRequestType? Type { get; set; } + + public string FingerprintPhrase { get; set; } + } + + public enum AuthRequestType : byte + { + AuthenticateAndUnlock = 0, + Unlock = 1 + } +} diff --git a/src/Core/Models/Request/TokenRequest.cs b/src/Core/Models/Request/TokenRequest.cs index fe299e455..75d14fdb9 100644 --- a/src/Core/Models/Request/TokenRequest.cs +++ b/src/Core/Models/Request/TokenRequest.cs @@ -15,13 +15,14 @@ namespace Bit.Core.Models.Request public string CodeVerifier { get; set; } public string RedirectUri { get; set; } public string Token { get; set; } + public string AuthRequestId { get; set; } public TwoFactorProviderType? Provider { get; set; } public bool? Remember { get; set; } public string CaptchaToken { get; set; } public DeviceRequest Device { get; set; } public TokenRequest(string[] credentials, string[] codes, TwoFactorProviderType? provider, string token, - bool? remember, string captchaToken, DeviceRequest device = null) + bool? remember, string captchaToken, DeviceRequest device = null, string authRequestId = null) { if (credentials != null && credentials.Length > 1) { @@ -39,6 +40,7 @@ namespace Bit.Core.Models.Request Remember = remember; Device = device; CaptchaToken = captchaToken; + AuthRequestId = authRequestId; } public Dictionary ToIdentityToken(string clientId) @@ -67,6 +69,11 @@ namespace Bit.Core.Models.Request throw new Exception("must provide credentials or codes"); } + if (AuthRequestId != null) + { + obj.Add("authRequest", AuthRequestId); + } + if (Device != null) { obj.Add("deviceType", ((int)Device.Type).ToString()); diff --git a/src/Core/Models/Response/PasswordlessLoginResponse.cs b/src/Core/Models/Response/PasswordlessLoginResponse.cs index 20113de8e..4aaedc2a7 100644 --- a/src/Core/Models/Response/PasswordlessLoginResponse.cs +++ b/src/Core/Models/Response/PasswordlessLoginResponse.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using Bit.Core.Enums; +using Bit.Core.Models.Data; namespace Bit.Core.Models.Response { @@ -13,7 +15,19 @@ namespace Bit.Core.Models.Response public string Key { get; set; } public string MasterPasswordHash { get; set; } public DateTime CreationDate { get; set; } - public bool RequestApproved { get; set; } + public DateTime? ResponseDate { get; set; } + public bool? RequestApproved { get; set; } public string Origin { get; set; } + public string RequestAccessCode { get; set; } + public Tuple RequestKeyPair { get; set; } + + public bool IsAnswered => RequestApproved != null && ResponseDate != null; + + public bool IsExpired => CreationDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes) < DateTime.UtcNow; + } + + public class PasswordlessLoginsResponse + { + public List Data { get; set; } } } diff --git a/src/Core/Services/ApiService.cs b/src/Core/Services/ApiService.cs index 256135310..e4c0db826 100644 --- a/src/Core/Services/ApiService.cs +++ b/src/Core/Services/ApiService.cs @@ -536,11 +536,27 @@ namespace Bit.Core.Services #region PasswordlessLogin + public async Task> GetAuthRequestAsync() + { + var response = await SendAsync(HttpMethod.Get, $"/auth-requests/", null, true, true); + return response.Data; + } + public Task GetAuthRequestAsync(string id) { return SendAsync(HttpMethod.Get, $"/auth-requests/{id}", null, true, true); } + public Task GetAuthResponseAsync(string id, string accessCode) + { + return SendAsync(HttpMethod.Get, $"/auth-requests/{id}/response?code={accessCode}", null, false, true); + } + + public Task PostCreateRequestAsync(PasswordlessCreateLoginRequest passwordlessCreateLoginRequest) + { + return SendAsync(HttpMethod.Post, $"/auth-requests", passwordlessCreateLoginRequest, false, true); + } + public Task PutAuthRequestAsync(string id, string encKey, string encMasterPasswordHash, string deviceIdentifier, bool requestApproved) { var request = new PasswordlessLoginRequest(encKey, encMasterPasswordHash, deviceIdentifier, requestApproved); diff --git a/src/Core/Services/AuthService.cs b/src/Core/Services/AuthService.cs index f85473397..4e95cf847 100644 --- a/src/Core/Services/AuthService.cs +++ b/src/Core/Services/AuthService.cs @@ -24,8 +24,8 @@ namespace Bit.Core.Services private readonly IPlatformUtilsService _platformUtilsService; private readonly IMessagingService _messagingService; private readonly IKeyConnectorService _keyConnectorService; + private readonly IPasswordGenerationService _passwordGenerationService; private readonly bool _setCryptoKeys; - private SymmetricCryptoKey _key; public AuthService( @@ -40,6 +40,7 @@ namespace Bit.Core.Services IMessagingService messagingService, IVaultTimeoutService vaultTimeoutService, IKeyConnectorService keyConnectorService, + IPasswordGenerationService passwordGenerationService, bool setCryptoKeys = true) { _cryptoService = cryptoService; @@ -52,6 +53,7 @@ namespace Bit.Core.Services _platformUtilsService = platformUtilsService; _messagingService = messagingService; _keyConnectorService = keyConnectorService; + _passwordGenerationService = passwordGenerationService; _setCryptoKeys = setCryptoKeys; TwoFactorProviders = new Dictionary(); @@ -137,6 +139,14 @@ namespace Bit.Core.Services null, captchaToken); } + public async Task LogInPasswordlessAsync(string email, string accessCode, string authRequestId, byte[] decryptionKey, string userKeyCiphered, string localHashedPasswordCiphered) + { + var decKey = await _cryptoService.RsaDecryptAsync(userKeyCiphered, decryptionKey); + var decPasswordHash = await _cryptoService.RsaDecryptAsync(localHashedPasswordCiphered, decryptionKey); + return await LogInHelperAsync(email, accessCode, Encoding.UTF8.GetString(decPasswordHash), null, null, null, new SymmetricCryptoKey(decKey), null, null, + null, null, authRequestId: authRequestId); + } + public async Task LogInSsoAsync(string code, string codeVerifier, string redirectUrl, string orgId) { SelectedTwoFactorProviderType = null; @@ -286,7 +296,7 @@ namespace Bit.Core.Services private async Task LogInHelperAsync(string email, string hashedPassword, string localHashedPassword, string code, string codeVerifier, string redirectUrl, SymmetricCryptoKey key, TwoFactorProviderType? twoFactorProvider = null, string twoFactorToken = null, bool? remember = null, - string captchaToken = null, string orgId = null) + string captchaToken = null, string orgId = null, string authRequestId = null) { var storedTwoFactorToken = await _tokenService.GetTwoFactorTokenAsync(email); var appId = await _appIdService.GetAppIdAsync(); @@ -322,6 +332,10 @@ namespace Bit.Core.Services request = new TokenRequest(emailPassword, codeCodeVerifier, TwoFactorProviderType.Remember, storedTwoFactorToken, false, captchaToken, deviceRequest); } + else if (authRequestId != null) + { + request = new TokenRequest(emailPassword, null, null, null, false, null, deviceRequest, authRequestId); + } else { request = new TokenRequest(emailPassword, codeCodeVerifier, null, null, false, captchaToken, deviceRequest); @@ -471,11 +485,21 @@ namespace Bit.Core.Services SelectedTwoFactorProviderType = null; } + public async Task> GetPasswordlessLoginRequestsAsync() + { + return await _apiService.GetAuthRequestAsync(); + } + public async Task GetPasswordlessLoginRequestByIdAsync(string id) { return await _apiService.GetAuthRequestAsync(id); } + public async Task GetPasswordlessLoginResponseAsync(string id, string accessCode) + { + return await _apiService.GetAuthResponseAsync(id, accessCode); + } + public async Task PasswordlessLoginAsync(string id, string pubKey, bool requestApproved) { var publicKey = CoreHelpers.Base64UrlDecode(pubKey); @@ -485,5 +509,25 @@ namespace Bit.Core.Services var deviceId = await _appIdService.GetAppIdAsync(); return await _apiService.PutAuthRequestAsync(id, encryptedKey.EncryptedString, encryptedMasterPassword.EncryptedString, deviceId, requestApproved); } + + public async Task PasswordlessCreateLoginRequestAsync(string email) + { + var deviceId = await _appIdService.GetAppIdAsync(); + var keyPair = await _cryptoFunctionService.RsaGenerateKeyPairAsync(2048); + var generatedFingerprintPhrase = await _cryptoService.GetFingerprintAsync(email, keyPair.Item1); + var fingerprintPhrase = string.Join("-", generatedFingerprintPhrase); + var publicB64 = Convert.ToBase64String(keyPair.Item1); + var accessCode = await _passwordGenerationService.GeneratePasswordAsync(new PasswordGenerationOptions(true) { Length = 25 }); + var passwordlessCreateLoginRequest = new PasswordlessCreateLoginRequest(email, publicB64, deviceId, accessCode, AuthRequestType.AuthenticateAndUnlock, fingerprintPhrase); + var response = await _apiService.PostCreateRequestAsync(passwordlessCreateLoginRequest); + + if (response != null) + { + response.RequestKeyPair = keyPair; + response.RequestAccessCode = accessCode; + } + + return response; + } } } diff --git a/src/Core/Services/CryptoService.cs b/src/Core/Services/CryptoService.cs index 5cd5312eb..96977ca5a 100644 --- a/src/Core/Services/CryptoService.cs +++ b/src/Core/Services/CryptoService.cs @@ -723,7 +723,7 @@ namespace Bit.Core.Services return await _cryptoFunctionService.AesDecryptAsync(data, iv, theKey.EncKey); } - private async Task RsaDecryptAsync(string encValue) + public async Task RsaDecryptAsync(string encValue, byte[] privateKey = null) { var headerPieces = encValue.Split('.'); EncryptionType? encType = null; @@ -750,7 +750,12 @@ namespace Bit.Core.Services } var data = Convert.FromBase64String(encPieces[0]); - var privateKey = await GetPrivateKeyAsync(); + + if (privateKey is null) + { + privateKey = await GetPrivateKeyAsync(); + } + if (privateKey == null) { throw new Exception("No private key."); diff --git a/src/Core/Services/StateService.cs b/src/Core/Services/StateService.cs index 2071810c0..e13efadd6 100644 --- a/src/Core/Services/StateService.cs +++ b/src/Core/Services/StateService.cs @@ -46,6 +46,12 @@ namespace Bit.Core.Services return activeUserId; } + public async Task GetActiveUserEmailAsync() + { + var activeUserId = await GetActiveUserIdAsync(); + return await GetEmailAsync(activeUserId); + } + public async Task IsActiveAccountAsync(string userId = null) { if (userId == null) diff --git a/src/Core/Services/SyncService.cs b/src/Core/Services/SyncService.cs index ba90d1da9..cf3db3a7e 100644 --- a/src/Core/Services/SyncService.cs +++ b/src/Core/Services/SyncService.cs @@ -24,6 +24,7 @@ namespace Bit.Core.Services private readonly IPolicyService _policyService; private readonly ISendService _sendService; private readonly IKeyConnectorService _keyConnectorService; + private readonly ILogger _logger; private readonly Func, Task> _logoutCallbackAsync; public SyncService( @@ -39,6 +40,7 @@ namespace Bit.Core.Services IPolicyService policyService, ISendService sendService, IKeyConnectorService keyConnectorService, + ILogger logger, Func, Task> logoutCallbackAsync) { _stateService = stateService; @@ -53,6 +55,7 @@ namespace Bit.Core.Services _policyService = policyService; _sendService = sendService; _keyConnectorService = keyConnectorService; + _logger = logger; _logoutCallbackAsync = logoutCallbackAsync; } @@ -382,5 +385,45 @@ namespace Bit.Core.Services new Dictionary(); await _sendService.ReplaceAsync(sends); } + + public async Task SyncPasswordlessLoginRequestsAsync() + { + try + { + var userId = await _stateService.GetActiveUserIdAsync(); + // if the user has not enabled passwordless logins ignore requests + if (!await _stateService.GetApprovePasswordlessLoginsAsync(userId)) + { + return; + } + + var loginRequests = await _apiService.GetAuthRequestAsync(); + if (loginRequests == null || !loginRequests.Any()) + { + return; + } + + var validLoginRequest = loginRequests.Where(l => !l.IsAnswered && !l.IsExpired) + .OrderByDescending(x => x.CreationDate) + .FirstOrDefault(); + + if (validLoginRequest is null) + { + return; + } + + await _stateService.SetPasswordlessLoginNotificationAsync(new PasswordlessRequestNotification() + { + Id = validLoginRequest.Id, + UserId = userId + }); + + _messagingService.Send(Constants.PasswordlessLoginRequestKey); + } + catch (Exception ex) + { + _logger.Exception(ex); + } + } } } diff --git a/src/Core/Utilities/ServiceContainer.cs b/src/Core/Utilities/ServiceContainer.cs index 4015d960e..003432f30 100644 --- a/src/Core/Utilities/ServiceContainer.cs +++ b/src/Core/Utilities/ServiceContainer.cs @@ -29,6 +29,8 @@ namespace Bit.Core.Utilities var messagingService = Resolve("messagingService"); var cryptoFunctionService = Resolve("cryptoFunctionService"); var cryptoService = Resolve("cryptoService"); + var logger = Resolve(); + SearchService searchService = null; var tokenService = new TokenService(stateService); @@ -67,7 +69,7 @@ namespace Bit.Core.Utilities }); var syncService = new SyncService(stateService, apiService, settingsService, folderService, cipherService, cryptoService, collectionService, organizationService, messagingService, policyService, sendService, - keyConnectorService, (extras) => + keyConnectorService, logger, (extras) => { messagingService.Send("logout", extras); return Task.CompletedTask; @@ -77,7 +79,7 @@ namespace Bit.Core.Utilities var totpService = new TotpService(cryptoFunctionService); var authService = new AuthService(cryptoService, cryptoFunctionService, apiService, stateService, tokenService, appIdService, i18nService, platformUtilsService, messagingService, vaultTimeoutService, - keyConnectorService); + keyConnectorService, passwordGenerationService); var exportService = new ExportService(folderService, cipherService, cryptoService); var auditService = new AuditService(cryptoFunctionService, apiService); var environmentService = new EnvironmentService(apiService, stateService); diff --git a/src/iOS.Autofill/CredentialProviderViewController.cs b/src/iOS.Autofill/CredentialProviderViewController.cs index 711fb0652..930d8b673 100644 --- a/src/iOS.Autofill/CredentialProviderViewController.cs +++ b/src/iOS.Autofill/CredentialProviderViewController.cs @@ -425,10 +425,10 @@ namespace Bit.iOS.Autofill } } - private void LaunchHomePage(bool checkRememberedEmail = true) + private void LaunchHomePage(bool shouldCheckRememberEmail = true) { var appOptions = new AppOptions { IosExtension = true }; - var homePage = new HomePage(appOptions, checkRememberedEmail: checkRememberedEmail); + var homePage = new HomePage(appOptions, shouldCheckRememberEmail); var app = new App.App(appOptions); ThemeManager.SetTheme(app.Resources); ThemeManager.ApplyResourcesTo(homePage); @@ -457,8 +457,8 @@ namespace Bit.iOS.Autofill ThemeManager.ApplyResourcesTo(environmentPage); if (environmentPage.BindingContext is EnvironmentPageViewModel vm) { - vm.SubmitSuccessAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); - vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); + vm.SubmitSuccessAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); } var navigationPage = new NavigationPage(environmentPage); @@ -476,7 +476,7 @@ namespace Bit.iOS.Autofill if (registerPage.BindingContext is RegisterPageViewModel vm) { vm.RegistrationSuccess = () => DismissViewController(false, () => LaunchLoginFlow(vm.Email)); - vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); } var navigationPage = new NavigationPage(registerPage); @@ -497,8 +497,9 @@ namespace Bit.iOS.Autofill vm.StartTwoFactorAction = () => DismissViewController(false, () => LaunchTwoFactorFlow(false)); vm.UpdateTempPasswordAction = () => DismissViewController(false, () => LaunchUpdateTempPasswordFlow()); vm.StartSsoLoginAction = () => DismissViewController(false, () => LaunchLoginSsoFlow()); + vm.LogInWithDeviceAction = () => DismissViewController(false, () => LaunchLoginWithDevice(email)); vm.LogInSuccessAction = () => DismissLockAndContinue(); - vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); } var navigationPage = new NavigationPage(loginPage); @@ -509,6 +510,29 @@ namespace Bit.iOS.Autofill LogoutIfAuthed(); } + private void LaunchLoginWithDevice(string email = null) + { + var appOptions = new AppOptions { IosExtension = true }; + var app = new App.App(appOptions); + var loginWithDevicePage = new LoginPasswordlessRequestPage(email, appOptions); + ThemeManager.SetTheme(app.Resources); + ThemeManager.ApplyResourcesTo(loginWithDevicePage); + if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) + { + vm.StartTwoFactorAction = () => DismissViewController(false, () => LaunchTwoFactorFlow(false)); + vm.UpdateTempPasswordAction = () => DismissViewController(false, () => LaunchUpdateTempPasswordFlow()); + vm.LogInSuccessAction = () => DismissLockAndContinue(); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage()); + } + + var navigationPage = new NavigationPage(loginWithDevicePage); + var loginController = navigationPage.CreateViewController(); + loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; + PresentViewController(loginController, true, null); + + LogoutIfAuthed(); + } + private void LaunchLoginSsoFlow() { var loginPage = new LoginSsoPage(); @@ -604,7 +628,14 @@ namespace Bit.iOS.Autofill switch (navTarget) { case NavigationTarget.HomeLogin: - DismissViewController(false, () => LaunchHomePage()); + if (navParams is HomeNavigationParams homeParams) + { + DismissViewController(false, () => LaunchHomePage(homeParams.ShouldCheckRememberEmail)); + } + else + { + DismissViewController(false, () => LaunchHomePage()); + } break; case NavigationTarget.Login: if (navParams is LoginNavigationParams loginParams) diff --git a/src/iOS.Extension/LoadingViewController.cs b/src/iOS.Extension/LoadingViewController.cs index b60837779..debc634d7 100644 --- a/src/iOS.Extension/LoadingViewController.cs +++ b/src/iOS.Extension/LoadingViewController.cs @@ -446,10 +446,10 @@ namespace Bit.iOS.Extension }); } - private void LaunchHomePage(bool checkRememberedEmail = true) + private void LaunchHomePage(bool shouldCheckRememberEmail = true) { var appOptions = new AppOptions { IosExtension = true }; - var homePage = new HomePage(appOptions, checkRememberedEmail: checkRememberedEmail); + var homePage = new HomePage(appOptions, shouldCheckRememberEmail); var app = new App.App(appOptions); ThemeManager.SetTheme(app.Resources); ThemeManager.ApplyResourcesTo(homePage); @@ -478,8 +478,8 @@ namespace Bit.iOS.Extension ThemeManager.ApplyResourcesTo(environmentPage); if (environmentPage.BindingContext is EnvironmentPageViewModel vm) { - vm.SubmitSuccessAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); - vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); + vm.SubmitSuccessAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); } var navigationPage = new NavigationPage(environmentPage); @@ -497,7 +497,7 @@ namespace Bit.iOS.Extension if (registerPage.BindingContext is RegisterPageViewModel vm) { vm.RegistrationSuccess = () => DismissViewController(false, () => LaunchLoginFlow(vm.Email)); - vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); } var navigationPage = new NavigationPage(registerPage); @@ -518,8 +518,9 @@ namespace Bit.iOS.Extension vm.StartTwoFactorAction = () => DismissViewController(false, () => LaunchTwoFactorFlow(false)); vm.UpdateTempPasswordAction = () => DismissViewController(false, () => LaunchUpdateTempPasswordFlow()); vm.StartSsoLoginAction = () => DismissViewController(false, () => LaunchLoginSsoFlow()); + vm.LogInWithDeviceAction = () => DismissViewController(false, () => LaunchLoginWithDevice(email)); vm.LogInSuccessAction = () => DismissLockAndContinue(); - vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(checkRememberedEmail: false)); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage(shouldCheckRememberEmail: false)); } var navigationPage = new NavigationPage(loginPage); @@ -530,6 +531,29 @@ namespace Bit.iOS.Extension LogoutIfAuthed(); } + private void LaunchLoginWithDevice(string email = null) + { + var appOptions = new AppOptions { IosExtension = true }; + var app = new App.App(appOptions); + var loginWithDevicePage = new LoginPasswordlessRequestPage(email, appOptions); + ThemeManager.SetTheme(app.Resources); + ThemeManager.ApplyResourcesTo(loginWithDevicePage); + if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) + { + vm.StartTwoFactorAction = () => DismissViewController(false, () => LaunchTwoFactorFlow(false)); + vm.UpdateTempPasswordAction = () => DismissViewController(false, () => LaunchUpdateTempPasswordFlow()); + vm.LogInSuccessAction = () => DismissLockAndContinue(); + vm.CloseAction = () => DismissViewController(false, () => LaunchHomePage()); + } + + var navigationPage = new NavigationPage(loginWithDevicePage); + var loginController = navigationPage.CreateViewController(); + loginController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; + PresentViewController(loginController, true, null); + + LogoutIfAuthed(); + } + private void LaunchLoginSsoFlow() { var loginPage = new LoginSsoPage(); diff --git a/src/iOS.ShareExtension/LoadingViewController.cs b/src/iOS.ShareExtension/LoadingViewController.cs index 93213cff2..b6d8abed0 100644 --- a/src/iOS.ShareExtension/LoadingViewController.cs +++ b/src/iOS.ShareExtension/LoadingViewController.cs @@ -287,9 +287,9 @@ namespace Bit.iOS.ShareExtension return _app; } - private void LaunchHomePage(bool checkRememberedEmail = true) + private void LaunchHomePage(bool shouldCheckRememberEmail = true) { - var homePage = new HomePage(_appOptions.Value, checkRememberedEmail: checkRememberedEmail); + var homePage = new HomePage(_appOptions.Value, shouldCheckRememberEmail); SetupAppAndApplyResources(homePage); if (homePage.BindingContext is HomeViewModel vm) { @@ -311,8 +311,8 @@ namespace Bit.iOS.ShareExtension ThemeManager.ApplyResourcesTo(environmentPage); if (environmentPage.BindingContext is EnvironmentPageViewModel vm) { - vm.SubmitSuccessAction = () => DismissAndLaunch(() => LaunchHomePage(checkRememberedEmail: false)); - vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage(checkRememberedEmail: false)); + vm.SubmitSuccessAction = () => DismissAndLaunch(() => LaunchHomePage(shouldCheckRememberEmail: false)); + vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage(shouldCheckRememberEmail: false)); } NavigateToPage(environmentPage); @@ -325,7 +325,7 @@ namespace Bit.iOS.ShareExtension if (registerPage.BindingContext is RegisterPageViewModel vm) { vm.RegistrationSuccess = () => DismissAndLaunch(() => LaunchLoginFlow(vm.Email)); - vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage(checkRememberedEmail: false)); + vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage(shouldCheckRememberEmail: false)); } NavigateToPage(registerPage); } @@ -339,17 +339,31 @@ namespace Bit.iOS.ShareExtension vm.StartTwoFactorAction = () => DismissAndLaunch(() => LaunchTwoFactorFlow(false)); vm.UpdateTempPasswordAction = () => DismissAndLaunch(() => LaunchUpdateTempPasswordFlow()); vm.StartSsoLoginAction = () => DismissAndLaunch(() => LaunchLoginSsoFlow()); - vm.LogInSuccessAction = () => - { - DismissLockAndContinue(); - }; - vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage(checkRememberedEmail: false)); + vm.LogInWithDeviceAction = () => DismissAndLaunch(() => LaunchLoginWithDevice(email)); + vm.LogInSuccessAction = () => { DismissLockAndContinue(); }; + vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage(shouldCheckRememberEmail: false)); } NavigateToPage(loginPage); LogoutIfAuthed(); } + private void LaunchLoginWithDevice(string email = null) + { + var loginWithDevicePage = new LoginPasswordlessRequestPage(email, _appOptions.Value); + SetupAppAndApplyResources(loginWithDevicePage); + if (loginWithDevicePage.BindingContext is LoginPasswordlessRequestViewModel vm) + { + vm.StartTwoFactorAction = () => DismissAndLaunch(() => LaunchTwoFactorFlow(false)); + vm.UpdateTempPasswordAction = () => DismissAndLaunch(() => LaunchUpdateTempPasswordFlow()); + vm.LogInSuccessAction = () => { DismissLockAndContinue(); }; + vm.CloseAction = () => DismissAndLaunch(() => LaunchHomePage()); + } + NavigateToPage(loginWithDevicePage); + + LogoutIfAuthed(); + } + private void LaunchLoginSsoFlow() { var loginPage = new LoginSsoPage(); @@ -427,7 +441,14 @@ namespace Bit.iOS.ShareExtension switch (navTarget) { case NavigationTarget.HomeLogin: - ExecuteLaunch(() => LaunchHomePage()); + if (navParams is HomeNavigationParams homeParams) + { + ExecuteLaunch(() => LaunchHomePage(homeParams.ShouldCheckRememberEmail)); + } + else + { + ExecuteLaunch(() => LaunchHomePage()); + } break; case NavigationTarget.Login: if (navParams is LoginNavigationParams loginParams) diff --git a/store/apple/en-IN/copy.resx b/store/apple/en-IN/copy.resx index db8ca26a7..1a32e3d98 100644 --- a/store/apple/en-IN/copy.resx +++ b/store/apple/en-IN/copy.resx @@ -146,8 +146,7 @@ Global Translations Bitwarden translations exist in 40 languages and are growing, thanks to our global community. Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. - +Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. Max 4000 characters diff --git a/store/apple/hr/copy.resx b/store/apple/hr/copy.resx index 87d7905dc..ddac98021 100644 --- a/store/apple/hr/copy.resx +++ b/store/apple/hr/copy.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden - Besplatni upravitelj lozinki + Bitwarden - besplatni upravitelj lozinki Max 30 characters @@ -130,7 +130,7 @@ Upravljajte, spremajte, osigurajte i dijelite neograničen broj lozinki na neogr Generirajte jake, jedinstvene i nasumične lozinke bazirane na sigurnosnim zahtjevima za svaku web stranicu koju često posjećujete. -Bitwarden Send omoguzćuje jednostavno i brzo slanje šifriranih podataka --- datoteki ili teksta -- direktno, bilo kome. +Bitwarden Send omoguzćuje jednostavno i brzo slanje šifriranih podataka --- datoteka ili teksta -- direktno, bilo kome. Bitwarden nudi Teams i Enterprise planove za tvrtke kako biste sigurno mogli dijeliti lozinke s kolegama na poslu. @@ -146,7 +146,8 @@ Svjetski dostupan Bitwarden je, zahvaljujući našoj globalnoj zajednici, dostupan na više od 40 jezika. Podržani svi OS -Osigurajte i sigurno dijelite osjetljive podatke sadržane u vašem Bitwarden trezoru iz bilo kojeg preglednika, mobilnog uređaja ili stolnog računala s bilo kojim OS. +Osigurajte i sigurno dijelite osjetljive podatke sadržane u vašem Bitwarden trezoru iz bilo kojeg preglednika, mobilnog uređaja ili stolnog računala s bilo kojim OS. + Max 4000 characters diff --git a/store/apple/ja/copy.resx b/store/apple/ja/copy.resx index 3e735f69c..7f8408dc3 100644 --- a/store/apple/ja/copy.resx +++ b/store/apple/ja/copy.resx @@ -122,32 +122,31 @@ Max 30 characters - Bitwarden, Inc. is the parent company of 8bit Solutions LLC. + Bitwarden, Inc. は 8bit Solutions LLC の親会社です。 -NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS & WORLD REPORT, CNET, AND MORE. +The Verge、U.S. NEWS & WORLD REPORT、CNET などでベスト パスワード マネージャーに選ばれました。 -Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go. +どこからでも無制限のデバイスで無制限のパスワードを管理、保存、保護、共有します。 Bitwarden は、自宅、職場、外出先を問わず、オープンソースのパスワード管理ソリューションをすべての人に提供します。 -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +頻繁に使用するすべての Web サイトのセキュリティ要件に基づいて、強力で一意のランダムなパスワードを生成します。 -Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone. +Bitwarden Send は、暗号化された情報 (ファイルと平文) を迅速に誰にでも直接送信します。 -Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues. +Bitwarden は企業向けに Teams および Enterprise プランを提供しているため、パスワードを同僚と安全に共有できます。 -Why Choose Bitwarden: +Bitwarden を選ぶ理由: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +世界クラスの暗号化 +パスワードは高度なエンド ツー エンドの暗号化 (AES-256 ビット、ソルト付きハッシュタグ、PBKDF2 SHA-256) で保護されるため、データは安全かつプライベートに保たれます。 -Built-in Password Generator -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +組み込みのパスワードジェネレーター +頻繁に使用するすべての Web サイトのセキュリティ要件に基づいて、強力で一意のランダムなパスワードを生成します。 -Global Translations -Bitwarden translations exist in 40 languages and are growing, thanks to our global community. +グローバル翻訳 +Bitwarden の翻訳は 40 の言語に存在し、グローバル コミュニティのおかげで成長を続けています。 -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. - +クロスプラットフォーム アプリケーション +ブラウザ、モバイル デバイス、デスクトップ OS などから Bitwarden Vault 内の機密データを保護して共有します。 Max 4000 characters diff --git a/store/apple/nb/copy.resx b/store/apple/nb/copy.resx index fd04e12c8..a29564aa0 100644 --- a/store/apple/nb/copy.resx +++ b/store/apple/nb/copy.resx @@ -122,31 +122,31 @@ Max 30 characters - Bitwarden, Inc. is the parent company of 8bit Solutions LLC. + Bitwarden, Inc. er morselskapet til 8bit Solutions LLC. -NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS & WORLD REPORT, CNET, AND MORE. +BESTE PASSORD MANAGER AV VERDIEN, NYHETER og ARBEID RAPPORT, KNET, OG MORES. -Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go. +Håndtering, lagring, sikker, og deling av ubegrenset med passord på tvers av ubegrenset antall enheter fra hvor som helst. Bitwarden leverer passordbehandlingsløsninger med åpen kildekode til alle, enten hjemme, på jobb eller på farten. -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +Generer sterke, unike, og tilfeldige passord basert på sikkerhetskrav for alle nettsteder du hyppiger. -Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone. +Bitwarden Sende raskt sender krypterte informasjonsfiler --- og klartekst -- direkte til alle. -Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues. +Bitwarden tilbyr Lag og Enterprise planer for firmaer så du kan sikkert dele passord med kolleger. -Why Choose Bitwarden: +Hvorfor velge Bitwarden: World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Passord er beskyttet med avansert ende-til-ende-kryptering (AES-256 bit, Saltet hashtag, og PBKDF2 SHA-256) så dataene dine forblir sikre og private. -Built-in Password Generator -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +Innebygd passordgenerator +Generer sterke, unike og tilfeldige passord basert på sikkerhetskrav for alle nettsteder du hyppiger. -Global Translations -Bitwarden translations exist in 40 languages and are growing, thanks to our global community. +Globale oversettelser +Bitwarden finnes på 40 språk og vokser igjen, takket være vårt globale nettsamfunn. Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Secure og del sensitive data i Bitwarden sitt hvelv fra enhver nettleser, mobil enhet eller desktop OS og mer Max 4000 characters diff --git a/store/google/en-IN/copy.resx b/store/google/en-IN/copy.resx index 44644822e..3024149c8 100644 --- a/store/google/en-IN/copy.resx +++ b/store/google/en-IN/copy.resx @@ -150,8 +150,7 @@ Global Translations Bitwarden translations exist in 40 languages and are growing, thanks to our global community. Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. - +Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. Max 4000 characters diff --git a/store/google/fi/copy.resx b/store/google/fi/copy.resx index 9c18ed7d2..b84d36aea 100644 --- a/store/google/fi/copy.resx +++ b/store/google/fi/copy.resx @@ -122,7 +122,7 @@ Max 30 characters - Bitwarden on käyttäjätunnusten ja salasanojen hallintapalvelu, joka auttaa suojaamaan sinua verkossa. + Bitwarden on tunnusten ja salasanojen hallinta, joka suojaa sinua verkossa. Max 80 characters diff --git a/store/google/hr/copy.resx b/store/google/hr/copy.resx index 065143c33..41559c29f 100644 --- a/store/google/hr/copy.resx +++ b/store/google/hr/copy.resx @@ -134,7 +134,7 @@ Upravljajte, spremajte, osigurajte i dijelite neograničen broj lozinki na neogr Generirajte jake, jedinstvene i nasumične lozinke bazirane na sigurnosnim zahtjevima za svaku web stranicu koju često posjećujete. -Bitwarden Send omoguzćuje jednostavno i brzo slanje šifriranih podataka --- datoteki ili teksta -- direktno, bilo kome. +Bitwarden Send omoguzćuje jednostavno i brzo slanje šifriranih podataka --- datoteka ili teksta -- direktno, bilo kome. Bitwarden nudi Teams i Enterprise planove za tvrtke kako biste sigurno mogli dijeliti lozinke s kolegama na poslu. @@ -150,7 +150,8 @@ Svjetski dostupan Bitwarden je, zahvaljujući našoj globalnoj zajednici, dostupan na više od 40 jezika. Podržani svi OS -Osigurajte i sigurno dijelite osjetljive podatke sadržane u vašem Bitwarden trezoru iz bilo kojeg preglednika, mobilnog uređaja ili stolnog računala s bilo kojim OS. +Osigurajte i sigurno dijelite osjetljive podatke sadržane u vašem Bitwarden trezoru iz bilo kojeg preglednika, mobilnog uređaja ili stolnog računala s bilo kojim OS. + Max 4000 characters diff --git a/store/google/ja/copy.resx b/store/google/ja/copy.resx index 9af66db23..94d9f5a5d 100644 --- a/store/google/ja/copy.resx +++ b/store/google/ja/copy.resx @@ -126,32 +126,31 @@ Max 80 characters - Bitwarden, Inc. is the parent company of 8bit Solutions LLC. + Bitwarden, Inc. は 8bit Solutions LLC の親会社です。 -NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS & WORLD REPORT, CNET, AND MORE. +The Verge、U.S. NEWS & WORLD REPORT、CNET などでベスト パスワード マネージャーに選ばれました。 -Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go. +どこからでも無制限のデバイスで無制限のパスワードを管理、保存、保護、共有します。 Bitwarden は、自宅、職場、外出先を問わず、オープンソースのパスワード管理ソリューションをすべての人に提供します。 -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +頻繁に使用するすべての Web サイトのセキュリティ要件に基づいて、強力で一意のランダムなパスワードを生成します。 -Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone. +Bitwarden Send は、暗号化された情報 (ファイルと平文) を迅速に誰にでも直接送信します。 -Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues. +Bitwarden は企業向けに Teams および Enterprise プランを提供しているため、パスワードを同僚と安全に共有できます。 -Why Choose Bitwarden: +Bitwarden を選ぶ理由: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +世界クラスの暗号化 +パスワードは高度なエンド ツー エンドの暗号化 (AES-256 ビット、ソルト付きハッシュタグ、PBKDF2 SHA-256) で保護されるため、データは安全かつプライベートに保たれます。 -Built-in Password Generator -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +組み込みのパスワードジェネレーター +頻繁に使用するすべての Web サイトのセキュリティ要件に基づいて、強力で一意のランダムなパスワードを生成します。 -Global Translations -Bitwarden translations exist in 40 languages and are growing, thanks to our global community. +グローバル翻訳 +Bitwarden の翻訳は 40 の言語に存在し、グローバル コミュニティのおかげで成長を続けています。 -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. - +クロスプラットフォーム アプリケーション +ブラウザ、モバイル デバイス、デスクトップ OS などから Bitwarden Vault 内の機密データを保護して共有します。 Max 4000 characters diff --git a/store/google/nb/copy.resx b/store/google/nb/copy.resx index 204c3722e..c0412e48e 100644 --- a/store/google/nb/copy.resx +++ b/store/google/nb/copy.resx @@ -126,31 +126,31 @@ Max 80 characters - Bitwarden, Inc. is the parent company of 8bit Solutions LLC. + Bitwarden, Inc. er morselskapet til 8bit Solutions LLC. -NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS & WORLD REPORT, CNET, AND MORE. +BESTE PASSORD MANAGER AV VERDIEN, NYHETER og ARBEID RAPPORT, KNET, OG MORES. -Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go. +Håndtering, lagring, sikker, og deling av ubegrenset med passord på tvers av ubegrenset antall enheter fra hvor som helst. Bitwarden leverer passordbehandlingsløsninger med åpen kildekode til alle, enten hjemme, på jobb eller på farten. -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +Generer sterke, unike, og tilfeldige passord basert på sikkerhetskrav for alle nettsteder du hyppiger. -Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone. +Bitwarden Sende raskt sender krypterte informasjonsfiler --- og klartekst -- direkte til alle. -Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues. +Bitwarden tilbyr Lag og Enterprise planer for firmaer så du kan sikkert dele passord med kolleger. -Why Choose Bitwarden: +Hvorfor velge Bitwarden: World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Passord er beskyttet med avansert ende-til-ende-kryptering (AES-256 bit, Saltet hashtag, og PBKDF2 SHA-256) så dataene dine forblir sikre og private. -Built-in Password Generator -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +Innebygd passordgenerator +Generer sterke, unike og tilfeldige passord basert på sikkerhetskrav for alle nettsteder du hyppiger. -Global Translations -Bitwarden translations exist in 40 languages and are growing, thanks to our global community. +Globale oversettelser +Bitwarden finnes på 40 språk og vokser igjen, takket være vårt globale nettsamfunn. Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Secure og del sensitive data i Bitwarden sitt hvelv fra enhver nettleser, mobil enhet eller desktop OS og mer Max 4000 characters diff --git a/store/google/sr/copy.resx b/store/google/sr/copy.resx index f73361b06..cfb745798 100644 --- a/store/google/sr/copy.resx +++ b/store/google/sr/copy.resx @@ -126,31 +126,31 @@ Max 80 characters - Bitwarden, Inc. is the parent company of 8bit Solutions LLC. + Bitwarden, Inc. је матична компанија фирме 8bit Solutions LLC. -NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS & WORLD REPORT, CNET, AND MORE. +Именован као најбољи управљач лозинкама од стране новинских сајтова као што су THE VERGE, U.S. NEWS & WORLD REPORT, CNET, и других. -Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go. +Управљајте, чувајте, обезбедите, и поделите неограничен број лозинки са неограниченог броја уређаја где год да се налазите. Bitwarden свима доноси решења за управљање лозинкама која су отвореног кода, било да сте код куће, на послу, или на путу. -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +Генеришите јаке, јединствене, и насумичне лозинке у зависности од безбедносних захтева за сваки сајт који често посећујете. -Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone. +Bitwarden Send брзо преноси шифроване информације--- датотеке и обичан текст-- директно и свима. -Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues. +Bitwarden нуди планове за компаније и предузећа како бисте могли безбедно да делите лозинке са вашим колегама. -Why Choose Bitwarden: +Зашто изабрати Bitwarden: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Шифровање светске класе +Лозинке су заштићене напредним шифровањем од једног до другог краја (AES-256 bit, salted hashtag, и PBKDF2 SHA-256) како би ваши подаци остали безбедни и приватни. -Built-in Password Generator -Generate strong, unique, and random passwords based on security requirements for every website you frequent. +Уграђен генератор лозинки +Генеришите јаке, јединствене, и насумичне лозинке у зависности од безбедносних захтева за сваки сајт који често посећујете. -Global Translations -Bitwarden translations exist in 40 languages and are growing, thanks to our global community. +Глобално преведен +Bitwarden преводи постоје за 40 језика и стално се унапређују, захваљујући нашој глобалној заједници. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Вишеплатформне апликације +Обезбедите и поделите осетљиве податке у вашем Bitwarden сефу из било ког претраживача, мобилног уређаја, или desktop оперативног система, и других. Max 4000 characters