mirror of
https://github.com/bitwarden/mobile
synced 2026-01-21 20:03:16 +00:00
Compare commits
18 Commits
sg-804
...
CLOUDOPS-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8ac0adf83 | ||
|
|
164b8970d3 | ||
|
|
34fd30e157 | ||
|
|
8e09f0cc15 | ||
|
|
693a4ef776 | ||
|
|
0992a989d4 | ||
|
|
1b137a8a8a | ||
|
|
7e8e86a77a | ||
|
|
20c1e2d7f2 | ||
|
|
7870c2706b | ||
|
|
5a5f50605b | ||
|
|
0106732cbd | ||
|
|
9ae269dd57 | ||
|
|
04ed47d545 | ||
|
|
6160535c03 | ||
|
|
8d92373c88 | ||
|
|
6bfc8f7d49 | ||
|
|
44dfe0022c |
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@@ -11,6 +11,9 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
|
||||
env:
|
||||
BASE_PKG_NAME: com.x8bit.bitwarden
|
||||
|
||||
jobs:
|
||||
cloc:
|
||||
name: CLOC
|
||||
@@ -174,11 +177,11 @@ jobs:
|
||||
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
||||
run: |
|
||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||
$packageName = "com.x8bit.bitwarden";
|
||||
$packageName = "";
|
||||
|
||||
if ("${{ matrix.variant }}" -ne "prod")
|
||||
{
|
||||
$packageName = "com.x8bit.bitwarden.${{ matrix.variant }}";
|
||||
$packageName = "${{ env.BASE_PKG_NAME }}.${{ matrix.variant }}";
|
||||
}
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Sign Google Play Bundle Release Configuration"
|
||||
@@ -219,24 +222,24 @@ jobs:
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.aab
|
||||
path: ./com.x8bit.bitwarden.aab
|
||||
name: ${{ env.BASE_PKG_NAME }}.aab
|
||||
path: ./${{ env.BASE_PKG_NAME }}.aab
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Prod .apk artifact
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.apk
|
||||
path: ./com.x8bit.bitwarden.apk
|
||||
name: ${{ env.BASE_PKG_NAME }}.apk
|
||||
path: ./${{ env.BASE_PKG_NAME }}.apk
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Other .apk artifact
|
||||
if: ${{ matrix.variant != 'prod' }}
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||
name: ${{ env.BASE_PKG_NAME }}.${{ matrix.variant }}.apk
|
||||
path: ./${{ env.BASE_PKG_NAME }}.${{ matrix.variant }}.apk
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Deploy to Play Store
|
||||
@@ -248,10 +251,10 @@ jobs:
|
||||
run: |
|
||||
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/netcoreapp3.1/Publisher.dll"
|
||||
CREDS_PATH="$HOME/secrets/play_creds.json"
|
||||
AAB_PATH="$GITHUB_WORKSPACE/com.x8bit.bitwarden.aab"
|
||||
AAB_PATH="$GITHUB_WORKSPACE/${{env:BASE_PKG_NAME}}.aab"
|
||||
TRACK="internal"
|
||||
|
||||
dotnet $PUBLISHER_PATH $CREDS_PATH $AAB_PATH $TRACK
|
||||
dotnet $PUBLISHER_PATH $CREDS_PATH $AAB_PATH $TRACK ${{env:BASE_PKG_NAME}}
|
||||
shell: bash
|
||||
|
||||
|
||||
@@ -424,8 +427,8 @@ jobs:
|
||||
Write-Output "##### Copy FDroid apk to project root"
|
||||
Write-Output "########################################"
|
||||
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/FDroid/com.x8bit.bitwarden-Signed.apk");
|
||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden-fdroid.apk");
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/FDroid/$env:BASE_PKG_NAME-Signed.apk");
|
||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/$env:BASE_PKG_NAME-fdroid.apk");
|
||||
|
||||
Copy-Item $signedApkPath $signedApkDestPath
|
||||
shell: pwsh
|
||||
@@ -433,8 +436,8 @@ jobs:
|
||||
- name: Upload F-Droid .apk artifact
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
path: ./com.x8bit.bitwarden-fdroid.apk
|
||||
name: ${{ env.BASE_PKG_NAME }}.apk
|
||||
path: ./${{ env.BASE_PKG_NAME }}.apk
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
|
||||
25
.github/workflows/release.yml
vendored
25
.github/workflows/release.yml
vendored
@@ -1,5 +1,6 @@
|
||||
---
|
||||
name: Release
|
||||
run-name: Release ${{ inputs.release_type }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -19,6 +20,9 @@ on:
|
||||
default: true
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
BASE_PKG_NAME: com.x8bit.bitwarden
|
||||
|
||||
jobs:
|
||||
release:
|
||||
name: Create Release
|
||||
@@ -54,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:
|
||||
@@ -72,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:
|
||||
@@ -87,9 +92,9 @@ jobs:
|
||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||
uses: ncipollo/release-action@40bb172bd05f266cf9ba4ff965cb61e9ee5f6d01 # v1.9.0
|
||||
with:
|
||||
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
|
||||
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
|
||||
./com.x8bit.bitwarden-fdroid.apk/com.x8bit.bitwarden-fdroid.apk,
|
||||
artifacts: "./${{ BASE_PKG_NAME }}.aab/${{ BASE_PKG_NAME }}.aab,
|
||||
./${{ BASE_PKG_NAME }}.apk/${{ BASE_PKG_NAME }}.apk,
|
||||
./${{ BASE_PKG_NAME }}-fdroid.apk/${{ BASE_PKG_NAME }}-fdroid.apk,
|
||||
./Bitwarden iOS.zip"
|
||||
commit: ${{ github.sha }}
|
||||
tag: v${{ steps.version.outputs.version }}
|
||||
@@ -99,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 }}'
|
||||
@@ -107,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 }}'
|
||||
@@ -131,16 +136,16 @@ jobs:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: ${{ needs.release.outputs.branch-name }}
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
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:
|
||||
workflow: build.yml
|
||||
workflow_conclusion: success
|
||||
branch: master
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
name: ${{ BASE_PKG_NAME }}-fdroid.apk
|
||||
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 # v2.5.1
|
||||
@@ -196,7 +201,7 @@ jobs:
|
||||
echo "keystorepass=\"$FDROID_STORE_KEYSTORE_PASSWORD\"" >>config.py
|
||||
echo "local_copy_dir=\"$TEMP_DIR\"" >>config.py
|
||||
mkdir -p repo
|
||||
mv $GITHUB_WORKSPACE/com.x8bit.bitwarden-fdroid.apk ./repo/
|
||||
mv $GITHUB_WORKSPACE/${{ BASE_PKG_NAME }}-fdroid.apk ./repo/
|
||||
fdroid update
|
||||
fdroid server update
|
||||
cd ..
|
||||
|
||||
@@ -9,5 +9,6 @@ namespace Bit.App.Abstractions
|
||||
void Init(Func<AppOptions> getOptionsFunc, IAccountsManagerHost accountsManagerHost);
|
||||
Task NavigateOnAccountChangeAsync(bool? isAuthed = null);
|
||||
Task LogOutAsync(string userId, bool userInitiated, bool expired);
|
||||
Task PromptToSwitchToExistingAccountAsync(string userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,9 @@
|
||||
<Compile Update="Pages\Accounts\LoginPasswordlessPage.xaml.cs">
|
||||
<DependentUpon>LoginPasswordlessPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\LoginPasswordlessRequestPage.xaml.cs">
|
||||
<DependentUpon>LoginPasswordlessRequestPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
@@ -457,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)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
Padding="1"
|
||||
StyleClass="btn-icon-secondary"
|
||||
BackgroundColor="{Binding IconLabelBorderColor, Source={x:Reference _iconLabelButton}}"
|
||||
BorderColor="Transparent"
|
||||
HasShadow="False">
|
||||
<Frame.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding ButtonCommand, Source={x:Reference _iconLabelButton}}" />
|
||||
@@ -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">
|
||||
<StackLayout
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Bit.App.Controls
|
||||
nameof(Label), typeof(string), typeof(IconLabelButton));
|
||||
|
||||
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
|
||||
nameof(ButtonCommand), typeof(Command), typeof(IconLabelButton));
|
||||
nameof(ButtonCommand), typeof(ICommand), typeof(IconLabelButton));
|
||||
|
||||
public static readonly BindableProperty IconLabelColorProperty = BindableProperty.Create(
|
||||
nameof(IconLabelColor), typeof(Color), typeof(IconLabelButton), Color.White);
|
||||
|
||||
@@ -15,14 +15,14 @@ namespace Bit.App.Pages
|
||||
private readonly AppOptions _appOptions;
|
||||
private IBroadcasterService _broadcasterService;
|
||||
|
||||
public HomePage(AppOptions appOptions = null, bool checkRememberedEmail = true)
|
||||
public HomePage(AppOptions appOptions = null, bool shouldCheckRememberEmail = true)
|
||||
{
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("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) =>
|
||||
{
|
||||
|
||||
@@ -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<IStateService>("stateService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
_accountManager = ServiceContainer.Resolve<IAccountsManager>();
|
||||
|
||||
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)
|
||||
|
||||
@@ -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}"/>
|
||||
<controls:IconLabelButton
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
@@ -26,9 +27,9 @@ namespace Bit.App.Pages
|
||||
_vm.Page = this;
|
||||
_vm.StartTwoFactorAction = () => 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);
|
||||
|
||||
@@ -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<ILogger>("logger");
|
||||
_apiService = ServiceContainer.Resolve<IApiService>();
|
||||
_appIdService = ServiceContainer.Resolve<IAppIdService>();
|
||||
_accountManager = ServiceContainer.Resolve<IAccountsManager>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
76
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml
Normal file
76
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.LoginPasswordlessRequestPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:LoginPasswordlessRequestViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
|
||||
<ContentPage.BindingContext>
|
||||
<pages:LoginPasswordlessRequestViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1" x:Name="_closeItem"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout
|
||||
Padding="7, 0, 7, 20">
|
||||
<Label
|
||||
Text="{u:I18n LogInInitiated}"
|
||||
FontSize="Title"
|
||||
FontAttributes="Bold"
|
||||
Margin="0,14,0,21"/>
|
||||
<Label
|
||||
Text="{u:I18n ANotificationHasBeenSentToYourDevice}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,10"/>
|
||||
<Label
|
||||
Text="{u:I18n PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,24"/>
|
||||
<Label
|
||||
Text="{u:I18n FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
<controls:MonoLabel
|
||||
FormattedText="{Binding FingerprintPhrase}"
|
||||
FontSize="Medium"
|
||||
TextColor="{DynamicResource FingerprintPhrase}"/>
|
||||
<Label
|
||||
Text="{u:I18n ResendNotification}"
|
||||
StyleClass="text-md"
|
||||
HorizontalOptions="Start"
|
||||
Margin="0,40,0,0"
|
||||
TextColor="{DynamicResource HyperlinkColor}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding CreatePasswordlessLoginCommand}" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0,30,0,0">
|
||||
<Label
|
||||
Text="{u:I18n NeedAnotherOption}"
|
||||
FontSize="Small"
|
||||
VerticalTextAlignment="End"/>
|
||||
<Label
|
||||
Text="{u:I18n ViewAllLoginOptions}"
|
||||
StyleClass="text-md"
|
||||
VerticalTextAlignment="End"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Margin="5, 0"
|
||||
TextColor="{DynamicResource HyperlinkColor}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding CloseCommand}" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</StackLayout>
|
||||
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</pages:BaseContentPage>
|
||||
65
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs
Normal file
65
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs
Normal file
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
194
src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs
Normal file
194
src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs
Normal file
@@ -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<byte[], byte[]> _requestKeyPair;
|
||||
|
||||
public LoginPasswordlessRequestViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
_authService = ServiceContainer.Resolve<IAuthService>();
|
||||
_syncService = ServiceContainer.Resolve<ISyncService>();
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>();
|
||||
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,22 @@ namespace Bit.App.Pages
|
||||
protected abstract IPlatformUtilsService platformUtilsService { get; }
|
||||
protected string _captchaToken = null;
|
||||
|
||||
protected async Task<bool> HandleCaptchaAsync(string captchaSiteKey, bool needsCaptcha, Func<Task> onSuccess)
|
||||
{
|
||||
if (!needsCaptcha)
|
||||
{
|
||||
_captchaToken = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (await HandleCaptchaAsync(captchaSiteKey))
|
||||
{
|
||||
await onSuccess();
|
||||
_captchaToken = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async Task<bool> HandleCaptchaAsync(string CaptchaSiteKey)
|
||||
{
|
||||
var callbackUri = "bitwarden://captcha-callback";
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -189,6 +189,7 @@ namespace Bit.App.Pages
|
||||
if (await _stateService.GetSyncOnRefreshAsync() && Refreshing && !SyncRefreshing)
|
||||
{
|
||||
SyncRefreshing = true;
|
||||
await _syncService.SyncPasswordlessLoginRequestsAsync();
|
||||
await _syncService.FullSyncAsync(false);
|
||||
return;
|
||||
}
|
||||
|
||||
63
src/App/Resources/AppResources.Designer.cs
generated
63
src/App/Resources/AppResources.Designer.cs
generated
@@ -481,6 +481,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to A notification has been sent to your device..
|
||||
/// </summary>
|
||||
public static string ANotificationHasBeenSentToYourDevice {
|
||||
get {
|
||||
return ResourceManager.GetString("ANotificationHasBeenSentToYourDevice", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to API access token.
|
||||
/// </summary>
|
||||
@@ -3480,6 +3489,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Log in initiated.
|
||||
/// </summary>
|
||||
public static string LogInInitiated {
|
||||
get {
|
||||
return ResourceManager.GetString("LogInInitiated", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Login.
|
||||
/// </summary>
|
||||
@@ -3966,6 +3984,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Need another option?.
|
||||
/// </summary>
|
||||
public static string NeedAnotherOption {
|
||||
get {
|
||||
return ResourceManager.GetString("NeedAnotherOption", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Never.
|
||||
/// </summary>
|
||||
@@ -4705,6 +4732,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device..
|
||||
/// </summary>
|
||||
public static string PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice {
|
||||
get {
|
||||
return ResourceManager.GetString("PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Plus addressed email.
|
||||
/// </summary>
|
||||
@@ -5003,6 +5039,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Resend notification.
|
||||
/// </summary>
|
||||
public static string ResendNotification {
|
||||
get {
|
||||
return ResourceManager.GetString("ResendNotification", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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..
|
||||
/// </summary>
|
||||
@@ -5831,6 +5876,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to This request is no longer valid.
|
||||
/// </summary>
|
||||
public static string ThisRequestIsNoLongerValid {
|
||||
get {
|
||||
return ResourceManager.GetString("ThisRequestIsNoLongerValid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to 3 days.
|
||||
/// </summary>
|
||||
@@ -6542,6 +6596,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to View all log in options.
|
||||
/// </summary>
|
||||
public static string ViewAllLoginOptions {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewAllLoginOptions", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to View item.
|
||||
/// </summary>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2474,21 +2474,42 @@
|
||||
هل تريد التبديل إلى هذا الحساب؟</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>جديد هنا؟</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>احصل على تلميح كلمة المرور الرئيسية</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>تسجيل الدخول كـ {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>ليس أنت؟</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>تسجيل الدخول باستخدام كلمة المرور الرئيسية</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>تسجيل الدخول باستخدام جهاز آخر</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2489,4 +2489,25 @@ Bu hesaba keçmək istəyirsiniz?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Başqa cihazla giriş et</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Giriş etmə başladıldı</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Cihazınıza bir bildiriş göndərildi.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>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.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Bildirişi təkrar göndər</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Başqa bir seçimə ehtiyacınız var?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Bütün giriş etmə seçimlərinə bax</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Bu tələb artıq yararsızdır</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -349,7 +349,7 @@
|
||||
<value>Адправіць</value>
|
||||
</data>
|
||||
<data name="Sync" xml:space="preserve">
|
||||
<value>Сінхранізавана</value>
|
||||
<value>Сінхранізаваць</value>
|
||||
<comment>The title for the sync page.</comment>
|
||||
</data>
|
||||
<data name="ThankYou" xml:space="preserve">
|
||||
@@ -1622,7 +1622,7 @@
|
||||
<value>Біяметрычныя праверка</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Біяметрыяй</value>
|
||||
<value>біяметрыяй</value>
|
||||
</data>
|
||||
<data name="UseBiometricsToUnlock" xml:space="preserve">
|
||||
<value>Выкарыстоўваць біяметрычныя даныя для разблакіроўкі</value>
|
||||
@@ -2490,4 +2490,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Увайсці з іншай прылады</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Ініцыяваны ўваход</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Апавяшчэнне было адпраўлена на вашу прыладу.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Пераканайцеся, што ваша сховішча разблакіравана, а фраза адбітка пальца супадае з іншай прыладай.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Адправіць апавяшчэнне паўторна</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Неабходны іншы варыянт?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Паглядзець усе варыянты ўваходу</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Гэты запыт больш не дзейнічае</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2491,4 +2491,25 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Вписване с друго устройство</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Вписването е стартирано</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Към устройството Ви е изпратено известие.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Уверете се, че трезорът Ви е отключен и че Уникалната фраза съвпада с другото устройство.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Повторно изпращане на известието</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Предпочитате друг вариант?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Вижте всички възможности за вписване</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Тази зявка вече не е приложима</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Voleu canviar a aquest compte?</value>
|
||||
<value>No sou vosaltres?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Inicia sessió amb la teua contrasenya mestra</value>
|
||||
<value>Inicia sessió amb la contrasenya mestra</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Inicia sessió amb un altre dispositiu</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>S'ha iniciat la sessió</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>S'ha enviat una notificació al vostre dispositiu.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Assegureu-vos que la vostra caixa forta estiga desbloquejada i que la frase d'empremta digital coincidisca amb l'altre dispositiu.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Torna a enviar la notificació</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Necessiteu una altra opció?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Veure totes les opcions d'inici de sessió</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Aquesta sol·licitud ja no és vàlida</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1457,11 +1457,11 @@ Načtení proběhne automaticky.</value>
|
||||
<value>Nejsou k dispozici žádné složky k zobrazení.</value>
|
||||
</data>
|
||||
<data name="FingerprintPhrase" xml:space="preserve">
|
||||
<value>Fráze otisku prstu</value>
|
||||
<value>Fráze otisku účtu</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="YourAccountsFingerprint" xml:space="preserve">
|
||||
<value>Fráze otisku prstu vašeho účtu</value>
|
||||
<value>Fráze otisku vašeho účtu</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="LearnOrgConfirmation" xml:space="preserve">
|
||||
@@ -2468,26 +2468,47 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Požadavek na přihlášení již vypršel.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
<value>Pokus o přihlášení z:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
Chcete se přepnout na tento účet?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Jste tu noví?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Získat nápovědu pro hlavní heslo</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Přihlášování jako {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Nejste to vy?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Přihlásit se pomocí hlavního hesla</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>Přihlásit se pomocí jiného zařízení</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Přihlášení zahájeno</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Na vaše zařízení bylo odesláno oznámení.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Ujistěte se, že je váš trezor odemčen a fráze otisku prstu se shodují s druhým zařízením.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Odeslat oznámení znovu</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Potřebujete jinou možnost?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Zobrazit všechny možnosti přihlášení</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Tento požadavek již není platný</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Vil du skifte til denne konto?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log ind med en anden enhed</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Indlogning påbegyndt</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>En notifikation er sendt til din enhed.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Sørg for, at din boks er oplåst, samt at Fingeraftrykssætningen på den anden enhed matcher.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Gensend notifikation</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Behov for en anden mulighed?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Vis alle indlogningsmuligheder</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Anmodningen er ikke længere gyldig</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
<value>Ordner</value>
|
||||
</data>
|
||||
<data name="FolderUpdated" xml:space="preserve">
|
||||
<value>Ordner wurde aktualisiert</value>
|
||||
<value>Ordner aktualisiert</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Webseite besuchen</value>
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Eintrag wurde gelöscht</value>
|
||||
<value>Eintrag gelöscht</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -416,7 +416,7 @@
|
||||
<value>Neuer Eintrag</value>
|
||||
</data>
|
||||
<data name="AppExtension" xml:space="preserve">
|
||||
<value>App Erweiterung</value>
|
||||
<value>App-Erweiterung</value>
|
||||
</data>
|
||||
<data name="AutofillAccessibilityDescription" xml:space="preserve">
|
||||
<value>Verwende den Bitwarden Dienst in den Bedienungshilfen, um deine Zugangsdaten in Apps und im Web automatisch ausfüllen zu lassen.</value>
|
||||
@@ -428,7 +428,7 @@
|
||||
<value>Mehrdeutige Zeichen vermeiden</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtension" xml:space="preserve">
|
||||
<value>Bitwarden App Erweiterung</value>
|
||||
<value>Bitwarden App-Erweiterung</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
|
||||
<value>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.</value>
|
||||
@@ -477,13 +477,13 @@
|
||||
<value>Gebe die E-Mail Adresse deines Kontos ein, um den Hinweis für dein Master-Passwort zu erhalten.</value>
|
||||
</data>
|
||||
<data name="ExntesionReenable" xml:space="preserve">
|
||||
<value>App Erweiterung wieder aktivieren</value>
|
||||
<value>App-Erweiterung wieder aktivieren</value>
|
||||
</data>
|
||||
<data name="ExtensionAlmostDone" xml:space="preserve">
|
||||
<value>Fast geschafft!</value>
|
||||
</data>
|
||||
<data name="ExtensionEnable" xml:space="preserve">
|
||||
<value>App Erweiterung aktivieren</value>
|
||||
<value>App-Erweiterung aktivieren</value>
|
||||
</data>
|
||||
<data name="ExtensionInSafari" xml:space="preserve">
|
||||
<value>In Safari findest du Bitwarden unter dem Teilen-Symbol (Hinweis: scrolle auf der untersten Zeile des Menüs nach rechts).</value>
|
||||
@@ -647,7 +647,7 @@
|
||||
<value>Bist du sicher, dass du das aktuelle Passwort überschreiben möchtest?</value>
|
||||
</data>
|
||||
<data name="PushNotificationAlert" xml:space="preserve">
|
||||
<value>Bitwarden aktualisiert deinen Tresor mit Pushbenachrichtigungen. Für die bestmögliche Benutzererfahrung tippe im folgenden Dialogfenster auf "Ok", um Pushbenachrichtigungen zu aktivieren.</value>
|
||||
<value>Bitwarden aktualisiert deinen Tresor mit Push-Benachrichtigungen. Für die bestmögliche Benutzererfahrung tippe im folgenden Dialogfenster auf "Ok", um Push-Benachrichtigungen zu aktivieren.</value>
|
||||
<comment>Push notifications for apple products</comment>
|
||||
</data>
|
||||
<data name="RateTheApp" xml:space="preserve">
|
||||
@@ -705,10 +705,10 @@
|
||||
<comment>What Apple calls their fingerprint reader.</comment>
|
||||
</data>
|
||||
<data name="TwoStepLogin" xml:space="preserve">
|
||||
<value>Zwei-Faktor Authentifizierung</value>
|
||||
<value>Zwei-Faktor-Authentifizierung</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>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?</value>
|
||||
<value>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?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Mit {0} entsperren</value>
|
||||
@@ -831,7 +831,7 @@
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>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).</value>
|
||||
<value>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).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>Wiederherstellungscode</value>
|
||||
@@ -1726,7 +1726,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>Eintrag wurde wiederhergestellt</value>
|
||||
<value>Eintrag wiederhergestellt</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -2489,4 +2489,25 @@ Möchtest du zu diesem Konto wechseln?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Mit einem anderen Gerät anmelden</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Anmeldung initiiert</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Eine Benachrichtigung wurde an dein Gerät gesendet.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Bitte stelle sicher, dass dein Tresor entsperrt ist und die Fingerabdruck-Phrase mit dem anderen Gerät übereinstimmt.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Benachrichtigung erneut senden</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Brauchst du eine andere Option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Alle Anmelde-Optionen anzeigen</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Diese Anfrage ist nicht mehr gültig</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2499,4 +2499,25 @@ Do you want to switch to this account?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log in with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2499,9 +2499,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2491,4 +2491,25 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Iniciar sesión con otro dispositivo</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Inicio de sesión en proceso</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Se ha enviado una notificación a tu dispositivo.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Por favor, asegúrese de que su bóveda está desbloqueada y la frase de huella dactilar coincide en el otro dispositivo.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Enviar nueva notificación</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>¿Necesitas otra opción?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Ver todas las opciones de inicio de sesión</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Esta solicitud ya no es válida</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Soovid selle konto peale lülituda?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Logi sisse läbi teise seadme</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Sisselogimine on käivitatud</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Sinu seadmesse saadeti teavitus.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Veendu, et hoidla on lahti lukustatud ja sõrmejälje fraasid seadmete vahel ühtivad.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Saada märguanne uuesti</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Soovid teist valikut kasutada?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Vaata kõiki valikuid</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>See päring ei ole enam kehtiv</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1575,7 +1575,7 @@
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<value>Solarized iluna</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
@@ -2464,29 +2464,50 @@
|
||||
<value>Baztertu</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
<value>Sarbide eskaera iraungi da.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
<value>Saio hasiera saiakera hemendik:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
Kontu honetara aldatu nahi duzu?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Berria hemendik?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Jaso pasahitz nagusiaren pista</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>{0} bezala hasi saioa</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Ez zara zu?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Hasi saioa pasahitz nagusiarekin</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>Hasi saioa beste gailu batekin</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Saioa hastea martxan da</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Jakinarazpen bat bidali da zure gailura.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Mesedez, ziurtatu kutxa gotorra desblokeatuta dagoela eta hatz-marka digitalaren esaldia bat datorrela beste gailuarekin.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Berbidali jakinarazpena</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Beste aukerarik behar al duzu?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Ikusi erregistro guztiak ezarpenetan</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2491,4 +2491,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>با دستگاه دیگری وارد شوید</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Synkronoidaan holvi alasveto-eleellä.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Kertakirjautuminen (SSO)</value>
|
||||
<value>Yrityksen kertakirjautuminen (SSO)</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Kirjaudu sisään käyttäen organisaatiosi kertakirjautumista (SSO). Syötä organisaatiosi tunniste aloittaaksesi.</value>
|
||||
@@ -1810,7 +1810,8 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Ladataan</value>
|
||||
</data>
|
||||
<data name="AcceptPolicies" xml:space="preserve">
|
||||
<value>Aktivoimalla tämän valinnan hyväksyt seuraavat: </value>
|
||||
<value>Valitsemalla tämän hyväksyt seuraavat:
|
||||
</value>
|
||||
</data>
|
||||
<data name="AcceptPoliciesError" xml:space="preserve">
|
||||
<value>Palveluehtoja ja tietosuojakäytäntöä ei ole vahvistettu.</value>
|
||||
@@ -2482,7 +2483,7 @@ Haluatko vaihtaa tähän tiliin?</value>
|
||||
<value>Kirjaudutaan tunnuksella {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Etkö se ole sinä?</value>
|
||||
<value>Etkö se ollut sinä?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Kirjaudu pääsalasanalla</value>
|
||||
@@ -2490,4 +2491,25 @@ Haluatko vaihtaa tähän tiliin?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Kirjaudu toisella laitteella</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Kirjautuminen aloitettu</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Laitteellesi on lähetetty ilmoitus.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Varmista, että holvisi on avattu ja tunnistelauseke täsmää toisella laitteella.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Lähetä ilmoitus uudelleen</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Tarvitsetko toisen vaihtoehdon?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Näytä kaikki kirjautumisvaihtoehdot</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Pyyntö ei ole enää voimassa.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Voulez-vous basculer vers ce compte ?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Connectez-vous avec un autre appareil</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Connexion initiée</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Une notification a été envoyée à votre appareil.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Veuillez vous assurer que votre coffre est déverrouillé et que l'empreinte digitale est identique sur l'autre appareil.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Renvoyer la notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Besoin d'une autre option ?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Voir toutes les options de connexion</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Cette demande n'est plus valide</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2488,9 +2488,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1763,7 +1763,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2487,9 +2487,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -657,7 +657,7 @@
|
||||
<value>Razmotri da nam pomogneš dobrom recenzijom!</value>
|
||||
</data>
|
||||
<data name="RegeneratePassword" xml:space="preserve">
|
||||
<value>Obnovi lozinku</value>
|
||||
<value>Ponovno generiraj lozinku</value>
|
||||
</data>
|
||||
<data name="RetypeMasterPassword" xml:space="preserve">
|
||||
<value>Ponovno upiši glavnu lozinku</value>
|
||||
@@ -1901,7 +1901,7 @@
|
||||
<value>Datoteka koju želiš poslati</value>
|
||||
</data>
|
||||
<data name="FileTypeIsSelected" xml:space="preserve">
|
||||
<value>Odabran je datotečni Send.</value>
|
||||
<value>Odabrana je vrsta datoteke.</value>
|
||||
</data>
|
||||
<data name="FileTypeIsNotSelected" xml:space="preserve">
|
||||
<value>Vrsta datoteke nije odabrana, dodirnite za odabir.</value>
|
||||
@@ -2062,7 +2062,7 @@
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendFilePremiumRequired" xml:space="preserve">
|
||||
<value>Kod besplatnog računa moguće je dijeljenje samo teksta. Za slanje datoteka potrebno je Premium članstvo.</value>
|
||||
<value>Kod besplatnog računa moguće je dijeljenje samo teksta. Za slanje datoteka potrebno je premium članstvo.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendFileEmailVerificationRequired" xml:space="preserve">
|
||||
@@ -2445,7 +2445,7 @@
|
||||
<value>Koristi konfigurirani catch-all sandučić svoje domene.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Kreiraj pseudonim e-pošte s vanjskom uslugom prosljeđivanja.</value>
|
||||
<value>Generiraj pseudonim e-pošte s vanjskom uslugom prosljeđivanja.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Nasumično</value>
|
||||
@@ -2488,4 +2488,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Prijava drugim uređajem</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Prijava pokrenuta</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Obavijest je poslana na tvoj uređaj.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Ponovno pošalji obavijest</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Trebaš drugu opciju?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Pogledaj sve mogućnosti prijave</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1761,7 +1761,7 @@
|
||||
<value>A széf szinkronizálása lehúzó művelettel.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Vállalati önálló bejelentkezés</value>
|
||||
<value>Vállalati egyszeri bejelentkezés</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Gyors bejelentkezés a szervezeti önálló bejelentkező portálba. A kezdéshez meg kell adni a szervezeti azonosítót.</value>
|
||||
@@ -2489,4 +2489,25 @@ Szeretnénk átváltani erre a fiókra?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Bejelentkezés más eszközzel</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>A bejelentkezés elindításra került.</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A rendszer értesítést küldött az eszközre.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>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.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Értesítés újraküldése</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Másik opció szükséges?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Összes bejelentkezési opció megtekintése</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>A kérés már nem érvényes.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1575,7 +1575,7 @@
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<value>Solarizzato scuro</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
@@ -2468,26 +2468,47 @@ seleziona Aggiungi TOTP per salvare la chiave in modo sicuro</value>
|
||||
<value>La richiesta di accesso è già scaduta.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
<value>Tentativo di accesso da:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
Vuoi passare a questo account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Nuovo da queste parti?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Ottieni l'indizio della password principale</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Accesso come {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Non sei tu?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Accedi con la password principale</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>Accedi con un altro dispositivo</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Login avviato</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Una notifica è stata inviata al tuo dispositivo.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Assicurati che la tua cassaforte sia sbloccata e che la "frase impronta" corrisponda sull'altro dispositivo.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Invia nuova notifica</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Hai bisogno di un'altra opzione?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Visualizza tutte le opzioni di accesso</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>La richiesta non è più valida</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>別のデバイスでログイン</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>ログイン開始</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>デバイスに通知を送信しました。</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>保管庫がロックされていることと、パスフレーズが他のデバイスと一致していることを確認してください。</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>通知を再送信する</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>別の選択肢が必要ですか?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>すべてのログインオプションを表示</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>このリクエストは無効になりました</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Vai pārslēgties uz šo kontu?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Pierakstīties ar citu ierīci</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Uzsākta pierakstīšanās</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Uz ierīci ir nosūtīts paziņojums.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Jāpārliecinās, ka glabātava ir atslēgta un atpazīšanas vārdkopa ir tāda pati arī citā ierīcē.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Atkārtoti nosūtīt paziņojumu</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Nepieciešama cita iespēja?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Apskatīt visas pierakstīšanās iespējas</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Šis pieprasījums vairs nav derīgs</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1576,7 +1576,7 @@ Skanning skjer automatisk.</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<value>Solarisert mørk</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
@@ -2469,26 +2469,47 @@ velg Legg til TOTP for å lagre nøkkelen sikkert</value>
|
||||
<value>Innloggingsforespørselen har allerede utløpt.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
<value>Innloggingsforsøk:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
Vil du bytte til denne kontoen?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Nytt rundt her?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Få et hint om superpassordet</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Logger inn som {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Ikke du?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Logg inn med hovedpassord</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>Logg inn med en annen enhet</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Wilt u naar dit account wisselen?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Inloggen met een ander apparaat</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Dit verzoek is niet langer geldig</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Czy chcesz przełączyć się na to konto?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Logowanie innym urządzeniem</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Logowanie rozpoczęte</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Powiadomienie zostało wysłane na urządzenie.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Upewnij się, że sejf jest odblokowany, a unikalny identyfikator konta pasuje do drugiego urządzenia.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Wyślij ponownie powiadomienie</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Potrzebujesz innego sposobu?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Zobacz wszystkie sposoby logowania</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Ta prośba nie jest już ważna</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2491,4 +2491,25 @@ Você deseja mudar para esta conta?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Entrar com outro dispositivo</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Login iniciado</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Uma notificação foi enviada para seu dispositivo.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Por favor, certifique-se de que o seu cofre esteja desbloqueado e a frase de identificação corresponda ao outro dispositivo.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Reenviar notificação</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Precisa de outra opção?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Ver todas as opções de login</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Este pedido não é mais válido</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Deseja mudar para esta conta?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Iniciar sessão com outro dispositivo</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Este pedido já não é válido</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@ Doriți să comutați la acest cont?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Autentificați-vă cu un alt dispozitiv</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -705,10 +705,10 @@
|
||||
<comment>What Apple calls their fingerprint reader.</comment>
|
||||
</data>
|
||||
<data name="TwoStepLogin" xml:space="preserve">
|
||||
<value>Двухфакторная аутентификация</value>
|
||||
<value>Двухэтапная аутентификация</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>Двухэтапная аутентификация повышает защиту вашего аккаунта, требуя подтверждения входа на другом устройстве, например, с помощью ключа безопасности, приложения-аутентификатора, SMS, телефонного звонка или email. Двухфакторная аутентификация включается на bitwarden.com. Перейти на сайт сейчас?</value>
|
||||
<value>Двухэтапная аутентификация делает аккаунт более защищенным, поскольку требуется подтверждение входа при помощи другого устройства, например, ключа безопасности, приложения-аутентификатора, SMS, телефонного звонка или электронной почты. Двухэтапная аутентификация включается на bitwarden.com. Перейти на сайт сейчас?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Разблокировка {0}</value>
|
||||
@@ -831,7 +831,7 @@
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>Для этой учетной записи включена двухфакторная аутентификация, однако ни один из настроенных вариантов аутентификации не поддерживается на этом устройстве. Используйте поддерживаемое устройство и/или добавьте другие варианты, которые поддерживаются на большинстве устройств (например, приложение-аутентификатор).</value>
|
||||
<value>У этой учетной записи включена двухэтапная аутентификация, однако ни один из настроенных вариантов не поддерживается на этом устройстве. Используйте поддерживаемое устройство и/или добавьте другие варианты, которые поддерживаются на большинстве устройств (например, приложение-аутентификатор).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>Код восстановления</value>
|
||||
@@ -846,10 +846,10 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="TwoStepLoginOptions" xml:space="preserve">
|
||||
<value>Настройки двухфакторной аутентификации</value>
|
||||
<value>Настройки двухэтапной аутентификации</value>
|
||||
</data>
|
||||
<data name="UseAnotherTwoStepMethod" xml:space="preserve">
|
||||
<value>Использовать другой метод двухфакторной аутентификации</value>
|
||||
<value>Использовать другой метод двухэтапной аутентификации</value>
|
||||
</data>
|
||||
<data name="VerificationEmailNotSent" xml:space="preserve">
|
||||
<value>Не удалось отправить письмо подтверждения. Повторить.</value>
|
||||
@@ -919,7 +919,7 @@
|
||||
<value>Если к вашему логину прикреплен ключ аутентификации, то код подтверждения TOTP будет скопирован при автозаполнении логина.</value>
|
||||
</data>
|
||||
<data name="CopyTotpAutomatically" xml:space="preserve">
|
||||
<value>Копировать TOTP автоматически</value>
|
||||
<value>Скопировать TOTP автоматически</value>
|
||||
</data>
|
||||
<data name="PremiumRequired" xml:space="preserve">
|
||||
<value>Для использования этой функции требуется Премиум.</value>
|
||||
@@ -1471,7 +1471,7 @@
|
||||
<value>Экспортировать хранилище</value>
|
||||
</data>
|
||||
<data name="LockNow" xml:space="preserve">
|
||||
<value>Заблокировать сейчас</value>
|
||||
<value>Заблокировать</value>
|
||||
</data>
|
||||
<data name="PIN" xml:space="preserve">
|
||||
<value>PIN-код</value>
|
||||
@@ -1614,10 +1614,10 @@
|
||||
<value>Общие</value>
|
||||
</data>
|
||||
<data name="ToggleVisibility" xml:space="preserve">
|
||||
<value>Изменить видимость</value>
|
||||
<value>Вкл/выкл видимость</value>
|
||||
</data>
|
||||
<data name="LoginExpired" xml:space="preserve">
|
||||
<value>Истек срок действия вашей сессии.</value>
|
||||
<value>Истек срок действия вашего сеанса.</value>
|
||||
</data>
|
||||
<data name="BiometricsDirection" xml:space="preserve">
|
||||
<value>Биометрическая верификация.</value>
|
||||
@@ -1635,7 +1635,7 @@
|
||||
<value>3. На экране настроек приложений Android для Bitwarden перейдите в раздел "Отображение поверх других приложений" (в разделе "Дополнительно") и коснитесь переключателя, чтобы включить поддержку наложения.</value>
|
||||
</data>
|
||||
<data name="OverlayPermission" xml:space="preserve">
|
||||
<value>Разрешения</value>
|
||||
<value>Разрешение</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenOverlayPermissionSettings" xml:space="preserve">
|
||||
<value>Открыть настройки разрешения наложения</value>
|
||||
@@ -1762,7 +1762,7 @@
|
||||
<value>Синхронизация хранилища жестом смахивания вниз.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Единая корпоративная авторизация (SSO)</value>
|
||||
<value>Единая корпоративная авторизация</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Авторизуйтесь при помощи единого корпоративного портала. Чтобы начать, введите идентификатор вашей организации.</value>
|
||||
@@ -2092,7 +2092,7 @@
|
||||
<value>Обновить мастер-пароль</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить мастер-пароль сейчас. В результате текущая сессия будет завершена, потребуется повторный вход. Активные сессии на других устройствах могут оставаться активными в течение одного часа.</value>
|
||||
<value>Мастер-пароль недавно был изменен администратором вашей организации. Чтобы получить доступ к хранилищу, вы должны обновить мастер-пароль сейчас. В результате текущий сеанс будет завершен, потребуется повторный вход. Активные сеансы на других устройствах могут оставаться активными в течение одного часа.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Обновление пароля</value>
|
||||
@@ -2490,4 +2490,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Войти с другого устройства</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Вход инициирован</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>На ваше устройство отправлено уведомление.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Убедитесь, что ваше хранилище разблокировано, а фраза отпечатка соответствует другому устройству.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Отправить уведомление повторно</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Нужен другой вариант?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Посмотреть все варианты авторизации</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Этот запрос больше не действителен</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Skenovanie prebehne automaticky.</value>
|
||||
<value>Synchronizácia trezora potiahnutím nadol</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Prihlásenie cez prihlasovací formulár spoločnosti (SSO)</value>
|
||||
<value>Jednotné prihlásenie pre podniky (SSO)</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Prihláste sa prostredníctvom prihlasovacieho portálu (SSO) vašej organizácie. Najskôr zadajte identifikátor vašej organizácie.</value>
|
||||
@@ -2490,4 +2490,25 @@ Chcete prepnúť na toto konto?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Prihlásenie pomocou iného zariadenia</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Iniciované prihlásenie</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Do vášho zariadenia bolo odoslané upozornenie.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Skontrolujte, či je trezor odomknutý, a či sa fráza odtlačku prsta zhoduje na druhom zariadení.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Znova odoslať upozornenie</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Potrebujete inú možnosť?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Zobraziť všetky možnosti prihlásenia</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Táto požiadavka už nie je platná</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1576,7 +1576,7 @@
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<value>Solarized црно</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
@@ -2395,7 +2395,7 @@
|
||||
<value>„Ухвати све“ е-порука</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded email alias</value>
|
||||
<value>Прослеђен псеудоним е-поште</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Случајна реч</value>
|
||||
@@ -2443,10 +2443,10 @@
|
||||
<value>Непозната {0} грешка.</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmailDescription" xml:space="preserve">
|
||||
<value>Use your email provider's subaddress capabilities</value>
|
||||
<value>Користите могућности подадресе вашег добављача е-поште</value>
|
||||
</data>
|
||||
<data name="CatchAllEmailDescription" xml:space="preserve">
|
||||
<value>Use your domain's configured catch-all inbox.</value>
|
||||
<value>Користите подешено catch-all пријемно сандуче вашег домена.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Генеришите псеудоним е-поште помоћу екстерне услуге прослеђивања.</value>
|
||||
@@ -2455,10 +2455,10 @@
|
||||
<value>Случајно</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
<value>Откривање услуге приступачности</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
<value>Битварден користи услугу приступачности да тражи поља за пријаву у апликацијама и веб локацијама, а затим успоставља одговарајуће ИД-ове поља за уношење корисничког имена и лозинке када се пронађе подударање за апликацију или сајт. Не чувамо ниједну информацију коју нам пружа услуга, нити покушавамо да контролишемо било које елементе на екрану осим уноса текста акредитива.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Прихвати</value>
|
||||
@@ -2475,21 +2475,42 @@
|
||||
Да ли желите да пређете на овај налог?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Нов овде?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Добити савет за Главну Лозинку</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Пријављивање као {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Не ти?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Пријавите се са главном лозинком</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>Пријавите се са другим уређајем</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Пријава је покренута</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Обавештење је послато на ваш уређај.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Уверите се да је ваш сеф откључан и да се фраза отиска прста подудара на другом уређају.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Поново послати обавештење</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Треба Вам друга опције?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Погледајте сав извештај у опције</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Овај захтев више не важи</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2492,4 +2492,25 @@ Vill du byta till detta konto?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Logga in med en annan enhet</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Inloggning påbörjad</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>En avisering har skickats till din enhet.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Se till att ditt valv är upplåst och att fingeravtrycksfrasen matchar på den andra enheten.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Skicka avisering igen</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Behöver du fler alternativ?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Visa alla inloggningsalternativ</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2486,9 +2486,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1769,7 +1769,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
@@ -2493,9 +2493,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2489,4 +2489,25 @@ Bu hesaba geçmek ister misiniz?</value>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Başka bir cihazla giriş yap</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Giriş başlatıldı</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Cihazınıza bir bildirim gönderildi.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Lütfen kasanızın kilidinin açık olduğundan ve parmak izi ifadesinin diğer cihazla eşleştiğinden emin olun.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Bildirimi yeniden gönder</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Başka bir seçeneğe mi ihtiyacınız var?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Tüm giriş seçeneklerini gör</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Bu istek artık geçerli değil</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -708,7 +708,7 @@
|
||||
<value>Двоетапна перевірка</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>Двоетапна перевірка робить ваш обліковий запис більш захищеним, вимагаючи підтвердження входу з використанням іншого пристрою, наприклад, за допомогою коду безпеки, програми авторизації, SMS, телефонного виклику, або е-пошти. Ви можете увімкнути двоетапну перевірку в сховищі на bitwarden.com. Хочете перейти на вебсайт зараз?</value>
|
||||
<value>Двоетапна перевірка дає змогу надійніше захистити ваш обліковий запис, вимагаючи підтвердження входу з використанням іншого пристрою, наприклад, за допомогою коду безпеки, програми авторизації, SMS, телефонного виклику, або е-пошти. Ви можете налаштувати двоетапну перевірку в сховищі на bitwarden.com. Хочете перейти на вебсайт зараз?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Розблокування з {0}</value>
|
||||
@@ -2490,4 +2490,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Увійти з іншого пристрою</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Ініційовано вхід</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Сповіщення було надіслано на ваш пристрій.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Переконайтеся, що ваше сховище розблоковане, а фраза відбитка збігається з іншим пристроєм.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Надіслати сповіщення ще раз</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Потрібен інший варіант?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Переглянути всі варіанти входу</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Цей запит більше недійсний</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2485,9 +2485,30 @@ Do you want to switch to this account?</value>
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log In with master password</value>
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2490,4 +2490,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>使用其他设备登录</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>登录已发起</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>通知已发送到您的设备。</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>请确保您的密码库已解锁,并且指纹短语与其他设备上的相匹配。</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>重新发送通知</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>需要其他选项吗?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>查看所有登录选项</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>请求已失效</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1762,7 +1762,7 @@
|
||||
<value>使用下拉手勢同步密碼庫。</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>企業單一登入</value>
|
||||
<value>企業單一登入(SSO)</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>若要使用組織的單一登入入口快速登入。請先輸入您的組織識別碼。</value>
|
||||
@@ -2490,4 +2490,25 @@
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>使用其他裝置登入</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>登入已發起</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>通知已傳送至您的裝置。</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>重新傳送通知</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>檢視所有登入選項</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>此請求已失效</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
src/App/Utilities/AccountManagement/HomeNavigationParams.cs
Normal file
14
src/App/Utilities/AccountManagement/HomeNavigationParams.cs
Normal file
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -83,8 +83,11 @@ namespace Bit.Core.Abstractions
|
||||
Task<SendResponse> PutSendAsync(string id, SendRequest request);
|
||||
Task<SendResponse> PutSendRemovePasswordAsync(string id);
|
||||
Task DeleteSendAsync(string id);
|
||||
Task<List<PasswordlessLoginResponse>> GetAuthRequestAsync();
|
||||
Task<PasswordlessLoginResponse> GetAuthRequestAsync(string id);
|
||||
Task<PasswordlessLoginResponse> GetAuthResponseAsync(string id, string accessCode);
|
||||
Task<PasswordlessLoginResponse> PutAuthRequestAsync(string id, string key, string masterPasswordHash, string deviceIdentifier, bool requestApproved);
|
||||
Task<PasswordlessLoginResponse> PostCreateRequestAsync(PasswordlessCreateLoginRequest passwordlessCreateLoginRequest);
|
||||
Task<string> GetUsernameFromAsync(ForwardedEmailServiceType service, UsernameGeneratorConfig config);
|
||||
Task<bool> GetKnownDeviceAsync(string email, string deviceIdentifier);
|
||||
}
|
||||
|
||||
@@ -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<AuthResult> LogInSsoAsync(string code, string codeVerifier, string redirectUrl, string orgId);
|
||||
Task<AuthResult> LogInCompleteAsync(string email, string masterPassword, TwoFactorProviderType twoFactorProvider, string twoFactorToken, bool? remember = null);
|
||||
Task<AuthResult> LogInTwoFactorAsync(TwoFactorProviderType twoFactorProvider, string twoFactorToken, string captchaToken, bool? remember = null);
|
||||
Task<AuthResult> LogInPasswordlessAsync(string email, string accessCode, string authRequestId, byte[] decryptionKey, string userKeyCiphered, string localHashedPasswordCiphered);
|
||||
|
||||
Task<List<PasswordlessLoginResponse>> GetPasswordlessLoginRequestsAsync();
|
||||
Task<PasswordlessLoginResponse> GetPasswordlessLoginRequestByIdAsync(string id);
|
||||
Task<PasswordlessLoginResponse> GetPasswordlessLoginResponseAsync(string id, string accessCode);
|
||||
Task<PasswordlessLoginResponse> PasswordlessLoginAsync(string id, string pubKey, bool requestApproved);
|
||||
Task<PasswordlessLoginResponse> PasswordlessCreateLoginRequestAsync(string email);
|
||||
|
||||
void LogOut(Action callback);
|
||||
void Init();
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace Bit.Core.Abstractions
|
||||
Task<int> RandomNumberAsync(int min, int max);
|
||||
Task<Tuple<SymmetricCryptoKey, EncString>> RemakeEncKeyAsync(SymmetricCryptoKey key);
|
||||
Task<EncString> RsaEncryptAsync(byte[] data, byte[] publicKey = null);
|
||||
Task<byte[]> RsaDecryptAsync(string encValue, byte[] privateKey = null);
|
||||
Task SetEncKeyAsync(string encKey);
|
||||
Task SetEncPrivateKeyAsync(string encPrivateKey);
|
||||
Task SetKeyAsync(SymmetricCryptoKey key);
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Bit.Core.Abstractions
|
||||
{
|
||||
List<AccountView> AccountViews { get; }
|
||||
Task<string> GetActiveUserIdAsync();
|
||||
Task<string> GetActiveUserEmailAsync();
|
||||
Task<bool> IsActiveAccountAsync(string userId = null);
|
||||
Task SetActiveUserAsync(string userId);
|
||||
Task CheckExtensionActiveUserAndSwitchIfNeededAsync();
|
||||
|
||||
@@ -14,5 +14,7 @@ namespace Bit.Core.Abstractions
|
||||
Task<bool> SyncDeleteFolderAsync(SyncFolderNotification notification);
|
||||
Task<bool> SyncUpsertCipherAsync(SyncCipherNotification notification, bool isEdit);
|
||||
Task<bool> SyncUpsertFolderAsync(SyncFolderNotification notification, bool isEdit);
|
||||
// Passwordless code will be moved to an independent service in future techdept
|
||||
Task SyncPasswordlessLoginRequestsAsync();
|
||||
}
|
||||
}
|
||||
|
||||
34
src/Core/Models/Request/PasswordlessCreateLoginRequest.cs
Normal file
34
src/Core/Models/Request/PasswordlessCreateLoginRequest.cs
Normal file
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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<string, string> 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());
|
||||
|
||||
@@ -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<byte[], byte[]> 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<PasswordlessLoginResponse> Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,11 +536,27 @@ namespace Bit.Core.Services
|
||||
|
||||
#region PasswordlessLogin
|
||||
|
||||
public async Task<List<PasswordlessLoginResponse>> GetAuthRequestAsync()
|
||||
{
|
||||
var response = await SendAsync<object, PasswordlessLoginsResponse>(HttpMethod.Get, $"/auth-requests/", null, true, true);
|
||||
return response.Data;
|
||||
}
|
||||
|
||||
public Task<PasswordlessLoginResponse> GetAuthRequestAsync(string id)
|
||||
{
|
||||
return SendAsync<object, PasswordlessLoginResponse>(HttpMethod.Get, $"/auth-requests/{id}", null, true, true);
|
||||
}
|
||||
|
||||
public Task<PasswordlessLoginResponse> GetAuthResponseAsync(string id, string accessCode)
|
||||
{
|
||||
return SendAsync<object, PasswordlessLoginResponse>(HttpMethod.Get, $"/auth-requests/{id}/response?code={accessCode}", null, false, true);
|
||||
}
|
||||
|
||||
public Task<PasswordlessLoginResponse> PostCreateRequestAsync(PasswordlessCreateLoginRequest passwordlessCreateLoginRequest)
|
||||
{
|
||||
return SendAsync<object, PasswordlessLoginResponse>(HttpMethod.Post, $"/auth-requests", passwordlessCreateLoginRequest, false, true);
|
||||
}
|
||||
|
||||
public Task<PasswordlessLoginResponse> PutAuthRequestAsync(string id, string encKey, string encMasterPasswordHash, string deviceIdentifier, bool requestApproved)
|
||||
{
|
||||
var request = new PasswordlessLoginRequest(encKey, encMasterPasswordHash, deviceIdentifier, requestApproved);
|
||||
|
||||
@@ -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<TwoFactorProviderType, TwoFactorProvider>();
|
||||
@@ -137,6 +139,14 @@ namespace Bit.Core.Services
|
||||
null, captchaToken);
|
||||
}
|
||||
|
||||
public async Task<AuthResult> 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<AuthResult> LogInSsoAsync(string code, string codeVerifier, string redirectUrl, string orgId)
|
||||
{
|
||||
SelectedTwoFactorProviderType = null;
|
||||
@@ -286,7 +296,7 @@ namespace Bit.Core.Services
|
||||
private async Task<AuthResult> 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<List<PasswordlessLoginResponse>> GetPasswordlessLoginRequestsAsync()
|
||||
{
|
||||
return await _apiService.GetAuthRequestAsync();
|
||||
}
|
||||
|
||||
public async Task<PasswordlessLoginResponse> GetPasswordlessLoginRequestByIdAsync(string id)
|
||||
{
|
||||
return await _apiService.GetAuthRequestAsync(id);
|
||||
}
|
||||
|
||||
public async Task<PasswordlessLoginResponse> GetPasswordlessLoginResponseAsync(string id, string accessCode)
|
||||
{
|
||||
return await _apiService.GetAuthResponseAsync(id, accessCode);
|
||||
}
|
||||
|
||||
public async Task<PasswordlessLoginResponse> 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<PasswordlessLoginResponse> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,7 +723,7 @@ namespace Bit.Core.Services
|
||||
return await _cryptoFunctionService.AesDecryptAsync(data, iv, theKey.EncKey);
|
||||
}
|
||||
|
||||
private async Task<byte[]> RsaDecryptAsync(string encValue)
|
||||
public async Task<byte[]> 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.");
|
||||
|
||||
@@ -46,6 +46,12 @@ namespace Bit.Core.Services
|
||||
return activeUserId;
|
||||
}
|
||||
|
||||
public async Task<string> GetActiveUserEmailAsync()
|
||||
{
|
||||
var activeUserId = await GetActiveUserIdAsync();
|
||||
return await GetEmailAsync(activeUserId);
|
||||
}
|
||||
|
||||
public async Task<bool> IsActiveAccountAsync(string userId = null)
|
||||
{
|
||||
if (userId == null)
|
||||
|
||||
@@ -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<Tuple<string, bool, bool>, Task> _logoutCallbackAsync;
|
||||
|
||||
public SyncService(
|
||||
@@ -39,6 +40,7 @@ namespace Bit.Core.Services
|
||||
IPolicyService policyService,
|
||||
ISendService sendService,
|
||||
IKeyConnectorService keyConnectorService,
|
||||
ILogger logger,
|
||||
Func<Tuple<string, bool, bool>, 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<string, SendData>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Bit.Core.Utilities
|
||||
var messagingService = Resolve<IMessagingService>("messagingService");
|
||||
var cryptoFunctionService = Resolve<ICryptoFunctionService>("cryptoFunctionService");
|
||||
var cryptoService = Resolve<ICryptoService>("cryptoService");
|
||||
var logger = Resolve<ILogger>();
|
||||
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
</value>
|
||||
Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
<data name="Keywords" xml:space="preserve">
|
||||
|
||||
@@ -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.</value>
|
||||
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.
|
||||
</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
<data name="Keywords" xml:space="preserve">
|
||||
|
||||
@@ -122,32 +122,31 @@
|
||||
<comment>Max 30 characters</comment>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
|
||||
<value>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.
|
||||
</value>
|
||||
クロスプラットフォーム アプリケーション
|
||||
ブラウザ、モバイル デバイス、デスクトップ OS などから Bitwarden Vault 内の機密データを保護して共有します。</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
<data name="Keywords" xml:space="preserve">
|
||||
|
||||
@@ -122,31 +122,31 @@
|
||||
<comment>Max 30 characters</comment>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
|
||||
<value>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
|
||||
</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
|
||||
@@ -9,25 +9,34 @@ using Google.Apis.Services;
|
||||
|
||||
namespace Bit.Publisher
|
||||
{
|
||||
|
||||
// static class to hold global variables, etc.
|
||||
static class Globals
|
||||
{
|
||||
// global string
|
||||
// private const string Package = "com.x8bit.bitwarden";
|
||||
public static string Package;
|
||||
}
|
||||
|
||||
|
||||
public class Program
|
||||
{
|
||||
private const string Package = "com.x8bit.bitwarden";
|
||||
|
||||
private static string _aabFilePath;
|
||||
private static string _credsFilePath;
|
||||
private static string _track;
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (args.Length < 3)
|
||||
if (args.Length < 4)
|
||||
{
|
||||
throw new ArgumentException("Not enough arguments.");
|
||||
throw new ArgumentException("Not enough arguments (needs 4), got: " + args.Length);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_credsFilePath = args[0];
|
||||
_aabFilePath = args[1];
|
||||
Globals.Package = args[3];
|
||||
|
||||
var track = args[2].Substring(0, 1).ToLower();
|
||||
if (track == "a")
|
||||
@@ -79,7 +88,7 @@ namespace Bit.Publisher
|
||||
});
|
||||
service.HttpClient.Timeout = TimeSpan.FromMinutes(3);
|
||||
|
||||
var editRequest = service.Edits.Insert(null, Package);
|
||||
var editRequest = service.Edits.Insert(null, Globals.Package);
|
||||
var edit = await editRequest.ExecuteAsync();
|
||||
|
||||
Console.WriteLine("Created edit with id {0}.", edit.Id);
|
||||
@@ -87,7 +96,7 @@ namespace Bit.Publisher
|
||||
Bundle aab = null;
|
||||
using (var stream = new FileStream(_aabFilePath, FileMode.Open))
|
||||
{
|
||||
var uploadMedia = service.Edits.Bundles.Upload(Package, edit.Id, stream,
|
||||
var uploadMedia = service.Edits.Bundles.Upload(Globals.Package, edit.Id, stream,
|
||||
"application/octet-stream");
|
||||
|
||||
var progress = await uploadMedia.UploadAsync();
|
||||
@@ -114,12 +123,12 @@ namespace Bit.Publisher
|
||||
{
|
||||
new TrackRelease { VersionCodes = new List<long?> { aab.VersionCode }, Status = "completed" }
|
||||
}
|
||||
}, Package, edit.Id, _track);
|
||||
}, Globals.Package, edit.Id, _track);
|
||||
|
||||
var updatedTrack = await trackRequest.ExecuteAsync();
|
||||
Console.WriteLine("Track {0} has been updated.", updatedTrack.TrackValue);
|
||||
|
||||
var commitRequest = service.Edits.Commit(Package, edit.Id);
|
||||
var commitRequest = service.Edits.Commit(Globals.Package, edit.Id);
|
||||
var commitEdit = await commitRequest.ExecuteAsync();
|
||||
Console.WriteLine("App edit with id {0} has been comitted.", commitEdit.Id);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user