1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-05 23:53:33 +00:00

Compare commits

..

58 Commits

Author SHA1 Message Date
André Bispo
2014d7f562 [PM-2287] Add trust device to master password unlock. Change trust device method. Remove email from SSO login page. 2023-07-10 19:37:32 +01:00
André Bispo
8a399235f4 code format 2023-07-10 18:36:36 +01:00
André Bispo
ce55750e60 [PM-2293] Trust device after admin request login. 2023-07-10 15:34:54 +01:00
André Bispo
a15269bafe [PM-2293] Change boolean variable expression. 2023-07-10 13:44:26 +01:00
André Bispo
8a59e17fc9 Merge branch 'feature/pm-1208-f3-options' into feature/pm-2293-admin-approval 2023-07-10 12:37:31 +01:00
André Bispo
548bd12a8e Merge branch 'feature/pm-1029-tde-login' into feature/pm-1208-f3-options 2023-07-10 12:37:13 +01:00
André Bispo
58542fd255 Merge branch 'master' into feature/pm-1029-tde-login 2023-07-10 12:36:59 +01:00
André Bispo
fc300f3e3f Merge branch 'feature/pm-1208-f3-options' into feature/pm-2293-admin-approval
# Conflicts:
#	src/App/Pages/Accounts/LoginApproveDeviceViewModel.cs
#	src/App/Resources/AppResources.resx
2023-07-10 12:36:22 +01:00
André Bispo
800b4c71de Merge branch 'feature/pm-1029-tde-login' into feature/pm-1208-f3-options
# Conflicts:
#	src/Core/Models/Response/DeviceResponse.cs
#	src/Core/Services/ApiService.cs
2023-07-10 12:32:27 +01:00
André Bispo
7bcf1c377f [PM-2293] Refactor AuthRequestType enum. Add label. Remove unnecessary actions. 2023-07-07 17:09:13 +01:00
github-actions[bot]
11947ce99a Autosync the updated translations (#2603)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-07-07 05:13:18 +00:00
Jake Fink
3053eaa036 [PM-1379] add DeviceTrustCryptoService with establish trust logic (#2535)
* [PM-1379] add DeviceCryptoService with establish trust logic

* PM-1379 update api location and other minor refactors

* pm-1379 fix encoding

* update trusted device keys api call to Put

* [PM-1379] rename DeviceCryptoService to DeviceTrustCryptoService
- refactors to prevent side effects

* [PM-1379] rearrange methods in DeviceTrustCryptoService

* [PM-1379] rearrange methods in abstraction

* [PM-1379] deconstruct tuples

* [PM-1379] remove extra tasks
2023-07-05 16:13:20 -04:00
André Bispo
109a84607a [PM-2293] Change screen text based on AuthRequestType 2023-07-05 09:36:31 +01:00
André Bispo
d2b6c73a75 [PM-2293] Add Actions to ApproveWithDevicePage 2023-07-05 08:43:00 +01:00
André Bispo
9dc6a725cf [PM-2293] Add AuthRequestType to PasswordlessLoginPage. 2023-07-05 08:42:17 +01:00
mpbw2
4abb472998 Revert "reset lock delay when returning from activity result (#2539)" (#2597)
This reverts commit 0288a6659c.
2023-07-03 09:56:10 -04:00
André Bispo
6268f0776b Merge branch 'feature/pm-1029-tde-login' into feature/pm-1208-f3-options 2023-07-03 10:34:53 +01:00
André Bispo
cbbc41be67 [PM-1208] Add continue button and not you option 2023-07-03 10:34:02 +01:00
github-actions[bot]
1d541e5b8e Autosync the updated translations (#2595)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-30 07:06:12 +00:00
ifernandezdiaz
175b9936b6 [PM-2798] Fixing Toolbar locators in FolderAddEditPage (#2592)
* Fixing Toolbar locators

* Adding Matt's suggestions
2023-06-29 15:50:01 -03:00
ifernandezdiaz
72e67bd6f2 [PM-2691] Adding AutomationIDs for Vault Page sections (#2580)
* Adding IDs for Vault Page sections

* Removing extra spaces

* Adding Matt's comments

* Fixing Filters Id bug

* Adding Fede's suggestions

* Fixing Settings Ids issues

* Fixing AutomationIds issues with RecyclerViews + implementing AutomationId helper class

* Adding Fede's suggestion

* Adding latest Fede's suggestions
2023-06-29 15:37:08 -03:00
André Bispo
e164fb9823 Merge branch 'feature/pm-1029-tde-login' into feature/pm-1208-f3-options
# Conflicts:
#	src/App/Resources/AppResources.resx
#	src/Core/Abstractions/IApiService.cs
#	src/Core/Services/StateService.cs
2023-06-29 14:36:46 +01:00
André Bispo
87866304a6 [PM-1208] Add device related api endpoint. Add AccoundDecryptOptions model and property to user Account. 2023-06-28 22:37:08 +01:00
ifernandezdiaz
216c6abcf6 [PM-2737] Adding AutomationIDs for Send page elements (#2583)
* Adding AutomationIDs for Send page elements

* Fixing some spaces

* Adding Matt's suggestion

* Adding Fede's suggestion

* Removing unnecesarry breaks
2023-06-28 14:07:03 -04:00
Federico Maccaroni
1014563c75 [PM-192] Refactor forwarded email providers (#2579)
* PM-192 Refactor Forwarded email providers to use better patterns and code reuse.

* PM-192 fix format
2023-06-27 18:49:38 -03:00
ifernandezdiaz
3506269811 [PM-2688] Adding IDs for Options and Folders pages (#2585)
* Adding IDs for Options and Folders pages

* Fixing extra spaces
2023-06-26 10:31:57 -03:00
ifernandezdiaz
31487a31bb [PM-2748] Refactoring locator strategy for Cipher Details page (#2586)
* Refactoring locator strategy for Cipher Details page

* Fixing extra spaces
2023-06-26 10:30:13 -03:00
ifernandezdiaz
1407aa5655 [PM-2678] Adding IDs for Settings Page elements (#2584)
* Adding IDS for Settings elements

* Adding IDS for Settings elements
2023-06-23 13:31:24 -03:00
github-actions[bot]
16f59e2698 Autosync the updated translations (#2582)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-23 05:40:37 +00:00
ifernandezdiaz
d876b54f45 Adding IDs for AttachmentPage elements (#2577) 2023-06-20 17:49:26 -03:00
ifernandezdiaz
6644e3b449 [PM-2545] Adding Automation IDs for CipherDetailsPage elements (#2576)
* Adding IDs to CipherDetailsPage

* Fixing extra spaces

* Fixing extra space
2023-06-20 16:26:43 -03:00
ifernandezdiaz
8d98d1d5bd [PM-2612] Adding AutomationIDs for LoginPasswordlessPage elements (#2574)
* Adding AutomationIDs for LoginPasswordlessPag elements

* Adding AutomationIDs for LoginPasswordlessRequest page elements

* Fixing missing space
2023-06-20 15:12:15 -03:00
ifernandezdiaz
3e9711f8f2 [PM-2611] Adding IDs for Cipher/Send search results (#2575)
* Adding IDs for Cipher/Send search results

* Adding missing spaces
2023-06-20 11:28:54 -03:00
github-actions[bot]
3af37f01d3 Autosync the updated translations (#2570)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-19 09:05:12 +00:00
ifernandezdiaz
43d2d386b1 [PM-2645] Adding IDs for Account Switching elements (#2572)
* Adding IDs for Account Switching elements

* Fixing Active/Inactive vault icon IDs
2023-06-16 16:20:09 -03:00
ifernandezdiaz
bc5c11b47f Adding AutomationIDs on Generator page elements (#2569)
* Adding AutomationIDs on Generator pages

* Adding missing spaces
2023-06-15 16:11:55 -03:00
ifernandezdiaz
52843b4181 [PM-2544] Adding AutomationIDs for CipherAddEditViewPage elements (#2564)
* Adding AutomationIDs for Add/Edit Items page

* Adding IDs to CustomFields

* Adding Matt's suggestions

* Adding newest suggestions
2023-06-14 09:34:38 -03:00
Federico Maccaroni
98705e443f PM-2575 Fixed extension freeze when using the return button on the keyboard when unlocking the extension. Also added way to prevent multiple executions of checking the password and logging exceptions. (#2568) 2023-06-13 22:38:08 +02:00
mpbw2
1332ef7b43 Enhancement to login field detection for Android autofill (#2561) 2023-06-13 13:54:28 -04:00
mpbw2
04e30c2146 Update F-Droid listing author name (#2501)
Update F-Droid listing author name to `Bitwarden Inc`
2023-06-13 18:46:41 +02:00
Opeyemi
f604da13a1 add more comment to missing actions (#2567) 2023-06-13 15:57:02 +01:00
github-actions[bot]
dcf9acb51c Autosync the updated translations (#2562)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-09 09:19:34 +02:00
Federico Maccaroni
3b087c50ae PM-1076 added warning on unlocking iOS extensions when the kdf type is argon2id and the memory is higher than 48MB, to let the user know that unlocking might crash the extension (#2560) 2023-06-07 16:21:51 +02:00
ifernandezdiaz
1c13ed9895 [PS-2558] Mobile Automation - Starting automationIDs additions to our codebase (#2558)
* Adding locators for Environment, Hope, Login and Register pages

* Adding Locators on LockPage

* Adding Álison's suggestions
2023-06-06 21:00:01 -03:00
Federico Maccaroni
eeb634e698 PM-1798 Added accessibility names on entries on cipher add (#2550) 2023-06-05 18:58:38 +02:00
github-actions[bot]
8bc2df6c8a Autosync the updated translations (#2555)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-04 16:23:34 +02:00
github-actions[bot]
7cd40d4d89 Bumped version to 2023.5.1 (#2554)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-06-01 12:18:12 -04:00
Federico Maccaroni
bebf23785d PM-2232 Fix api response not being read as string because the content was not being considered json when it was indeed. Now Netacea messages are shown on the UI. (#2541) 2023-06-01 10:35:35 +03:00
github-actions[bot]
e78833cbcb Bumped version to 2023.5.0 (#2553)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-31 09:33:47 -04:00
github-actions[bot]
b7ff636862 Autosync the updated translations (#2540)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-26 08:12:16 +02:00
mpbw2
0288a6659c reset lock delay when returning from activity result (#2539) 2023-05-25 11:43:45 -04:00
André Bispo
c7fd113f26 [PM-2347] Refresh feature flags when environment urls change (#2538) 2023-05-25 14:37:53 +01:00
Michał Chęciński
79241731e7 Add github actions to renovate (#2536)
* Add github actions to renovate

* Add gh actions manager

* Apply whole renovate config

* Add newline
2023-05-24 16:04:39 +02:00
github-actions[bot]
74e9914f5b Autosync the updated translations (#2531)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-22 11:35:15 +02:00
André Bispo
65307f6eab [PM-1351][PM-190] Add a mobile service to retrieve feature flags from API (#2431) 2023-05-19 12:42:41 +01:00
github-actions[bot]
e9f83aee90 Autosync the updated translations (#2524)
Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com>
2023-05-19 08:28:02 +02:00
André Bispo
84a82f0876 [PM-1208] Add Device approval options screen. View model waiting for additional logic to be added. 2023-05-17 17:46:45 +01:00
Federico Maccaroni
fdaf743868 PM-2249 Fix vault timeout action policy check (#2521) 2023-05-15 15:28:18 +02:00
182 changed files with 5502 additions and 2052 deletions

57
.github/renovate.json vendored
View File

@@ -1,22 +1,37 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
"schedule:monthly",
":maintainLockFilesMonthly",
":preserveSemverRanges",
":rebaseStalePrs",
":disableDependencyDashboard"
],
"enabledManagers": [
"nuget"
],
"packageRules": [
{
"matchManagers": ["nuget"],
"groupName": "Nuget updates",
"groupSlug": "nuget",
"separateMajorMinor": false
}
]
}
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base",
":combinePatchMinorReleases",
":dependencyDashboard",
":maintainLockFilesWeekly",
":pinAllExceptPeerDependencies",
":prConcurrentLimit10",
":rebaseStalePrs",
"schedule:weekends",
":separateMajorReleases"
],
"enabledManagers": ["cargo", "github-actions", "npm", "nuget"],
"packageRules": [
{
"groupName": "cargo minor",
"matchManagers": ["cargo"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "gh minor",
"matchManagers": ["github-actions"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "npm minor",
"matchManagers": ["npm"],
"matchUpdateTypes": ["minor", "patch"]
},
{
"groupName": "nuget minor",
"matchManagers": ["nuget"],
"matchUpdateTypes": ["minor", "patch"]
},
]
}

View File

@@ -793,7 +793,7 @@ jobs:
done
- name: Upload Sources
uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9
uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

@@ -30,7 +30,7 @@ jobs:
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Download translations
uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9
uses: crowdin/github-action@965d501f160af7b1f88aed4c29154b0caf1e94b9 # v1.9.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Enforce Label
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # v2.2.2
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2
with:
BANNED_LABELS: "hold,needs-qa"
BANNED_LABELS_DESCRIPTION: "PRs with the hold or needs-qa labels cannot be merged"

View File

@@ -1,23 +0,0 @@
# Runs on creation of Pull Requests
# If the PR destination branch is master, add a needs-qa label
---
name: Label Issue Pull Request
on:
pull_request:
types:
- opened # Check when PR is opened
paths-ignore:
- .github/workflows/** # We don't need QA on workflow changes
branches:
- 'master' # We only want to check when PRs target master
jobs:
add-needs-qa-label:
runs-on: ubuntu-latest
steps:
- name: Add label to pull request
uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4
if: ${{ !github.event.pull_request.head.repo.fork }}
with:
add-labels: "needs-qa"

View File

@@ -68,7 +68,7 @@ jobs:
- name: Download all artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success
@@ -76,7 +76,7 @@ jobs:
- name: Dry Run - Download all artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success
@@ -130,7 +130,7 @@ jobs:
- name: Download F-Droid .apk artifact
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success
@@ -139,7 +139,7 @@ jobs:
- 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
uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615 # v2.27.0
with:
workflow: build.yml
workflow_conclusion: success

View File

@@ -159,6 +159,7 @@
<Compile Include="Constants.cs" />
<Compile Include="Effects\RemoveFontPaddingEffect.cs" />
<Compile Include="Services\WatchDeviceService.cs" />
<Compile Include="Renderers\CustomLabelRenderer.cs" />
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="Assets\bwi-font.ttf" />

View File

@@ -12,7 +12,7 @@ namespace Bit.Droid.Autofill
private List<Field> _passwordFields = null;
private List<Field> _usernameFields = null;
private HashSet<string> _ignoreSearchTerms = new HashSet<string> { "search", "find", "recipient", "edit" };
private HashSet<string> _usernameTerms = new HashSet<string> { "email", "phone", "username"};
private HashSet<string> _usernameTerms = new HashSet<string> { "email", "phone", "username" };
private HashSet<string> _passwordTerms = new HashSet<string> { "password", "pswd" };
public List<AutofillId> AutofillIds { get; private set; } = new List<AutofillId>();
@@ -54,15 +54,14 @@ namespace Bit.Droid.Autofill
if (HintToFieldsMap.ContainsKey(View.AutofillHintPassword))
{
_passwordFields.AddRange(HintToFieldsMap[View.AutofillHintPassword]);
return _passwordFields;
}
}
else
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
if (!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => FieldIsPassword(f)).ToList();
if (!_passwordFields.Any())
{
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
return _passwordFields;
}
@@ -87,24 +86,26 @@ namespace Bit.Droid.Autofill
{
_usernameFields.AddRange(HintToFieldsMap[View.AutofillHintUsername]);
}
if (_usernameFields.Any())
{
return _usernameFields;
}
}
else
{
foreach (var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
.LastOrDefault();
if (usernameField != null)
{
_usernameFields.Add(usernameField);
}
}
if (!_usernameFields.Any())
foreach (var passwordField in PasswordFields)
{
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId)
.LastOrDefault();
if (usernameField != null)
{
_usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList();
_usernameFields.Add(usernameField);
}
}
if (!_usernameFields.Any())
{
_usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList();
}
return _usernameFields;
}
}

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.4.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.5.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />

View File

@@ -0,0 +1,31 @@
using System;
using Bit.App.Controls;
using System.ComponentModel;
using Xamarin.Forms.Platform.Android;
using Android.Content;
using Xamarin.Forms;
using Bit.Droid.Renderers;
[assembly: ExportRenderer(typeof(CustomLabel), typeof(CustomLabelRenderer))]
namespace Bit.Droid.Renderers
{
public class CustomLabelRenderer : LabelRenderer
{
public CustomLabelRenderer(Context context)
: base(context)
{ }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var label = sender as CustomLabel;
switch (e.PropertyName)
{
case nameof(CustomLabel.AutomationId):
Control.ContentDescription = label.AutomationId;
break;
}
base.OnElementPropertyChanged(sender, e);
}
}
}

View File

@@ -145,6 +145,7 @@
<Folder Include="Controls\DateTime\" />
<Folder Include="Controls\IconLabelButton\" />
<Folder Include="Controls\PasswordStrengthProgressBar\" />
<Folder Include="Utilities\Automation\" />
</ItemGroup>
<ItemGroup>
@@ -440,5 +441,6 @@
<None Remove="MessagePack" />
<None Remove="MessagePack.MSBuild.Tasks" />
<None Remove="Controls\PasswordStrengthProgressBar\" />
<None Remove="Utilities\Automation\" />
</ItemGroup>
</Project>

View File

@@ -38,6 +38,7 @@ namespace Bit.App
private readonly IFileService _fileService;
private readonly IAccountsManager _accountsManager;
private readonly IPushNotificationService _pushNotificationService;
private readonly IConfigService _configService;
private static bool _isResumed;
// these variables are static because the app is launching new activities on notification click, creating new instances of App.
private static bool _pendingCheckPasswordlessLoginRequests;
@@ -61,6 +62,7 @@ namespace Bit.App
_fileService = ServiceContainer.Resolve<IFileService>();
_accountsManager = ServiceContainer.Resolve<IAccountsManager>("accountsManager");
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
_configService = ServiceContainer.Resolve<IConfigService>();
_accountsManager.Init(() => Options, this);
@@ -169,6 +171,10 @@ namespace Bit.App
new NavigationPage(new UpdateTempPasswordPage()));
});
}
else if (message.Command == "syncCompleted")
{
await _configService.GetAsync(true);
}
else if (message.Command == Constants.PasswordlessLoginRequestKey
|| message.Command == "unlocked"
|| message.Command == AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED)
@@ -293,6 +299,8 @@ namespace Bit.App
// Reset delay on every start
_vaultTimeoutService.DelayLockAndLogoutMs = null;
}
await _configService.GetAsync();
_messagingService.Send("startEventTimer");
}

View File

@@ -30,13 +30,15 @@
BackgroundColor="{DynamicResource BackgroundColor}"
VerticalOptions="Start"
RowHeight="{Binding AccountListRowHeight, Source={x:Reference _mainOverlay}}"
effects:ScrollViewContentInsetAdjustmentBehaviorEffect.ContentInsetAdjustmentBehavior="Never">
effects:ScrollViewContentInsetAdjustmentBehaviorEffect.ContentInsetAdjustmentBehavior="Never"
AutomationId="AccountListView">
<ListView.ItemTemplate>
<DataTemplate x:DataType="view:AccountView">
<controls:AccountViewCell
Account="{Binding .}"
SelectAccountCommand="{Binding SelectAccountCommand, Source={x:Reference _mainOverlay}}"
LongPressAccountCommand="{Binding LongPressAccountCommand, Source={x:Reference _mainOverlay}}"
AutomationId="AccountViewCell"
/>
</DataTemplate>
</ListView.ItemTemplate>

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
@@ -60,20 +60,23 @@
Text="{Binding AccountView.Email}"
IsVisible="{Binding IsActive}"
StyleClass="accountlist-title, accountlist-title-platform"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountEmailLabel" />
<Label
Grid.Row="0"
Text="{Binding AccountView.Email}"
IsVisible="{Binding IsActive, Converter={StaticResource inverseBool}}"
StyleClass="accountlist-title, accountlist-title-platform"
TextColor="{DynamicResource MutedColor}"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountEmailLabel" />
<Label
Grid.Row="1"
IsVisible="{Binding ShowHostname}"
Text="{Binding AccountView.Hostname}"
StyleClass="accountlist-sub, accountlist-sub-platform"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountHostUrlLabel" />
<Label
Grid.Row="2"
Text="{u:I18n AccountUnlocked}"
@@ -81,7 +84,8 @@
StyleClass="accountlist-sub, accountlist-sub-platform"
FontAttributes="Italic"
TextTransform="Lowercase"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountStatusLabel" />
<Label
Grid.Row="2"
Text="{u:I18n AccountLocked}"
@@ -89,7 +93,8 @@
StyleClass="accountlist-sub, accountlist-sub-platform"
FontAttributes="Italic"
TextTransform="Lowercase"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountStatusLabel" />
<Label
Grid.Row="2"
Text="{u:I18n AccountLoggedOut}"
@@ -97,7 +102,8 @@
StyleClass="accountlist-sub, accountlist-sub-platform"
FontAttributes="Italic"
TextTransform="Lowercase"
LineBreakMode="TailTruncation" />
LineBreakMode="TailTruncation"
AutomationId="AccountStatusLabel" />
</Grid>
<controls:IconLabel
@@ -107,7 +113,8 @@
Margin="12,0"
HorizontalOptions="Center"
VerticalOptions="Center"
StyleClass="list-icon, list-icon-platform" />
StyleClass="list-icon, list-icon-platform"
AutomationId="InactiveVaultIcon" />
<controls:IconLabel
Grid.Column="2"
Text="{Binding AuthStatusIconActive}"
@@ -116,7 +123,8 @@
HorizontalOptions="Center"
VerticalOptions="Center"
StyleClass="list-icon, list-icon-platform"
TextColor="{DynamicResource TextColor}"/>
TextColor="{DynamicResource TextColor}"
AutomationId="ActiveVaultIcon" />
</Grid>
<Grid
@@ -147,7 +155,8 @@
StyleClass="accountlist-title, accountlist-title-platform"
LineBreakMode="TailTruncation"
VerticalOptions="Center"
Grid.Column="1" />
Grid.Column="1"
AutomationId="AddAccountButton" />
</Grid>
</Grid>
</ViewCell>

View File

@@ -9,7 +9,8 @@
StyleClass="list-row, list-row-platform"
RowSpacing="0"
ColumnSpacing="0"
x:DataType="controls:CipherViewCellViewModel">
x:DataType="controls:CipherViewCellViewModel"
AutomationId="CipherCell">
<Grid.Resources>
<u:IconGlyphConverter x:Key="iconGlyphConverter"/>
@@ -36,7 +37,8 @@
IsVisible="{Binding ShowIconImage, Converter={StaticResource inverseBool}}"
Text="{Binding Cipher, Converter={StaticResource iconGlyphConverter}}"
ShouldUpdateFontSizeDynamicallyForAccesibility="True"
AutomationProperties.IsInAccessibleTree="False" />
AutomationProperties.IsInAccessibleTree="False"
AutomationId="CipherTypeIcon" />
<ff:CachedImage
x:Name="_iconImage"
@@ -52,7 +54,8 @@
Aspect="AspectFit"
IsVisible="{Binding ShowIconImage}"
Source="{Binding IconImageSource, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="False" />
AutomationProperties.IsInAccessibleTree="False"
AutomationId="CipherWebsiteIcon" />
<Grid RowSpacing="0" ColumnSpacing="0" Grid.Row="0" Grid.Column="1" VerticalOptions="Center" Padding="0, 7">
<Grid.RowDefinitions>
@@ -71,7 +74,8 @@
Grid.Column="0"
Grid.Row="0"
StyleClass="list-title, list-title-platform"
Text="{Binding Cipher.Name}" />
Text="{Binding Cipher.Name}"
AutomationId="CipherNameLabel" />
<Label
LineBreakMode="TailTruncation"
Grid.Column="0"
@@ -80,7 +84,8 @@
StyleClass="list-subtitle, list-subtitle-platform"
Text="{Binding Cipher.SubTitle}"
IsVisible="{Binding Source={RelativeSource Self}, Path=Text,
Converter={StaticResource stringHasValueConverter}}"/>
Converter={StaticResource stringHasValueConverter}}"
AutomationId="CipherSubTitleLabel" />
<controls:IconLabel
Grid.Column="1"
Grid.Row="0"
@@ -91,7 +96,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Collection}}"
IsVisible="{Binding Cipher.Shared, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Shared}" />
AutomationProperties.Name="{u:I18n Shared}"
AutomationId="CipherInCollectionIcon" />
<controls:IconLabel
Grid.Column="2"
Grid.Row="0"
@@ -102,7 +108,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Paperclip}}"
IsVisible="{Binding Cipher.HasAttachments, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Attachments}" />
AutomationProperties.Name="{u:I18n Attachments}"
AutomationId="CipherWithAttachmentsIcon" />
</Grid>
<controls:MiButton
@@ -114,6 +121,7 @@
VerticalOptions="CenterAndExpand"
HorizontalOptions="EndAndExpand"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="CipherOptionsButton" />
</controls:ExtendedGrid>

View File

@@ -0,0 +1,13 @@
using System;
using Xamarin.Forms;
namespace Bit.App.Controls
{
public class CustomLabel : Label
{
public CustomLabel()
{
}
}
}

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<controls:ExtendedGrid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Controls.SendViewCell"
@@ -54,14 +54,16 @@
Grid.Column="0"
Grid.Row="0"
StyleClass="list-title, list-title-platform"
Text="{Binding Send.Name}" />
Text="{Binding Send.Name}"
AutomationId="SendNameLabel" />
<Label
LineBreakMode="TailTruncation"
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="6"
StyleClass="list-subtitle, list-subtitle-platform"
Text="{Binding Send.DisplayDate}" />
Text="{Binding Send.DisplayDate}"
AutomationId="SendDateLabel" />
<controls:IconLabel
Grid.Column="1"
Grid.Row="0"
@@ -72,7 +74,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.ExclamationTriangle}}"
IsVisible="{Binding Send.Disabled, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Disabled}" />
AutomationProperties.Name="{u:I18n Disabled}"
AutomationId="DisabledSendLabel" />
<controls:IconLabel
Grid.Column="2"
Grid.Row="0"
@@ -83,7 +86,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Key}}"
IsVisible="{Binding Send.HasPassword, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Password}" />
AutomationProperties.Name="{u:I18n Password}"
AutomationId="PasswordProtectedSendLabel" />
<controls:IconLabel
Grid.Column="3"
Grid.Row="0"
@@ -94,7 +98,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Ban}}"
IsVisible="{Binding Send.MaxAccessCountReached, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n MaxAccessCountReached}" />
AutomationProperties.Name="{u:I18n MaxAccessCountReached}"
AutomationId="SendMaxAccessCountReachedLabel" />
<controls:IconLabel
Grid.Column="4"
Grid.Row="0"
@@ -105,7 +110,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Clock}}"
IsVisible="{Binding Send.Expired, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Expired}" />
AutomationProperties.Name="{u:I18n Expired}"
AutomationId="ExpiredSendLabel" />
<controls:IconLabel
Grid.Column="5"
Grid.Row="0"
@@ -116,7 +122,8 @@
Text="{Binding Source={x:Static core:BitwardenIcons.Trash}}"
IsVisible="{Binding Send.PendingDelete, Mode=OneTime}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n PendingDelete}" />
AutomationProperties.Name="{u:I18n PendingDelete}"
AutomationId="SendWithPendingDeletionLabel" />
</Grid>
<controls:MiButton
@@ -129,6 +136,7 @@
VerticalOptions="CenterAndExpand"
HorizontalOptions="EndAndExpand"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="SendOptionsButton" />
</controls:ExtendedGrid>

View File

@@ -33,7 +33,8 @@
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="BooleanCustomFieldNameLabel" />
<Label
Text="{Binding Field.Name, Mode=OneWay}"
IsVisible="{Binding IsEditing}"
@@ -49,13 +50,15 @@
Grid.Row="1"
Grid.Column="0"
Margin="0, 5, 0, 0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="BooleanCustomFieldValueLabel" />
<Switch
IsToggled="{Binding BooleanValue}"
IsVisible="{Binding IsEditing}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2" />
Grid.RowSpan="2"
AutomationId="BooleanCustomFieldValueToggle" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Cog}}"

View File

@@ -31,7 +31,8 @@
Text="{Binding Field.Name, Mode=OneWay}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="HiddenCustomFieldNameLabel" />
<StackLayout
Grid.Row="1"
Grid.Column="0"
@@ -39,7 +40,8 @@
<controls:MonoLabel
Text="{Binding ValueText, Mode=OneWay}"
StyleClass="box-value"
IsVisible="{Binding ShowHiddenValue}" />
IsVisible="{Binding ShowHiddenValue}"
AutomationId="HiddenCustomFieldValueLabel" />
<controls:MonoLabel
Text="{Binding Field.MaskedValue, Mode=OneWay}"
StyleClass="box-value"
@@ -54,7 +56,10 @@
IsPassword="{Binding ShowHiddenValue, Converter={StaticResource inverseBool}}"
IsEnabled="{Binding ShowViewHidden}"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False">
IsTextPredictionEnabled="False"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{Binding Field.Name}"
AutomationId="HiddenCustomFieldValueEntry">
<Entry.Keyboard>
<Keyboard x:FactoryMethod="Create">
<x:Arguments>
@@ -72,7 +77,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationId="HiddenCustomFieldShowValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"

View File

@@ -29,13 +29,15 @@
Text="{Binding Field.Name, Mode=OneWay}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="LinkedCustomFieldNameLabel" />
<controls:IconLabel
Text="{Binding ValueText, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="LinkedCustomFieldValueLabel" />
<StackLayout
StyleClass="box-row, box-row-input"
IsVisible="{Binding IsEditing}">
@@ -44,7 +46,8 @@
ItemsSource="{Binding LinkedFieldOptions, Mode=OneTime}"
SelectedIndex="{Binding LinkedFieldOptionSelectedIndex}"
ItemDisplayBinding="{Binding Key}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="LinkedCustomFieldValuePicker" />
</StackLayout>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
@@ -55,7 +58,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="LinkedCustomFieldOptionsButton" />
</Grid>
<BoxView StyleClass="box-row-separator" IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
</StackLayout>

View File

@@ -29,19 +29,24 @@
Text="{Binding Field.Name, Mode=OneWay}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="TextCustomFieldNameLabel" />
<Label
Text="{Binding ValueText, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}"
AutomationId="TextCustomFieldValueLabel" />
<Entry
Text="{Binding Field.Value}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding IsEditing}" />
IsVisible="{Binding IsEditing}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{Binding Field.Name}"
AutomationId="TextCustomFieldValueEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -51,7 +56,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Copy}" />
AutomationProperties.Name="{u:I18n Copy}"
AutomationId="TextCustomFieldCopyValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Cog}}"
@@ -61,7 +67,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="TextCustomFieldOptionsButton" />
</Grid>
<BoxView StyleClass="box-row-separator" IsVisible="{Binding IsEditing, Mode=OneWay, Converter={StaticResource inverseBool}}" />
</StackLayout>

View File

@@ -34,7 +34,8 @@
Placeholder="ex. https://bitwarden.company.com"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="ServerUrlEntry"/>
</StackLayout>
<Label
Text="{u:I18n SelfHostedEnvironmentFooter}"
@@ -53,7 +54,8 @@
x:Name="_webVaultEntry"
Text="{Binding WebVaultUrl}"
Keyboard="Url"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="WebVaultUrlEntry"/>
</StackLayout>
<StackLayout StyleClass="box-row">
<Label
@@ -63,7 +65,8 @@
x:Name="_apiEntry"
Text="{Binding ApiUrl}"
Keyboard="Url"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ApiUrlEntry"/>
</StackLayout>
<StackLayout StyleClass="box-row">
<Label
@@ -73,7 +76,8 @@
x:Name="_identityEntry"
Text="{Binding IdentityUrl}"
Keyboard="Url"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityUrlEntry"/>
</StackLayout>
<StackLayout StyleClass="box-row">
<Label
@@ -85,7 +89,8 @@
Keyboard="Url"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="IconsUrlEntry"/>
</StackLayout>
<Label
Text="{u:I18n CustomEnvironmentFooter}"

View File

@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Models.Data;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
@@ -18,7 +19,8 @@ namespace Bit.App.Pages
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
PageTitle = AppResources.Settings;
BaseUrl = _environmentService.BaseUrl;
BaseUrl = _environmentService.BaseUrl == EnvironmentUrlData.DefaultEU.Base || EnvironmentUrlData.DefaultUS.Base == _environmentService.BaseUrl ?
string.Empty : _environmentService.BaseUrl;
WebVaultUrl = _environmentService.WebVaultUrl;
ApiUrl = _environmentService.ApiUrl;
IdentityUrl = _environmentService.IdentityUrl;

View File

@@ -23,12 +23,9 @@
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
<ToolbarItem x:Name="_closeButton" Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1"/>
<ToolbarItem
Icon="cog_environment.png" Clicked="Environment_Clicked" Order="Primary"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
@@ -53,7 +50,9 @@
Keyboard="Email"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding ContinueCommand}">
ReturnCommand="{Binding ContinueCommand}"
AutomationId="EmailAddressEntry"
>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
@@ -66,7 +65,28 @@
</Entry>
<StackLayout
Orientation="Horizontal"
Margin="0, 16, 0 ,0">
Margin="0, 6, 0 ,0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ShowEnvironmentPickerCommand}" />
</StackLayout.GestureRecognizers>
<Label
Text="{Binding RegionText}"
FontSize="13"
TextColor="{DynamicResource MutedColor}"
VerticalOptions="Center"
VerticalTextAlignment="Center"/>
<controls:IconLabel
Text="{Binding SelectedEnvironmentName}"
FontSize="13"
TextColor="{DynamicResource PrimaryColor}"
VerticalOptions="Center"
VerticalTextAlignment="Center"
AutomationId="RegionSelectorDropdown"/>
</StackLayout>
<StackLayout
Orientation="Horizontal"
Margin="0, 20, 0 ,0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding RememberEmailCommand}" />
@@ -76,21 +96,27 @@
StyleClass="text-sm"
HorizontalOptions="FillAndExpand"
VerticalOptions="Center"
VerticalTextAlignment="Center"/>
VerticalTextAlignment="Center"
/>
<Switch
Scale="0.8"
IsToggled="{Binding RememberEmail}"
VerticalOptions="Center"/>
VerticalOptions="Center"
AutomationId="RememberMeSwitch"
/>
</StackLayout>
</StackLayout>
<Button Text="{u:I18n Continue}"
StyleClass="btn-primary"
IsEnabled="{Binding CanContinue}"
Command="{Binding ContinueCommand}" />
Command="{Binding ContinueCommand}"
AutomationId="ContinueButton"
/>
<Label FormattedText="{Binding CreateAccountText}"
Margin="0, 10"
StyleClass="box-footer-label">
StyleClass="box-footer-label"
AutomationId="CreateAccountLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CreateAccountCommand}" />
</Label.GestureRecognizers>
@@ -116,5 +142,4 @@
MainPage="{Binding Source={x:Reference _page}}"
BindingContext="{Binding AccountSwitchingOverlayViewModel}"/>
</AbsoluteLayout>
</pages:BaseContentPage>

View File

@@ -15,6 +15,8 @@ namespace Bit.App.Pages
private readonly AppOptions _appOptions;
private IBroadcasterService _broadcasterService;
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
public HomePage(AppOptions appOptions = null)
{
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
@@ -70,6 +72,14 @@ namespace Bit.App.Pages
});
}
});
try
{
await _vm.UpdateEnvironment();
}
catch (Exception ex)
{
_logger.Value?.Exception(ex);
}
}
protected override bool OnBackButtonPressed()
@@ -128,14 +138,6 @@ namespace Bit.App.Pages
await Navigation.PushModalAsync(new NavigationPage(page));
}
private void Environment_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.StartEnvironmentAction();
}
}
private async Task StartEnvironmentAsync()
{
await _accountListOverlay.HideAsync();

View File

@@ -4,7 +4,10 @@ using Bit.App.Abstractions;
using Bit.App.Controls;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Models.Data;
using Bit.Core.Models.Response;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
@@ -17,16 +20,19 @@ namespace Bit.App.Pages
{
private readonly IStateService _stateService;
private readonly IMessagingService _messagingService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly ILogger _logger;
private readonly IEnvironmentService _environmentService;
private readonly IAccountsManager _accountManager;
private readonly IConfigService _configService;
private bool _showCancelButton;
private bool _rememberEmail;
private string _email;
private string _selectedEnvironmentName;
private bool _isEmailEnabled;
private bool _canLogin;
private IPlatformUtilsService _platformUtilsService;
private ILogger _logger;
private IEnvironmentService _environmentService;
private IAccountsManager _accountManager;
private bool _displayEuEnvironment;
public HomeViewModel()
{
@@ -36,6 +42,7 @@ namespace Bit.App.Pages
_logger = ServiceContainer.Resolve<ILogger>();
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
_accountManager = ServiceContainer.Resolve<IAccountsManager>();
_configService = ServiceContainer.Resolve<IConfigService>();
PageTitle = AppResources.Bitwarden;
@@ -49,6 +56,8 @@ namespace Bit.App.Pages
onException: _logger.Exception, allowsMultipleExecutions: false);
CloseCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(CloseAction),
onException: _logger.Exception, allowsMultipleExecutions: false);
ShowEnvironmentPickerCommand = new AsyncCommand(ShowEnvironmentPickerAsync,
onException: _logger.Exception, allowsMultipleExecutions: false);
InitAsync().FireAndForget();
}
@@ -71,6 +80,13 @@ namespace Bit.App.Pages
additionalPropertyNames: new[] { nameof(CanContinue) });
}
public string SelectedEnvironmentName
{
get => $"{_selectedEnvironmentName} {BitwardenIcons.AngleDown}";
set => SetProperty(ref _selectedEnvironmentName, value);
}
public string RegionText => $"{AppResources.Region}:";
public bool CanContinue => !string.IsNullOrEmpty(Email);
public FormattedString CreateAccountText
@@ -101,11 +117,13 @@ namespace Bit.App.Pages
public AsyncCommand ContinueCommand { get; }
public AsyncCommand CloseCommand { get; }
public AsyncCommand CreateAccountCommand { get; }
public AsyncCommand ShowEnvironmentPickerCommand { get; }
public async Task InitAsync()
{
Email = await _stateService.GetRememberedEmailAsync();
RememberEmail = !string.IsNullOrEmpty(Email);
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag, forceRefresh: true);
}
public async Task ContinueToLoginStepAsync()
@@ -144,5 +162,59 @@ namespace Bit.App.Pages
await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage, AppResources.AnErrorHasOccurred, AppResources.Ok);
}
}
public async Task ShowEnvironmentPickerAsync()
{
_displayEuEnvironment = await _configService.GetFeatureFlagBoolAsync(Constants.DisplayEuEnvironmentFlag);
var options = _displayEuEnvironment
? new string[] { AppResources.US, AppResources.EU, AppResources.SelfHosted }
: new string[] { AppResources.US, AppResources.SelfHosted };
await Device.InvokeOnMainThreadAsync(async () =>
{
var result = await Page.DisplayActionSheet(AppResources.DataRegion, AppResources.Cancel, null, options);
if (result is null || result == AppResources.Cancel)
{
return;
}
if (result == AppResources.SelfHosted)
{
StartEnvironmentAction?.Invoke();
return;
}
await _environmentService.SetUrlsAsync(result == AppResources.EU ? EnvironmentUrlData.DefaultEU : EnvironmentUrlData.DefaultUS);
await _configService.GetAsync(true);
SelectedEnvironmentName = result;
});
}
public async Task UpdateEnvironment()
{
var environmentsSaved = await _stateService.GetPreAuthEnvironmentUrlsAsync();
if (environmentsSaved == null || environmentsSaved.IsEmpty)
{
await _environmentService.SetUrlsAsync(EnvironmentUrlData.DefaultUS);
environmentsSaved = EnvironmentUrlData.DefaultUS;
SelectedEnvironmentName = AppResources.US;
return;
}
if (environmentsSaved.Base == EnvironmentUrlData.DefaultUS.Base)
{
SelectedEnvironmentName = AppResources.US;
}
else if (environmentsSaved.Base == EnvironmentUrlData.DefaultEU.Base)
{
SelectedEnvironmentName = AppResources.EU;
}
else
{
await _configService.GetAsync(true);
SelectedEnvironmentName = AppResources.SelfHosted;
}
}
}
}

View File

@@ -24,7 +24,8 @@
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
@@ -71,7 +72,8 @@
Grid.Row="1"
Grid.Column="0"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="PinEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -81,7 +83,8 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"/>
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
AutomationId="PinVisibilityToggle" />
</Grid>
<Grid
x:Name="_passwordGrid"
@@ -111,7 +114,8 @@
Grid.Row="1"
Grid.Column="0"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="MasterPasswordEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -121,7 +125,9 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}" />
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
AutomationId="PasswordVisibilityToggle"
/>
</Grid>
<StackLayout
StyleClass="box-row"
@@ -147,7 +153,8 @@
x:Name="_unlockButton"
Text="{u:I18n Unlock}"
StyleClass="btn-primary"
Clicked="Unlock_Clicked" />
Clicked="Unlock_Clicked"
AutomationId="UnlockVaultButton" />
</StackLayout>
</StackLayout>
</ScrollView>

View File

@@ -33,7 +33,7 @@ namespace Bit.App.Pages
private readonly WeakEventManager<int?> _secretEntryFocusWeakEventManager = new WeakEventManager<int?>();
private readonly IPolicyService _policyService;
private readonly IPasswordGenerationService _passwordGenerationService;
private IDeviceTrustCryptoService _deviceTrustCryptoService;
private string _email;
private string _masterPassword;
private string _pin;
@@ -65,6 +65,7 @@ namespace Bit.App.Pages
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
_policyService = ServiceContainer.Resolve<IPolicyService>();
_passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>();
_deviceTrustCryptoService = ServiceContainer.Resolve<IDeviceTrustCryptoService>();
PageTitle = AppResources.VerifyMasterPassword;
TogglePasswordCommand = new Command(TogglePassword);
@@ -454,6 +455,11 @@ namespace Bit.App.Pages
{
await _cryptoService.SetKeyAsync(key);
}
if (await _deviceTrustCryptoService.GetUserTrustDeviceChoiceForDecryptionAsync())
{
await _deviceTrustCryptoService.TrustDeviceAsync();
await _deviceTrustCryptoService.SetUserTrustDeviceChoiceForDecryptionAsync(false);
}
await DoContinueAsync();
}

View 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.LoginApproveDevicePage"
xmlns:pages="clr-namespace:Bit.App.Pages"
xmlns:u="clr-namespace:Bit.App.Utilities"
x:DataType="pages:LoginApproveDeviceViewModel"
x:Name="_page"
Title="{Binding PageTitle}">
<ContentPage.BindingContext>
<pages:LoginApproveDeviceViewModel />
</ContentPage.BindingContext>
<StackLayout Padding="10, 10">
<StackLayout Padding="5, 10" Orientation="Horizontal">
<StackLayout HorizontalOptions="FillAndExpand">
<Label
StyleClass="text-md"
Text="{u:I18n RememberThisDevice}"/>
<Label
StyleClass="box-sub-label"
Text="{u:I18n TurnOffUsingPublicDevice}"/>
</StackLayout>
<Switch
Scale="0.8"
IsToggled="{Binding RememberThisDevice}"
VerticalOptions="Center"/>
</StackLayout>
<StackLayout Margin="0, 20, 0, 0">
<Button
x:Name="_continue"
Text="{u:I18n Continue}"
StyleClass="btn-primary"
Command="{Binding ContinueCommand}"
IsVisible="{Binding ContinueEnabled}"/>
<Button
x:Name="_approveWithMyOtherDevice"
Text="{u:I18n ApproveWithMyOtherDevice}"
StyleClass="btn-primary"
Command="{Binding ApproveWithMyOtherDeviceCommand}"
IsVisible="{Binding ApproveWithMyOtherDeviceEnabled}"/>
<Button
x:Name="_requestAdminApproval"
Text="{u:I18n RequestAdminApproval}"
StyleClass="box-button-row"
Command="{Binding RequestAdminApprovalCommand}"
IsVisible="{Binding RequestAdminApprovalEnabled}"/>
<Button
x:Name="_approveWithMasterPassword"
Text="{u:I18n ApproveWithMasterPassword}"
StyleClass="box-button-row"
Command="{Binding ApproveWithMasterPasswordCommand}"
IsVisible="{Binding ApproveWithMasterPasswordEnabled}"/>
<Label
Text="{Binding LoggingInAsText}"
StyleClass="text-sm"
Margin="0,40,0,0"
AutomationId="LoggingInAsLabel"
/>
<Label
Text="{u:I18n NotYou}"
StyleClass="text-md"
HorizontalOptions="Start"
TextColor="{DynamicResource HyperlinkColor}"
AutomationId="NotYouLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="Cancel_Clicked" />
</Label.GestureRecognizers>
</Label>
</StackLayout>
</StackLayout>
</pages:BaseContentPage>

View File

@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public partial class LoginApproveDevicePage : BaseContentPage
{
private readonly LoginApproveDeviceViewModel _vm;
private readonly AppOptions _appOptions;
public LoginApproveDevicePage(AppOptions appOptions = null)
{
InitializeComponent();
_vm = BindingContext as LoginApproveDeviceViewModel;
_vm.LogInWithMasterPassword = () => StartLogInWithMasterPassword().FireAndForget();
_vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget();
_vm.RequestAdminApprovalAction = () => RequestAdminApprovalAsync().FireAndForget();
_vm.CloseAction = () => { Navigation.PopModalAsync(); };
_vm.Page = this;
_appOptions = appOptions;
}
protected override void OnAppearing()
{
_vm.InitAsync();
}
private void Cancel_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.CloseAction();
}
}
private async Task StartLogInWithMasterPassword()
{
var page = new LockPage(_appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private async Task StartLoginWithDeviceAsync()
{
var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.AuthenticateAndUnlock, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private async Task RequestAdminApprovalAsync()
{
var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.AdminApproval, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
}
}

View File

@@ -0,0 +1,140 @@
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.App.Utilities.AccountManagement;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Request;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class LoginApproveDeviceViewModel : BaseViewModel
{
private bool _rememberThisDevice;
private bool _approveWithMyOtherDeviceEnabled;
private bool _requestAdminApprovalEnabled;
private bool _approveWithMasterPasswordEnabled;
private bool _continueEnabled;
private string _email;
private readonly IStateService _stateService;
private readonly IApiService _apiService;
private IDeviceTrustCryptoService _deviceTrustCryptoService;
public ICommand ApproveWithMyOtherDeviceCommand { get; }
public ICommand RequestAdminApprovalCommand { get; }
public ICommand ApproveWithMasterPasswordCommand { get; }
public ICommand ContinueCommand { get; }
public Action LogInWithMasterPassword { get; set; }
public Action LogInWithDeviceAction { get; set; }
public Action RequestAdminApprovalAction { get; set; }
public Action CloseAction { get; set; }
public LoginApproveDeviceViewModel()
{
_stateService = ServiceContainer.Resolve<IStateService>();
_apiService = ServiceContainer.Resolve<IApiService>();
_deviceTrustCryptoService = ServiceContainer.Resolve<IDeviceTrustCryptoService>();
PageTitle = AppResources.LoggedIn;
ApproveWithMyOtherDeviceCommand = new AsyncCommand(() => CheckDeviceTrustAndInvoke(LogInWithDeviceAction),
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
RequestAdminApprovalCommand = new AsyncCommand(() => CheckDeviceTrustAndInvoke(RequestAdminApprovalAction),
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
ApproveWithMasterPasswordCommand = new AsyncCommand(() => CheckDeviceTrustAndInvoke(LogInWithMasterPassword),
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
ContinueCommand = new AsyncCommand(InitAsync,
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
}
public string LoggingInAsText => string.Format(AppResources.LoggingInAsX, Email);
public bool RememberThisDevice
{
get => _rememberThisDevice;
set => SetProperty(ref _rememberThisDevice, value);
}
public bool ApproveWithMyOtherDeviceEnabled
{
get => _approveWithMyOtherDeviceEnabled;
set => SetProperty(ref _approveWithMyOtherDeviceEnabled, value);
}
public bool RequestAdminApprovalEnabled
{
get => _requestAdminApprovalEnabled;
set => SetProperty(ref _requestAdminApprovalEnabled, value);
}
public bool ApproveWithMasterPasswordEnabled
{
get => _approveWithMasterPasswordEnabled;
set => SetProperty(ref _approveWithMasterPasswordEnabled, value);
}
public bool ContinueEnabled
{
get => _continueEnabled;
set => SetProperty(ref _continueEnabled, value);
}
public string Email
{
get => _email;
set => SetProperty(ref _email, value, additionalPropertyNames:
new string[] {
nameof(LoggingInAsText)
});
}
public async Task InitAsync()
{
try
{
Email = await _stateService.GetRememberedEmailAsync();
var decryptOptions = await _stateService.GetAccountDecryptionOptions();
RequestAdminApprovalEnabled = decryptOptions != null && decryptOptions.TrustedDeviceOption != null && decryptOptions.TrustedDeviceOption.HasAdminApproval;
ApproveWithMasterPasswordEnabled = decryptOptions != null && decryptOptions.HasMasterPassword;
}
catch (Exception ex)
{
HandleException(ex);
}
try
{
ApproveWithMyOtherDeviceEnabled = await _apiService.GetDevicesExistenceByTypes(DeviceTypeExtensions.GetDesktopAndMobileTypes().ToArray());
}
catch (Exception ex)
{
HandleException(ex);
}
// TODO: Change this expression to, Appear if the browser is trusted and shared the key with the app
ContinueEnabled = !RequestAdminApprovalEnabled && !ApproveWithMasterPasswordEnabled && !ApproveWithMyOtherDeviceEnabled;
}
private async Task CheckDeviceTrustAndInvoke(Action action)
{
await _deviceTrustCryptoService.SetUserTrustDeviceChoiceForDecryptionAsync(RememberThisDevice);
await Device.InvokeOnMainThreadAsync(action);
}
}
}

View File

@@ -9,23 +9,23 @@
xmlns:u="clr-namespace:Bit.App.Utilities"
x:DataType="pages:LoginPageViewModel"
x:Name="_page"
Title="{Binding PageTitle}">
Title="{Binding PageTitle}"
AutomationId="PageTitleLabel">
<ContentPage.BindingContext>
<pages:LoginPageViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<controls:ExtendedToolbarItem
x:Name="_accountAvatar"
x:Key="accountAvatar"
IconImageSource="{Binding AvatarImageSource}"
Command="{Binding Source={x:Reference _accountListOverlay}, Path=ToggleVisibililtyCommand}"
Order="Primary"
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
@@ -34,7 +34,8 @@
<ToolbarItem Icon="more_vert.png" Clicked="More_Clicked" Order="Primary"
x:Name="_moreItem" x:Key="moreItem"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="OptionsButton" />
<ToolbarItem Text="{u:I18n GetPasswordHint}"
x:Key="getPasswordHint"
x:Name="_getPasswordHint"
@@ -75,7 +76,9 @@
Grid.Row="1"
Grid.Column="0"
ReturnType="Go"
ReturnCommand="{Binding LogInCommand}" />
ReturnCommand="{Binding LogInCommand}"
AutomationId="MasterPasswordEntry"
/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -84,6 +87,7 @@
Grid.Column="1"
Grid.RowSpan="1"
AutomationProperties.IsInAccessibleTree="True"
AutomationId="PasswordVisibilityToggle"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"/>
<Label
@@ -93,7 +97,9 @@
Padding="0,5,0,0"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2">
Grid.ColumnSpan="2"
AutomationId="GetMasterPasswordHintLabel"
>
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="Hint_Clicked" />
</Label.GestureRecognizers>
@@ -104,19 +110,24 @@
<Button x:Name="_loginWithMasterPassword"
Text="{u:I18n LogInWithMasterPassword}"
StyleClass="btn-primary"
Clicked="LogIn_Clicked" />
Clicked="LogIn_Clicked"
AutomationId="LogInWithMasterPasswordButton"
/>
<controls:IconLabelButton
HorizontalOptions="Fill"
VerticalOptions="CenterAndExpand"
Icon="{Binding Source={x:Static core:BitwardenIcons.Device}}"
Label="{u:I18n LogInWithAnotherDevice}"
ButtonCommand="{Binding LogInWithDeviceCommand}"
IsVisible="{Binding IsKnownDevice}"/>
IsVisible="{Binding IsKnownDevice}"
AutomationId="LogInWithAnotherDeviceButton"
/>
<controls:IconLabelButton
HorizontalOptions="Fill"
VerticalOptions="CenterAndExpand"
Icon="{Binding Source={x:Static core:BitwardenIcons.Suitcase}}"
Label="{u:I18n LogInSso}">
Label="{u:I18n LogInSso}"
AutomationId="LogInWithSsoButton">
<controls:IconLabelButton.GestureRecognizers>
<TapGestureRecognizer Tapped="LogInSSO_Clicked" />
</controls:IconLabelButton.GestureRecognizers>
@@ -124,12 +135,15 @@
<Label
Text="{Binding LoggingInAsText}"
StyleClass="text-sm"
Margin="0,40,0,0"/>
Margin="0,40,0,0"
AutomationId="LoggingInAsLabel"
/>
<Label
Text="{u:I18n NotYou}"
StyleClass="text-md"
HorizontalOptions="Start"
TextColor="{DynamicResource HyperlinkColor}">
TextColor="{DynamicResource HyperlinkColor}"
AutomationId="NotYouLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="Cancel_Clicked" />
</Label.GestureRecognizers>

View File

@@ -4,6 +4,7 @@ using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
@@ -135,7 +136,7 @@ namespace Bit.App.Pages
private async Task StartLoginWithDeviceAsync()
{
var page = new LoginPasswordlessRequestPage(_vm.Email, _appOptions);
var page = new LoginPasswordlessRequestPage(_vm.Email, AuthRequestType.AuthenticateAndUnlock, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}

View File

@@ -41,6 +41,7 @@ namespace Bit.App.Pages
private bool _isEmailEnabled;
private bool _isKnownDevice;
private bool _isExecutingLogin;
private string _environmentHostName;
public LoginPageViewModel()
{
@@ -115,6 +116,16 @@ namespace Bit.App.Pages
set => SetProperty(ref _isKnownDevice, value);
}
public string EnvironmentDomainName
{
get => _environmentHostName;
set => SetProperty(ref _environmentHostName, value,
additionalPropertyNames: new string[]
{
nameof(LoggingInAsText)
});
}
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
public Command LogInCommand { get; }
public Command TogglePasswordCommand { get; }
@@ -122,7 +133,7 @@ namespace Bit.App.Pages
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 string LoggingInAsText => string.Format(AppResources.LoggingInAsXOnY, Email, EnvironmentDomainName);
public bool IsIosExtension { get; set; }
public bool CanRemoveAccount { get; set; }
public Action StartTwoFactorAction { get; set; }
@@ -151,6 +162,7 @@ namespace Bit.App.Pages
Email = await _stateService.GetRememberedEmailAsync();
}
CanRemoveAccount = await _stateService.GetActiveUserEmailAsync() != Email;
EnvironmentDomainName = CoreHelpers.GetDomain((await _stateService.GetPreAuthEnvironmentUrlsAsync())?.Base);
IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, await _appIdService.GetAppIdAsync());
}
catch (ApiException apiEx) when (apiEx.Error.StatusCode == System.Net.HttpStatusCode.Unauthorized)

View File

@@ -32,7 +32,8 @@
<Label
Text="{Binding LogInAttemptByLabel}"
FontSize="Small"
Margin="0,0,0,24"/>
Margin="0,0,0,24"
AutomationId="LogInAttemptByLabel" />
<Label
Text="{u:I18n FingerprintPhrase}"
FontSize="Small"
@@ -41,7 +42,8 @@
FormattedText="{Binding LoginRequest.FingerprintPhrase}"
FontSize="Medium"
TextColor="{DynamicResource FingerprintPhrase}"
Margin="0,0,0,27"/>
Margin="0,0,0,27"
AutomationId="FingerprintValueLabel" />
<Label
Text="{u:I18n DeviceType}"
FontSize="Small"
@@ -49,7 +51,8 @@
<Label
Text="{Binding LoginRequest.DeviceType}"
FontSize="Small"
Margin="0,0,0,21"/>
Margin="0,0,0,21"
AutomationId="DeviceTypeValueLabel" />
<Label
Text="{u:I18n IpAddress}"
IsVisible="{Binding ShowIpAddress}"
@@ -59,7 +62,8 @@
Text="{Binding LoginRequest.IpAddress}"
IsVisible="{Binding ShowIpAddress}"
FontSize="Small"
Margin="0,0,0,21"/>
Margin="0,0,0,21"
AutomationId="IpAddressValueLabel" />
<Label
Text="{u:I18n Time}"
FontSize="Small"
@@ -67,7 +71,8 @@
<Label
Text="{Binding TimeOfRequestText}"
FontSize="Small"
Margin="0,0,0,57"/>
Margin="0,0,0,57"
AutomationId="TimeOfRequestValueLabel" />
</StackLayout>
</ScrollView>
@@ -75,11 +80,13 @@
Text="{u:I18n ConfirmLogIn}"
Command="{Binding AcceptRequestCommand}"
Margin="0,0,0,17"
StyleClass="btn-primary"/>
StyleClass="btn-primary"
AutomationId="ConfirmLoginButton" />
<Button
Text="{u:I18n DenyLogIn}"
Command="{Binding RejectRequestCommand}"
StyleClass="btn-secundary"/>
StyleClass="btn-secundary"
AutomationId="DenyLoginButton" />
</StackLayout>
</pages:BaseContentPage>

View File

@@ -21,16 +21,17 @@
<StackLayout
Padding="7, 0, 7, 20">
<Label
Text="{u:I18n LogInInitiated}"
Text="{Binding Tittle}"
FontSize="Title"
FontAttributes="Bold"
Margin="0,14,0,21"/>
Margin="0,14,0,21"
AutomationId="LogInInitiatedLabel" />
<Label
Text="{u:I18n ANotificationHasBeenSentToYourDevice}"
Text="{Binding SubTittle}"
FontSize="Small"
Margin="0,0,0,10"/>
<Label
Text="{u:I18n PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice}"
Text="{Binding Description}"
FontSize="Small"
Margin="0,0,0,24"/>
<Label
@@ -40,13 +41,16 @@
<controls:MonoLabel
FormattedText="{Binding FingerprintPhrase}"
FontSize="Medium"
TextColor="{DynamicResource FingerprintPhrase}"/>
TextColor="{DynamicResource FingerprintPhrase}"
AutomationId="FingerprintPhraseValue" />
<Label
Text="{u:I18n ResendNotification}"
IsVisible="{Binding ResendNotificationVisible}"
StyleClass="text-md"
HorizontalOptions="Start"
Margin="0,40,0,0"
TextColor="{DynamicResource HyperlinkColor}">
TextColor="{DynamicResource HyperlinkColor}"
AutomationId="ResendNotificationButton">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CreatePasswordlessLoginCommand}" />
</Label.GestureRecognizers>
@@ -55,7 +59,7 @@
Orientation="Horizontal"
Margin="0,30,0,0">
<Label
Text="{u:I18n NeedAnotherOption}"
Text="{Binding OtherOptions}"
FontSize="Small"
VerticalTextAlignment="End"/>
<Label
@@ -64,7 +68,8 @@
VerticalTextAlignment="End"
VerticalOptions="CenterAndExpand"
Margin="5, 0"
TextColor="{DynamicResource HyperlinkColor}">
TextColor="{DynamicResource HyperlinkColor}"
AutomationId="ViewAllLoginOptionsButton">
<Label.GestureRecognizers>
<TapGestureRecognizer Command="{Binding CloseCommand}" />
</Label.GestureRecognizers>

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core.Enums;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -12,13 +13,14 @@ namespace Bit.App.Pages
private LoginPasswordlessRequestViewModel _vm;
private readonly AppOptions _appOptions;
public LoginPasswordlessRequestPage(string email, AppOptions appOptions = null)
public LoginPasswordlessRequestPage(string email, AuthRequestType authRequestType, AppOptions appOptions = null)
{
InitializeComponent();
_appOptions = appOptions;
_vm = BindingContext as LoginPasswordlessRequestViewModel;
_vm.Page = this;
_vm.Email = email;
_vm.AuthRequestType = authRequestType;
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
_vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -32,6 +33,7 @@ namespace Bit.App.Pages
private IPlatformUtilsService _platformUtilsService;
private IEnvironmentService _environmentService;
private ILogger _logger;
private IDeviceTrustCryptoService _deviceTrustCryptoService;
protected override II18nService i18nService => _i18nService;
protected override IEnvironmentService environmentService => _environmentService;
@@ -44,6 +46,7 @@ namespace Bit.App.Pages
private string _email;
private string _requestId;
private string _requestAccessCode;
private AuthRequestType _authRequestType;
// Item1 publicKey, Item2 privateKey
private Tuple<byte[], byte[]> _requestKeyPair;
@@ -57,6 +60,7 @@ namespace Bit.App.Pages
_i18nService = ServiceContainer.Resolve<II18nService>();
_stateService = ServiceContainer.Resolve<IStateService>();
_logger = ServiceContainer.Resolve<ILogger>();
_deviceTrustCryptoService = ServiceContainer.Resolve<IDeviceTrustCryptoService>();
PageTitle = AppResources.LogInWithAnotherDevice;
@@ -77,6 +81,70 @@ namespace Bit.App.Pages
public ICommand CreatePasswordlessLoginCommand { get; }
public ICommand CloseCommand { get; }
public string Tittle
{
get
{
switch (_authRequestType)
{
case AuthRequestType.AuthenticateAndUnlock:
return AppResources.LogInInitiated;
case AuthRequestType.AdminApproval:
return AppResources.AdminApprovalRequested;
default:
return string.Empty;
};
}
}
public string SubTittle
{
get
{
switch (_authRequestType)
{
case AuthRequestType.AuthenticateAndUnlock:
return AppResources.ANotificationHasBeenSentToYourDevice;
case AuthRequestType.AdminApproval:
return AppResources.YourRequestHasBeenSentToYourAdmin;
default:
return string.Empty;
};
}
}
public string Description
{
get
{
switch (_authRequestType)
{
case AuthRequestType.AuthenticateAndUnlock:
return AppResources.PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice;
case AuthRequestType.AdminApproval:
return AppResources.YouWillBeNotifiedOnceApproved;
default:
return string.Empty;
};
}
}
public string OtherOptions
{
get
{
switch (_authRequestType)
{
case AuthRequestType.AuthenticateAndUnlock:
return AppResources.NeedAnotherOption;
case AuthRequestType.AdminApproval:
return AppResources.TroubleLoggingIn;
default:
return string.Empty;
};
}
}
public string FingerprintPhrase
{
get => _fingerprintPhrase;
@@ -89,6 +157,21 @@ namespace Bit.App.Pages
set => SetProperty(ref _email, value);
}
public AuthRequestType AuthRequestType
{
get => _authRequestType;
set => SetProperty(ref _authRequestType, value, additionalPropertyNames: new string[]
{
nameof(Tittle),
nameof(SubTittle),
nameof(Description),
nameof(OtherOptions),
nameof(ResendNotificationVisible)
});
}
public bool ResendNotificationVisible => AuthRequestType == AuthRequestType.AuthenticateAndUnlock;
public void StartCheckLoginRequestStatus()
{
try
@@ -154,6 +237,11 @@ namespace Bit.App.Pages
else
{
_syncService.FullSyncAsync(true).FireAndForget();
if (await _deviceTrustCryptoService.GetUserTrustDeviceChoiceForDecryptionAsync())
{
await _deviceTrustCryptoService.TrustDeviceAsync();
await _deviceTrustCryptoService.SetUserTrustDeviceChoiceForDecryptionAsync(false);
}
LogInSuccessAction?.Invoke();
}
}
@@ -168,7 +256,7 @@ namespace Bit.App.Pages
{
await Device.InvokeOnMainThreadAsync(() => _deviceActionService.ShowLoadingAsync(AppResources.Loading));
var response = await _authService.PasswordlessCreateLoginRequestAsync(_email);
var response = await _authService.PasswordlessCreateLoginRequestAsync(_email, AuthRequestType);
if (response != null)
{
FingerprintPhrase = response.FingerprintPhrase;

View File

@@ -110,6 +110,11 @@ namespace Bit.App.Pages
{
RestoreAppOptionsFromCopy();
await AppHelpers.ClearPreviousPage();
// Just for testing the screen
Application.Current.MainPage = new NavigationPage(new LoginApproveDevicePage(_appOptions));
return;
if (await _vaultTimeoutService.IsLockedAsync())
{
Application.Current.MainPage = new NavigationPage(new LockPage(_appOptions));

View File

@@ -35,7 +35,8 @@
x:Name="_email"
Text="{Binding Email}"
Keyboard="Email"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="EmailAddressEntry"/>
</StackLayout>
<Grid StyleClass="box-row">
<Grid.RowDefinitions>
@@ -59,7 +60,8 @@
IsTextPredictionEnabled="False"
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
Grid.Row="1"
Grid.Column="0" />
Grid.Column="0"
AutomationId="MasterPasswordEntry"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -69,7 +71,8 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"/>
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
AutomationId="PasswordVisibilityToggle"/>
</Grid>
<Label
StyleClass="box-sub-label"
@@ -109,7 +112,8 @@
IsTextPredictionEnabled="False"
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
Grid.Row="1"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ConfirmMasterPasswordEntry"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -118,6 +122,7 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationId="ConfirmPasswordVisibilityToggle"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}" />
</Grid>
@@ -130,7 +135,8 @@
Text="{Binding Hint}"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="MasterPasswordHintLabel" />
</StackLayout>
<Label
Text="{u:I18n MasterPasswordHintDescription}"
@@ -142,7 +148,8 @@
IsToggled="{Binding CheckExposedMasterPassword}"
StyleClass="box-value"
HorizontalOptions="Start"
Margin="0, 0, 10, 0"/>
Margin="0, 0, 10, 0"
AutomationId="CheckExposedMasterPasswordToggle"/>
<Label
Text="{u:I18n CheckKnownDataBreachesForThisPassword}"
StyleClass="box-footer-label"
@@ -154,7 +161,8 @@
IsToggled="{Binding AcceptPolicies}"
StyleClass="box-value"
HorizontalOptions="Start"
Margin="0, 0, 10, 0"/>
Margin="0, 0, 10, 0"
AutomationId="AcceptPoliciesToggle"/>
<Label StyleClass="box-footer-label"
HorizontalOptions="Fill">
<Label.FormattedText>

View File

@@ -27,7 +27,8 @@
Clicked="Clear_Clicked"
Order="Secondary"
x:Name="_clearItem"
x:Key="clearItem" />
x:Key="clearItem"
AutomationId="ClearPasswordList" />
<ToolbarItem Icon="more_vert.png"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}"
@@ -43,7 +44,8 @@
Margin="20, 0"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"></Label>
HorizontalTextAlignment="Center"
AutomationId="NoPasswordsDisplayedLabel"></Label>
<controls:ExtendedCollectionView
IsVisible="{Binding ShowNoData, Converter={StaticResource inverseBool}}"
ItemsSource="{Binding History}"
@@ -56,7 +58,8 @@
StyleClass="list-row, list-row-platform"
Padding="10"
RowSpacing="0"
ColumnSpacing="10">
ColumnSpacing="10"
AutomationId="GeneratedPasswordRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
@@ -71,12 +74,14 @@
Grid.Column="0"
Grid.Row="0"
StyleClass="list-title, list-title-platform, text-html"
Text="{Binding Password, Mode=OneWay, Converter={StaticResource coloredPassword}}" />
Text="{Binding Password, Mode=OneWay, Converter={StaticResource coloredPassword}}"
AutomationId="GeneratedPasswordValue" />
<Label LineBreakMode="TailTruncation"
Grid.Column="0"
Grid.Row="1"
StyleClass="list-subtitle, list-subtitle-platform"
Text="{Binding Date, Mode=OneWay, Converter={StaticResource dateTime}}" />
Text="{Binding Date, Mode=OneWay, Converter={StaticResource dateTime}}"
AutomationId="GeneratedPasswordDateLabel" />
<controls:IconButton
StyleClass="list-row-button, list-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Paste}}"
@@ -86,7 +91,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyPassword}" />
AutomationProperties.Name="{u:I18n CopyPassword}"
AutomationId="CopyPasswordValueButton" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>

View File

@@ -71,7 +71,8 @@
<Label
Text="{u:I18n PasswordGeneratorPolicyInEffect}"
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="PasswordGeneratorPolicyInEffectLabel" />
</Frame>
</Grid>
<Grid IsVisible="{Binding IsUsername, Converter={StaticResource inverseBool}}"
@@ -82,21 +83,24 @@
x:Name="lblPassword"
StyleClass="text-lg, text-html"
Text="{Binding ColoredPassword, Mode=OneWay}"
Margin="0, 20" />
Margin="0, 20"
AutomationId="GeneratedPasswordLabel" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
Command="{Binding CopyCommand}"
Grid.Column="1"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyPassword}" />
AutomationProperties.Name="{u:I18n CopyPassword}"
AutomationId="CopyValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Generate}}"
Command="{Binding RegenerateCommand}"
Grid.Column="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n GeneratePassword}" />
AutomationProperties.Name="{u:I18n GeneratePassword}"
AutomationId="RegenerateValueButton" />
</Grid>
<Grid IsVisible="{Binding IsUsername}"
StyleClass="box-row"
@@ -107,21 +111,24 @@
StyleClass="text-lg, text-html"
Text="{Binding ColoredUsername, Mode=OneWay}"
Margin="0, 20"
HorizontalOptions="Start" />
HorizontalOptions="Start"
AutomationId="GeneratedPasswordLabel" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
Command="{Binding CopyCommand}"
Grid.Column="1"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyUsername}" />
AutomationProperties.Name="{u:I18n CopyUsername}"
AutomationId="CopyValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Generate}}"
Command="{Binding RegenerateUsernameCommand}"
Grid.Column="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n GenerateUsername}" />
AutomationProperties.Name="{u:I18n GenerateUsername}"
AutomationId="RegenerateValueButton" />
</Grid>
<BoxView StyleClass="box-row-separator"/>
<StackLayout StyleClass="box"
@@ -135,7 +142,8 @@
ItemsSource="{Binding GeneratorTypeOptions, Mode=OneTime}"
SelectedItem="{Binding GeneratorTypeSelected}"
ItemDisplayBinding="{Binding ., Converter={StaticResource localizableEnum}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="GeneratorTypePicker" />
</StackLayout>
<Label Text="{u:I18n Options, Header=True}"
StyleClass="box-header, box-header-platform"
@@ -161,7 +169,8 @@
ItemsSource="{Binding UsernameTypeOptions, Mode=OneTime}"
SelectedItem="{Binding UsernameTypeSelected}"
ItemDisplayBinding="{Binding ., Converter={StaticResource localizableEnum}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="UsernameTypePicker" />
<Label
StyleClass="box-footer-label"
Text="{Binding UsernameTypeDescriptionLabel}" />
@@ -172,7 +181,8 @@
StyleClass="box-label" />
<Entry x:Name="_plusAddressedEmailEntry"
Text="{Binding PlusAddressedEmail}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="PlusAddressedEmailEntry" />
<Label IsVisible="{Binding ShowUsernameEmailType}"
Text="{u:I18n EmailType}"
StyleClass="box-label"
@@ -203,7 +213,8 @@
<Entry
x:Name="_catchAllEmailDomainNameEntry"
Text="{Binding CatchAllEmailDomain}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="CatchAllEmailDomainEntry" />
<Label IsVisible="{Binding ShowUsernameEmailType}"
Text="{u:I18n EmailType}"
StyleClass="box-label"
@@ -236,26 +247,27 @@
ItemsSource="{Binding ForwardedEmailServiceTypeOptions, Mode=OneTime}"
SelectedItem="{Binding ForwardedEmailServiceSelected}"
ItemDisplayBinding="{Binding ., Converter={StaticResource localizableEnum}}"
StyleClass="box-value" />
<!--ANONADDY OPTIONS-->
<Grid IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.AnonAddy}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
StyleClass="box-value"
AutomationId="ServiceTypePicker" />
<Grid
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Margin="0,10,0,0"
Text="{u:I18n APIAccessToken}"
Text="{Binding ForwardedEmailApiSecretLabel}"
StyleClass="box-label"/>
<Entry
x:Name="_anonAddyApiAccessTokenEntry"
Text="{Binding AnonAddyApiAccessToken}"
IsPassword="{Binding ShowAnonAddyApiAccessToken, Converter={StaticResource inverseBool}}"
Grid.Row="1"/>
Text="{Binding ForwardedEmailApiSecret}"
IsPassword="{Binding ShowForwardedEmailApiSecret, Converter={StaticResource inverseBool}}"
Grid.Row="1"
AutomationId="ForwardedEmailApiSecretEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowAnonAddyApiAccessToken, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Text="{Binding ShowForwardedEmailApiSecret, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
Grid.Column="1"
AutomationId="ShowForwardedEmailApiSecretButton" />
</Grid>
<Label IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.AnonAddy}}"
Text="{u:I18n DomainNameRequiredParenthesis}"
@@ -264,91 +276,8 @@
<Entry IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.AnonAddy}}"
x:Name="_anonAddyDomainNameEntry"
Text="{Binding AnonAddyDomainName}"
StyleClass="box-value"/>
<!--FIREFOX RELAY OPTIONS-->
<Grid StyleClass="box-row, box-row-input"
IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.FirefoxRelay}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Text="{u:I18n APIAccessToken}"
StyleClass="box-label"/>
<Entry
x:Name="_firefoxRelayApiAccessTokenEntry"
Text="{Binding FirefoxRelayApiAccessToken}"
StyleClass="box-value"
Grid.Row="1"
IsPassword="{Binding ShowFirefoxRelayApiAccessToken, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowFirefoxRelayApiAccessToken, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
<!--SIMPLELOGIN OPTIONS-->
<Grid StyleClass="box-row, box-row-input"
IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.SimpleLogin}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Text="{u:I18n APIKeyRequiredParenthesis}"
StyleClass="box-label"/>
<Entry
x:Name="_simpleLoginApiKeyEntry"
Text="{Binding SimpleLoginApiKey}"
StyleClass="box-value"
Grid.Row="1"
IsPassword="{Binding ShowSimpleLoginApiKey, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowSimpleLoginApiKey, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
<!--DUCKDUCKGO OPTIONS-->
<Grid StyleClass="box-row, box-row-input"
IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.DuckDuckGo}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Text="{u:I18n APIKeyRequiredParenthesis}"
StyleClass="box-label"/>
<Entry
x:Name="_duckDuckGoApiAccessTokenEntry"
Text="{Binding DuckDuckGoApiKey}"
StyleClass="box-value"
Grid.Row="1"
IsPassword="{Binding ShowDuckDuckGoApiKey, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowDuckDuckGoApiKey, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
<!--FASTMAIL OPTIONS-->
<Grid StyleClass="box-row, box-row-input"
IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.Fastmail}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Text="{u:I18n APIKeyRequiredParenthesis}"
StyleClass="box-label"/>
<Entry
x:Name="_fastmailApiAccessTokenEntry"
Text="{Binding FastmailApiKey}"
StyleClass="box-value"
Grid.Row="1"
IsPassword="{Binding ShowFastmailApiKey, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowFastmailApiKey, Converter={StaticResource iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
StyleClass="box-value"
AutomationId="AnonAddyDomainNameEntry" />
</StackLayout>
<!--RANDOM WORD OPTIONS-->
<Grid IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}">
@@ -359,7 +288,8 @@
<Switch
IsToggled="{Binding CapitalizeRandomWordUsername}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="CapitalizeRandomWordUsernameToggle" />
</Grid>
<BoxView IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}"
StyleClass="box-row-separator" />
@@ -371,7 +301,8 @@
<Switch
IsToggled="{Binding IncludeNumberRandomWordUsername}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="IncludeNumberRandomWordUsernameToggle" />
</Grid>
<BoxView IsVisible="{Binding UsernameTypeSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:UsernameType.RandomWord}}"
StyleClass="box-row-separator" />
@@ -386,7 +317,8 @@
x:Name="_passwordTypePicker"
ItemsSource="{Binding PasswordTypeOptions, Mode=OneTime}"
SelectedIndex="{Binding PasswordTypeSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="PasswordTypePicker" />
</StackLayout>
<StackLayout Spacing="0"
Padding="0"
@@ -403,12 +335,14 @@
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="NumberOfWordsLabel" />
<controls:ExtendedStepper
Value="{Binding NumWords}"
Maximum="20"
Minimum="3"
Increment="1" />
Increment="1"
AutomationId="NumberOfWordsStepper" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-input">
@@ -419,7 +353,8 @@
Text="{Binding WordSeparator}"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False"
StyleClass="box-value">
StyleClass="box-value"
AutomationId="WordSeparatorEntry">
<Entry.Effects>
<effects:NoEmojiKeyboardEffect />
</Entry.Effects>
@@ -435,7 +370,8 @@
IsEnabled="{Binding EnforcedPolicyOptions.Capitalize,
Converter={StaticResource inverseBool}}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="CapitalizePassphraseToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
@@ -448,7 +384,8 @@
IsEnabled="{Binding EnforcedPolicyOptions.IncludeNumber,
Converter={StaticResource inverseBool}}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="IncludeNumbersToggle" />
</StackLayout>
</StackLayout>
<StackLayout Spacing="0" Padding="0" IsVisible="{Binding IsPassword}">
@@ -462,7 +399,8 @@
StyleClass="box-sub-label"
VerticalOptions="CenterAndExpand"
HorizontalTextAlignment="End"
WidthRequest="50" />
WidthRequest="50"
AutomationId="PasswordLengthLabel" />
<controls:ExtendedSlider
DragCompleted="LengthSlider_DragCompleted"
Value="{Binding Length}"
@@ -471,7 +409,8 @@
VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand"
Maximum="128"
Minimum="5" />
Minimum="5"
AutomationId="PasswordLengthSlider" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
@@ -488,7 +427,8 @@
StyleClass="box-value"
HorizontalOptions="End"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n UppercaseAtoZ}"/>
AutomationProperties.Name="{u:I18n UppercaseAtoZ}"
AutomationId="UppercaseAtoZToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
@@ -505,7 +445,8 @@
StyleClass="box-value"
HorizontalOptions="End"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n LowercaseAtoZ}"/>
AutomationProperties.Name="{u:I18n LowercaseAtoZ}"
AutomationId="LowercaseAtoZToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
@@ -522,7 +463,8 @@
StyleClass="box-value"
HorizontalOptions="End"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n NumbersZeroToNine}"/>
AutomationProperties.Name="{u:I18n NumbersZeroToNine}"
AutomationId="NumbersZeroToNineToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
@@ -539,7 +481,8 @@
StyleClass="box-value"
HorizontalOptions="End"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n SpecialCharacters}"/>
AutomationProperties.Name="{u:I18n SpecialCharacters}"
AutomationId="SpecialCharactersToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-stepper">
@@ -554,12 +497,14 @@
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="MinNumberValueLabel" />
<controls:ExtendedStepper
Value="{Binding MinNumber}"
Maximum="5"
Minimum="0"
Increment="1" />
Increment="1"
AutomationId="MinNumberStepper" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-stepper">
@@ -574,12 +519,14 @@
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="End"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="MinSpecialValueLabel" />
<controls:ExtendedStepper
Value="{Binding MinSpecial}"
Maximum="5"
Minimum="0"
Increment="1" />
Increment="1"
AutomationId="MinSpecialStepper" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout StyleClass="box-row, box-row-switch">
@@ -590,7 +537,8 @@
<Switch
IsToggled="{Binding AvoidAmbiguousChars}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="AvoidAmbiguousCharsToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>

View File

@@ -8,6 +8,7 @@ using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
@@ -23,7 +24,7 @@ namespace Bit.App.Pages
private readonly IUsernameGenerationService _usernameGenerationService;
private readonly ITokenService _tokenService;
private readonly IDeviceActionService _deviceActionService;
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
private PasswordGenerationOptions _options;
private UsernameGenerationOptions _usernameOptions;
@@ -49,11 +50,7 @@ namespace Bit.App.Pages
private bool _doneIniting;
private bool _showTypePicker;
private string _emailWebsite;
private bool _showFirefoxRelayApiAccessToken;
private bool _showAnonAddyApiAccessToken;
private bool _showSimpleLoginApiKey;
private bool _showDuckDuckGoApiKey;
private bool _showFastmailApiKey;
private bool _showForwardedEmailApiSecret;
private bool _editMode;
public GeneratorPageViewModel()
@@ -96,7 +93,7 @@ namespace Bit.App.Pages
UsernameTypePromptHelpCommand = new Command(UsernameTypePromptHelp);
RegenerateCommand = new AsyncCommand(RegenerateAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
RegenerateUsernameCommand = new AsyncCommand(RegenerateUsernameAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
ToggleForwardedEmailHiddenValueCommand = new AsyncCommand(ToggleForwardedEmailHiddenValueAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
ToggleForwardedEmailHiddenValueCommand = new Command(() => ShowForwardedEmailApiSecret = !ShowForwardedEmailApiSecret);
CopyCommand = new AsyncCommand(CopyAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
CloseCommand = new AsyncCommand(CloseAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
}
@@ -415,7 +412,6 @@ namespace Bit.App.Pages
public string UsernameTypeDescriptionLabel => GetUsernameTypeLabelDescription(UsernameTypeSelected);
public ForwardedEmailServiceType ForwardedEmailServiceSelected
{
get => _usernameOptions.ServiceType;
@@ -425,7 +421,11 @@ namespace Bit.App.Pages
{
_usernameOptions.ServiceType = value;
Username = Constants.DefaultUsernameGenerated;
TriggerPropertyChanged(nameof(ForwardedEmailServiceSelected));
TriggerPropertyChanged(nameof(ForwardedEmailServiceSelected), new string[]
{
nameof(ForwardedEmailApiSecret),
nameof(ForwardedEmailApiSecretLabel)
});
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
@@ -445,27 +445,104 @@ namespace Bit.App.Pages
}
}
public string AnonAddyApiAccessToken
public string ForwardedEmailApiSecret
{
get => _usernameOptions.AnonAddyApiAccessToken;
get
{
switch (ForwardedEmailServiceSelected)
{
case ForwardedEmailServiceType.AnonAddy:
return _usernameOptions.AnonAddyApiAccessToken;
case ForwardedEmailServiceType.DuckDuckGo:
return _usernameOptions.DuckDuckGoApiKey;
case ForwardedEmailServiceType.Fastmail:
return _usernameOptions.FastMailApiKey;
case ForwardedEmailServiceType.FirefoxRelay:
return _usernameOptions.FirefoxRelayApiAccessToken;
case ForwardedEmailServiceType.SimpleLogin:
return _usernameOptions.SimpleLoginApiKey;
default:
return null;
}
}
set
{
if (_usernameOptions.AnonAddyApiAccessToken != value)
bool changed = false;
switch (ForwardedEmailServiceSelected)
{
_usernameOptions.AnonAddyApiAccessToken = value;
TriggerPropertyChanged(nameof(AnonAddyApiAccessToken));
case ForwardedEmailServiceType.AnonAddy:
if (_usernameOptions.AnonAddyApiAccessToken != value)
{
_usernameOptions.AnonAddyApiAccessToken = value;
changed = true;
}
break;
case ForwardedEmailServiceType.DuckDuckGo:
if (_usernameOptions.DuckDuckGoApiKey != value)
{
_usernameOptions.DuckDuckGoApiKey = value;
changed = true;
}
break;
case ForwardedEmailServiceType.Fastmail:
if (_usernameOptions.FastMailApiKey != value)
{
_usernameOptions.FastMailApiKey = value;
changed = true;
}
break;
case ForwardedEmailServiceType.FirefoxRelay:
if (_usernameOptions.FirefoxRelayApiAccessToken != value)
{
_usernameOptions.FirefoxRelayApiAccessToken = value;
changed = true;
}
break;
case ForwardedEmailServiceType.SimpleLogin:
if (_usernameOptions.SimpleLoginApiKey != value)
{
_usernameOptions.SimpleLoginApiKey = value;
changed = true;
}
break;
default:
break;
}
if (changed)
{
TriggerPropertyChanged(nameof(ForwardedEmailApiSecret));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool ShowAnonAddyApiAccessToken
public string ForwardedEmailApiSecretLabel
{
get
{
return _showAnonAddyApiAccessToken;
switch (ForwardedEmailServiceSelected)
{
case ForwardedEmailServiceType.AnonAddy:
case ForwardedEmailServiceType.FirefoxRelay:
return AppResources.APIAccessToken;
case ForwardedEmailServiceType.DuckDuckGo:
case ForwardedEmailServiceType.Fastmail:
case ForwardedEmailServiceType.SimpleLogin:
return AppResources.APIKeyRequiredParenthesis;
default:
return null;
}
}
set => SetProperty(ref _showAnonAddyApiAccessToken, value);
}
public bool ShowForwardedEmailApiSecret
{
get
{
return _showForwardedEmailApiSecret;
}
set => SetProperty(ref _showForwardedEmailApiSecret, value);
}
public string AnonAddyDomainName
@@ -482,99 +559,6 @@ namespace Bit.App.Pages
}
}
public string FirefoxRelayApiAccessToken
{
get => _usernameOptions.FirefoxRelayApiAccessToken;
set
{
if (_usernameOptions.FirefoxRelayApiAccessToken != value)
{
_usernameOptions.FirefoxRelayApiAccessToken = value;
TriggerPropertyChanged(nameof(FirefoxRelayApiAccessToken));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool ShowFirefoxRelayApiAccessToken
{
get
{
return _showFirefoxRelayApiAccessToken;
}
set => SetProperty(ref _showFirefoxRelayApiAccessToken, value);
}
public string SimpleLoginApiKey
{
get => _usernameOptions.SimpleLoginApiKey;
set
{
if (_usernameOptions.SimpleLoginApiKey != value)
{
_usernameOptions.SimpleLoginApiKey = value;
TriggerPropertyChanged(nameof(SimpleLoginApiKey));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool ShowSimpleLoginApiKey
{
get
{
return _showSimpleLoginApiKey;
}
set => SetProperty(ref _showSimpleLoginApiKey, value);
}
public string DuckDuckGoApiKey
{
get => _usernameOptions.DuckDuckGoApiKey;
set
{
if (_usernameOptions.DuckDuckGoApiKey != value)
{
_usernameOptions.DuckDuckGoApiKey = value;
TriggerPropertyChanged(nameof(DuckDuckGoApiKey));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool ShowDuckDuckGoApiKey
{
get
{
return _showDuckDuckGoApiKey;
}
set => SetProperty(ref _showDuckDuckGoApiKey, value);
}
public string FastmailApiKey
{
get => _usernameOptions.FastMailApiKey;
set
{
if (_usernameOptions.FastMailApiKey != value)
{
_usernameOptions.FastMailApiKey = value;
TriggerPropertyChanged(nameof(FastmailApiKey));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool ShowFastmailApiKey
{
get
{
return _showFastmailApiKey;
}
set => SetProperty(ref _showFastmailApiKey, value);
}
public bool CapitalizeRandomWordUsername
{
get => _usernameOptions.CapitalizeRandomWordUsername;
@@ -807,12 +791,9 @@ namespace Bit.App.Pages
TriggerPropertyChanged(nameof(PlusAddressedEmailTypeSelected));
TriggerPropertyChanged(nameof(IncludeNumberRandomWordUsername));
TriggerPropertyChanged(nameof(CapitalizeRandomWordUsername));
TriggerPropertyChanged(nameof(SimpleLoginApiKey));
TriggerPropertyChanged(nameof(FirefoxRelayApiAccessToken));
TriggerPropertyChanged(nameof(ForwardedEmailApiSecret));
TriggerPropertyChanged(nameof(ForwardedEmailApiSecretLabel));
TriggerPropertyChanged(nameof(AnonAddyDomainName));
TriggerPropertyChanged(nameof(AnonAddyApiAccessToken));
TriggerPropertyChanged(nameof(DuckDuckGoApiKey));
TriggerPropertyChanged(nameof(FastmailApiKey));
TriggerPropertyChanged(nameof(CatchAllEmailDomain));
TriggerPropertyChanged(nameof(ForwardedEmailServiceSelected));
TriggerPropertyChanged(nameof(UsernameTypeSelected));
@@ -845,15 +826,23 @@ namespace Bit.App.Pages
{
_logger.Value.Exception(ex);
string message = AppResources.GenericErrorMessage;
if (IsUsername && UsernameTypeSelected == UsernameType.ForwardedEmailAlias)
{
await Device.InvokeOnMainThreadAsync(() => Page.DisplayAlert(
AppResources.AnErrorHasOccurred, string.Format(AppResources.UnknownXErrorMessage, ForwardedEmailServiceSelected), AppResources.Ok));
}
else
{
await Device.InvokeOnMainThreadAsync(() => Page.DisplayAlert(AppResources.AnErrorHasOccurred, AppResources.GenericErrorMessage, AppResources.Ok));
if (ex is ForwardedEmailInvalidSecretException)
{
message = ForwardedEmailServiceSelected == ForwardedEmailServiceType.AnonAddy || ForwardedEmailServiceSelected == ForwardedEmailServiceType.FirefoxRelay
? AppResources.InvalidAPIToken
: AppResources.InvalidAPIKey;
}
else
{
message = string.Format(AppResources.UnknownXErrorMessage, ForwardedEmailServiceSelected);
}
}
await Device.InvokeOnMainThreadAsync(() => Page.DisplayAlert(AppResources.AnErrorHasOccurred, message, AppResources.Ok));
}
private string GetUsernameTypeLabelDescription(UsernameType value)
@@ -870,27 +859,5 @@ namespace Bit.App.Pages
return string.Empty;
}
}
private async Task ToggleForwardedEmailHiddenValueAsync()
{
switch (ForwardedEmailServiceSelected)
{
case ForwardedEmailServiceType.AnonAddy:
ShowAnonAddyApiAccessToken = !ShowAnonAddyApiAccessToken;
break;
case ForwardedEmailServiceType.FirefoxRelay:
ShowFirefoxRelayApiAccessToken = !ShowFirefoxRelayApiAccessToken;
break;
case ForwardedEmailServiceType.SimpleLogin:
ShowSimpleLoginApiKey = !ShowSimpleLoginApiKey;
break;
case ForwardedEmailServiceType.DuckDuckGo:
ShowDuckDuckGoApiKey = !ShowDuckDuckGoApiKey;
break;
case ForwardedEmailServiceType.Fastmail:
ShowFastmailApiKey = !ShowFastmailApiKey;
break;
}
}
}
}

View File

@@ -71,7 +71,8 @@
<Label
Text="{u:I18n SendDisabledWarning}"
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="SendDisabledWarningMessageLabel" />
</Frame>
<Frame
IsVisible="{Binding SendOptionsPolicyInEffect}"
@@ -83,7 +84,8 @@
<Label
Text="{u:I18n SendOptionsPolicyInEffect}"
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="SendOptionsPolicyInEffectLabel" />
</Frame>
<StackLayout StyleClass="box-row">
<Label
@@ -93,7 +95,8 @@
x:Name="_nameEntry"
Text="{Binding Send.Name}"
IsEnabled="{Binding SendEnabled}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="SendNameEntry" />
<Label
Text="{u:I18n NameInfo}"
StyleClass="box-footer-label"
@@ -123,6 +126,7 @@
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n File}"
AutomationProperties.HelpText="{Binding FileTypeAccessibilityLabel}"
AutomationId="SendFileButton"
Grid.Column="0">
</Button>
<Button
@@ -135,6 +139,7 @@
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Text}"
AutomationProperties.HelpText="{Binding TextTypeAccessibilityLabel}"
AutomationId="SendTextButton"
Grid.Column="1">
</Button>
</Grid>
@@ -152,12 +157,14 @@
Text="{Binding Send.File.FileName, Mode=OneWay}"
StyleClass="box-value"
VerticalTextAlignment="Center"
HorizontalOptions="StartAndExpand" />
HorizontalOptions="StartAndExpand"
AutomationId="SendFileNameLabel" />
<Label
Text="{Binding Send.File.SizeName, Mode=OneWay}"
StyleClass="box-sub-label"
HorizontalTextAlignment="End"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="SendFileSizeLabel" />
</StackLayout>
<StackLayout
IsVisible="{Binding EditMode, Converter={StaticResource inverseBool}}"
@@ -168,20 +175,23 @@
LineBreakMode="CharacterWrap"
StyleClass="text-sm, text-muted"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="SendNoFileChosenLabel" />
<Label
IsVisible="{Binding FileName, Converter={StaticResource notNull}}"
Text="{Binding FileName}"
LineBreakMode="CharacterWrap"
StyleClass="text-sm, text-muted"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="SendCurrentFileNameLabel" />
<Button
Text="{u:I18n ChooseFile}"
IsVisible="{Binding IsAddFromShare, Converter={StaticResource inverseBool}}"
IsEnabled="{Binding SendEnabled}"
StyleClass="box-button-row"
Clicked="ChooseFile_Clicked" />
Clicked="ChooseFile_Clicked"
AutomationId="SendChooseFileButton" />
<Label
Margin="0, 5, 0, 0"
Text="{u:I18n MaxFileSize}"
@@ -207,7 +217,8 @@
Text="{Binding Send.Text.Text}"
IsEnabled="{Binding SendEnabled}"
StyleClass="box-value"
Margin="{Binding EditorMargins}"
Margin="{Binding EditorMargins}"
AutomationId="SendTextContentEntry"
effects:ScrollEnabledEffect.IsScrollEnabled="false" >
<Editor.Behaviors>
<behaviors:EditorPreventAutoBottomScrollingOnFocusedBehavior ParentScrollView="{x:Reference _scrollView}" />
@@ -235,7 +246,8 @@
IsToggled="{Binding Send.Text.Hidden}"
IsEnabled="{Binding SendEnabled}"
HorizontalOptions="End"
Margin="10,0,0,0" />
Margin="10,0,0,0"
AutomationId="SendHideTextByDefaultToggle" />
</StackLayout>
</StackLayout>
<StackLayout
@@ -249,7 +261,8 @@
IsToggled="{Binding ShareOnSave}"
IsEnabled="{Binding SendEnabled}"
HorizontalOptions="End"
Margin="10,0,0,0" />
Margin="10,0,0,0"
AutomationId="SendShareSendAfterSaveToggle" />
</StackLayout>
<StackLayout
Orientation="Horizontal"
@@ -263,21 +276,24 @@
StyleClass="box-row-button"
TextColor="{DynamicResource PrimaryColor}"
Margin="0"
AutomationProperties.IsInAccessibleTree="False"/>
AutomationProperties.IsInAccessibleTree="False"
AutomationId="SendShowHideOptionsButton" />
<controls:IconButton
x:Name="_btnOptionsUp"
Text="{Binding Source={x:Static core:BitwardenIcons.ChevronUp}}"
StyleClass="box-row-button"
TextColor="{DynamicResource PrimaryColor}"
IsVisible="{Binding ShowOptions}"
AutomationProperties.IsInAccessibleTree="False"/>
AutomationProperties.IsInAccessibleTree="False"
AutomationId="SendOptionsDisplayed" />
<controls:IconButton
x:Name="_btnOptionsDown"
Text="{Binding Source={x:Static core:BitwardenIcons.AngleDown}}"
StyleClass="box-row-button"
TextColor="{DynamicResource PrimaryColor}"
IsVisible="{Binding ShowOptions, Converter={StaticResource inverseBool}}"
AutomationProperties.IsInAccessibleTree="False"/>
AutomationProperties.IsInAccessibleTree="False"
AutomationId="SendOptionsHidden" />
</StackLayout>
<StackLayout IsVisible="{Binding ShowOptions}">
<StackLayout
@@ -294,7 +310,8 @@
IsEnabled="{Binding SendEnabled}"
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n DeletionTime}" />
AutomationProperties.Name="{u:I18n DeletionTime}"
AutomationId="SendDeletionOptionsPicker" />
<Grid
IsVisible="{Binding ShowDeletionCustomPickers}"
Margin="0,5,0,0">
@@ -308,14 +325,16 @@
IsEnabled="{Binding SendEnabled}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n DeletionDate}"
Grid.Column="0" />
Grid.Column="0"
AutomationId="SendCustomDeletionDatePicker" />
<controls:ExtendedTimePicker
NullableTime="{Binding DeletionDateTimeViewModel.Time, Mode=TwoWay}"
Format="t"
IsEnabled="{Binding SendEnabled}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n DeletionTime}"
Grid.Column="1" />
Grid.Column="1"
AutomationId="SendCustomDeletionTimePicker" />
</Grid>
<Label
Text="{u:I18n DeletionDateInfo}"
@@ -334,7 +353,8 @@
IsEnabled="{Binding SendEnabled}"
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ExpirationTime}" />
AutomationProperties.Name="{u:I18n ExpirationTime}"
AutomationId="SendExpirationOptionsPicker" />
<Grid
IsVisible="{Binding ShowExpirationCustomPickers}"
Margin="0,5,0,0">
@@ -349,7 +369,8 @@
IsEnabled="{Binding SendEnabled}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ExpirationDate}"
Grid.Column="0" />
Grid.Column="0"
AutomationId="SendCustomExpirationDatePicker" />
<controls:ExtendedTimePicker
NullableTime="{Binding ExpirationDateTimeViewModel.Time, Mode=TwoWay}"
PlaceHolder="--:-- --"
@@ -357,7 +378,8 @@
IsEnabled="{Binding SendEnabled}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ExpirationTime}"
Grid.Column="1" />
Grid.Column="1"
AutomationId="SendCustomExpirationTimePicker" />
</Grid>
<StackLayout
Orientation="Horizontal"
@@ -374,7 +396,8 @@
FontSize="{Binding SegmentedButtonFontSize}"
IsEnabled="{Binding SendEnabled}"
StyleClass="box-row-button"
Clicked="ClearExpirationDate_Clicked" />
Clicked="ClearExpirationDate_Clicked"
AutomationId="SendClearExpirationDateButton" />
</StackLayout>
</StackLayout>
<StackLayout
@@ -393,13 +416,15 @@
Keyboard="Numeric"
MaxLength="9"
TextChanged="OnMaxAccessCountTextChanged"
HorizontalOptions="FillAndExpand" />
HorizontalOptions="FillAndExpand"
AutomationId="SendMaxAccessCountEntry" />
<controls:ExtendedStepper
x:Name="_maxAccessCountStepper"
Value="{Binding MaxAccessCount}"
Maximum="999999999"
IsEnabled="{Binding SendEnabled}"
Margin="10,0,0,0" />
Margin="10,0,0,0"
AutomationId="SendMaxAccessCountStepper" />
</StackLayout>
<Label
Text="{u:I18n MaximumAccessCountInfo}"
@@ -419,7 +444,8 @@
<Label
Text="{Binding Send.AccessCount, Mode=OneWay}"
StyleClass="box-label"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="SendCurrentAccessCountLabel" />
</StackLayout>
</StackLayout>
<StackLayout
@@ -436,7 +462,8 @@
StyleClass="box-value"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False"
HorizontalOptions="FillAndExpand" />
HorizontalOptions="FillAndExpand"
AutomationId="SendNewPasswordEntry" />
<controls:IconButton
IsEnabled="{Binding SendEnabled}"
StyleClass="box-row-button, box-row-button-platform"
@@ -445,7 +472,8 @@
Margin="10,0,0,0"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}" />
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
AutomationId="SendShowHidePasswordButton" />
</StackLayout>
<Label
Text="{u:I18n PasswordInfo}"
@@ -464,7 +492,8 @@
IsEnabled="{Binding SendEnabled}"
StyleClass="box-value"
Margin="{Binding EditorMargins}"
effects:ScrollEnabledEffect.IsScrollEnabled="false" >
effects:ScrollEnabledEffect.IsScrollEnabled="false"
AutomationId="SendNotesEntry">
<Editor.Behaviors>
<behaviors:EditorPreventAutoBottomScrollingOnFocusedBehavior ParentScrollView="{x:Reference _scrollView}" />
</Editor.Behaviors>
@@ -492,7 +521,8 @@
IsToggled="{Binding Send.HideEmail}"
IsEnabled="{Binding DisableHideEmailControl, Converter={StaticResource inverseBool}}"
HorizontalOptions="End"
Margin="10,0,0,0" />
Margin="10,0,0,0"
AutomationId="SendHideEmailSwitch" />
</StackLayout>
<StackLayout
StyleClass="box-row, box-row-switch"
@@ -506,7 +536,8 @@
IsToggled="{Binding Send.Disabled}"
IsEnabled="{Binding SendEnabled}"
HorizontalOptions="End"
Margin="10,0,0,0" />
Margin="10,0,0,0"
AutomationId="SendDeactivateSwitch" />
</StackLayout>
</StackLayout>

View File

@@ -25,7 +25,8 @@
Priority="-2"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" x:Name="_closeItem" />
<ToolbarItem Text="{u:I18n Save}" Clicked="Save_Clicked" Order="Primary" x:Name="_saveItem"/>
</ContentPage.ToolbarItems>

View File

@@ -44,13 +44,15 @@
<controls:SendViewCell
Send="{Binding Send}"
ButtonCommand="{Binding BindingContext.SendOptionsCommand, Source={x:Reference _page}}"
ShowOptions="{Binding BindingContext.SendEnabled, Source={x:Reference _page}}" />
ShowOptions="{Binding BindingContext.SendEnabled, Source={x:Reference _page}}"
AutomationId="SendCell" />
</DataTemplate>
<DataTemplate x:Key="sendGroupTemplate"
x:DataType="pages:SendGroupingsPageListItem">
<controls:ExtendedStackLayout Orientation="Horizontal"
StyleClass="list-row, list-row-platform">
StyleClass="list-row, list-row-platform"
AutomationId="{Binding AutomationId}">
<controls:IconLabel Text="{Binding Icon, Mode=OneWay}"
HorizontalOptions="Start"
VerticalOptions="Center"
@@ -64,12 +66,14 @@
LineBreakMode="TailTruncation"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
StyleClass="list-title" />
StyleClass="list-title"
AutomationId="SendFilterNameLabel" />
<Label Text="{Binding ItemCount, Mode=OneWay}"
HorizontalOptions="End"
VerticalOptions="CenterAndExpand"
HorizontalTextAlignment="End"
StyleClass="list-sub" />
StyleClass="list-sub"
AutomationId="SendFilterCountLabel" />
</controls:ExtendedStackLayout>
</DataTemplate>

View File

@@ -66,5 +66,27 @@ namespace Bit.App.Pages
return _icon;
}
}
public string AutomationId
{
get
{
if (_name != null)
{
return "SendItem";
}
if (Type != null)
{
switch (Type.Value)
{
case SendType.Text:
return "SendTextFilter";
case SendType.File:
return "SendFileFilter";
}
}
return null;
}
}
}
}

View File

@@ -59,7 +59,8 @@
Margin="20, 0"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="NoSendDisplayedLabel" />
<controls:ExtendedCollectionView
IsVisible="{Binding ShowList}"
ItemsSource="{Binding Sends}"
@@ -67,13 +68,15 @@
SelectionMode="Single"
SelectionChanged="RowSelected"
StyleClass="list, list-platform"
ExtraDataForLogging="Sends Page">
ExtraDataForLogging="Sends Page"
AutomationId="SendCellList">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="views:SendView">
<controls:SendViewCell
Send="{Binding .}"
ButtonCommand="{Binding BindingContext.SendOptionsCommand, Source={x:Reference _page}}"
ShowOptions="{Binding BindingContext.SendEnabled, Source={x:Reference _page}}" />
ShowOptions="{Binding BindingContext.SendEnabled, Source={x:Reference _page}}"
AutomationId="SendCell" />
</DataTemplate>
</CollectionView.ItemTemplate>
</controls:ExtendedCollectionView>

View File

@@ -13,8 +13,13 @@
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
<ToolbarItem Text="{u:I18n Save}" Clicked="Save_Clicked" Order="Primary" />
<ToolbarItem Text="{u:I18n Cancel}"
Clicked="Close_Clicked"
Order="Primary"
Priority="-1" />
<ToolbarItem Text="{u:I18n Save}"
Clicked="Save_Clicked"
Order="Primary" />
<ToolbarItem Text="{u:I18n Delete}"
Clicked="Delete_Clicked"
Order="Secondary"
@@ -43,7 +48,8 @@
StyleClass="box-value"
x:Name="_nameEntry"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
ReturnCommand="{Binding SubmitCommand}"
AutomationId="FolderNameEntry" />
</StackLayout>
</StackLayout>
</StackLayout>

View File

@@ -31,7 +31,8 @@
Margin="20, 0"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center"></Label>
HorizontalTextAlignment="Center"
AutomationId="NoFoldersLabel"></Label>
<controls:ExtendedCollectionView
IsVisible="{Binding ShowNoData, Converter={StaticResource inverseBool}}"
ItemsSource="{Binding Folders}"
@@ -44,10 +45,12 @@
<DataTemplate x:DataType="views:FolderView">
<controls:ExtendedStackLayout
StyleClass="list-row, list-row-platform"
Padding="10">
Padding="10"
AutomationId="FolderCell">
<Label LineBreakMode="TailTruncation"
StyleClass="list-title, list-title-platform"
Text="{Binding Name, Mode=OneWay}" />
Text="{Binding Name, Mode=OneWay}"
AutomationId="FolderName" />
</controls:ExtendedStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>

View File

@@ -27,7 +27,8 @@
x:Name="_themePicker"
ItemsSource="{Binding ThemeOptions, Mode=OneTime}"
SelectedIndex="{Binding ThemeSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ThemeSelectorPicker" />
</StackLayout>
<Label
StyleClass="box-footer-label"
@@ -44,7 +45,8 @@
x:Name="_autoDarkThemePicker"
ItemsSource="{Binding AutoDarkThemeOptions, Mode=OneTime}"
SelectedIndex="{Binding AutoDarkThemeSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="DefaultDarkThemePicker" />
</StackLayout>
<Label
StyleClass="box-footer-label"
@@ -59,7 +61,8 @@
x:Name="_uriMatchPicker"
ItemsSource="{Binding UriMatchOptions, Mode=OneTime}"
SelectedIndex="{Binding UriMatchSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="DefaultUriMatchDetectionPicker" />
</StackLayout>
<Label
Text="{u:I18n DefaultUriMatchDetectionDescription}"
@@ -74,7 +77,8 @@
x:Name="_clearClipboardPicker"
ItemsSource="{Binding ClearClipboardOptions, Mode=OneTime}"
SelectedIndex="{Binding ClearClipboardSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ClearClipboardPicker" />
</StackLayout>
<Label
Text="{u:I18n ClearClipboardDescription}"
@@ -90,7 +94,8 @@
ItemsSource="{Binding LocalesOptions, Mode=OneTime}"
SelectedItem="{Binding SelectedLocale}"
ItemDisplayBinding="{Binding Value}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="LanguagePicker" />
</StackLayout>
<Label
Text="{u:I18n LanguageChangeRequiresAppRestart}"
@@ -105,7 +110,8 @@
<Switch
IsToggled="{Binding AutoTotpCopy}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="CopyTotpAutomaticallyToggle" />
</StackLayout>
<Label
Text="{u:I18n CopyTotpAutomaticallyDescription}"
@@ -120,7 +126,8 @@
<Switch
IsToggled="{Binding Favicon}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="ShowWebsiteIconsToggle" />
</StackLayout>
<Label
Text="{u:I18n ShowWebsiteIconsDescription}"

View File

@@ -32,19 +32,21 @@
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Center" />
</Frame>
<Label IsVisible="{Binding UseFrame, Converter={StaticResource inverseBool}}"
<controls:CustomLabel IsVisible="{Binding UseFrame, Converter={StaticResource inverseBool}}"
Text="{Binding Name, Mode=OneWay}"
LineBreakMode="{Binding LineBreakMode}"
HorizontalOptions="StartAndExpand"
VerticalOptions="CenterAndExpand"
StyleClass="list-title"/>
<Label Text="{Binding SubLabel, Mode=OneWay}"
StyleClass="list-title"
AutomationId="{Binding AutomationIdSettingName}" />
<controls:CustomLabel Text="{Binding SubLabel, Mode=OneWay}"
IsVisible="{Binding ShowSubLabel}"
HorizontalOptions="End"
HorizontalTextAlignment="End"
VerticalOptions="CenterAndExpand"
TextColor="{Binding SubLabelColor}"
StyleClass="list-sub" />
StyleClass="list-sub"
AutomationId="{Binding AutomationIdSettingStatus}" />
</controls:ExtendedStackLayout>
</DataTemplate>
<DataTemplate
@@ -57,7 +59,8 @@
Padding="10"
HasShadow="False"
BackgroundColor="Transparent"
BorderColor="{DynamicResource PrimaryColor}">
BorderColor="{DynamicResource PrimaryColor}"
AutomationId="SettingActivePolicyTextLabel">
<Label
Text="{Binding Name, Mode=OneWay}"
StyleClass="text-muted, text-sm, text-bold"
@@ -75,7 +78,8 @@
VerticalOptions="Center"
FontSize="Small"
TextColor="{Binding SubLabelColor}"
StyleClass="list-sub" Margin="-5"/>
StyleClass="list-sub" Margin="-5"
AutomationId="SettingCustomVaultTimeoutPicker" />
<controls:ExtendedStackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="ActivateTimePicker"/>
</controls:ExtendedStackLayout.GestureRecognizers>

View File

@@ -1,7 +1,9 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.App.Utilities.Automation;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -22,5 +24,29 @@ namespace Bit.App.Pages
public Color SubLabelColor => SubLabelTextEnabled ?
ThemeManager.GetResourceColor("SuccessColor") :
ThemeManager.GetResourceColor("MutedColor");
public string AutomationIdSettingName
{
get
{
return AutomationIdsHelper.AddSuffixFor(
UseFrame ? "EnabledPolicy"
: AutomationIdsHelper.ToEnglishTitleCase(Name)
, SuffixType.Cell);
}
}
public string AutomationIdSettingStatus
{
get
{
if (UseFrame)
{
return null;
}
return AutomationIdsHelper.AddSuffixFor(AutomationIdsHelper.ToEnglishTitleCase(Name), SuffixType.SettingValue);
}
}
}
}

View File

@@ -382,7 +382,7 @@ namespace Bit.App.Pages
public async Task VaultTimeoutActionAsync()
{
if (_vaultTimeoutPolicy != null &&
!string.IsNullOrEmpty(_vaultTimeoutPolicy.GetString(Policy.MINUTES_KEY)))
!string.IsNullOrEmpty(_vaultTimeoutPolicy.GetString(Policy.ACTION_KEY)))
{
// do nothing if we have a policy set
return;

View File

@@ -33,23 +33,25 @@
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row" Padding="10, 20"
IsVisible="{Binding HasAttachments, Converter={StaticResource inverseBool}}">
<Label Text="{u:I18n NoAttachments}" HorizontalTextAlignment="Center" />
<Label Text="{u:I18n NoAttachments}" HorizontalTextAlignment="Center" AutomationId="NoAttachmentsLabel" />
</StackLayout>
<controls:RepeaterView ItemsSource="{Binding Attachments}" IsVisible="{Binding HasAttachments}">
<controls:RepeaterView ItemsSource="{Binding Attachments}" IsVisible="{Binding HasAttachments}" AutomationId="AttachmentsList">
<controls:RepeaterView.ItemTemplate>
<DataTemplate x:DataType="views:AttachmentView">
<StackLayout Spacing="0" Padding="0">
<StackLayout Orientation="Horizontal" StyleClass="box-row" Spacing="10">
<StackLayout Orientation="Horizontal" StyleClass="box-row" Spacing="10" AutomationId="AttachmentRow">
<Label
Text="{Binding FileName, Mode=OneWay}"
StyleClass="box-value"
VerticalTextAlignment="Center"
HorizontalOptions="StartAndExpand" />
HorizontalOptions="StartAndExpand"
AutomationId="AttachmentFileNameLabel" />
<Label
Text="{Binding SizeName, Mode=OneWay}"
StyleClass="box-sub-label"
HorizontalTextAlignment="End"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="AttachmentFileSizeLabel" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Trash}}"
@@ -57,7 +59,8 @@
CommandParameter="{Binding .}"
VerticalOptions="Center"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Delete}" />
AutomationProperties.Name="{u:I18n Delete}"
AutomationId="AttachmentDeleteButton" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
@@ -77,17 +80,20 @@
LineBreakMode="CharacterWrap"
StyleClass="text-sm, text-muted"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="NoFileChosenLabel" />
<Label
IsVisible="{Binding FileName, Converter={StaticResource notNull}}"
Text="{Binding FileName}"
LineBreakMode="CharacterWrap"
StyleClass="text-sm, text-muted"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="NewAttachmentNameLabel" />
</StackLayout>
<Button Text="{u:I18n ChooseFile}" StyleClass="box-button-row"
Clicked="ChooseFile_Clicked"></Button>
Clicked="ChooseFile_Clicked"
AutomationId="ChooseFileButton"></Button>
<Label
Margin="0, 10, 0, 0"
Text="{u:I18n MaxFileSize}"

View File

@@ -57,16 +57,16 @@
x:Key="deleteItem" />
<DataTemplate x:Key="TextCustomFieldDataTemplate">
<il:TextCustomFieldItemLayout />
<il:TextCustomFieldItemLayout AutomationId="TextCustomFieldItem" />
</DataTemplate>
<DataTemplate x:Key="BooleanCustomFieldDataTemplate">
<il:BooleanCustomFieldItemLayout />
<il:BooleanCustomFieldItemLayout AutomationId="BooleanCustomFieldItem" />
</DataTemplate>
<DataTemplate x:Key="HiddenCustomFieldDataTemplate">
<il:HiddenCustomFieldItemLayout />
<il:HiddenCustomFieldItemLayout AutomationId="HiddenCustomFieldItem" />
</DataTemplate>
<DataTemplate x:Key="LinkedCustomFieldDataTemplate">
<il:LinkedCustomFieldItemLayout />
<il:LinkedCustomFieldItemLayout AutomationId="LinkedCustomFieldItem" />
</DataTemplate>
<dts:CustomFieldItemTemplateSelector x:Key="CustomFieldItemTemplateSelector"
@@ -100,7 +100,8 @@
<Label
Text="{u:I18n PersonalOwnershipPolicyInEffect}"
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="PersonalOwnershipPolicyLabel"/>
</Frame>
</Grid>
<StackLayout StyleClass="box-row-header">
@@ -116,7 +117,8 @@
x:Name="_typePicker"
ItemsSource="{Binding TypeOptions, Mode=OneTime}"
SelectedIndex="{Binding TypeSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemTypePicker" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -125,7 +127,10 @@
<Entry
x:Name="_nameEntry"
Text="{Binding Cipher.Name}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Name}"
AutomationId="ItemNameEntry" />
</StackLayout>
<StackLayout IsVisible="{Binding IsLogin}" Spacing="0" Padding="0">
<Grid StyleClass="box-row, box-row-input"
@@ -138,7 +143,10 @@
x:Name="_loginUsernameEntry"
Text="{Binding Cipher.Login.Username}"
StyleClass="box-value"
Grid.Row="1"/>
Grid.Row="1"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Username}"
AutomationId="LoginUsernameEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Generate}}"
@@ -146,7 +154,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n GenerateUsername}" />
AutomationProperties.Name="{u:I18n GenerateUsername}"
AutomationId="GenerateUsernameButton" />
</Grid>
<Grid StyleClass="box-row, box-row-input">
<Grid.RowDefinitions>
@@ -174,7 +183,10 @@
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False"
IsEnabled="{Binding Cipher.ViewPassword}"/>
IsEnabled="{Binding Cipher.ViewPassword}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Password}"
AutomationId="LoginPasswordEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.CheckCircle}}"
@@ -184,7 +196,8 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CheckPassword}"
IsVisible="{Binding Cipher.ViewPassword}" />
IsVisible="{Binding Cipher.ViewPassword}"
AutomationId="CheckPasswordButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -195,7 +208,8 @@
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
IsVisible="{Binding Cipher.ViewPassword}" />
IsVisible="{Binding Cipher.ViewPassword}"
AutomationId="ViewPasswordButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Generate}}"
@@ -205,7 +219,8 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n GeneratePassword}"
IsVisible="{Binding Cipher.ViewPassword}" />
IsVisible="{Binding Cipher.ViewPassword}"
AutomationId="RegeneratePasswordButton" />
</Grid>
<Grid StyleClass="box-row, box-row-input">
@@ -241,7 +256,8 @@
Padding="0,15"
HorizontalOptions="Center"
VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="SetupTotpButton" />
</Frame>
<controls:MonoEntry
x:Name="_loginTotpEntry"
@@ -254,7 +270,10 @@
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="{Binding TotpColumnSpan}" />
Grid.ColumnSpan="{Binding TotpColumnSpan}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n AuthenticatorKey}"
AutomationId="LoginTotpEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -262,7 +281,10 @@
IsVisible="{Binding HasTotpValue}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2" />
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyTotp}"
AutomationId="CopyTotpValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Camera}}"
@@ -272,7 +294,8 @@
Grid.RowSpan="2"
IsVisible="{Binding HasTotpValue}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ScanQrTitle}" />
AutomationProperties.Name="{u:I18n ScanQrTitle}"
/>
</Grid>
</StackLayout>
<StackLayout IsVisible="{Binding IsCard}" Spacing="0" Padding="0">
@@ -283,7 +306,8 @@
<Entry
x:Name="_cardholderNameEntry"
Text="{Binding Cipher.Card.CardholderName}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="CardholderNameEntry" />
</StackLayout>
<Grid StyleClass="box-row, box-row-input">
<Grid.RowDefinitions>
@@ -307,7 +331,10 @@
Grid.Column="0"
IsPassword="{Binding ShowCardNumber, Converter={StaticResource inverseBool}}"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False" />
IsTextPredictionEnabled="False"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Number}"
AutomationId="CardNumberEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowCardNumberIcon}"
@@ -316,7 +343,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationId="ShowCardNumberButton" />
</Grid>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -326,7 +354,8 @@
x:Name="_cardBrandPicker"
ItemsSource="{Binding CardBrandOptions, Mode=OneTime}"
SelectedIndex="{Binding CardBrandSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="CardBrandPicker" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -336,7 +365,8 @@
x:Name="_cardExpMonthPicker"
ItemsSource="{Binding CardExpMonthOptions, Mode=OneTime}"
SelectedIndex="{Binding CardExpMonthSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="CardExpirationMonthPicker" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -346,7 +376,10 @@
x:Name="_cardExpYearEntry"
Text="{Binding Cipher.Card.ExpYear}"
StyleClass="box-value"
Keyboard="Numeric" />
Keyboard="Numeric"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ExpirationYear}"
AutomationId="CardExpirationYearEntry" />
</StackLayout>
<Grid StyleClass="box-row, box-row-input">
<Grid.RowDefinitions>
@@ -371,7 +404,10 @@
Keyboard="Numeric"
IsPassword="{Binding ShowCardCode, Converter={StaticResource inverseBool}}"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False" />
IsTextPredictionEnabled="False"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n SecurityCode}"
AutomationId="CardSecurityCodeEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowCardCodeIcon}"
@@ -380,7 +416,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationId="CardShowSecurityCodeButton" />
</Grid>
</StackLayout>
<StackLayout IsVisible="{Binding IsIdentity}" Spacing="0" Padding="0">
@@ -392,7 +429,8 @@
x:Name="_identityTitlePicker"
ItemsSource="{Binding IdentityTitleOptions, Mode=OneTime}"
SelectedIndex="{Binding IdentityTitleSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityTitlePicker" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -401,7 +439,10 @@
<Entry
x:Name="_identityFirstNameEntry"
Text="{Binding Cipher.Identity.FirstName}"
StyleClass="box-value,capitalize-word-input"/>
StyleClass="box-value,capitalize-word-input"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n FirstName}"
AutomationId="IdentityFirstNameEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -410,7 +451,10 @@
<Entry
x:Name="_identityMiddleNameEntry"
Text="{Binding Cipher.Identity.MiddleName}"
StyleClass="box-value,capitalize-word-input" />
StyleClass="box-value,capitalize-word-input"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n MiddleName}"
AutomationId="IdentityMiddleNameEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -419,7 +463,10 @@
<Entry
x:Name="_identityLastNameEntry"
Text="{Binding Cipher.Identity.LastName}"
StyleClass="box-value,capitalize-word-input" />
StyleClass="box-value,capitalize-word-input"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n LastName}"
AutomationId="IdentityLastNameEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -428,7 +475,10 @@
<Entry
x:Name="_identityUsernameEntry"
Text="{Binding Cipher.Identity.Username}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Username}"
AutomationId="IdentityUsernameEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -437,7 +487,10 @@
<Entry
x:Name="_identityCompanyEntry"
Text="{Binding Cipher.Identity.Company}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Company}"
AutomationId="IdentityCompanyEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -446,7 +499,10 @@
<Entry
x:Name="_identitySsnEntry"
Text="{Binding Cipher.Identity.SSN}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n SSN}"
AutomationId="IdentitySsnEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -455,7 +511,10 @@
<Entry
x:Name="_identityPassportNumberEntry"
Text="{Binding Cipher.Identity.PassportNumber}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n PassportNumber}"
AutomationId="IdentityPassportNumberEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -464,7 +523,10 @@
<Entry
x:Name="_identityLicenseNumberEntry"
Text="{Binding Cipher.Identity.LicenseNumber}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n LicenseNumber}"
AutomationId="IdentityLicenseNumberEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -474,7 +536,10 @@
x:Name="_identityEmailEntry"
Keyboard="Email"
Text="{Binding Cipher.Identity.Email}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Email}"
AutomationId="IdentityEmailEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -484,7 +549,10 @@
x:Name="_identityPhoneEntry"
Text="{Binding Cipher.Identity.Phone}"
Keyboard="Telephone"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Phone}"
AutomationId="IdentityPhoneEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -493,7 +561,10 @@
<Entry
x:Name="_identityAddress1Entry"
Text="{Binding Cipher.Identity.Address1}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Address1}"
AutomationId="IdentityAddressOneEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -502,7 +573,10 @@
<Entry
x:Name="_identityAddress2Entry"
Text="{Binding Cipher.Identity.Address2}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Address2}"
AutomationId="IdentityAddressTwoEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -511,7 +585,10 @@
<Entry
x:Name="_identityAddress3Entry"
Text="{Binding Cipher.Identity.Address3}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Address3}"
AutomationId="IdentityAddressThreeEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -520,7 +597,10 @@
<Entry
x:Name="_identityCityEntry"
Text="{Binding Cipher.Identity.City}"
StyleClass="box-value,capitalize-sentence-input" />
StyleClass="box-value,capitalize-sentence-input"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CityTown}"
AutomationId="IdentityCityEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -529,7 +609,10 @@
<Entry
x:Name="_identityStateEntry"
Text="{Binding Cipher.Identity.State}"
StyleClass="box-value,capitalize-sentence-input" />
StyleClass="box-value,capitalize-sentence-input"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n StateProvince}"
AutomationId="IdentityStateEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -538,7 +621,10 @@
<Entry
x:Name="_identityPostalCodeEntry"
Text="{Binding Cipher.Identity.PostalCode}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ZipPostalCode}"
AutomationId="IdentityPostalCodeEntry" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-input">
<Label
@@ -547,7 +633,10 @@
<Entry
x:Name="_identityCountryEntry"
Text="{Binding Cipher.Identity.Country}"
StyleClass="box-value,capitalize-sentence-input" />
StyleClass="box-value,capitalize-sentence-input"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Country}"
AutomationId="IdentityCountryEntry" />
</StackLayout>
</StackLayout>
</StackLayout>
@@ -559,7 +648,7 @@
<controls:RepeaterView ItemsSource="{Binding Uris}">
<controls:RepeaterView.ItemTemplate>
<DataTemplate x:DataType="views:LoginUriView">
<Grid StyleClass="box-row, box-row-input">
<Grid StyleClass="box-row, box-row-input" AutomationId="UriListGrid" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -578,7 +667,10 @@
Keyboard="Url"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0" />
Grid.Column="0"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n URI}"
AutomationId="LoginUriEntry" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Cog}}"
@@ -588,13 +680,15 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
AutomationProperties.Name="{u:I18n Options}"
AutomationId="LoginUriOptionsButton" />
</Grid>
</DataTemplate>
</controls:RepeaterView.ItemTemplate>
</controls:RepeaterView>
<Button Text="{u:I18n NewUri}" StyleClass="box-button-row"
Clicked="NewUri_Clicked"></Button>
Clicked="NewUri_Clicked"
AutomationId="LoginAddNewUriButton"></Button>
</StackLayout>
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row-header">
@@ -609,7 +703,8 @@
x:Name="_folderPicker"
ItemsSource="{Binding FolderOptions, Mode=OneTime}"
SelectedIndex="{Binding FolderSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="FolderPicker" />
</StackLayout>
<StackLayout StyleClass="box-row, box-row-switch">
<Label
@@ -619,7 +714,8 @@
<Switch
IsToggled="{Binding Cipher.Favorite}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="ItemFavoriteToggle" />
</StackLayout>
<StackLayout x:Name="_passwordPrompt" StyleClass="box-row, box-row-switch">
<Label
@@ -631,13 +727,14 @@
Command="{Binding PasswordPromptHelpCommand}"
TextColor="{DynamicResource MutedColor}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.Name="{u:I18n MasterPasswordRePromptHelp}"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding PasswordPrompt}"
Toggled="PasswordPrompt_Toggled"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="MasterPasswordRepromptToggle" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
@@ -652,7 +749,10 @@
AutoSize="TextChanges"
StyleClass="box-value"
effects:ScrollEnabledEffect.IsScrollEnabled="false"
Text="{Binding Cipher.Notes}">
Text="{Binding Cipher.Notes}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Notes}"
AutomationId="ItemNotesEntry">
<Editor.Behaviors>
<behaviors:EditorPreventAutoBottomScrollingOnFocusedBehavior ParentScrollView="{x:Reference _scrollView}" />
</Editor.Behaviors>
@@ -671,9 +771,11 @@
<StackLayout
Spacing="0"
BindableLayout.ItemsSource="{Binding Fields}"
BindableLayout.ItemTemplateSelector="{StaticResource CustomFieldItemTemplateSelector}" />
BindableLayout.ItemTemplateSelector="{StaticResource CustomFieldItemTemplateSelector}"
AutomationId="CustomFieldsList" />
<Button Text="{u:I18n NewCustomField}" StyleClass="box-button-row"
Clicked="NewField_Clicked"></Button>
Clicked="NewField_Clicked"
AutomationId="NewCustomFieldButton"></Button>
</StackLayout>
<StackLayout StyleClass="box" IsVisible="{Binding ShowOwnershipOptions}">
<StackLayout StyleClass="box-row-header">
@@ -688,7 +790,8 @@
x:Name="_ownershipPicker"
ItemsSource="{Binding OwnershipOptions, Mode=OneTime}"
SelectedIndex="{Binding OwnershipSelectedIndex}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemOwnershipPicker" />
</StackLayout>
</StackLayout>
<StackLayout StyleClass="box" IsVisible="{Binding ShowCollections}">
@@ -699,7 +802,8 @@
<StackLayout Spacing="0" Padding="0"
IsVisible="{Binding HasCollections, Converter={StaticResource inverseBool}}">
<StackLayout StyleClass="box-row, box-row-switch">
<Label Text="{u:I18n NoCollectionsToList}" />
<Label Text="{u:I18n NoCollectionsToList}"
AutomationId="NoCollectionsToListLabel" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
@@ -709,15 +813,17 @@
<controls:RepeaterView.ItemTemplate>
<DataTemplate x:DataType="pages:CollectionViewModel">
<StackLayout Spacing="0" Padding="0">
<StackLayout StyleClass="box-row, box-row-switch">
<StackLayout StyleClass="box-row, box-row-switch" AutomationId="CollectionItemCell">
<Label
Text="{Binding Collection.Name}"
StyleClass="box-label-regular"
HorizontalOptions="StartAndExpand" />
HorizontalOptions="StartAndExpand"
AutomationId="CollectionItemNameLabel" />
<Switch
IsToggled="{Binding Checked}"
StyleClass="box-value"
HorizontalOptions="End" />
HorizontalOptions="End"
AutomationId="CollectionItemSwitch" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
@@ -727,5 +833,4 @@
</StackLayout>
</StackLayout>
</ScrollView>
</pages:BaseContentPage>

View File

@@ -49,16 +49,16 @@
x:Name="_cloneItem" x:Key="cloneItem" />
<DataTemplate x:Key="TextCustomFieldDataTemplate">
<il:TextCustomFieldItemLayout />
<il:TextCustomFieldItemLayout AutomationId="TextCustomFieldItem" />
</DataTemplate>
<DataTemplate x:Key="BooleanCustomFieldDataTemplate">
<il:BooleanCustomFieldItemLayout />
<il:BooleanCustomFieldItemLayout AutomationId="BooleanCustomFieldItem" />
</DataTemplate>
<DataTemplate x:Key="HiddenCustomFieldDataTemplate">
<il:HiddenCustomFieldItemLayout />
<il:HiddenCustomFieldItemLayout AutomationId="HiddenCustomFieldItem" />
</DataTemplate>
<DataTemplate x:Key="LinkedCustomFieldDataTemplate">
<il:LinkedCustomFieldItemLayout />
<il:LinkedCustomFieldItemLayout AutomationId="LinkedCustomFieldItem" />
</DataTemplate>
<dts:CustomFieldItemTemplateSelector x:Key="CustomFieldItemTemplateSelector"
@@ -69,23 +69,26 @@
<ScrollView x:Key="scrollView" x:Name="_scrollView">
<StackLayout Spacing="20" x:Name="_mainLayout">
<StackLayout StyleClass="box">
<StackLayout StyleClass="box" AutomationId="ItemInformationSection">
<StackLayout StyleClass="box-row-header">
<Label Text="{u:I18n ItemInformation, Header=True}"
StyleClass="box-header, box-header-platform" />
</StackLayout>
<StackLayout StyleClass="box-row">
<StackLayout StyleClass="box-row" AutomationId="ItemRow">
<Label
Text="{u:I18n Name}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Name, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
<StackLayout IsVisible="{Binding IsLogin}" Spacing="0" Padding="0">
<Grid StyleClass="box-row"
IsVisible="{Binding Cipher.Login.Username, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Login.Username, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -98,12 +101,14 @@
Text="{u:I18n Username}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Login.Username, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ItemValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -113,12 +118,14 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyUsername}" />
AutomationProperties.Name="{u:I18n CopyUsername}"
AutomationId="CopyValueButton" />
</Grid>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Login.Username, Converter={StaticResource stringHasValue}}" />
<Grid StyleClass="box-row"
IsVisible="{Binding Cipher.Login.Password, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Login.Password, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -133,20 +140,23 @@
Text="{u:I18n Password}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ItemName" />
<controls:MonoLabel
Text="{Binding Cipher.Login.MaskedPassword, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding ShowPassword, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
AutomationId="ItemValue" />
<controls:MonoLabel
Text="{Binding ColoredPassword, Mode=OneWay}"
StyleClass="box-value, text-html"
Grid.Row="1"
Grid.Column="0"
LineBreakMode="CharacterWrap"
IsVisible="{Binding ShowPassword}" />
IsVisible="{Binding ShowPassword}"
AutomationId="ItemValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.CheckCircle}}"
@@ -156,7 +166,8 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CheckPassword}"
IsVisible="{Binding Cipher.ViewPassword}" />
IsVisible="{Binding Cipher.ViewPassword}"
AutomationId="CheckPasswordButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
@@ -167,7 +178,8 @@
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"
IsVisible="{Binding Cipher.ViewPassword}" />
IsVisible="{Binding Cipher.ViewPassword}"
AutomationId="ViewValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -178,11 +190,14 @@
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyPassword}"
IsVisible="{Binding Cipher.ViewPassword}" />
IsVisible="{Binding Cipher.ViewPassword}"
AutomationId="CopyValueButton" />
</Grid>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Login.Password, Converter={StaticResource stringHasValue}}" />
<Grid StyleClass="box-row" IsVisible="{Binding ShowTotp}">
<Grid StyleClass="box-row"
IsVisible="{Binding ShowTotp}"
AutomationId="ItemRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -197,7 +212,8 @@
Text="{u:I18n VerificationCodeTotp}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ItemName" />
<controls:MonoLabel
Text="{Binding TotpCodeFormatted, Mode=OneWay}"
IsVisible="{Binding ShowUpgradePremiumTotpText, Converter={StaticResource inverseBool}}"
@@ -205,14 +221,16 @@
Grid.Row="1"
Grid.Column="0"
VerticalTextAlignment="Start"
VerticalOptions="Start" />
VerticalOptions="Start"
AutomationId="ItemValue" />
<controls:CircularProgressbarView
Progress="{Binding TotpProgress}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
VerticalOptions="FillAndExpand"
AutomationId="LoginTotpProgressBar" />
<Label
Text="{Binding TotpSec, Mode=OneWay}"
Style="{DynamicResource textTotp}"
@@ -234,7 +252,8 @@
Grid.Column="2"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyTotp}" />
AutomationProperties.Name="{u:I18n CopyTotp}"
AutomationId="CopyValueButton" />
<Label
Text="{u:I18n PremiumSubscriptionRequired}"
StyleClass="box-footer-label"
@@ -242,24 +261,29 @@
Margin="0,5,0,2"
Grid.Column="0"
Grid.Row="1"
HorizontalOptions="FillAndExpand" />
HorizontalOptions="FillAndExpand"
AutomationId="ShowUpgradePremiumTotpLabel" />
</Grid>
<BoxView StyleClass="box-row-separator" IsVisible="{Binding ShowTotp}" />
</StackLayout>
<StackLayout IsVisible="{Binding IsCard}" Spacing="0" Padding="0">
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Card.CardholderName, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Card.CardholderName, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n CardholderName}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Card.CardholderName, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Card.CardholderName, Converter={StaticResource stringHasValue}}" />
<Grid StyleClass="box-row"
IsVisible="{Binding Cipher.Card.Number, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Card.Number, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -273,19 +297,22 @@
Text="{u:I18n Number}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ItemName" />
<controls:MonoLabel
Text="{Binding Cipher.Card.MaskedNumber, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding ShowCardNumber, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding ShowCardNumber, Converter={StaticResource inverseBool}}"
AutomationId="ItemValue" />
<controls:MonoLabel
Text="{Binding Cipher.Card.Number, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding ShowCardNumber}" />
IsVisible="{Binding ShowCardNumber}"
AutomationId="ItemValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowCardNumberIcon}"
@@ -294,7 +321,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationId="ShowValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -304,34 +332,42 @@
Grid.Column="2"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopyNumber}" />
AutomationProperties.Name="{u:I18n CopyNumber}"
AutomationId="CopyValueButton" />
</Grid>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Card.Number, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Card.Brand, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Card.Brand, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n Brand}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Card.Brand, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Card.Brand, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Card.Expiration, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Card.Expiration, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n Expiration}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Card.Expiration, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Card.Expiration, Converter={StaticResource stringHasValue}}" />
<Grid StyleClass="box-row"
IsVisible="{Binding Cipher.Card.Code, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Card.Code, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -345,19 +381,22 @@
Text="{u:I18n SecurityCode}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
Grid.Column="0"
AutomationId="ItemName" />
<controls:MonoLabel
Text="{Binding Cipher.Card.MaskedCode, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding ShowCardCode, Converter={StaticResource inverseBool}}" />
IsVisible="{Binding ShowCardCode, Converter={StaticResource inverseBool}}"
AutomationId="ItemValue" />
<controls:MonoLabel
Text="{Binding Cipher.Card.Code, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0"
IsVisible="{Binding ShowCardCode}" />
IsVisible="{Binding ShowCardCode}"
AutomationId="ItemValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowCardCodeIcon}"
@@ -366,7 +405,8 @@
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
AutomationProperties.Name="{u:I18n ToggleVisibility}"
AutomationId="ShowValueButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -376,124 +416,156 @@
Grid.Column="2"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n CopySecurityCode}" />
AutomationProperties.Name="{u:I18n CopySecurityCode}"
AutomationId="CopyValueButton" />
</Grid>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Card.Code, Converter={StaticResource stringHasValue}}" />
</StackLayout>
<StackLayout IsVisible="{Binding IsIdentity}" Spacing="0" Padding="0">
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.FullName, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.FullName, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n IdentityName}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.FullName, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.FullName, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.Username, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.Username, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n Username}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.Username, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.Username, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.Company, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.Company, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n Company}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.Company, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.Company, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.SSN, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.SSN, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n SSN}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.SSN, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.SSN, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.PassportNumber, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.PassportNumber, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n PassportNumber}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.PassportNumber, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.PassportNumber, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.LicenseNumber, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.LicenseNumber, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n LicenseNumber}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.LicenseNumber, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.LicenseNumber, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.Email, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.Email, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow">
<Label
Text="{u:I18n Email}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.Email, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.Email, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row"
IsVisible="{Binding Cipher.Identity.Phone, Converter={StaticResource stringHasValue}}">
IsVisible="{Binding Cipher.Identity.Phone, Converter={StaticResource stringHasValue}}"
AutomationId="ItemRow" >
<Label
Text="{u:I18n Phone}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.Phone, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="ItemValue" />
</StackLayout>
<BoxView StyleClass="box-row-separator"
IsVisible="{Binding Cipher.Identity.Phone, Converter={StaticResource stringHasValue}}" />
<StackLayout StyleClass="box-row" IsVisible="{Binding ShowIdentityAddress}">
<StackLayout StyleClass="box-row" IsVisible="{Binding ShowIdentityAddress}"
AutomationId="ItemRow">
<Label
Text="{u:I18n Address}"
StyleClass="box-label" />
StyleClass="box-label"
AutomationId="ItemName" />
<Label
Text="{Binding Cipher.Identity.Address1, Mode=OneWay}"
IsVisible="{Binding Cipher.Identity.Address1, Converter={StaticResource stringHasValue}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityAddressOneLabel" />
<Label
Text="{Binding Cipher.Identity.Address2, Mode=OneWay}"
IsVisible="{Binding Cipher.Identity.Address2, Converter={StaticResource stringHasValue}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityAddressTwoLabel" />
<Label
Text="{Binding Cipher.Identity.Address3, Mode=OneWay}"
IsVisible="{Binding Cipher.Identity.Address3, Converter={StaticResource stringHasValue}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityAddressThreeLabel" />
<Label
Text="{Binding Cipher.Identity.FullAddressPart2, Mode=OneWay}"
IsVisible="{Binding Cipher.Identity.FullAddressPart2, Converter={StaticResource stringHasValue}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityFullAddressPartTwoLabel" />
<Label
Text="{Binding Cipher.Identity.Country, Mode=OneWay}"
IsVisible="{Binding Cipher.Identity.Country, Converter={StaticResource stringHasValue}}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="IdentityCountryLabel" />
</StackLayout>
<BoxView StyleClass="box-row-separator" IsVisible="{Binding ShowIdentityAddress}" />
</StackLayout>
@@ -503,11 +575,11 @@
<Label Text="{u:I18n URIs, Header=True}"
StyleClass="box-header, box-header-platform" />
</StackLayout>
<controls:RepeaterView ItemsSource="{Binding Cipher.Login.Uris}">
<controls:RepeaterView ItemsSource="{Binding Cipher.Login.Uris}" AutomationId="CipherUriContainer">
<controls:RepeaterView.ItemTemplate>
<DataTemplate x:DataType="views:LoginUriView">
<StackLayout Spacing="0" Padding="0">
<Grid StyleClass="box-row">
<Grid StyleClass="box-row" AutomationId="UriRow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
@@ -533,7 +605,8 @@
Text="{Binding HostOrUri, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0" />
Grid.Column="0"
AutomationId="UriValue" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.ShareSquare}}"
@@ -544,7 +617,8 @@
Grid.RowSpan="2"
IsVisible="{Binding CanLaunch, Mode=OneWay}"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Launch}" />
AutomationProperties.Name="{u:I18n Launch}"
AutomationId="LaunchUriButton" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Clone}}"
@@ -554,7 +628,8 @@
Grid.Column="2"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Copy}" />
AutomationProperties.Name="{u:I18n Copy}"
AutomationId="CopyUriButton" />
</Grid>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
@@ -568,14 +643,15 @@
<Label Text="{u:I18n Notes, Header=True}"
StyleClass="box-header, box-header-platform" />
</StackLayout>
<StackLayout StyleClass="box-row">
<StackLayout StyleClass="box-row" AutomationId="NotesRow">
<controls:SelectableLabel
Text="{Binding Cipher.Notes, Mode=OneWay}"
StyleClass="box-value" />
StyleClass="box-value"
AutomationId="CipherNotesLabel" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
<StackLayout StyleClass="box" IsVisible="{Binding Cipher.HasFields}">
<StackLayout StyleClass="box" IsVisible="{Binding Cipher.HasFields}" AutomationId="CustomFieldsContainer">
<StackLayout StyleClass="box-row-header">
<Label Text="{u:I18n CustomFields, Header=True}"
StyleClass="box-header, box-header-platform" />
@@ -590,21 +666,23 @@
<Label Text="{u:I18n Attachments, Header=True}"
StyleClass="box-header, box-header-platform" />
</StackLayout>
<controls:RepeaterView ItemsSource="{Binding Cipher.Attachments}">
<controls:RepeaterView ItemsSource="{Binding Cipher.Attachments}" AutomationId="CipherAttachmentsContainer">
<controls:RepeaterView.ItemTemplate>
<DataTemplate x:DataType="views:AttachmentView">
<StackLayout Spacing="0" Padding="0">
<StackLayout Orientation="Horizontal" StyleClass="box-row" Spacing="10">
<StackLayout Orientation="Horizontal" StyleClass="box-row" Spacing="10" AutomationId="CipherAttachment">
<Label
Text="{Binding FileName, Mode=OneWay}"
StyleClass="box-value"
VerticalTextAlignment="Center"
HorizontalOptions="StartAndExpand" />
HorizontalOptions="StartAndExpand"
AutomationId="CipherAttachmentFileNameLabel" />
<Label
Text="{Binding SizeName, Mode=OneWay}"
StyleClass="box-sub-label"
HorizontalTextAlignment="End"
VerticalTextAlignment="Center" />
VerticalTextAlignment="Center"
AutomationId="CipherAttachmentFileSizeLabel" />
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding Source={x:Static core:BitwardenIcons.Download}}"
@@ -612,7 +690,8 @@
CommandParameter="{Binding .}"
VerticalOptions="Center"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Download}" />
AutomationProperties.Name="{u:I18n Download}"
AutomationId="CipherAttachmentDownloadButton" />
</StackLayout>
<BoxView StyleClass="box-row-separator" />
</StackLayout>
@@ -622,17 +701,20 @@
</StackLayout>
<StackLayout StyleClass="box-bottom">
<Label FormattedText="{Binding UpdatedText}"
StyleClass="box-footer-label" />
StyleClass="box-footer-label"
AutomationId="CipherUpdatedDateLabel" />
<Label FormattedText="{Binding PasswordUpdatedText}"
StyleClass="box-footer-label"
IsVisible="{Binding Cipher.PasswordRevisionDisplayDate, Converter={StaticResource notNull}}">
IsVisible="{Binding Cipher.PasswordRevisionDisplayDate, Converter={StaticResource notNull}}"
AutomationId="CipherUpdatedPasswordDateLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="PasswordHistory_Tapped" />
</Label.GestureRecognizers>
</Label>
<Label FormattedText="{Binding PasswordHistoryText}"
StyleClass="box-footer-label"
IsVisible="{Binding Cipher.HasPasswordHistory}">
IsVisible="{Binding Cipher.HasPasswordHistory}"
AutomationId="CipherPasswordHistoryLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="PasswordHistory_Tapped" />
</Label.GestureRecognizers>
@@ -662,6 +744,7 @@
AbsoluteLayout.LayoutBounds="1, 1, AutoSize, AutoSize"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n EditItem}"
AutomationId="CipherEditButton"
IsVisible="{Binding CanEdit}">
<Button.Effects>
<effects:FabShadowEffect />

View File

@@ -19,7 +19,8 @@
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
<ToolbarItem IconImageSource="search.png" Clicked="Search_Clicked"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Search}" />

View File

@@ -41,7 +41,8 @@
HorizontalOptions="FillAndExpand"
TextChanged="SearchBar_TextChanged"
SearchButtonPressed="SearchBar_SearchButtonPressed"
Placeholder="{Binding PageTitle}" />
Placeholder="{Binding PageTitle}"
AutomationId="SearchBar" />
</StackLayout>
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform"
x:Name="_separator" x:Key="separator" />
@@ -91,7 +92,8 @@
Source="empty_items_state" />
<Label
Text="{u:I18n ThereAreNoItemsThatMatchTheSearch}"
HorizontalTextAlignment="Center" />
HorizontalTextAlignment="Center"
AutomationId="NoSearchResultsLabel" />
<Button
Text="{u:I18n AddAnItem}"
Command="{Binding AddCipherCommand}"
@@ -104,7 +106,8 @@
SelectionMode="Single"
SelectionChanged="RowSelected"
StyleClass="list, list-platform"
ExtraDataForLogging="Ciphers Page">
ExtraDataForLogging="Ciphers Page"
AutomationId="CipherList">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="views:CipherView">
<controls:CipherViewCell

View File

@@ -25,7 +25,8 @@
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
AutomationProperties.Name="{u:I18n Account}"
AutomationId="AccountIconButton" />
<ToolbarItem Icon="search.png" Clicked="Search_Clicked"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Search}" />
@@ -59,13 +60,14 @@
<controls:AuthenticatorViewCell
Cipher="{Binding Cipher}"
WebsiteIconsEnabled="{Binding BindingContext.WebsiteIconsEnabled, Source={x:Reference _page}}"
TotpSec="{Binding TotpSec}"/>
TotpSec="{Binding TotpSec}" />
</DataTemplate>
<DataTemplate x:Key="groupTemplate"
x:DataType="pages:GroupingsPageListItem">
<controls:ExtendedStackLayout Orientation="Horizontal"
StyleClass="list-row, list-row-platform">
StyleClass="list-row, list-row-platform"
AutomationId="{Binding AutomationId}">
<controls:IconLabel Text="{Binding Icon, Mode=OneWay}"
HorizontalOptions="Start"
VerticalOptions="Center"
@@ -79,12 +81,14 @@
LineBreakMode="TailTruncation"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
StyleClass="list-title"/>
StyleClass="list-title"
AutomationId="ItemNameLabel" />
<Label Text="{Binding ItemCount, Mode=OneWay}"
HorizontalOptions="End"
VerticalOptions="CenterAndExpand"
HorizontalTextAlignment="End"
StyleClass="list-sub"/>
StyleClass="list-sub"
AutomationId="ItemCountLabel" />
</controls:ExtendedStackLayout>
</DataTemplate>
@@ -95,7 +99,8 @@
Spacing="0"
Padding="0"
VerticalOptions="FillAndExpand"
StyleClass="list-row-header-container, list-row-header-container-platform">
StyleClass="list-row-header-container, list-row-header-container-platform"
AutomationId="{Binding AutomationId}">
<BoxView
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
<StackLayout StyleClass="list-row-header, list-row-header-platform">
@@ -104,7 +109,8 @@
StyleClass="list-header, list-header-platform" />
<Label
Text="{Binding ItemCount}"
StyleClass="list-header-sub" />
StyleClass="list-header-sub"
AutomationId="SectionItemCount" />
</StackLayout>
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
</StackLayout>
@@ -147,7 +153,8 @@
IsVisible="{Binding ShowNoData}">
<Label
Text="{Binding NoDataText}"
HorizontalTextAlignment="Center"></Label>
HorizontalTextAlignment="Center"
AutomationId="NoDataDisplayed"></Label>
<Button
Text="{u:I18n AddAnItem}"
Clicked="AddButton_Clicked"

View File

@@ -1,4 +1,6 @@
namespace Bit.App.Pages
using Bit.App.Utilities.Automation;
namespace Bit.App.Pages
{
public class GroupingsPageHeaderListItem : IGroupingsPageListItem
{
@@ -10,5 +12,12 @@
public string Title { get; }
public string ItemCount { get; set; }
public string AutomationId
{
get
{
return AutomationIdsHelper.AddSuffixFor(AutomationIdsHelper.ToEnglishTitleCase(Title), SuffixType.Header);
}
}
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Bit.App.Utilities.Automation;
namespace Bit.App.Pages
{
@@ -32,5 +33,6 @@ namespace Bit.App.Pages
public string Name { get; set; }
public string NameShort => string.IsNullOrWhiteSpace(Name) || Name.Length == 0 ? "-" : Name[0].ToString();
public string ItemCount { get; set; }
public string AutomationId => AutomationIdsHelper.AddSuffixFor(NameShort, SuffixType.ListGroup);
}
}

View File

@@ -1,4 +1,5 @@
using Bit.App.Resources;
using Bit.App.Utilities.Automation;
using Bit.Core;
using Bit.Core.Enums;
using Bit.Core.Models.View;
@@ -115,5 +116,38 @@ namespace Bit.App.Pages
return _icon;
}
}
public string AutomationId
{
get
{
if (Type != null)
{
return AutomationIdsHelper.AddSuffixFor(System.Enum.GetName(typeof(CipherType), Type.Value), SuffixType.Filter);
}
if (IsTrash)
{
return AutomationIdsHelper.AddSuffixFor("Trash", SuffixType.Filter);
}
if (Folder != null)
{
return AutomationIdsHelper.AddSuffixFor("Folder", SuffixType.Filter);
}
if (Collection != null)
{
return AutomationIdsHelper.AddSuffixFor("Collection", SuffixType.Filter);
}
if (IsTotpCode)
{
return AutomationIdsHelper.AddSuffixFor("TOTP", SuffixType.ListItem);
}
return null;
}
}
}
}

View File

@@ -202,6 +202,24 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Biometric unlock for this account is disabled pending verification of master password..
/// </summary>
public static string AccountBiometricInvalidated {
get {
return ResourceManager.GetString("AccountBiometricInvalidated", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Autofill biometric unlock for this account is disabled pending verification of master password..
/// </summary>
public static string AccountBiometricInvalidatedExtension {
get {
return ResourceManager.GetString("AccountBiometricInvalidatedExtension", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Your new account has been created! You may now log in..
/// </summary>
@@ -400,6 +418,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Admin approval requested.
/// </summary>
public static string AdminApprovalRequested {
get {
return ResourceManager.GetString("AdminApprovalRequested", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to All.
/// </summary>
@@ -544,6 +571,24 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Approve with master password.
/// </summary>
public static string ApproveWithMasterPassword {
get {
return ResourceManager.GetString("ApproveWithMasterPassword", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Approve with my other device.
/// </summary>
public static string ApproveWithMyOtherDevice {
get {
return ResourceManager.GetString("ApproveWithMyOtherDevice", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to April.
/// </summary>
@@ -967,24 +1012,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Biometric unlock disabled pending verification of master password..
/// </summary>
public static string AccountBiometricInvalidated {
get {
return ResourceManager.GetString("AccountBiometricInvalidated", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Biometric unlock for autofill disabled pending verification of master password..
/// </summary>
public static string AccountBiometricInvalidatedExtension {
get {
return ResourceManager.GetString("AccountBiometricInvalidatedExtension", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Biometrics.
/// </summary>
@@ -1750,6 +1777,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Data region.
/// </summary>
public static string DataRegion {
get {
return ResourceManager.GetString("DataRegion", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password updated.
/// </summary>
@@ -2326,6 +2362,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to EU.
/// </summary>
public static string EU {
get {
return ResourceManager.GetString("EU", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Exact.
/// </summary>
@@ -3244,6 +3289,24 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Invalid API key.
/// </summary>
public static string InvalidAPIKey {
get {
return ResourceManager.GetString("InvalidAPIKey", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid API token.
/// </summary>
public static string InvalidAPIToken {
get {
return ResourceManager.GetString("InvalidAPIToken", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Invalid email address..
/// </summary>
@@ -3550,6 +3613,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Logged in!.
/// </summary>
public static string LoggedIn {
get {
return ResourceManager.GetString("LoggedIn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Logged in as {0} on {1}..
/// </summary>
@@ -3577,6 +3649,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Logging in as {0} on {1}.
/// </summary>
public static string LoggingInAsXOnY {
get {
return ResourceManager.GetString("LoggingInAsXOnY", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Log In.
/// </summary>
@@ -3876,6 +3957,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Master password re-prompt help.
/// </summary>
public static string MasterPasswordRePromptHelp {
get {
return ResourceManager.GetString("MasterPasswordRePromptHelp", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Match detection.
/// </summary>
@@ -5129,6 +5219,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Region.
/// </summary>
public static string Region {
get {
return ResourceManager.GetString("Region", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Remember me.
/// </summary>
@@ -5138,6 +5237,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Remember this device.
/// </summary>
public static string RememberThisDevice {
get {
return ResourceManager.GetString("RememberThisDevice", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Remove.
/// </summary>
@@ -5210,6 +5318,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Request admin approval.
/// </summary>
public static string RequestAdminApproval {
get {
return ResourceManager.GetString("RequestAdminApproval", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Request one-time password.
/// </summary>
@@ -5462,6 +5579,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Self-hosted.
/// </summary>
public static string SelfHosted {
get {
return ResourceManager.GetString("SelfHosted", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Self-hosted environment.
/// </summary>
@@ -6191,6 +6317,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Trouble logging in?.
/// </summary>
public static string TroubleLoggingIn {
get {
return ResourceManager.GetString("TroubleLoggingIn", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Try again.
/// </summary>
@@ -6200,6 +6335,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Turn off using a public device.
/// </summary>
public static string TurnOffUsingPublicDevice {
get {
return ResourceManager.GetString("TurnOffUsingPublicDevice", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 20 seconds.
/// </summary>
@@ -6389,6 +6533,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve..
/// </summary>
public static string UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve {
get {
return ResourceManager.GetString("UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unlock vault.
/// </summary>
@@ -6524,6 +6677,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to US.
/// </summary>
public static string US {
get {
return ResourceManager.GetString("US", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use another two-step login method.
/// </summary>
@@ -7064,6 +7226,24 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Your request has been sent to your admin..
/// </summary>
public static string YourRequestHasBeenSentToYourAdmin {
get {
return ResourceManager.GetString("YourRequestHasBeenSentToYourAdmin", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You will be notified once approved. .
/// </summary>
public static string YouWillBeNotifiedOnceApproved {
get {
return ResourceManager.GetString("YouWillBeNotifiedOnceApproved", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to To continue, hold your YubiKey NEO against the back of the device or insert your YubiKey into your device&apos;s USB port, then touch its button..
/// </summary>

View File

@@ -1753,10 +1753,10 @@ Skandering gebeur outomaties.</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Biometriese ontgrendeling vir hierdie rekening is gedeaktiveer hangende bevestiging van hoofwagwoord.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Outovul-biometriese ontgrendeline vir hierdie rekening is gedeaktiveer hangende bevestiging van hoofwagwoord.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Aktiveer sinchronisering by verfrissing</value>
@@ -2495,8 +2495,8 @@ Wil u na die rekening omskakel?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Kry hoofwagwoord wenk</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Teken in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Teken aan as {0} op {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Nie jy nie?</value>
@@ -2609,10 +2609,37 @@ Wil u na die rekening omskakel?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Daar is geen items wat met die soekterm ooreenstem nie</value>
</data>
<data name="US" xml:space="preserve">
<value>VS</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Selghehuisves</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Datastreek</value>
</data>
<data name="Region" xml:space="preserve">
<value>Streek</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
<value>U hoofwagwoord voldoen nie aan een of meer van die organisasiebeleide nie. Om toegang tot die kluis te kry, moet u nou u hoofwagwoord bywerk. Deur voort te gaan sal u van u huidige sessie afgeteken word, en u sal weer moet aanteken. Aktiewe sessies op ander toestelle kan vir tot een uur aktief bly.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
<value>Huidige hoofwagwoord</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -1753,10 +1753,10 @@
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>تم تعطيل فتح القفل الحيوي لهذا الحساب في انتظار التحقق من كلمة المرور الرئيسية.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>إلغاء القفل الحيوي للملء التلقائي لهذا الحساب معطل في انتظار التحقق من كلمة المرور الرئيسية.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>تمكين المزامنة عند التحديث</value>
@@ -2496,8 +2496,8 @@
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>احصل على تلميح كلمة المرور الرئيسية</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>تسجيل الدخول كـ {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>تسجيل الدخول كـ {0} في {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>ليس أنت؟</value>
@@ -2610,10 +2610,37 @@
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>لا توجد عناصر تطابق البحث</value>
</data>
<data name="US" xml:space="preserve">
<value>الولايات المتحدة</value>
</data>
<data name="EU" xml:space="preserve">
<value>الاتحاد الأوروبي</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>استضافة ذاتية</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>منطقة البيانات</value>
</data>
<data name="Region" xml:space="preserve">
<value>المنطقة</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>كلمة المرور الرئيسية الخاصة بك لا تفي بواحدة أو أكثر من سياسات مؤسستك. من أجل الوصول إلى الخزنة، يجب عليك تحديث كلمة المرور الرئيسية الآن. سيتم تسجيل خروجك من الجلسة الحالية، مما يتطلب منك تسجيل الدخول مرة أخرى. وقد تظل الجلسات النشطة على أجهزة أخرى نشطة لمدة تصل إلى ساعة واحدة.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>كلمة المرور الرئيسية الحالية</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2494,8 +2494,8 @@ Bu hesaba keçmək istəyirsiniz?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Ana parol üçün məsləhət alın</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>{0} olaraq giriş edilir</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>{1} üzərində {0} olaraq giriş edildi</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Siz deyilsiniz?</value>
@@ -2608,10 +2608,37 @@ Bu hesaba keçmək istəyirsiniz?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Axtarışa uyğun gələn heç bir element yoxdur</value>
</data>
<data name="US" xml:space="preserve">
<value>ABŞ</value>
</data>
<data name="EU" xml:space="preserve">
<value>AB</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Öz-özünə sahiblik edən</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data bölgəsi</value>
</data>
<data name="Region" xml:space="preserve">
<value>Bölgə</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Ana parolunuz təşkilatınızdakı siyasətlərdən birinə və ya bir neçəsinə uyğun gəlmir. Anbara müraciət üçün ana parolunuzu indi güncəlləməlisiniz. Davam etsəniz, hazırkı seansdan çıxış etmiş və təkrar giriş etməli olacaqsınız. Digər cihazlardakı aktiv seanslar bir saata qədər aktiv qalmağa davam edə bilər.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Hazırkı ana parol</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Ana parolu təkrar soruş köməyi</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Yetərsiz yaddaşa görə kilid açma uğursuz ola bilər. Həll etmək üçün KDF yaddaş tənzimləmələrinizi azaldın</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Yararsız API açarı</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Yararsız API tokeni</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Атрымаць падказку да асноўнага пароля</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Увайсці як {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Вы ўваходзіце як {0} у {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Не вы?</value>
@@ -2609,10 +2609,37 @@
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Адсутнічаюць элементы, якія адпавядаюць пошуку</value>
</data>
<data name="US" xml:space="preserve">
<value>ЗША</value>
</data>
<data name="EU" xml:space="preserve">
<value>ЕС</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Уласнае размяшчэнне</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Рэгіён даных</value>
</data>
<data name="Region" xml:space="preserve">
<value>Рэгіён</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Ваш асноўны пароль не адпавядае адной або некалькім палітыкам арганізацыі. Для атрымання доступу да сховішча, вы павінны абнавіць яго. Працягваючы, вы выйдзіце з бягучага сеанса і вам неабходна будзе ўвайсці паўторна. Актыўныя сеансы на іншых прыладах могуць заставацца актыўнымі на працягу адной гадзіны.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Бягучы асноўны пароль</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Дапамога з паўторным запытам асноўнага пароля</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Па прычыне недахопу памяці можа адбыцца збой разблакіроўкі. Паменшыце налады памяці KDF, каб вырашыць гэту праблему</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Памылковы ключ API</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Памылковы токен API</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ select Add TOTP to store the key safely</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Получете подсказване за главната парола</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Вписване като {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Влизате като {0} в {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Това не сте Вие?</value>
@@ -2609,10 +2609,37 @@ select Add TOTP to store the key safely</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Няма елементи, които отговарят на търсенето</value>
</data>
<data name="US" xml:space="preserve">
<value>САЩ</value>
</data>
<data name="EU" xml:space="preserve">
<value>ЕС</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Собствен хостинг</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Регион на данните</value>
</data>
<data name="Region" xml:space="preserve">
<value>Регион</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Вашата главна парола не отговаря на една или повече политики на организацията Ви. За да получите достъп до трезора, трябва да промените главната си парола сега. Това означава, че ще бъдете отписан(а) от текущата си сесия и ще трябва да се впишете отново. Активните сесии на други устройства може да продължат да бъдат активни още един час.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Текуща главна парола</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Помощ за повторното запитване за главната парола</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Отключването може да бъде неуспешно заради недостатъчно памет. Намалете настройките на паметта за KDF, за да разрешите проблема.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Неправилен ключ за ППИ</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Неправилен идентификатор за ППИ</value>
</data>
</root>

View File

@@ -346,7 +346,7 @@
<comment>Confirmation message after successfully deleting a login.</comment>
</data>
<data name="Submit" xml:space="preserve">
<value>Submit</value>
<value>জমা দিন</value>
</data>
<data name="Sync" xml:space="preserve">
<value>Sync</value>
@@ -356,7 +356,7 @@
<value>ধন্যবাদ</value>
</data>
<data name="Tools" xml:space="preserve">
<value>Tools</value>
<value>টুলস</value>
<comment>The title for the tools page.</comment>
</data>
<data name="URI" xml:space="preserve">
@@ -379,7 +379,7 @@
<comment>Confirmation message after successfully copying a value to the clipboard.</comment>
</data>
<data name="VerifyFingerprint" xml:space="preserve">
<value>Verify fingerprint</value>
<value>আঙ্গুলের ছাপ যাচাই করুন</value>
</data>
<data name="VerifyMasterPassword" xml:space="preserve">
<value>প্রধান পাসওয়ার্ড যাচাইকরণ</value>
@@ -397,7 +397,7 @@
<value>আমাদের ওয়েবসাইটে ঢু মেরে আসুন</value>
</data>
<data name="VisitOurWebsiteDescription" xml:space="preserve">
<value>Visit our website to get help, news, email us, and/or learn more about how to use Bitwarden.</value>
<value>সাহায্য পেতে, খবর পেতে, আমাদের ইমেল করতে এবং/অথবা বিটওয়ার্ডেন কীভাবে ব্যবহার করবেন সে সম্পর্কে আরও জানতে আমাদের ওয়েবসাইট দেখুন।</value>
</data>
<data name="Website" xml:space="preserve">
<value>ওয়েবসাইট</value>
@@ -413,7 +413,7 @@
<value>আপনার নতুন অ্যাকাউন্ট তৈরি করা হয়েছে! আপনি এখন লগইন করতে পারবেন।</value>
</data>
<data name="AddAnItem" xml:space="preserve">
<value>Add an Item</value>
<value>একটি আইটেম যোগ করুন</value>
</data>
<data name="AppExtension" xml:space="preserve">
<value>App extension</value>
@@ -440,13 +440,13 @@
<value>Bitwarden Auto-fill Service</value>
</data>
<data name="BitwardenAutofillAccessibilityServiceDescription" xml:space="preserve">
<value>Use the Bitwarden accessibility service to auto-fill your logins.</value>
<value>আপনার লগইনগুলি স্বয়ংক্রিয়ভাবে পূরণ করতে বিটওয়ার্ডেন অ্যাক্সেসিবিলিটি পরিষেবা ব্যবহার করুন৷</value>
</data>
<data name="ChangeEmail" xml:space="preserve">
<value>ইমেইল পরিবর্তন করুন</value>
</data>
<data name="ChangeEmailConfirmation" xml:space="preserve">
<value>You can change your email address on the bitwarden.com web vault. Do you want to visit the website now?</value>
<value>আপনি bitwarden.com ওয়েব ভল্টে আপনার ইমেল ঠিকানা পরিবর্তন করতে পারেন। আপনি কি এখনই ওয়েবসাইট ভিজিট করতে চান?</value>
</data>
<data name="ChangeMasterPassword" xml:space="preserve">
<value>প্রধান পাসওয়ার্ড পরিবর্তন</value>
@@ -511,7 +511,7 @@
<value>প্রিয়</value>
</data>
<data name="Fingerprint" xml:space="preserve">
<value>Fingerprint</value>
<value>আঙুলের ছাপ</value>
</data>
<data name="GeneratePassword" xml:space="preserve">
<value>পাসওয়ার্ড তৈরি করুন</value>
@@ -584,7 +584,7 @@
<value>যদি আপনি আপনার পাসওয়ার্ড ভুলে যান তাহলে একটি প্রধান পাসওয়ার্ডের ইঙ্গিতটি আপনাকে মনে করাতে সাহায্য করতে পারে।</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<value>মাস্টার পাসওয়ার্ড কমপক্ষে {0} অক্ষরের হতে হবে।</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>সর্বনিম্ন সংখ্যা</value>
@@ -595,7 +595,7 @@
<comment>Minimum special characters for password generator settings</comment>
</data>
<data name="MoreSettings" xml:space="preserve">
<value>More settings</value>
<value>আরও সেটিংস</value>
</data>
<data name="MustLogInMainApp" xml:space="preserve">
<value>You must log into the main Bitwarden app before you can use the extension.</value>
@@ -684,7 +684,7 @@
<value>Item saved</value>
</data>
<data name="Submitting" xml:space="preserve">
<value>Submitting...</value>
<value>জমা দেওয়া হচ্ছে...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="Syncing" xml:space="preserve">
@@ -717,7 +717,7 @@
<value>Unlock with PIN code</value>
</data>
<data name="Validating" xml:space="preserve">
<value>Validating</value>
<value>কার্যকর করা হচ্ছে</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="VerificationCode" xml:space="preserve">
@@ -876,7 +876,7 @@
<value>Unable to download file.</value>
</data>
<data name="UnableToOpenFile" xml:space="preserve">
<value>Your device cannot open this type of file.</value>
<value>আপনার ডিভাইস এই ধরনের ফাইল খুলতে পারে না।</value>
</data>
<data name="Downloading" xml:space="preserve">
<value>ডাউনলোড হচ্ছে...</value>
@@ -2496,8 +2496,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2610,10 +2610,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2494,8 +2494,8 @@ Skeniranje će biti izvršeno automatski.</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Dobijte podsjetnik glavne lozinke</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Prijava kao {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Nisi ti?</value>
@@ -2608,10 +2608,37 @@ Skeniranje će biti izvršeno automatski.</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Voleu canviar a aquest compte?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Obteniu la pista de la contrasenya mestra</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Connectat com {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Inici de sessió com a {0} a {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>No sou vosaltres?</value>
@@ -2609,10 +2609,37 @@ Voleu canviar a aquest compte?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>No hi ha elements que coincidisquen amb la cerca</value>
</data>
<data name="US" xml:space="preserve">
<value>EUA</value>
</data>
<data name="EU" xml:space="preserve">
<value>UE</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Autoallotjat</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Regió de dades</value>
</data>
<data name="Region" xml:space="preserve">
<value>Regió</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>La vostra contrasenya mestra no compleix una o més de les polítiques de l'organització. Per accedir a la caixa forta, heu d'actualitzar-la ara. Si continueu, es tancarà la sessió actual i us demanarà que torneu a iniciar-la. Les sessions en altres dispositius poden continuar romanent actives fins a una hora.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Contrasenya mestra actual</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Ajuda per tornar a demanar la contrasenya mestra</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>El desbloqueig pot fallar a causa de memòria insuficient. Disminueix la configuració de memòria KDF per resoldre-ho</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Clau API no vàlida</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Token API no vàlid</value>
</data>
</root>

View File

@@ -2494,8 +2494,8 @@ Chcete se přepnout na tento účet?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Získat nápovědu pro hlavní heslo</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Přihlášování jako {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Přihlašování jako {0} na {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Nejste to Vy?</value>
@@ -2608,10 +2608,37 @@ Chcete se přepnout na tento účet?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Neexistují žádné položky, které by odpovídaly hledání</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Vlastní hosting</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Datový region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Vaše hlavní heslo nesplňuje jednu nebo více zásad Vaší organizace. Pro přístup k trezoru musíte nyní aktualizovat své hlavní heslo. Pokračování Vás odhlásí z Vaší aktuální relace a bude nutné se přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Aktuální hlavní heslo</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Nápověda pro znovuzeptání se na hlavní heslo</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Odemknutí může selhat z důvodu nedostatku paměti. Pro vyřešení snižte nastavení paměti KDF.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Neplatný klíč API</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Neplatný token API</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2610,10 +2610,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Vil du skifte til denne konto?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Få hovedadgangskodetip</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logger ind som {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logger ind som {0} på {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Ikke dig?</value>
@@ -2609,10 +2609,37 @@ Vil du skifte til denne konto?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Ingen emner matcher søgningen</value>
</data>
<data name="US" xml:space="preserve">
<value>USA</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Selv-hostet</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Dataregion</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Din hovedadgangskode overholder ikke én eller flere organisationspolitikker. For at få adgang til boksen skal hovedadgangskode opdateres nu. Fortsættes, logges du ud af den nuværende session og vil skulle logger ind igen. Aktive sessioner på andre enheder kan forblive aktive i op til én time.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Aktuel hovedadgangskode</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Hjælp til genanmodning om hovedadgangskode</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Oplåsning kan fejle grundet utilstrækkelig hukommelse. Reducér KDF-hukommelsesindstillinger for at afhjælpe</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Ugyldig API-nøgle</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Ugyldigt API-token</value>
</data>
</root>

View File

@@ -2494,8 +2494,8 @@ Möchtest du zu diesem Konto wechseln?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Hinweis zum Master-Passwort erhalten</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Anmelden als {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Anmelden als {0} auf {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Nicht du?</value>
@@ -2608,10 +2608,37 @@ Möchtest du zu diesem Konto wechseln?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Es gibt keine Einträge, die mit der Suche übereinstimmen</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Selbst gehostet</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Datenregion</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Dein Master-Passwort entspricht nicht einer oder mehreren Richtlinien deiner Organisation. Um auf den Tresor zugreifen zu können, musst du dein Master-Passwort jetzt aktualisieren. Wenn du fortfährst, wirst du von deiner aktuellen Sitzung abgemeldet und musst dich erneut anmelden. Aktive Sitzungen auf anderen Geräten können noch bis zu einer Stunde lang aktiv bleiben.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Aktuelles Master-Passwort</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Hilfe zum erneuten Abfragen des Master-Passworts</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Das Entsperren kann aufgrund von unzureichendem Arbeitsspeicher fehlschlagen. Verringere deine KDF-Speichereinstellungen, um das Problem zu beheben.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Ungültiger API-Schlüssel</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Ungültiger API-Token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Λάβετε υπόδειξη κύριου κωδικού</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Σύνδεση ως {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Σύνδεση ως {0} στις {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Δεν είστε εσείς;</value>
@@ -2609,10 +2609,37 @@
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Δεν υπάρχουν στοιχεία που να ταιριάζουν με την αναζήτηση</value>
</data>
<data name="US" xml:space="preserve">
<value>ΗΠΑ</value>
</data>
<data name="EU" xml:space="preserve">
<value>ΕΕ</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Αυτο-φιλοξενούμενο</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Περιοχή δεδομένων</value>
</data>
<data name="Region" xml:space="preserve">
<value>Περιοχή</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Ο κύριος κωδικός πρόσβασής σας δεν πληροί μία ή περισσότερες πολιτικές του οργανισμού σας. Για να αποκτήσετε πρόσβαση στο Vault σας, πρέπει να ενημερώσετε τον κύριο κωδικό πρόσβασής σας τώρα. Η διαδικασία θα σας αποσυνδέσει από την τρέχουσα συνεδρία σας, απαιτώντας από εσάς να συνδεθείτε ξανά. Οι ενεργές συνεδρίες σε άλλες συσκευές ενδέχεται να συνεχίσουν να είναι ενεργές εώς και μία ώρα.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Τρέχων κύριος κωδικός</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2609,10 +2609,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2509,8 +2509,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2623,10 +2623,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -775,10 +775,10 @@
<value>Activado</value>
</data>
<data name="Off" xml:space="preserve">
<value>Apagado</value>
<value>No</value>
</data>
<data name="On" xml:space="preserve">
<value>Activado</value>
<value></value>
</data>
<data name="Status" xml:space="preserve">
<value>Estado</value>
@@ -2496,8 +2496,8 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Obtener pista de contraseña maestra</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Iniciando sesión como {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Iniciando sesión como {0} en {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>¿No eres tú?</value>
@@ -2610,10 +2610,37 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>No hay elementos que coincidan con la búsqueda</value>
</data>
<data name="US" xml:space="preserve">
<value>EE.UU.</value>
</data>
<data name="EU" xml:space="preserve">
<value>Unión Europea</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Autoalojado</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Región de datos</value>
</data>
<data name="Region" xml:space="preserve">
<value>Región</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Su contraseña maestra no cumple con una o más de las políticas de su organización. Para acceder a la caja fuerte, debe actualizar su contraseña maestra ahora. Proceder le desconectará de su sesión actual, requiriendo que vuelva a iniciar sesión. Las sesiones activas en otros dispositivos pueden seguir estando activas durante hasta una hora.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Contraseña maestra actual</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Ayuda de volver a pedir contraseña maestra</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>El desbloqueo puede fallar por falta de memoria. Disminuye los ajustes de memoria KDF para resolver</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Clave API no válida</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Token de API no válido</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Soovid selle konto peale lülituda?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Tuleta ülemparooli vihjega meelde</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Sisselogimas kui {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Sisselogimas kui {0} lehel {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Pole sina?</value>
@@ -2609,10 +2609,37 @@ Soovid selle konto peale lülituda?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Otsingusõnale ei vasta kirjeid</value>
</data>
<data name="US" xml:space="preserve">
<value>USA</value>
</data>
<data name="EU" xml:space="preserve">
<value>EL</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Enda majutatud</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Andmete salvestamise piirkond</value>
</data>
<data name="Region" xml:space="preserve">
<value>Piirkond</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Sinu ülemparool ei vasta ühele või rohkemale organisatsiooni poolt seatud poliitikale. Hoidlale ligipääsemiseks pead oma ülemaprooli uuendama. Jätkamisel logitakse sind praegusest sessioonist välja, mistõttu pead uuesti sisse logima. Teistes seadmetes olevad aktiivsed sessioonid aeguvad umbes ühe tunni jooksul.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Praegune ülemparool</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Vigane API võti</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Vigane API token</value>
</data>
</root>

View File

@@ -584,7 +584,7 @@
<value>Pasahitz nagusia ahazten baduzu, pista batek pasahitza gogoratzen lagunduko dizu.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<value>Pasahitz nagusiak {0} karaktere izan behar ditu gutxienez.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Gutxieneko zenbaki kopurua</value>
@@ -1752,10 +1752,10 @@
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Desblokeatze biometrikoa desgaituta dago kontu honentzat, pasahitz nagusia egiaztatzeko zain.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Desblokeatze biometriko automatikoa desgaituta dago kontu honentzat, pasahitz nagusia egiaztatzeko zain.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Gaitu eguneratzean sinkronizatzea</value>
@@ -2494,8 +2494,8 @@ Kontu honetara aldatu nahi duzu?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Jaso pasahitz nagusiaren pista</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>{0} bezala hasi saioa</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>{0} bezala saioa hasten {1}(e)n</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Ez zara zu?</value>
@@ -2531,31 +2531,31 @@ Kontu honetara aldatu nahi duzu?</value>
<value>Pending login requests</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
<value>Ukatu eskaera guztiak</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
<value>Ziur al zaude zain dauden saioa hasteko eskaera guztiak ukatu nahi dituzula?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
<value>Eskaerak ukatuta</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
<value>Ez dago eskaerarik zain</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Gaitu kameraren baimena eskanerra erabiltzeko</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
<value>Hizkuntza</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
<value>{0} hizkuntza ezarri da. Berrabiarazi aplikazioa mesedez aldaketa ikusi ahal izateko</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
<value>Hizkuntza aldatzeak aplikazioa berabiaraztea behar du</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
<value>Lehenetsia (Sistema)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Garrantzitsua</value>
@@ -2594,7 +2594,7 @@ Kontu honetara aldatu nahi duzu?</value>
<value>Pasahitz ahul hau datu-urraketa batean aurkitu da. Erabil ezazu beste inon erabili ez duzun pasahitz sendi bat zure kontua babesteko. Ziur zaude pasahitz hau erabili nahi duzula?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
<value>Erakundearen identifikazio bakarra (SSO) beharrezkoa da.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
@@ -2603,15 +2603,42 @@ Kontu honetara aldatu nahi duzu?</value>
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
<value>Bilatu elementu bat ala gehitu elementu berria</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
<value>Ez dago bilaketarekin bat datorren emaitzarik</value>
</data>
<data name="US" xml:space="preserve">
<value>AEB</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Eskualdea</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
<value>Uneko pasahitz nagusia</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -1753,10 +1753,10 @@
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>باز کردن قفل بیومتریک برای این حساب کاربری در انتظار تأیید کلمه عبور اصلی غیرفعال است.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>باز کردن قفل پر کردن خودکار بیومتریک برای این حساب کاربری در انتظار تأیید کلمه عبور اصلی غیرفعال است.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>فعال کردن همگام‌سازی در نوسازی</value>
@@ -2144,10 +2144,10 @@
<value>سیاست‌های سازمانتان بر مهلت زمانی گاوصندوق شما تأثیر می‌گذارد. حداکثر زمان مجاز گاوصندوق {0} ساعت و {1} دقیقه است</value>
</data>
<data name="VaultTimeoutPolicyWithActionInEffect" xml:space="preserve">
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s). Your vault timeout action is set to {2}.</value>
<value>سیاست‌های سازمانتان بر مهلت زمانی گاوصندوق شما تأثیر می‌گذارد. حداکثر زمان مجاز گاوصندوق {0} ساعت و {1} دقیقه است. عملگر مهلت زمانی گاوصندوق شما روی {2} تنظیم شده است.</value>
</data>
<data name="VaultTimeoutActionPolicyInEffect" xml:space="preserve">
<value>Your organization policies have set your vault timeout action to {0}.</value>
<value>سباست‌های سازمان شما، عملگر زمان‌بندی گاوصندوق شما را روی {0} تنظیم کرده است.</value>
</data>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>مهلت زمانی شما بیش از محدودیت های تعیین شده توسط سازمانتان است.</value>
@@ -2496,8 +2496,8 @@
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>دریافت یادآور کلمه عبور اصلی</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>در حال ورود به عنوان {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>درحال وارد شدن به عنوان {0} در {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>شما نیستید؟</value>
@@ -2610,10 +2610,37 @@
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>هیچ موردی وجود ندارد که با جستجو مطابقت داشته باشد</value>
</data>
<data name="US" xml:space="preserve">
<value>امریکا</value>
</data>
<data name="EU" xml:space="preserve">
<value>اروپا</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>خود میزبان</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>منطقه داده</value>
</data>
<data name="Region" xml:space="preserve">
<value>منطقه</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
<value>کلمه عبور اصلی شما با یک یا چند سیاست سازمان‌تان مطابقت ندارد. برای دسترسی به گاوصندوق، باید همین حالا کلمه عبور اصلی خود را به‌روز کنید. در صورت ادامه، شما از نشست فعلی خود خارج می‌شوید و باید دوباره وارد سیستم شوید. نشست فعال در دستگاه های دیگر ممکن است تا یک ساعت همچنان فعال باقی بمانند.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
<value>کلمه عبور اصلی فعلی</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>راهنمای درخواست مجدد کلمه عبور اصلی</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>باز کردن قفل ممکن است به دلیل حافظه ناکافی انجام شود. تنظیمات حافظه KDF خود را کاهش دهید تا حل شود.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>کلید API نامعتبر</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>کلید توکن API نامعتبر</value>
</data>
</root>

View File

@@ -937,7 +937,7 @@ Koodi luetaan automaattisesti.</value>
<value>Tiedosto</value>
</data>
<data name="NoFileChosen" xml:space="preserve">
<value>Ei valittua tiedostoa</value>
<value>Tiedostoa ei ole valittu.</value>
</data>
<data name="NoAttachments" xml:space="preserve">
<value>Ei liitteitä.</value>
@@ -1492,7 +1492,7 @@ Koodi luetaan automaattisesti.</value>
<value>Aseta PIN-koodi Bitwardenin avaukselle. PIN-asetukset tyhjentyvät, jos kirjaudut kokonaan ulos sovelluksesta.</value>
</data>
<data name="LoggedInAsOn" xml:space="preserve">
<value>Kirjautui tunnuksella {0} palvelimelle {1}.</value>
<value>Kirjautui palvelimelle {1} tunnuksella {0}.</value>
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
</data>
<data name="VaultLockedMasterPassword" xml:space="preserve">
@@ -1762,7 +1762,7 @@ Koodi luetaan automaattisesti.</value>
<value>Synkronoi holvi päivityksen yhteydessä</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Synkronoidaan holvi alasveto-eleellä.</value>
<value>Holvi synkronoidaan myös alasveto-eleellä suoritettavan päivityksen yhteydessä.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Yrityksen kertakirjautuminen (SSO)</value>
@@ -2367,7 +2367,7 @@ turvallisesti valitsemalla "Lisää TOTP"</value>
<value>Hyväksy kirjautumispyyntöjä</value>
</data>
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
<value>Hyväksy muiden laitteiden kirjautumispyynnöt tältä laitteelta.</value>
<value>Hyväksy laitteiden kirjautumispyyntöjä tältä laitteelta</value>
</data>
<data name="AllowNotifications" xml:space="preserve">
<value>Salli ilmoitukset</value>
@@ -2496,8 +2496,8 @@ Haluatko vaihtaa tähän tiliin?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Pyydä pääsalasanan vihjettä</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Kirjaudutaan tunnuksella {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Kirjaudutaan palvelimelle {1} tunnuksella {0}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Etkö se ollut sinä?</value>
@@ -2542,7 +2542,7 @@ Haluatko vaihtaa tähän tiliin?</value>
<value>Pyynnöt hylättiin</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Ei odottavia pyyntöjä</value>
<value>Odottavia pyyntöjä ei ole</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Myönnä kameran käyttöoikeus skannerin käyttämiseksi</value>
@@ -2554,7 +2554,7 @@ Haluatko vaihtaa tähän tiliin?</value>
<value>Kieleksi vaihdettiin {0}. Käynnistä sovellus uudelleen nähdäksesi muutoksen.</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Kielen vaihto edellyttää sovelluksen uudelleenkäynnistyksen</value>
<value>Kielen vaihto vaatii sovelluksen uudelleenkäynnistyksen.</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Oletus (järjestelmä)</value>
@@ -2610,10 +2610,37 @@ Haluatko vaihtaa tähän tiliin?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Hakua vastaavia kohteita ei ole</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Itse ylläpidetty</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Tietoalue</value>
</data>
<data name="Region" xml:space="preserve">
<value>Alue</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Pääsalasanasi ei täytä yhden tai useamman organisaatiokäytännön vaatimuksia ja holvin käyttämiseksi sinun on vaihdettava se nyt. Tämä uloskirjaa kaikki nykyiset istunnot pakottaen uudelleenkirjautumisen. Muiden laitteiden aktiiviset istunnot saattavat toimia vielä tunnin ajan.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Nykyinen pääsalasana</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Pääsalasanan uudelleenkyselyn ohje</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Lukituksen avaus voi epäonnistua riittämättömän keskusmuistin vuoksi. Korjaa madaltamalla KDF-muistiasetuksiasi.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Virheellinen API-avain</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Virheellinen API-tunniste</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Gusto mo bang pumunta sa account na ito?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Kunin ang palatandaan ng master password</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Nagla-log in bilang si {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Hindi ikaw?</value>
@@ -2610,10 +2610,37 @@ Gusto mo bang pumunta sa account na ito?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Walang mga item na tumutugma sa paghahanap</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Voulez-vous basculer vers ce compte ?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Obtenir l'indice du mot de passe principal</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Connecté en tant que {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Connexion en tant que {0} sur {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Ce n'est pas vous ?</value>
@@ -2610,10 +2610,37 @@ Voulez-vous basculer vers ce compte ?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Il n'y a pas d'éléments qui correspondent à la recherche</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Auto-hébergé</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Région des données</value>
</data>
<data name="Region" xml:space="preserve">
<value>Région</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Votre mot de passe principal ne répond pas aux exigences de politique de sécurité de cette organisation. Pour accéder au coffre, vous devez mettre à jour votre mot de passe principal dès maintenant. En poursuivant, vous serez déconnecté de votre session actuelle et vous devrez vous reconnecter. Les sessions actives sur d'autres appareils peuver rester actives pendant encore une heure.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Mot de passe principal actuel</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Aide sur la ressaisie du mot de passe principal</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Le déverrouillage peut échouer en raison d'une mémoire insuffisante. Diminuez les paramètres de mémoire KDF pour y remédier</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Clé API invalide</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Jeton API invalide</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2610,10 +2610,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2498,8 +2498,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2612,10 +2612,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -2493,8 +2493,8 @@
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Slanje podsjetnika glavne lozinke</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Prijava kao {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Nisi ti?</value>
@@ -2607,10 +2607,37 @@
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Nema stavki koje odgovaraju pretrazi</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2494,8 +2494,8 @@ Szeretnénk átváltani erre a fiókra?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Mesterjelszó emlékeztető kérése</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Bejelentkezve mint {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Bejelentkezve mint {0} :: {1}.</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Ez tévedés?</value>
@@ -2608,10 +2608,37 @@ Szeretnénk átváltani erre a fiókra?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Nincsenek a keresésnek megfelelő elemek.</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Saját kiszolgáló</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Adatrégió</value>
</data>
<data name="Region" xml:space="preserve">
<value>Régió</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>A mesterjelszó nem felel meg egy vagy több szervezeti szabályzatnak. A széf eléréséhez frissíteni kell a meszerjelszót. A továbblépés kijelentkeztet az aktuális munkamenetből és újra be kell jelentkezni. A többi eszközön lévő aktív munkamenetek akár egy óráig is aktívak maradhatnak.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Jelenlegi mesterjelszó</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Mesterjelszó újbóli bekérés súgó</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>A feloldás meghiúsulhat, mert nincs elegendő memória. A megoldáshoz csökkentsül a KDF memóriabeállításait.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Érvénytelen API kulcs</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Érvénytelen API vezérjel</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2609,10 +2609,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Vuoi passare a questo account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Ottieni suggerimento per la password principale</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Accedendo come</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Accedendo come {0} su {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Non sei tu?</value>
@@ -2609,10 +2609,37 @@ Vuoi passare a questo account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Nessun elemento corrisponde alla ricerca</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Area dati</value>
</data>
<data name="Region" xml:space="preserve">
<value>Regione</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>La tua password principale non soddisfa uno o più politiche della tua organizzazione. Per accedere alla cassaforte, aggiornala ora. Procedere ti farà uscire dalla sessione corrente, richiedendoti di accedere di nuovo. Le sessioni attive su altri dispositivi potrebbero continuare a rimanere attive per un massimo di un'ora.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Password principale corrente</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Aiuto per chiedere la password principale di nuovo</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Lo sblocco potrebbe fallire a causa di memoria insufficiente. Riduci le impostazioni della memoria KDF per risolvere il problema</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Chiave API non valida</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Token API non valido</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>マスターパスワードのヒントを取得する</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>{0} としてログイン</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>{1} で {0} としてログイン</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>あなたではないですか?</value>
@@ -2609,10 +2609,37 @@
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>検索に一致するアイテムはありません</value>
</data>
<data name="US" xml:space="preserve">
<value>米国</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>自己ホスト型</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>データのリージョン</value>
</data>
<data name="Region" xml:space="preserve">
<value>リージョン</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>マスターパスワードが組織のポリシーに適合していません。保管庫にアクセスするには、今すぐマスターパスワードを更新しなければなりません。続行すると現在のセッションからログアウトし、再度ログインする必要があります。 他のデバイス上のアクティブなセッションは、最大1時間アクティブであり続けることがあります。</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>現在のマスターパスワード</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>マスターパスワードの再プロンプトヘルプ</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>メモリ不足のためロック解除に失敗することがあります。KDF のメモリ設定を減らして解決してください</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>無効な API キー</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>無効な API トークン</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2610,10 +2610,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2610,10 +2610,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>마스터 비밀번호 힌트 얻기</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>{0}(으)로 로그인 중</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>본인이 아닌가요?</value>
@@ -2609,10 +2609,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>검색어와 일치하는 항목이 없습니다</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Ar norite pereiti prie šios paskyros?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Gauti pagrindinio slaptažodžio užuominą</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Prisijungiama kaip {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Ne jūs?</value>
@@ -2610,10 +2610,37 @@ Ar norite pereiti prie šios paskyros?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Elementų, atitinkančių paiešką, nėra</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Jūsų pagrindinis slaptažodis neatitinka vieno ar kelių organizacijos slaptažodžiui keliamų reikalavimų. Norėdami prisijungti prie saugyklos, jūs turite atnaujinti savo pagrindinį slaptažodį. Jeigu nuspręsite tęsti, jūs būsite atjungti nuo dabartinės sesijos ir jums reikės vėl prisijungti. Visos aktyvios sesijos kituose įrenginiuose gali išlikti aktyvios iki vienos valandos.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Dabartinis pagrindinis slaptažodis</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

View File

@@ -2495,8 +2495,8 @@ Vai pārslēgties uz šo kontu?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Saņemt galvenās paroles norādi</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Piesakās kā {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Piesakās {1} kā {0}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Tas neesi Tu?</value>
@@ -2609,10 +2609,37 @@ Vai pārslēgties uz šo kontu?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Nav vienumu, kas atbilstu meklējumam</value>
</data>
<data name="US" xml:space="preserve">
<value>ASV</value>
</data>
<data name="EU" xml:space="preserve">
<value>ES</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Pašizvietots</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Datu apgabals</value>
</data>
<data name="Region" xml:space="preserve">
<value>Apgabals</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Galvenā parole neatbilst vienam vai vairākiem apvienības nosacījumiem. Ir jāatjaunina galvenā parole, lai varētu piekļūt glabātavai. Turpinot notiks atteikšanās no pašreizējās sesijas, un būs nepieciešams pieteikties no jauna. Citās ierīcēs esošās sesijas var turpināt darboties līdz vienai stundai.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Pašreizējā galvenā parole</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Galvenās paroles pārvaicāšanas palīdzība</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Atslēgšana var neizdoties nepietiekamas atmiņas dēļ. Lai to novērstu, jāsamazina KDF atmiņas iestatījmi</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Nederīga API atslēga</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Nederīga API pilnvara</value>
</data>
</root>

View File

@@ -276,7 +276,7 @@
<value>നിങ്ങൾക്ക് ലോഗ് ഔട്ട് ചെയ്യണമെന്ന് ഉറപ്പാണോ?</value>
</data>
<data name="RemoveAccount" xml:space="preserve">
<value>Remove account</value>
<value>അക്കൗണ്ട് നീക്കംചെയ്യുക</value>
</data>
<data name="RemoveAccountConfirmation" xml:space="preserve">
<value>Are you sure you want to remove this account?</value>
@@ -584,7 +584,7 @@
<value>നിങ്ങളുടെ പാസ്‌വേഡ് മറന്നാൽ അത് ഓർമ്മിക്കാൻ ഒരു പ്രാഥമിക പാസ്‌വേഡ് സൂചന സഹായിക്കും.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<value>പ്രാഥമിക പാസ്‌വേഡിന് കുറഞ്ഞത് {0} പ്രതീകങ്ങളെങ്കിലും ദൈർഘ്യമുണ്ടായിരിക്കണം.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>കുറഞ്ഞ സംഖ്യകൾ</value>
@@ -775,10 +775,10 @@
<value>പ്രവർത്തനക്ഷമമാക്കി</value>
</data>
<data name="Off" xml:space="preserve">
<value>Off</value>
<value>ഓഫ്</value>
</data>
<data name="On" xml:space="preserve">
<value>On</value>
<value>ഓൺ</value>
</data>
<data name="Status" xml:space="preserve">
<value>അവസ്ഥ</value>
@@ -900,8 +900,8 @@
<value>ഓതന്റിക്കേറ്റർ കീ വായിക്കാൻ കഴിയുന്നില്ല.</value>
</data>
<data name="PointYourCameraAtTheQRCode" xml:space="preserve">
<value>Point your camera at the QR Code.
Scanning will happen automatically.</value>
<value>നിങ്ങളുടെ ക്യാമറ QR കോഡിലേക്ക് ചൂണ്ടുക.
സ്കാനിംഗ് സ്വയമേവ നടക്കും.</value>
</data>
<data name="ScanQrTitle" xml:space="preserve">
<value>QR കോഡ് സ്കാൻ ചെയ്യുക</value>
@@ -1080,7 +1080,7 @@ Scanning will happen automatically.</value>
<value>പേരിന്റെ അവസാന ഭാഗം</value>
</data>
<data name="FullName" xml:space="preserve">
<value>Full name</value>
<value>പൂര്‍ണ്ണമായ പേര്</value>
</data>
<data name="LicenseNumber" xml:space="preserve">
<value>ലൈസൻസ് നമ്പർ</value>
@@ -1210,7 +1210,7 @@ Scanning will happen automatically.</value>
<value>മറച്ചത്</value>
</data>
<data name="FieldTypeLinked" xml:space="preserve">
<value>Linked</value>
<value>ബന്ധിപ്പിച്ചത്</value>
</data>
<data name="FieldTypeText" xml:space="preserve">
<value>വാചകം</value>
@@ -1384,10 +1384,10 @@ Scanning will happen automatically.</value>
<value>കളക്ഷനുകൾ തിരയുക</value>
</data>
<data name="SearchFileSends" xml:space="preserve">
<value>Search file Sends</value>
<value>അയച്ച വാക്കുകൾ തിരയുക</value>
</data>
<data name="SearchTextSends" xml:space="preserve">
<value>Search text Sends</value>
<value>അയച്ച വാക്കുകൾ തിരയുക</value>
</data>
<data name="SearchGroup" xml:space="preserve">
<value>Search {0}</value>
@@ -1662,10 +1662,10 @@ Scanning will happen automatically.</value>
<value>Send a verification code to your email</value>
</data>
<data name="CodeSent" xml:space="preserve">
<value>Code sent!</value>
<value>കോഡ് അയച്ചു!</value>
</data>
<data name="ConfirmYourIdentity" xml:space="preserve">
<value>Confirm your identity to continue.</value>
<value>തുടരാൻ നിങ്ങളുടെ ഐഡന്റിറ്റി സ്ഥിരീകരിക്കുക.</value>
</data>
<data name="ExportVaultWarning" xml:space="preserve">
<value>ഈ എക്‌സ്‌പോർട്ടിൽ എൻക്രിപ്റ്റ് ചെയ്യാത്ത ഫോർമാറ്റിൽ നിങ്ങളുടെ വാൾട് ഡാറ്റ അടങ്ങിയിരിക്കുന്നു. എക്‌സ്‌പോർട് ചെയ്ത ഫയൽ സുരക്ഷിതമല്ലാത്ത ചാനലുകളിൽ (ഇമെയിൽ പോലുള്ളവ) നിങ്ങൾ സംഭരിക്കുകയോ അയയ്ക്കുകയോ ചെയ്യരുത്. നിങ്ങൾ ഇത് ഉപയോഗിച്ചുകഴിഞ്ഞാലുടൻ അത് മായ്ച്ചുകളയണം.</value>
@@ -1886,7 +1886,7 @@ Scanning will happen automatically.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="Text" xml:space="preserve">
<value>Text</value>
<value>വാചകം</value>
</data>
<data name="TypeText" xml:space="preserve">
<value>വാചകം</value>
@@ -1905,13 +1905,13 @@ Scanning will happen automatically.</value>
<value>നിങ്ങൾ അയയ്ക്കാൻ ആഗ്രഹിക്കുന്ന ഫയൽ.</value>
</data>
<data name="FileTypeIsSelected" xml:space="preserve">
<value>File type is selected.</value>
<value>ഫയൽ തരം തിരഞ്ഞെടുത്തു.</value>
</data>
<data name="FileTypeIsNotSelected" xml:space="preserve">
<value>File type is not selected, tap to select.</value>
<value>ഫയൽ തരം തിരഞ്ഞെടുത്തിട്ടില്ല, തിരഞ്ഞെടുക്കാൻ ടാപ്പുചെയ്യുക.</value>
</data>
<data name="TextTypeIsSelected" xml:space="preserve">
<value>Text type is selected.</value>
<value>ഫയൽ തരം തിരഞ്ഞെടുത്തു.</value>
</data>
<data name="TextTypeIsNotSelected" xml:space="preserve">
<value>Text type is not selected, tap to select.</value>
@@ -1927,7 +1927,7 @@ Scanning will happen automatically.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="PendingDelete" xml:space="preserve">
<value>Pending deletion</value>
<value>പരിപൂർണ്ണമാവാത്ത ഇല്ലാതാക്കൽ</value>
</data>
<data name="ExpirationDate" xml:space="preserve">
<value>കാലഹരണപ്പെടുന്ന തീയതി</value>
@@ -2495,8 +2495,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2609,10 +2609,37 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
</data>
<data name="MasterPasswordRePromptHelp" xml:space="preserve">
<value>Master password re-prompt help</value>
</data>
<data name="UnlockingMayFailDueToInsufficientMemoryDecreaseYourKDFMemorySettingsToResolve" xml:space="preserve">
<value>Unlocking may fail due to insufficient memory. Decrease your KDF memory settings to resolve.</value>
</data>
<data name="InvalidAPIKey" xml:space="preserve">
<value>Invalid API key</value>
</data>
<data name="InvalidAPIToken" xml:space="preserve">
<value>Invalid API token</value>
</data>
</root>

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