mirror of
https://github.com/bitwarden/mobile
synced 2026-01-21 20:03:16 +00:00
Compare commits
56 Commits
v2022.10.0
...
SG-816-add
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e9d3787d8 | ||
|
|
5b53c0c48f | ||
|
|
7e8e86a77a | ||
|
|
20c1e2d7f2 | ||
|
|
7870c2706b | ||
|
|
5a5f50605b | ||
|
|
0106732cbd | ||
|
|
9ae269dd57 | ||
|
|
04ed47d545 | ||
|
|
6160535c03 | ||
|
|
8d92373c88 | ||
|
|
6bfc8f7d49 | ||
|
|
69f02eef82 | ||
|
|
02b8e54988 | ||
|
|
99472d2548 | ||
|
|
5a4c81bd75 | ||
|
|
ee09c0abda | ||
|
|
9baa79e10b | ||
|
|
a8909a3ce6 | ||
|
|
b9b9c2e5ff | ||
|
|
89adab6784 | ||
|
|
77d8afcfe6 | ||
|
|
4fcb063190 | ||
|
|
5deba15373 | ||
|
|
505426cd6a | ||
|
|
3cb9f37997 | ||
|
|
4c2f5c05e5 | ||
|
|
eefc9bd239 | ||
|
|
d18efdea73 | ||
|
|
a72a0ec0ce | ||
|
|
c7e9f30a9a | ||
|
|
6c404c8229 | ||
|
|
e5de530c2c | ||
|
|
3a87378847 | ||
|
|
6048a10d6d | ||
|
|
a5ad43b134 | ||
|
|
539f8fe5b5 | ||
|
|
569922805f | ||
|
|
3972e3de8a | ||
|
|
ba677a96aa | ||
|
|
d800e9a43e | ||
|
|
2d35a00caa | ||
|
|
dc5698b353 | ||
|
|
abada481b7 | ||
|
|
1e5eab0574 | ||
|
|
c1101af582 | ||
|
|
1db4c4fc8b | ||
|
|
bc949fe87a | ||
|
|
a890ee6612 | ||
|
|
90e0b5dcf0 | ||
|
|
9631988fc2 | ||
|
|
b5f80da28d | ||
|
|
7e0b943b70 | ||
|
|
425be32c15 | ||
|
|
f9a32e4abc | ||
|
|
2f4cd36595 |
@@ -7,6 +7,12 @@
|
||||
"commands": [
|
||||
"dotnet-format"
|
||||
]
|
||||
},
|
||||
"cake.tool": {
|
||||
"version": "2.2.0",
|
||||
"commands": [
|
||||
"dotnet-cake"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
renovate.json → .github/renovate.json
vendored
0
renovate.json → .github/renovate.json
vendored
73
.github/workflows/build.yml
vendored
73
.github/workflows/build.yml
vendored
@@ -59,6 +59,10 @@ jobs:
|
||||
name: Android
|
||||
runs-on: windows-2022
|
||||
needs: setup
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
variant: ['prod', 'qa']
|
||||
steps:
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
@@ -67,7 +71,7 @@ jobs:
|
||||
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
|
||||
|
||||
|
||||
- name: Work Around for broken Windows 2022 Runner Image
|
||||
run: |
|
||||
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
|
||||
@@ -87,7 +91,6 @@ jobs:
|
||||
Write-Host "components were not installed"
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
nuget help | grep Version
|
||||
@@ -98,7 +101,8 @@ jobs:
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Decrypt secrets
|
||||
env:
|
||||
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||
@@ -109,12 +113,17 @@ jobs:
|
||||
--output ./src/Android/app_play-keystore.jks ./.github/secrets/app_play-keystore.jks.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/app_upload-keystore.jks ./.github/secrets/app_upload-keystore.jks.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/google-services.json ./.github/secrets/google-services.json.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output $HOME/secrets/play_creds.json ./.github/secrets/play_creds.json.gpg
|
||||
shell: bash
|
||||
|
||||
- name: Decrypt secrets - Google Services
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
env:
|
||||
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
|
||||
run: |
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/Android/google-services.json ./.github/secrets/google-services.json.gpg
|
||||
shell: bash
|
||||
- name: Increment version
|
||||
run: |
|
||||
BUILD_NUMBER=$((3000 + $GITHUB_RUN_NUMBER))
|
||||
@@ -142,26 +151,35 @@ jobs:
|
||||
run: dotnet test test/Core.Test/Core.Test.csproj
|
||||
|
||||
- name: Build Play Store publisher
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
run: dotnet build ./store/google/Publisher/Publisher.csproj -p:Configuration=Release
|
||||
|
||||
- name: Build for Play Store
|
||||
- name: Setup Android build (${{ matrix.variant }})
|
||||
run: dotnet cake build.cake --target Android --variant ${{ matrix.variant }}
|
||||
|
||||
- name: Build Android
|
||||
run: |
|
||||
$configuration = "Release";
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Build $configuration Configuration"
|
||||
Write-Output "########################################"
|
||||
|
||||
msbuild "$($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj")" "/p:Configuration=$configuration"
|
||||
|
||||
shell: pwsh
|
||||
|
||||
- name: Sign for Play Store
|
||||
- name: Sign Android Build
|
||||
env:
|
||||
PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
|
||||
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
|
||||
run: |
|
||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||
|
||||
$packageName = "com.x8bit.bitwarden";
|
||||
|
||||
if ("${{ matrix.variant }}" -ne "prod")
|
||||
{
|
||||
$packageName = "com.x8bit.bitwarden.${{ matrix.variant }}";
|
||||
}
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Sign Google Play Bundle Release Configuration"
|
||||
Write-Output "########################################"
|
||||
@@ -175,9 +193,8 @@ jobs:
|
||||
Write-Output "##### Copy Google Play Bundle to project root"
|
||||
Write-Output "########################################"
|
||||
|
||||
$signedAabPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/com.x8bit.bitwarden-Signed.aab");
|
||||
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden.aab");
|
||||
|
||||
$signedAabPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/$($packageName)-Signed.aab");
|
||||
$signedAabDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).aab");
|
||||
Copy-Item $signedAabPath $signedAabDestPath
|
||||
|
||||
Write-Output "########################################"
|
||||
@@ -193,33 +210,41 @@ jobs:
|
||||
Write-Output "##### Copy Release APK to project root"
|
||||
Write-Output "########################################"
|
||||
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/com.x8bit.bitwarden-Signed.apk");
|
||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/com.x8bit.bitwarden.apk");
|
||||
$signedApkPath = $($env:GITHUB_WORKSPACE + "/src/Android/bin/Release/$($packageName)-Signed.apk");
|
||||
$signedApkDestPath = $($env:GITHUB_WORKSPACE + "/$($packageName).apk");
|
||||
|
||||
Copy-Item $signedApkPath $signedApkDestPath
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload Play Store .aab artifact
|
||||
- name: Upload Prod .aab artifact
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.aab
|
||||
path: ./com.x8bit.bitwarden.aab
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Play Store .apk artifact
|
||||
- name: Upload Prod .apk artifact
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.apk
|
||||
path: ./com.x8bit.bitwarden.apk
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload Other .apk artifact
|
||||
if: ${{ matrix.variant != 'prod' }}
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Deploy to Play Store
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
if: ${{ matrix.variant == 'prod' && (( github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc' ) }}
|
||||
run: |
|
||||
PUBLISHER_PATH="$GITHUB_WORKSPACE/store/google/Publisher/bin/Release/netcoreapp3.1/Publisher.dll"
|
||||
CREDS_PATH="$HOME/secrets/play_creds.json"
|
||||
|
||||
21
.github/workflows/crowdin-pull.yml
vendored
21
.github/workflows/crowdin-pull.yml
vendored
@@ -24,17 +24,10 @@ jobs:
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
env:
|
||||
KEYVAULT: bitwarden-prod-kv
|
||||
SECRETS: |
|
||||
crowdin-api-token
|
||||
run: |
|
||||
for i in ${SECRETS//,/ }
|
||||
do
|
||||
VALUE=$(az keyvault secret show --vault-name $KEYVAULT --name $i --query value --output tsv)
|
||||
echo "::add-mask::$VALUE"
|
||||
echo "::set-output name=$i::$VALUE"
|
||||
done
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
|
||||
- name: Download translations
|
||||
uses: crowdin/github-action@12143a68c213f3c6d9913c9e5023224f7231face
|
||||
@@ -47,10 +40,12 @@ jobs:
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
download_translations: true
|
||||
github_user_name: "github-actions"
|
||||
github_user_email: "<>"
|
||||
github_user_name: "bitwarden-devops-bot"
|
||||
github_user_email: "106330231+bitwarden-devops-bot@users.noreply.github.com"
|
||||
commit_message: "Autosync the updated translations"
|
||||
localization_branch_name: crowdin-auto-sync
|
||||
create_pull_request: true
|
||||
pull_request_title: "Autosync Crowdin Translations"
|
||||
pull_request_body: "Autosync the updated translations"
|
||||
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||
gpg_passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
|
||||
5
.github/workflows/release.yml
vendored
5
.github/workflows/release.yml
vendored
@@ -1,5 +1,6 @@
|
||||
---
|
||||
name: Release
|
||||
run-name: Release ${{ inputs.release_type }}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -72,7 +73,7 @@ jobs:
|
||||
workflow_conclusion: success
|
||||
branch: ${{ steps.branch.outputs.branch-name }}
|
||||
|
||||
- name: Download all artifacts
|
||||
- name: Dry Run - Download all artifacts
|
||||
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
|
||||
with:
|
||||
@@ -133,7 +134,7 @@ jobs:
|
||||
branch: ${{ needs.release.outputs.branch-name }}
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
|
||||
- name: Download F-Droid .apk artifact
|
||||
- name: Dry Run - Download F-Droid .apk artifact
|
||||
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
|
||||
uses: dawidd6/action-download-artifact@575b1e4167df67acf7e692af784566618b23c71e # v2.17.10
|
||||
with:
|
||||
|
||||
40
.github/workflows/version-auto-bump.yml
vendored
40
.github/workflows/version-auto-bump.yml
vendored
@@ -2,39 +2,38 @@
|
||||
name: Version Auto Bump
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
push:
|
||||
tags:
|
||||
- v**
|
||||
|
||||
jobs:
|
||||
|
||||
setup:
|
||||
name: "Setup"
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
version_number: ${{ steps.version.outputs.new-version }}
|
||||
steps:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Get version to bump
|
||||
- name: Calculate bumped version
|
||||
id: version
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.event.release.tag }}
|
||||
RELEASE_TAG: ${{ github.ref }}
|
||||
run: |
|
||||
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]\.)([0-9])/\1/')
|
||||
CURR_VER=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]\.)([0-9])/\2/')
|
||||
echo $CURR_VER
|
||||
|
||||
((CURR_VER++))
|
||||
NEW_VER=$CURR_MAJOR$CURR_VER
|
||||
|
||||
echo $NEW_VER
|
||||
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/')
|
||||
CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/')
|
||||
echo "Current Major: $CURR_MAJOR"
|
||||
echo "Current Patch: $CURR_PATCH"
|
||||
|
||||
NEW_PATCH=$((CURR_PATCH+1))
|
||||
NEW_VER=$CURR_MAJOR.$NEW_PATCH
|
||||
echo "New Version: $NEW_VER"
|
||||
echo "::set-output name=new-version::$NEW_VER"
|
||||
|
||||
trigger_version_bump:
|
||||
name: "Trigger version bump workflow"
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
needs:
|
||||
- setup
|
||||
steps:
|
||||
@@ -45,13 +44,10 @@ jobs:
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
env:
|
||||
KEYVAULT: bitwarden-prod-kv
|
||||
SECRET: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
run: |
|
||||
VALUE=$(az keyvault secret show --vault-name $KEYVAULT --name $SECRET --query value --output tsv)
|
||||
echo "::add-mask::$VALUE"
|
||||
echo "::set-output name=$SECRET::$VALUE"
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
|
||||
|
||||
- name: Call GitHub API to trigger workflow bump
|
||||
env:
|
||||
|
||||
24
.github/workflows/version-bump.yml
vendored
24
.github/workflows/version-bump.yml
vendored
@@ -16,6 +16,26 @@ jobs:
|
||||
- name: Checkout Branch
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
||||
|
||||
- name: Login to Azure - Prod Subscription
|
||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||
|
||||
- name: Import GPG key
|
||||
uses: crazy-max/ghaction-import-gpg@c8bb57c57e8df1be8c73ff3d59deab1dbc00e0d1
|
||||
with:
|
||||
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||
git_user_signingkey: true
|
||||
git_commit_gpgsign: true
|
||||
|
||||
- name: Create Version Branch
|
||||
run: |
|
||||
git switch -c version_bump_${{ github.event.inputs.version_number }}
|
||||
@@ -52,8 +72,8 @@ jobs:
|
||||
|
||||
- name: Setup git
|
||||
run: |
|
||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
|
||||
git config --local user.name "bitwarden-devops-bot"
|
||||
|
||||
- name: Check if version changed
|
||||
id: version-changed
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -208,4 +208,5 @@ FakesAssemblies/
|
||||
# Other
|
||||
project.lock.json
|
||||
.DS_Store
|
||||
src/App/Css
|
||||
src/App/Css
|
||||
tools
|
||||
|
||||
345
build.cake
Normal file
345
build.cake
Normal file
@@ -0,0 +1,345 @@
|
||||
#addin nuget:?package=Cake.FileHelpers&version=5.0.0
|
||||
#addin nuget:?package=Cake.AndroidAppManifest&version=1.1.2
|
||||
#addin nuget:?package=Cake.Plist&version=0.7.0
|
||||
#addin nuget:?package=Cake.Incubator&version=7.0.0
|
||||
#tool dotnet:?package=GitVersion.Tool&version=5.10.3
|
||||
using Path = System.IO.Path;
|
||||
|
||||
var debugScript = Argument<bool>("debugScript", false);
|
||||
var target = Argument("target", "Default");
|
||||
var configuration = Argument("configuration", "Release");
|
||||
var variant = Argument("variant", "dev");
|
||||
|
||||
abstract record VariantConfig(
|
||||
string AppName,
|
||||
string AndroidPackageName,
|
||||
string iOSBundleId,
|
||||
string ApsEnvironment
|
||||
);
|
||||
|
||||
const string BASE_BUNDLE_ID_DROID = "com.x8bit.bitwarden";
|
||||
const string BASE_BUNDLE_ID_IOS = "com.8bit.bitwarden";
|
||||
|
||||
record Dev(): VariantConfig("Bitwarden Dev", $"{BASE_BUNDLE_ID_DROID}.dev", $"{BASE_BUNDLE_ID_IOS}.dev", "development");
|
||||
record QA(): VariantConfig("Bitwarden QA", $"{BASE_BUNDLE_ID_DROID}.qa", $"{BASE_BUNDLE_ID_IOS}.qa", "development");
|
||||
record Beta(): VariantConfig("Bitwarden Beta", $"{BASE_BUNDLE_ID_DROID}.beta", $"{BASE_BUNDLE_ID_IOS}.beta", "production");
|
||||
record Prod(): VariantConfig("Bitwarden", $"{BASE_BUNDLE_ID_DROID}", $"{BASE_BUNDLE_ID_IOS}", "production");
|
||||
|
||||
VariantConfig GetVariant() => variant.ToLower() switch{
|
||||
"qa" => new QA(),
|
||||
"beta" => new Beta(),
|
||||
"prod" => new Prod(),
|
||||
_ => new Dev()
|
||||
};
|
||||
|
||||
GitVersion _gitVersion; //will be set by GetGitInfo task
|
||||
var _slnPath = Path.Combine(""); //base path used to access files. If build.cake file is moved, just update this
|
||||
string _androidPackageName = string.Empty; //will be set by UpdateAndroidManifest task
|
||||
string CreateFeatureBranch(string prevVersionName, GitVersion git) => $"{prevVersionName}-{git.BranchName.Replace("/","-")}";
|
||||
string GetVersionName(string prevVersionName, VariantConfig buildVariant, GitVersion git) => buildVariant is Prod? prevVersionName : CreateFeatureBranch(prevVersionName, git);
|
||||
int CreateBuildNumber(int previousNumber) => ++previousNumber;
|
||||
|
||||
Task("GetGitInfo")
|
||||
.Does(()=> {
|
||||
_gitVersion = GitVersion(new GitVersionSettings());
|
||||
|
||||
if(debugScript)
|
||||
{
|
||||
Information($"GitVersion Dump:\n{_gitVersion.Dump()}");
|
||||
}
|
||||
|
||||
Information("Git data Load successfully.");
|
||||
});
|
||||
|
||||
#region Android
|
||||
Task("UpdateAndroidAppIcon")
|
||||
.Does(()=>{
|
||||
//TODO we'll implement variant icons later
|
||||
//manifest.ApplicationIcon = "@mipmap/ic_launcher";
|
||||
Information($"Updated Androix App Icon with success");
|
||||
});
|
||||
|
||||
|
||||
Task("UpdateAndroidManifest")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.Does(()=>
|
||||
{
|
||||
var buildVariant = GetVariant();
|
||||
var manifestPath = Path.Combine(_slnPath, "src", "Android", "Properties", "AndroidManifest.xml");
|
||||
|
||||
// Cake.AndroidAppManifest doesn't currently enable us to access nested items so, quick (not ideal) fix:
|
||||
var manifestText = FileReadText(manifestPath);
|
||||
manifestText = manifestText.Replace("com.x8bit.bitwarden.", buildVariant.AndroidPackageName + ".");
|
||||
manifestText = manifestText.Replace("android:label=\"Bitwarden\"", $"android:label=\"{buildVariant.AppName}\"");
|
||||
FileWriteText(manifestPath, manifestText);
|
||||
|
||||
var manifest = DeserializeAppManifest(manifestPath);
|
||||
|
||||
var prevVersionCode = manifest.VersionCode;
|
||||
var prevVersionName = manifest.VersionName;
|
||||
_androidPackageName = manifest.PackageName;
|
||||
|
||||
//manifest.VersionCode = CreateBuildNumber(prevVersionCode);
|
||||
manifest.VersionName = GetVersionName(prevVersionName, buildVariant, _gitVersion);
|
||||
manifest.PackageName = buildVariant.AndroidPackageName;
|
||||
manifest.ApplicationLabel = buildVariant.AppName;
|
||||
|
||||
//Information($"AndroidManigest.xml VersionCode from {prevVersionCode} to {manifest.VersionCode}");
|
||||
Information($"AndroidManigest.xml VersionName from {prevVersionName} to {manifest.VersionName}");
|
||||
Information($"AndroidManigest.xml PackageName from {_androidPackageName} to {buildVariant.AndroidPackageName}");
|
||||
Information($"AndroidManigest.xml ApplicationLabel to {buildVariant.AppName}");
|
||||
|
||||
SerializeAppManifest(manifestPath, manifest);
|
||||
|
||||
Information("AndroidManifest updated with success!");
|
||||
});
|
||||
|
||||
void ReplaceInFile(string filePath, string oldtext, string newtext)
|
||||
{
|
||||
var fileText = FileReadText(filePath);
|
||||
|
||||
if(string.IsNullOrEmpty(fileText) || !fileText.Contains(oldtext))
|
||||
{
|
||||
throw new Exception($"Couldn't find {filePath} or it didn't contain: {oldtext}");
|
||||
}
|
||||
|
||||
fileText = fileText.Replace(oldtext, newtext);
|
||||
|
||||
FileWriteText(filePath, fileText);
|
||||
Information($"{filePath} modified successfully.");
|
||||
}
|
||||
|
||||
Task("UpdateAndroidCodeFiles")
|
||||
.IsDependentOn("UpdateAndroidManifest")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
|
||||
//We're not using _androidPackageName here because the codefile is currently slightly different string than the one in AndroidManifest.xml
|
||||
var keyName = "com.8bit.bitwarden";
|
||||
var fixedPackageName = buildVariant.AndroidPackageName.Replace("x8bit", "8bit");
|
||||
var filePath = Path.Combine(_slnPath, "src", "Android", "Services", "BiometricService.cs");
|
||||
ReplaceInFile(filePath, keyName, fixedPackageName);
|
||||
|
||||
var packageFileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "Android", "MainActivity.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "MainApplication.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Constants.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Accessibility", "AccessibilityService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillHelpers.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "ClearClipboardAlarmReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "EventUploadReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "PackageReplacedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Receivers", "RestrictionsChangedReceiver.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Services", "DeviceActionService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "AutofillTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "GeneratorTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "Tiles", "MyVaultTileService.cs"),
|
||||
Path.Combine(_slnPath, "src", "Android", "google-services.json"),
|
||||
Path.Combine(_slnPath, "store", "google", "Publisher", "Program.cs"),
|
||||
};
|
||||
|
||||
foreach(string path in packageFileList)
|
||||
{
|
||||
ReplaceInFile(path, "com.x8bit.bitwarden", buildVariant.AndroidPackageName);
|
||||
}
|
||||
|
||||
var labelFileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "Android", "Autofill", "AutofillService.cs"),
|
||||
};
|
||||
|
||||
foreach(string path in labelFileList)
|
||||
{
|
||||
ReplaceInFile(path, "Bitwarden\"", $"{buildVariant.AppName}\"");
|
||||
}
|
||||
});
|
||||
#endregion Android
|
||||
|
||||
#region iOS
|
||||
enum iOSProjectType
|
||||
{
|
||||
Null,
|
||||
MainApp,
|
||||
Autofill,
|
||||
Extension,
|
||||
ShareExtension
|
||||
}
|
||||
|
||||
string GetiOSBundleId(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
|
||||
{
|
||||
iOSProjectType.Autofill => $"{buildVariant.iOSBundleId}.autofill",
|
||||
iOSProjectType.Extension => $"{buildVariant.iOSBundleId}.find-login-action-extension",
|
||||
iOSProjectType.ShareExtension => $"{buildVariant.iOSBundleId}.share-extension",
|
||||
_ => buildVariant.iOSBundleId
|
||||
};
|
||||
|
||||
string GetiOSBundleName(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
|
||||
{
|
||||
iOSProjectType.Autofill => $"{buildVariant.AppName} Autofill",
|
||||
iOSProjectType.Extension => $"{buildVariant.AppName} Extension",
|
||||
iOSProjectType.ShareExtension => $"{buildVariant.AppName} Share Extension",
|
||||
_ => buildVariant.AppName
|
||||
};
|
||||
|
||||
private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, GitVersion git, iOSProjectType projectType = iOSProjectType.MainApp)
|
||||
{
|
||||
var plistFile = File(plistPath);
|
||||
dynamic plist = DeserializePlist(plistFile);
|
||||
|
||||
var prevVersionName = plist["CFBundleShortVersionString"];
|
||||
var prevVersionString = plist["CFBundleVersion"];
|
||||
var prevVersion = int.Parse(plist["CFBundleVersion"]);
|
||||
var prevBundleId = plist["CFBundleIdentifier"];
|
||||
var prevBundleName = plist["CFBundleName"];
|
||||
//var newVersion = CreateBuildNumber(prevVersion).ToString();
|
||||
var newVersionName = GetVersionName(prevVersionName, buildVariant, git);
|
||||
var newBundleId = GetiOSBundleId(buildVariant, projectType);
|
||||
var newBundleName = GetiOSBundleName(buildVariant, projectType);
|
||||
|
||||
plist["CFBundleName"] = newBundleName;
|
||||
plist["CFBundleDisplayName"] = newBundleName;
|
||||
//plist["CFBundleVersion"] = newVersion;
|
||||
plist["CFBundleShortVersionString"] = newVersionName;
|
||||
plist["CFBundleIdentifier"] = newBundleId;
|
||||
|
||||
if(projectType == iOSProjectType.MainApp)
|
||||
{
|
||||
plist["CFBundleURLTypes"][0]["CFBundleURLName"] = $"{buildVariant.iOSBundleId}.url";
|
||||
}
|
||||
|
||||
if(projectType == iOSProjectType.Extension)
|
||||
{
|
||||
var keyText = plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"];
|
||||
plist["NSExtension"]["NSExtensionAttributes"]["NSExtensionActivationRule"] = keyText.Replace("com.8bit.bitwarden", buildVariant.iOSBundleId);
|
||||
}
|
||||
|
||||
SerializePlist(plistFile, plist);
|
||||
|
||||
Information($"Changed app name from {prevBundleName} to {newBundleName}");
|
||||
//Information($"Changed Bundle Version from {prevVersion} to {newVersion}");
|
||||
Information($"Changed Bundle Short Version name from {prevVersionName} to {newVersionName}");
|
||||
Information($"Changed Bundle Identifier from {prevBundleId} to {newBundleId}");
|
||||
Information($"{plistPath} updated with success!");
|
||||
}
|
||||
|
||||
private void UpdateiOSEntitlementsPlist(string entitlementsPath, VariantConfig buildVariant)
|
||||
{
|
||||
var EntitlementlistFile = File(entitlementsPath);
|
||||
dynamic Entitlements = DeserializePlist(EntitlementlistFile);
|
||||
|
||||
Entitlements["aps-environment"] = buildVariant.ApsEnvironment;
|
||||
Entitlements["keychain-access-groups"] = new List<string>() { "$(AppIdentifierPrefix)" + buildVariant.iOSBundleId };
|
||||
Entitlements["com.apple.security.application-groups"] = new List<string>() { $"group.{buildVariant.iOSBundleId}" };;
|
||||
|
||||
Information($"Changed ApsEnvironment name to {buildVariant.ApsEnvironment}");
|
||||
Information($"Changed keychain-access-groups bundleID to {buildVariant.iOSBundleId}");
|
||||
|
||||
SerializePlist(EntitlementlistFile, Entitlements);
|
||||
|
||||
Information($"{entitlementsPath} updated with success!");
|
||||
}
|
||||
|
||||
Task("UpdateiOSIcon")
|
||||
.Does(()=>{
|
||||
//TODO we'll implement variant icons later
|
||||
Information($"Updating IOS App Icon");
|
||||
});
|
||||
|
||||
Task("UpdateiOSPlist")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.MainApp);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
});
|
||||
|
||||
Task("UpdateiOSAutofillPlist")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.IsDependentOn("UpdateiOSPlist")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Autofill", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Autofill);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
});
|
||||
|
||||
Task("UpdateiOSExtensionPlist")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.IsDependentOn("UpdateiOSPlist")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.Extension", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.Extension);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
});
|
||||
|
||||
Task("UpdateiOSShareExtensionPlist")
|
||||
.IsDependentOn("GetGitInfo")
|
||||
.IsDependentOn("UpdateiOSPlist")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var infoPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Info.plist");
|
||||
var entitlementsPath = Path.Combine(_slnPath, "src", "iOS.ShareExtension", "Entitlements.plist");
|
||||
UpdateiOSInfoPlist(infoPath, buildVariant, _gitVersion, iOSProjectType.ShareExtension);
|
||||
UpdateiOSEntitlementsPlist(entitlementsPath, buildVariant);
|
||||
});
|
||||
|
||||
Task("UpdateiOSCodeFiles")
|
||||
.IsDependentOn("UpdateiOSPlist")
|
||||
.Does(()=> {
|
||||
var buildVariant = GetVariant();
|
||||
var fileList = new string[] {
|
||||
Path.Combine(_slnPath, "src", "iOS.Core", "Utilities", "iOSCoreHelpers.cs"),
|
||||
Path.Combine(_slnPath, "src", "iOS.Core", "Constants.cs"),
|
||||
Path.Combine(".github", "resources", "export-options-ad-hoc.plist"),
|
||||
Path.Combine(".github", "resources", "export-options-app-store.plist"),
|
||||
};
|
||||
|
||||
foreach(string path in fileList)
|
||||
{
|
||||
ReplaceInFile(path, "com.8bit.bitwarden", buildVariant.iOSBundleId);
|
||||
}
|
||||
});
|
||||
#endregion iOS
|
||||
|
||||
#region Main Tasks
|
||||
Task("Android")
|
||||
//.IsDependentOn("UpdateAndroidAppIcon")
|
||||
.IsDependentOn("UpdateAndroidManifest")
|
||||
.IsDependentOn("UpdateAndroidCodeFiles")
|
||||
.Does(()=>
|
||||
{
|
||||
Information("Android app updated");
|
||||
});
|
||||
|
||||
Task("iOS")
|
||||
//.IsDependentOn("UpdateiOSIcon")
|
||||
.IsDependentOn("UpdateiOSPlist")
|
||||
.IsDependentOn("UpdateiOSAutofillPlist")
|
||||
.IsDependentOn("UpdateiOSExtensionPlist")
|
||||
.IsDependentOn("UpdateiOSShareExtensionPlist")
|
||||
.IsDependentOn("UpdateiOSCodeFiles")
|
||||
.Does(()=>
|
||||
{
|
||||
Information("iOS app updated");
|
||||
});
|
||||
|
||||
Task("Default")
|
||||
.Does(() => {
|
||||
var usage = @"Missing target.
|
||||
|
||||
Usage:
|
||||
dotnet cake build.cake --target (Android | iOS) --variant (dev | qa | beta | prod)
|
||||
|
||||
Options:
|
||||
--debugScript=<bool> Script debug mode.
|
||||
";
|
||||
Information(usage);
|
||||
});
|
||||
#endregion Main Tasks
|
||||
|
||||
RunTarget(target);
|
||||
@@ -367,7 +367,7 @@ namespace Bit.Droid.Accessibility
|
||||
|
||||
public static string GetUri(AccessibilityNodeInfo root)
|
||||
{
|
||||
var uri = string.Concat(Constants.AndroidAppProtocol, root.PackageName);
|
||||
var uri = string.Concat(Core.Constants.AndroidAppProtocol, root.PackageName);
|
||||
if (SupportedBrowsers.ContainsKey(root.PackageName))
|
||||
{
|
||||
var browser = SupportedBrowsers[root.PackageName];
|
||||
|
||||
@@ -152,6 +152,11 @@
|
||||
<Compile Include="Utilities\IntentExtensions.cs" />
|
||||
<Compile Include="Renderers\CustomPageRenderer.cs" />
|
||||
<Compile Include="Effects\NoEmojiKeyboardEffect.cs" />
|
||||
<Compile Include="Receivers\NotificationDismissReceiver.cs" />
|
||||
<Compile Include="Services\FileService.cs" />
|
||||
<Compile Include="Services\AutofillHandler.cs" />
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Effects\RemoveFontPaddingEffect.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidAsset Include="Assets\bwi-font.ttf" />
|
||||
@@ -217,6 +222,10 @@
|
||||
<AndroidResource Include="Resources\drawable-v26\splash_screen_round.xml" />
|
||||
<AndroidResource Include="Resources\drawable\logo_rounded.xml" />
|
||||
<AndroidResource Include="Resources\drawable-night-v26\splash_screen_round.xml" />
|
||||
<AndroidResource Include="Resources\drawable\ic_notification.xml">
|
||||
<SubType></SubType>
|
||||
<Generator></Generator>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\drawable\splash_screen.xml" />
|
||||
|
||||
Binary file not shown.
@@ -134,7 +134,7 @@ namespace Bit.Droid.Autofill
|
||||
{
|
||||
case CipherType.Login:
|
||||
intent.PutExtra("autofillFrameworkName", parser.Uri
|
||||
.Replace(Constants.AndroidAppProtocol, string.Empty)
|
||||
.Replace(Core.Constants.AndroidAppProtocol, string.Empty)
|
||||
.Replace("https://", string.Empty)
|
||||
.Replace("http://", string.Empty));
|
||||
intent.PutExtra("autofillFrameworkUri", parser.Uri);
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
else
|
||||
{
|
||||
_uri = string.Concat(Constants.AndroidAppProtocol, PackageName);
|
||||
_uri = string.Concat(Core.Constants.AndroidAppProtocol, PackageName);
|
||||
}
|
||||
return _uri;
|
||||
}
|
||||
|
||||
7
src/Android/Constants.cs
Normal file
7
src/Android/Constants.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Bit.Droid
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const string PACKAGE_NAME = "com.x8bit.bitwarden";
|
||||
}
|
||||
}
|
||||
23
src/Android/Effects/RemoveFontPaddingEffect.cs
Normal file
23
src/Android/Effects/RemoveFontPaddingEffect.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Android.Widget;
|
||||
using Bit.Droid.Effects;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.Android;
|
||||
|
||||
[assembly: ExportEffect(typeof(RemoveFontPaddingEffect), nameof(RemoveFontPaddingEffect))]
|
||||
namespace Bit.Droid.Effects
|
||||
{
|
||||
public class RemoveFontPaddingEffect : PlatformEffect
|
||||
{
|
||||
protected override void OnAttached()
|
||||
{
|
||||
if (Control is TextView textView)
|
||||
{
|
||||
textView.SetIncludeFontPadding(false);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDetached()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
@@ -19,6 +20,8 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Droid.Receivers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Xamarin.Essentials;
|
||||
using ZXing.Net.Mobile.Android;
|
||||
using FileProvider = AndroidX.Core.Content.FileProvider;
|
||||
@@ -33,11 +36,13 @@ namespace Bit.Droid
|
||||
public class MainActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
private IDeviceActionService _deviceActionService;
|
||||
private IFileService _fileService;
|
||||
private IMessagingService _messagingService;
|
||||
private IBroadcasterService _broadcasterService;
|
||||
private IStateService _stateService;
|
||||
private IAppIdService _appIdService;
|
||||
private IEventService _eventService;
|
||||
private IPushNotificationListenerService _pushNotificationListenerService;
|
||||
private ILogger _logger;
|
||||
private PendingIntent _eventUploadPendingIntent;
|
||||
private AppOptions _appOptions;
|
||||
@@ -55,11 +60,13 @@ namespace Bit.Droid
|
||||
StrictMode.SetThreadPolicy(policy);
|
||||
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_appIdService = ServiceContainer.Resolve<IAppIdService>("appIdService");
|
||||
_eventService = ServiceContainer.Resolve<IEventService>("eventService");
|
||||
_pushNotificationListenerService = ServiceContainer.Resolve<IPushNotificationListenerService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
@@ -86,6 +93,7 @@ namespace Bit.Droid
|
||||
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
|
||||
Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
||||
_appOptions = GetOptions();
|
||||
CreateNotificationChannel();
|
||||
LoadApplication(new App.App(_appOptions));
|
||||
DisableAndroidFontScale();
|
||||
|
||||
@@ -143,6 +151,15 @@ namespace Bit.Droid
|
||||
AndroidHelpers.SetPreconfiguredRestrictionSettingsAsync(this)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
|
||||
if (Intent?.GetStringExtra(Core.Constants.NotificationData) is string notificationDataJson)
|
||||
{
|
||||
var notificationType = JToken.Parse(notificationDataJson).SelectToken(Core.Constants.NotificationDataType);
|
||||
if (notificationType.ToString() == PasswordlessNotificationData.TYPE)
|
||||
{
|
||||
_pushNotificationListenerService.OnNotificationTapped(JsonConvert.DeserializeObject<PasswordlessNotificationData>(notificationDataJson)).FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnNewIntent(Intent intent)
|
||||
@@ -196,13 +213,13 @@ namespace Bit.Droid
|
||||
public async override void OnRequestPermissionsResult(int requestCode, string[] permissions,
|
||||
[GeneratedEnum] Permission[] grantResults)
|
||||
{
|
||||
if (requestCode == Constants.SelectFilePermissionRequestCode)
|
||||
if (requestCode == Core.Constants.SelectFilePermissionRequestCode)
|
||||
{
|
||||
if (grantResults.Any(r => r != Permission.Granted))
|
||||
{
|
||||
_messagingService.Send("selectFileCameraPermissionDenied");
|
||||
}
|
||||
await _deviceActionService.SelectFileAsync();
|
||||
await _fileService.SelectFileAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -215,7 +232,7 @@ namespace Bit.Droid
|
||||
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
|
||||
{
|
||||
if (resultCode == Result.Ok &&
|
||||
(requestCode == Constants.SelectFileRequestCode || requestCode == Constants.SaveFileRequestCode))
|
||||
(requestCode == Core.Constants.SelectFileRequestCode || requestCode == Core.Constants.SaveFileRequestCode))
|
||||
{
|
||||
Android.Net.Uri uri = null;
|
||||
string fileName = null;
|
||||
@@ -237,7 +254,7 @@ namespace Bit.Droid
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestCode == Constants.SaveFileRequestCode)
|
||||
if (requestCode == Core.Constants.SaveFileRequestCode)
|
||||
{
|
||||
_messagingService.Send("selectSaveFileResult",
|
||||
new Tuple<string, string>(uri.ToString(), fileName));
|
||||
@@ -407,6 +424,25 @@ namespace Bit.Droid
|
||||
await _eventService.UploadEventsAsync();
|
||||
}
|
||||
|
||||
private void CreateNotificationChannel()
|
||||
{
|
||||
#if !FDROID
|
||||
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
||||
{
|
||||
// Notification channels are new in API 26 (and not a part of the
|
||||
// support library). There is no need to create a notification
|
||||
// channel on older versions of Android.
|
||||
return;
|
||||
}
|
||||
|
||||
var channel = new NotificationChannel(Core.Constants.AndroidNotificationChannelId, AppResources.AllNotifications, NotificationImportance.Default);
|
||||
if(GetSystemService(NotificationService) is NotificationManager notificationManager)
|
||||
{
|
||||
notificationManager.CreateNotificationChannel(channel);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private void DisableAndroidFontScale()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -46,8 +46,8 @@ namespace Bit.Droid
|
||||
{
|
||||
RegisterLocalServices();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Constants.ClearCiphersCacheKey,
|
||||
Constants.AndroidAllClearCipherCacheKeys);
|
||||
ServiceContainer.Init(deviceActionService.DeviceUserAgent, Core.Constants.ClearCiphersCacheKey,
|
||||
Core.Constants.AndroidAllClearCipherCacheKeys);
|
||||
InitializeAppSetup();
|
||||
|
||||
// TODO: Update when https://github.com/bitwarden/mobile/pull/1662 gets merged
|
||||
@@ -72,8 +72,9 @@ namespace Bit.Droid
|
||||
ServiceContainer.Resolve<IStateService>("stateService"),
|
||||
ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService"),
|
||||
ServiceContainer.Resolve<IAuthService>("authService"),
|
||||
ServiceContainer.Resolve<ILogger>("logger"));
|
||||
ServiceContainer.Register<IAccountsManager>("accountsManager", accountsManager);
|
||||
ServiceContainer.Resolve<ILogger>("logger"),
|
||||
ServiceContainer.Resolve<IMessagingService>("messagingService"));
|
||||
ServiceContainer.Register<IAccountsManager>("accountsManager", accountsManager);
|
||||
}
|
||||
#if !FDROID
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.Kitkat)
|
||||
@@ -138,8 +139,9 @@ namespace Bit.Droid
|
||||
var stateMigrationService =
|
||||
new StateMigrationService(liteDbStorage, preferencesStorage, secureStorageService);
|
||||
var clipboardService = new ClipboardService(stateService);
|
||||
var deviceActionService = new DeviceActionService(clipboardService, stateService, messagingService,
|
||||
broadcasterService, () => ServiceContainer.Resolve<IEventService>("eventService"));
|
||||
var deviceActionService = new DeviceActionService(stateService, messagingService);
|
||||
var fileService = new FileService(stateService, broadcasterService);
|
||||
var autofillHandler = new AutofillHandler(stateService, messagingService, clipboardService, new LazyResolve<IEventService>());
|
||||
var platformUtilsService = new MobilePlatformUtilsService(deviceActionService, clipboardService,
|
||||
messagingService, broadcasterService);
|
||||
var biometricService = new BiometricService();
|
||||
@@ -158,6 +160,8 @@ namespace Bit.Droid
|
||||
ServiceContainer.Register<IStateMigrationService>("stateMigrationService", stateMigrationService);
|
||||
ServiceContainer.Register<IClipboardService>("clipboardService", clipboardService);
|
||||
ServiceContainer.Register<IDeviceActionService>("deviceActionService", deviceActionService);
|
||||
ServiceContainer.Register<IFileService>(fileService);
|
||||
ServiceContainer.Register<IAutofillHandler>(autofillHandler);
|
||||
ServiceContainer.Register<IPlatformUtilsService>("platformUtilsService", platformUtilsService);
|
||||
ServiceContainer.Register<IBiometricService>("biometricService", biometricService);
|
||||
ServiceContainer.Register<ICryptoFunctionService>("cryptoFunctionService", cryptoFunctionService);
|
||||
|
||||
@@ -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="2022.9.2" 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="2022.10.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#if !FDROID
|
||||
using System;
|
||||
using Android.App;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Firebase.Messaging;
|
||||
using Newtonsoft.Json;
|
||||
@@ -16,34 +18,41 @@ namespace Bit.Droid.Push
|
||||
{
|
||||
public async override void OnNewToken(string token)
|
||||
{
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>("pushNotificationService");
|
||||
try {
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>("pushNotificationService");
|
||||
|
||||
await stateService.SetPushRegisteredTokenAsync(token);
|
||||
await pushNotificationService.RegisterAsync();
|
||||
await stateService.SetPushRegisteredTokenAsync(token);
|
||||
await pushNotificationService.RegisterAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Instance.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public async override void OnMessageReceived(RemoteMessage message)
|
||||
{
|
||||
if (message?.Data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
|
||||
if (data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (message?.Data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var data = message.Data.ContainsKey("data") ? message.Data["data"] : null;
|
||||
if (data == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = JObject.Parse(data);
|
||||
var listener = ServiceContainer.Resolve<IPushNotificationListenerService>(
|
||||
"pushNotificationListenerService");
|
||||
await listener.OnMessageAsync(obj, Device.Android);
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(ex.ToString());
|
||||
Logger.Instance.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
41
src/Android/Receivers/NotificationDismissReceiver.cs
Normal file
41
src/Android/Receivers/NotificationDismissReceiver.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using Android.Content;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Services;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using CoreConstants = Bit.Core.Constants;
|
||||
|
||||
namespace Bit.Droid.Receivers
|
||||
{
|
||||
[BroadcastReceiver(Name = Constants.PACKAGE_NAME + "." + nameof(NotificationDismissReceiver), Exported = false)]
|
||||
public class NotificationDismissReceiver : BroadcastReceiver
|
||||
{
|
||||
private readonly LazyResolve<IPushNotificationListenerService> _pushNotificationListenerService = new LazyResolve<IPushNotificationListenerService>();
|
||||
private readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>();
|
||||
|
||||
public override void OnReceive(Context context, Intent intent)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (intent?.GetStringExtra(CoreConstants.NotificationData) is string notificationDataJson)
|
||||
{
|
||||
var notificationType = JToken.Parse(notificationDataJson).SelectToken(CoreConstants.NotificationDataType);
|
||||
if (notificationType.ToString() == PasswordlessNotificationData.TYPE)
|
||||
{
|
||||
_pushNotificationListenerService.Value.OnNotificationDismissed(JsonConvert.DeserializeObject<PasswordlessNotificationData>(notificationDataJson)).FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_logger.Value.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
src/Android/Resources/drawable/ic_notification.xml
Normal file
4
src/Android/Resources/drawable/ic_notification.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<vector android:height="24dp" android:viewportHeight="420"
|
||||
android:viewportWidth="420" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FFFFFF" android:pathData="M350.43,40.516C347.563,37.65 344.153,36.178 340.281,36.178L79.487,36.178C75.538,36.178 72.206,37.65 69.338,40.516C66.472,43.384 65,46.716 65,50.665L65,224.527C65,237.466 67.557,250.405 72.593,263.112C77.629,275.895 83.904,287.207 91.42,297.046C98.857,306.964 107.768,316.571 118.149,325.869C128.455,335.242 138.063,342.99 146.817,349.19C155.573,355.387 164.715,361.198 174.243,366.699C183.773,372.2 190.514,375.919 194.543,377.933C198.572,379.871 201.749,381.421 204.151,382.426C205.932,383.357 207.948,383.821 210.04,383.821C212.131,383.821 214.145,383.357 215.929,382.426C218.329,381.344 221.584,379.871 225.534,377.933C229.563,375.997 236.304,372.2 245.832,366.699C255.365,361.198 264.506,355.311 273.262,349.19C282.017,342.99 291.545,335.242 301.928,325.869C312.232,316.493 321.142,306.886 328.657,297.046C336.096,287.129 342.372,275.819 347.407,263.112C352.444,250.328 355,237.466 355,224.527L355,50.665C354.768,46.716 353.296,43.384 350.43,40.516ZM316.804,226.154C316.804,289.067 209.883,343.302 209.883,343.302L209.883,73.368L316.804,73.368C316.804,73.368 316.804,163.242 316.804,226.154Z"/>
|
||||
</vector>
|
||||
@@ -6,4 +6,5 @@
|
||||
android:accessibilityFeedbackType="feedbackGeneric"
|
||||
android:accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
|
||||
android:notificationTimeout="100"
|
||||
android:canRetrieveWindowContent="true"/>
|
||||
android:canRetrieveWindowContent="true"
|
||||
android:isAccessibilityTool="false"/>
|
||||
@@ -1,10 +1,21 @@
|
||||
#if !FDROID
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using AndroidX.Core.App;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Droid.Receivers;
|
||||
using Bit.Droid.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
using Xamarin.Forms;
|
||||
using static Xamarin.Essentials.Platform;
|
||||
using Intent = Android.Content.Intent;
|
||||
|
||||
namespace Bit.Droid.Services
|
||||
{
|
||||
@@ -23,6 +34,11 @@ namespace Bit.Droid.Services
|
||||
|
||||
public bool IsRegisteredForPush => NotificationManagerCompat.From(Android.App.Application.Context)?.AreNotificationsEnabled() ?? false;
|
||||
|
||||
public Task<bool> AreNotificationsSettingsEnabledAsync()
|
||||
{
|
||||
return Task.FromResult(IsRegisteredForPush);
|
||||
}
|
||||
|
||||
public async Task<string> GetTokenAsync()
|
||||
{
|
||||
return await _stateService.GetPushCurrentTokenAsync();
|
||||
@@ -47,6 +63,50 @@ namespace Bit.Droid.Services
|
||||
// Do we ever need to unregister?
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public void DismissLocalNotification(string notificationId)
|
||||
{
|
||||
if (int.TryParse(notificationId, out int intNotificationId))
|
||||
{
|
||||
var notificationManager = NotificationManagerCompat.From(Android.App.Application.Context);
|
||||
notificationManager.Cancel(intNotificationId);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendLocalNotification(string title, string message, BaseNotificationData data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(data.Id))
|
||||
{
|
||||
throw new ArgumentNullException("notificationId cannot be null or empty.");
|
||||
}
|
||||
|
||||
var context = Android.App.Application.Context;
|
||||
var intent = new Intent(context, typeof(MainActivity));
|
||||
intent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
||||
var pendingIntentFlags = AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, true);
|
||||
var pendingIntent = PendingIntent.GetActivity(context, 20220801, intent, pendingIntentFlags);
|
||||
|
||||
var deleteIntent = new Intent(context, typeof(NotificationDismissReceiver));
|
||||
deleteIntent.PutExtra(Bit.Core.Constants.NotificationData, JsonConvert.SerializeObject(data));
|
||||
var deletePendingIntent = PendingIntent.GetBroadcast(context, 20220802, deleteIntent, pendingIntentFlags);
|
||||
|
||||
var builder = new NotificationCompat.Builder(context, Bit.Core.Constants.AndroidNotificationChannelId)
|
||||
.SetContentIntent(pendingIntent)
|
||||
.SetContentTitle(title)
|
||||
.SetContentText(message)
|
||||
.SetSmallIcon(Resource.Drawable.ic_notification)
|
||||
.SetColor((int)Android.Graphics.Color.White)
|
||||
.SetDeleteIntent(deletePendingIntent)
|
||||
.SetAutoCancel(true);
|
||||
|
||||
if (data is PasswordlessNotificationData passwordlessNotificationData && passwordlessNotificationData.TimeoutInMinutes > 0)
|
||||
{
|
||||
builder.SetTimeoutAfter(passwordlessNotificationData.TimeoutInMinutes * 60000);
|
||||
}
|
||||
|
||||
var notificationManager = NotificationManagerCompat.From(context);
|
||||
notificationManager.Notify(int.Parse(data.Id), builder.Build());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
210
src/Android/Services/AutofillHandler.cs
Normal file
210
src/Android/Services/AutofillHandler.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.App.Assist;
|
||||
using Android.Content;
|
||||
using Android.OS;
|
||||
using Android.Provider;
|
||||
using Android.Views.Autofill;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Droid.Autofill;
|
||||
using Plugin.CurrentActivity;
|
||||
|
||||
namespace Bit.Droid.Services
|
||||
{
|
||||
public class AutofillHandler : IAutofillHandler
|
||||
{
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly LazyResolve<IEventService> _eventService;
|
||||
|
||||
public AutofillHandler(IStateService stateService,
|
||||
IMessagingService messagingService,
|
||||
IClipboardService clipboardService,
|
||||
LazyResolve<IEventService> eventService)
|
||||
{
|
||||
_stateService = stateService;
|
||||
_messagingService = messagingService;
|
||||
_clipboardService = clipboardService;
|
||||
_eventService = eventService;
|
||||
}
|
||||
|
||||
public bool AutofillServiceEnabled()
|
||||
{
|
||||
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var afm = (AutofillManager)activity.GetSystemService(
|
||||
Java.Lang.Class.FromType(typeof(AutofillManager)));
|
||||
return afm.IsEnabled && afm.HasEnabledAutofillServices;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SupportsAutofillService()
|
||||
{
|
||||
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var type = Java.Lang.Class.FromType(typeof(AutofillManager));
|
||||
var manager = activity.GetSystemService(type) as AutofillManager;
|
||||
return manager.IsAutofillSupported;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Autofill(CipherView cipher)
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
if (activity == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (activity.Intent?.GetBooleanExtra("autofillFramework", false) ?? false)
|
||||
{
|
||||
if (cipher == null)
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
return;
|
||||
}
|
||||
var structure = activity.Intent.GetParcelableExtra(
|
||||
AutofillManager.ExtraAssistStructure) as AssistStructure;
|
||||
if (structure == null)
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
return;
|
||||
}
|
||||
var parser = new Parser(structure, activity.ApplicationContext);
|
||||
parser.Parse();
|
||||
if ((!parser.FieldCollection?.Fields?.Any() ?? true) || string.IsNullOrWhiteSpace(parser.Uri))
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
return;
|
||||
}
|
||||
var task = CopyTotpAsync(cipher);
|
||||
var dataset = AutofillHelpers.BuildDataset(activity, parser.FieldCollection, new FilledItem(cipher));
|
||||
var replyIntent = new Intent();
|
||||
replyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, dataset);
|
||||
activity.SetResult(Result.Ok, replyIntent);
|
||||
activity.Finish();
|
||||
var eventTask = _eventService.Value.CollectAsync(EventType.Cipher_ClientAutofilled, cipher.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new Intent();
|
||||
if (cipher?.Login == null)
|
||||
{
|
||||
data.PutExtra("canceled", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = CopyTotpAsync(cipher);
|
||||
data.PutExtra("uri", cipher.Login.Uri);
|
||||
data.PutExtra("username", cipher.Login.Username);
|
||||
data.PutExtra("password", cipher.Login.Password);
|
||||
}
|
||||
if (activity.Parent == null)
|
||||
{
|
||||
activity.SetResult(Result.Ok, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
activity.Parent.SetResult(Result.Ok, data);
|
||||
}
|
||||
activity.Finish();
|
||||
_messagingService.Send("finishMainActivity");
|
||||
if (cipher != null)
|
||||
{
|
||||
var eventTask = _eventService.Value.CollectAsync(EventType.Cipher_ClientAutofilled, cipher.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseAutofill()
|
||||
{
|
||||
Autofill(null);
|
||||
}
|
||||
|
||||
public bool AutofillAccessibilityServiceRunning()
|
||||
{
|
||||
var enabledServices = Settings.Secure.GetString(Application.Context.ContentResolver,
|
||||
Settings.Secure.EnabledAccessibilityServices);
|
||||
return Application.Context.PackageName != null &&
|
||||
(enabledServices?.Contains(Application.Context.PackageName) ?? false);
|
||||
}
|
||||
|
||||
public bool AutofillAccessibilityOverlayPermitted()
|
||||
{
|
||||
return Accessibility.AccessibilityHelpers.OverlayPermitted();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void DisableAutofillService()
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var type = Java.Lang.Class.FromType(typeof(AutofillManager));
|
||||
var manager = activity.GetSystemService(type) as AutofillManager;
|
||||
manager.DisableAutofillServices();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public bool AutofillServicesEnabled()
|
||||
{
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
|
||||
{
|
||||
// Android 5-6: Both accessibility & overlay are required or nothing happens
|
||||
return AutofillAccessibilityServiceRunning() && AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
if (Build.VERSION.SdkInt == BuildVersionCodes.N)
|
||||
{
|
||||
// Android 7: Only accessibility is required (overlay is optional when using quick-action tile)
|
||||
return AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
// Android 8+: Either autofill or accessibility is required
|
||||
return AutofillServiceEnabled() || AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
|
||||
private async Task CopyTotpAsync(CipherView cipher)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(cipher?.Login?.Totp))
|
||||
{
|
||||
var autoCopyDisabled = await _stateService.GetDisableAutoTotpCopyAsync();
|
||||
var canAccessPremium = await _stateService.CanAccessPremiumAsync();
|
||||
if ((canAccessPremium || cipher.OrganizationUseTotp) && !autoCopyDisabled.GetValueOrDefault())
|
||||
{
|
||||
var totpService = ServiceContainer.Resolve<ITotpService>("totpService");
|
||||
var totp = await totpService.GetCodeAsync(cipher.Login.Totp);
|
||||
if (totp != null)
|
||||
{
|
||||
await _clipboardService.CopyTextAsync(totp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.App.Assist;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.Nfc;
|
||||
@@ -14,20 +9,13 @@ using Android.Provider;
|
||||
using Android.Text;
|
||||
using Android.Text.Method;
|
||||
using Android.Views;
|
||||
using Android.Views.Autofill;
|
||||
using Android.Views.InputMethods;
|
||||
using Android.Webkit;
|
||||
using Android.Widget;
|
||||
using AndroidX.Core.App;
|
||||
using AndroidX.Core.Content;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Droid.Autofill;
|
||||
using Bit.Droid.Utilities;
|
||||
using Plugin.CurrentActivity;
|
||||
|
||||
@@ -35,38 +23,20 @@ namespace Bit.Droid.Services
|
||||
{
|
||||
public class DeviceActionService : IDeviceActionService
|
||||
{
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
private readonly Func<IEventService> _eventServiceFunc;
|
||||
private AlertDialog _progressDialog;
|
||||
object _progressDialogLock = new object();
|
||||
|
||||
private bool _cameraPermissionsDenied;
|
||||
private Toast _toast;
|
||||
private string _userAgent;
|
||||
|
||||
public DeviceActionService(
|
||||
IClipboardService clipboardService,
|
||||
IStateService stateService,
|
||||
IMessagingService messagingService,
|
||||
IBroadcasterService broadcasterService,
|
||||
Func<IEventService> eventServiceFunc)
|
||||
IMessagingService messagingService)
|
||||
{
|
||||
_clipboardService = clipboardService;
|
||||
_stateService = stateService;
|
||||
_messagingService = messagingService;
|
||||
_broadcasterService = broadcasterService;
|
||||
_eventServiceFunc = eventServiceFunc;
|
||||
|
||||
_broadcasterService.Subscribe(nameof(DeviceActionService), (message) =>
|
||||
{
|
||||
if (message.Command == "selectFileCameraPermissionDenied")
|
||||
{
|
||||
_cameraPermissionsDenied = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public string DeviceUserAgent
|
||||
@@ -212,184 +182,6 @@ namespace Bit.Droid.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OpenFile(byte[] fileData, string id, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var intent = BuildOpenFileIntent(fileData, fileName);
|
||||
if (intent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
activity.StartActivity(intent);
|
||||
return true;
|
||||
}
|
||||
catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanOpenFile(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var intent = BuildOpenFileIntent(new byte[0], string.Concat("opentest_", fileName));
|
||||
if (intent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var activities = activity.PackageManager.QueryIntentActivities(intent,
|
||||
PackageInfoFlags.MatchDefaultOnly);
|
||||
return (activities?.Count ?? 0) > 0;
|
||||
}
|
||||
catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
private Intent BuildOpenFileIntent(byte[] fileData, string fileName)
|
||||
{
|
||||
var extension = MimeTypeMap.GetFileExtensionFromUrl(fileName.Replace(' ', '_').ToLower());
|
||||
if (extension == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
|
||||
if (mimeType == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var cachePath = activity.CacheDir;
|
||||
var filePath = Path.Combine(cachePath.Path, fileName);
|
||||
File.WriteAllBytes(filePath, fileData);
|
||||
var file = new Java.IO.File(cachePath, fileName);
|
||||
if (!file.IsFile)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var intent = new Intent(Intent.ActionView);
|
||||
var uri = FileProvider.GetUriForFile(activity.ApplicationContext,
|
||||
"com.x8bit.bitwarden.fileprovider", file);
|
||||
intent.SetDataAndType(uri, mimeType);
|
||||
intent.SetFlags(ActivityFlags.GrantReadUriPermission);
|
||||
return intent;
|
||||
}
|
||||
catch { }
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool SaveFile(byte[] fileData, string id, string fileName, string contentUri)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
|
||||
if (contentUri != null)
|
||||
{
|
||||
var uri = Android.Net.Uri.Parse(contentUri);
|
||||
var stream = activity.ContentResolver.OpenOutputStream(uri);
|
||||
// Using java bufferedOutputStream due to this issue:
|
||||
// https://github.com/xamarin/xamarin-android/issues/3498
|
||||
var javaStream = new Java.IO.BufferedOutputStream(stream);
|
||||
javaStream.Write(fileData);
|
||||
javaStream.Flush();
|
||||
javaStream.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prompt for location to save file
|
||||
var extension = MimeTypeMap.GetFileExtensionFromUrl(fileName.Replace(' ', '_').ToLower());
|
||||
if (extension == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
|
||||
if (mimeType == null)
|
||||
{
|
||||
// Unable to identify so fall back to generic "any" type
|
||||
mimeType = "*/*";
|
||||
}
|
||||
|
||||
var intent = new Intent(Intent.ActionCreateDocument);
|
||||
intent.SetType(mimeType);
|
||||
intent.AddCategory(Intent.CategoryOpenable);
|
||||
intent.PutExtra(Intent.ExtraTitle, fileName);
|
||||
|
||||
activity.StartActivityForResult(intent, Constants.SaveFileRequestCode);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", ex.GetType(), ex.StackTrace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task ClearCacheAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeleteDir(CrossCurrentActivity.Current.Activity.CacheDir);
|
||||
await _stateService.SetLastFileCacheClearAsync(DateTime.UtcNow);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
public Task SelectFileAsync()
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var hasStorageWritePermission = !_cameraPermissionsDenied &&
|
||||
HasPermission(Manifest.Permission.WriteExternalStorage);
|
||||
var additionalIntents = new List<IParcelable>();
|
||||
if (activity.PackageManager.HasSystemFeature(PackageManager.FeatureCamera))
|
||||
{
|
||||
var hasCameraPermission = !_cameraPermissionsDenied && HasPermission(Manifest.Permission.Camera);
|
||||
if (!_cameraPermissionsDenied && !hasStorageWritePermission)
|
||||
{
|
||||
AskPermission(Manifest.Permission.WriteExternalStorage);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
if (!_cameraPermissionsDenied && !hasCameraPermission)
|
||||
{
|
||||
AskPermission(Manifest.Permission.Camera);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
if (!_cameraPermissionsDenied && hasCameraPermission && hasStorageWritePermission)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = new Java.IO.File(activity.FilesDir, "temp_camera_photo.jpg");
|
||||
if (!file.Exists())
|
||||
{
|
||||
file.ParentFile.Mkdirs();
|
||||
file.CreateNewFile();
|
||||
}
|
||||
var outputFileUri = FileProvider.GetUriForFile(activity,
|
||||
"com.x8bit.bitwarden.fileprovider", file);
|
||||
additionalIntents.AddRange(GetCameraIntents(outputFileUri));
|
||||
}
|
||||
catch (Java.IO.IOException) { }
|
||||
}
|
||||
}
|
||||
|
||||
var docIntent = new Intent(Intent.ActionOpenDocument);
|
||||
docIntent.AddCategory(Intent.CategoryOpenable);
|
||||
docIntent.SetType("*/*");
|
||||
var chooserIntent = Intent.CreateChooser(docIntent, AppResources.FileSource);
|
||||
if (additionalIntents.Count > 0)
|
||||
{
|
||||
chooserIntent.PutExtra(Intent.ExtraInitialIntents, additionalIntents.ToArray());
|
||||
}
|
||||
activity.StartActivityForResult(chooserIntent, Constants.SelectFileRequestCode);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> DisplayPromptAync(string title = null, string description = null,
|
||||
string text = null, string okButtonText = null, string cancelButtonText = null,
|
||||
bool numericKeyboard = false, bool autofocus = true, bool password = false)
|
||||
@@ -467,34 +259,6 @@ namespace Bit.Droid.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableAutofillService()
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var type = Java.Lang.Class.FromType(typeof(AutofillManager));
|
||||
var manager = activity.GetSystemService(type) as AutofillManager;
|
||||
manager.DisableAutofillServices();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public bool AutofillServicesEnabled()
|
||||
{
|
||||
if (Build.VERSION.SdkInt <= BuildVersionCodes.M)
|
||||
{
|
||||
// Android 5-6: Both accessibility & overlay are required or nothing happens
|
||||
return AutofillAccessibilityServiceRunning() && AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
if (Build.VERSION.SdkInt == BuildVersionCodes.N)
|
||||
{
|
||||
// Android 7: Only accessibility is required (overlay is optional when using quick-action tile)
|
||||
return AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
// Android 8+: Either autofill or accessibility is required
|
||||
return AutofillServiceEnabled() || AutofillAccessibilityServiceRunning();
|
||||
}
|
||||
|
||||
public string GetBuildNumber()
|
||||
{
|
||||
return Application.Context.ApplicationContext.PackageManager.GetPackageInfo(
|
||||
@@ -526,25 +290,6 @@ namespace Bit.Droid.Services
|
||||
return activity.PackageManager.HasSystemFeature(PackageManager.FeatureCamera);
|
||||
}
|
||||
|
||||
public bool SupportsAutofillService()
|
||||
{
|
||||
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var type = Java.Lang.Class.FromType(typeof(AutofillManager));
|
||||
var manager = activity.GetSystemService(type) as AutofillManager;
|
||||
return manager.IsAutofillSupported;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int SystemMajorVersion()
|
||||
{
|
||||
return (int)Build.VERSION.SdkInt;
|
||||
@@ -635,112 +380,6 @@ namespace Bit.Droid.Services
|
||||
title, cancel, destruction, buttons);
|
||||
}
|
||||
|
||||
public void Autofill(CipherView cipher)
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
if (activity == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (activity.Intent?.GetBooleanExtra("autofillFramework", false) ?? false)
|
||||
{
|
||||
if (cipher == null)
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
return;
|
||||
}
|
||||
var structure = activity.Intent.GetParcelableExtra(
|
||||
AutofillManager.ExtraAssistStructure) as AssistStructure;
|
||||
if (structure == null)
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
return;
|
||||
}
|
||||
var parser = new Parser(structure, activity.ApplicationContext);
|
||||
parser.Parse();
|
||||
if ((!parser.FieldCollection?.Fields?.Any() ?? true) || string.IsNullOrWhiteSpace(parser.Uri))
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
return;
|
||||
}
|
||||
var task = CopyTotpAsync(cipher);
|
||||
var dataset = AutofillHelpers.BuildDataset(activity, parser.FieldCollection, new FilledItem(cipher));
|
||||
var replyIntent = new Intent();
|
||||
replyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, dataset);
|
||||
activity.SetResult(Result.Ok, replyIntent);
|
||||
activity.Finish();
|
||||
var eventTask = _eventServiceFunc().CollectAsync(EventType.Cipher_ClientAutofilled, cipher.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = new Intent();
|
||||
if (cipher?.Login == null)
|
||||
{
|
||||
data.PutExtra("canceled", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
var task = CopyTotpAsync(cipher);
|
||||
data.PutExtra("uri", cipher.Login.Uri);
|
||||
data.PutExtra("username", cipher.Login.Username);
|
||||
data.PutExtra("password", cipher.Login.Password);
|
||||
}
|
||||
if (activity.Parent == null)
|
||||
{
|
||||
activity.SetResult(Result.Ok, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
activity.Parent.SetResult(Result.Ok, data);
|
||||
}
|
||||
activity.Finish();
|
||||
_messagingService.Send("finishMainActivity");
|
||||
if (cipher != null)
|
||||
{
|
||||
var eventTask = _eventServiceFunc().CollectAsync(EventType.Cipher_ClientAutofilled, cipher.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseAutofill()
|
||||
{
|
||||
Autofill(null);
|
||||
}
|
||||
|
||||
public void Background()
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
if (activity.Intent?.GetBooleanExtra("autofillFramework", false) ?? false)
|
||||
{
|
||||
activity.SetResult(Result.Canceled);
|
||||
activity.Finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
activity.MoveTaskToBack(true);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutofillAccessibilityServiceRunning()
|
||||
{
|
||||
var enabledServices = Settings.Secure.GetString(Application.Context.ContentResolver,
|
||||
Settings.Secure.EnabledAccessibilityServices);
|
||||
return Application.Context.PackageName != null &&
|
||||
(enabledServices?.Contains(Application.Context.PackageName) ?? false);
|
||||
}
|
||||
|
||||
public bool AutofillAccessibilityOverlayPermitted()
|
||||
{
|
||||
return Accessibility.AccessibilityHelpers.OverlayPermitted();
|
||||
}
|
||||
|
||||
public bool HasAutofillService()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OpenAccessibilityOverlayPermissionSettings()
|
||||
{
|
||||
@@ -771,25 +410,6 @@ namespace Bit.Droid.Services
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutofillServiceEnabled()
|
||||
{
|
||||
if (Build.VERSION.SdkInt < BuildVersionCodes.O)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var afm = (AutofillManager)activity.GetSystemService(
|
||||
Java.Lang.Class.FromType(typeof(AutofillManager)));
|
||||
return afm.IsEnabled && afm.HasEnabledAutofillServices;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenAccessibilitySettings()
|
||||
{
|
||||
try
|
||||
@@ -848,61 +468,6 @@ namespace Bit.Droid.Services
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DeleteDir(Java.IO.File dir)
|
||||
{
|
||||
if (dir != null && dir.IsDirectory)
|
||||
{
|
||||
var children = dir.List();
|
||||
for (int i = 0; i < children.Length; i++)
|
||||
{
|
||||
var success = DeleteDir(new Java.IO.File(dir, children[i]));
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return dir.Delete();
|
||||
}
|
||||
else if (dir != null && dir.IsFile)
|
||||
{
|
||||
return dir.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasPermission(string permission)
|
||||
{
|
||||
return ContextCompat.CheckSelfPermission(
|
||||
CrossCurrentActivity.Current.Activity, permission) == Permission.Granted;
|
||||
}
|
||||
|
||||
private void AskPermission(string permission)
|
||||
{
|
||||
ActivityCompat.RequestPermissions(CrossCurrentActivity.Current.Activity, new string[] { permission },
|
||||
Constants.SelectFilePermissionRequestCode);
|
||||
}
|
||||
|
||||
private List<IParcelable> GetCameraIntents(Android.Net.Uri outputUri)
|
||||
{
|
||||
var intents = new List<IParcelable>();
|
||||
var pm = CrossCurrentActivity.Current.Activity.PackageManager;
|
||||
var captureIntent = new Intent(MediaStore.ActionImageCapture);
|
||||
var listCam = pm.QueryIntentActivities(captureIntent, 0);
|
||||
foreach (var res in listCam)
|
||||
{
|
||||
var packageName = res.ActivityInfo.PackageName;
|
||||
var intent = new Intent(captureIntent);
|
||||
intent.SetComponent(new ComponentName(packageName, res.ActivityInfo.Name));
|
||||
intent.SetPackage(packageName);
|
||||
intent.PutExtra(MediaStore.ExtraOutput, outputUri);
|
||||
intents.Add(intent);
|
||||
}
|
||||
return intents;
|
||||
}
|
||||
|
||||
private Intent RateIntentForUrl(string url, Activity activity)
|
||||
{
|
||||
var intent = new Intent(Intent.ActionView, Android.Net.Uri.Parse($"{url}?id={activity.PackageName}"));
|
||||
@@ -920,24 +485,6 @@ namespace Bit.Droid.Services
|
||||
return intent;
|
||||
}
|
||||
|
||||
private async Task CopyTotpAsync(CipherView cipher)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(cipher?.Login?.Totp))
|
||||
{
|
||||
var autoCopyDisabled = await _stateService.GetDisableAutoTotpCopyAsync();
|
||||
var canAccessPremium = await _stateService.CanAccessPremiumAsync();
|
||||
if ((canAccessPremium || cipher.OrganizationUseTotp) && !autoCopyDisabled.GetValueOrDefault())
|
||||
{
|
||||
var totpService = ServiceContainer.Resolve<ITotpService>("totpService");
|
||||
var totp = await totpService.GetCodeAsync(cipher.Login.Totp);
|
||||
if (totp != null)
|
||||
{
|
||||
await _clipboardService.CopyTextAsync(totp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetSystemFontSizeScale()
|
||||
{
|
||||
var activity = CrossCurrentActivity.Current?.Activity as MainActivity;
|
||||
@@ -964,5 +511,20 @@ namespace Bit.Droid.Services
|
||||
}
|
||||
activity.RunOnUiThread(() => activity.Window.AddFlags(WindowManagerFlags.Secure));
|
||||
}
|
||||
|
||||
public void OpenAppSettings()
|
||||
{
|
||||
var intent = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings);
|
||||
intent.AddFlags(ActivityFlags.NewTask);
|
||||
var uri = Android.Net.Uri.FromParts("package", Application.Context.PackageName, null);
|
||||
intent.SetData(uri);
|
||||
Application.Context.StartActivity(intent);
|
||||
}
|
||||
|
||||
public void CloseExtensionPopUp()
|
||||
{
|
||||
// only used by iOS
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
278
src/Android/Services/FileService.cs
Normal file
278
src/Android/Services/FileService.cs
Normal file
@@ -0,0 +1,278 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Android;
|
||||
using Android.Content;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Android.Provider;
|
||||
using Android.Webkit;
|
||||
using AndroidX.Core.App;
|
||||
using AndroidX.Core.Content;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Plugin.CurrentActivity;
|
||||
|
||||
namespace Bit.Droid.Services
|
||||
{
|
||||
public class FileService : IFileService
|
||||
{
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IBroadcasterService _broadcasterService;
|
||||
|
||||
private bool _cameraPermissionsDenied;
|
||||
|
||||
public FileService(IStateService stateService, IBroadcasterService broadcasterService)
|
||||
{
|
||||
_stateService = stateService;
|
||||
_broadcasterService = broadcasterService;
|
||||
|
||||
_broadcasterService.Subscribe(nameof(FileService), (message) =>
|
||||
{
|
||||
if (message.Command == "selectFileCameraPermissionDenied")
|
||||
{
|
||||
_cameraPermissionsDenied = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public bool OpenFile(byte[] fileData, string id, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var intent = BuildOpenFileIntent(fileData, fileName);
|
||||
if (intent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
activity.StartActivity(intent);
|
||||
return true;
|
||||
}
|
||||
catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanOpenFile(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var intent = BuildOpenFileIntent(new byte[0], string.Concat("opentest_", fileName));
|
||||
if (intent == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var activities = activity.PackageManager.QueryIntentActivities(intent,
|
||||
PackageInfoFlags.MatchDefaultOnly);
|
||||
return (activities?.Count ?? 0) > 0;
|
||||
}
|
||||
catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
private Intent BuildOpenFileIntent(byte[] fileData, string fileName)
|
||||
{
|
||||
var extension = MimeTypeMap.GetFileExtensionFromUrl(fileName.Replace(' ', '_').ToLower());
|
||||
if (extension == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
|
||||
if (mimeType == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var cachePath = activity.CacheDir;
|
||||
var filePath = Path.Combine(cachePath.Path, fileName);
|
||||
File.WriteAllBytes(filePath, fileData);
|
||||
var file = new Java.IO.File(cachePath, fileName);
|
||||
if (!file.IsFile)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var intent = new Intent(Intent.ActionView);
|
||||
var uri = FileProvider.GetUriForFile(activity.ApplicationContext,
|
||||
"com.x8bit.bitwarden.fileprovider", file);
|
||||
intent.SetDataAndType(uri, mimeType);
|
||||
intent.SetFlags(ActivityFlags.GrantReadUriPermission);
|
||||
return intent;
|
||||
}
|
||||
catch { }
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool SaveFile(byte[] fileData, string id, string fileName, string contentUri)
|
||||
{
|
||||
try
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
|
||||
if (contentUri != null)
|
||||
{
|
||||
var uri = Android.Net.Uri.Parse(contentUri);
|
||||
var stream = activity.ContentResolver.OpenOutputStream(uri);
|
||||
// Using java bufferedOutputStream due to this issue:
|
||||
// https://github.com/xamarin/xamarin-android/issues/3498
|
||||
var javaStream = new Java.IO.BufferedOutputStream(stream);
|
||||
javaStream.Write(fileData);
|
||||
javaStream.Flush();
|
||||
javaStream.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prompt for location to save file
|
||||
var extension = MimeTypeMap.GetFileExtensionFromUrl(fileName.Replace(' ', '_').ToLower());
|
||||
if (extension == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension(extension);
|
||||
if (mimeType == null)
|
||||
{
|
||||
// Unable to identify so fall back to generic "any" type
|
||||
mimeType = "*/*";
|
||||
}
|
||||
|
||||
var intent = new Intent(Intent.ActionCreateDocument);
|
||||
intent.SetType(mimeType);
|
||||
intent.AddCategory(Intent.CategoryOpenable);
|
||||
intent.PutExtra(Intent.ExtraTitle, fileName);
|
||||
|
||||
activity.StartActivityForResult(intent, Core.Constants.SaveFileRequestCode);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", ex.GetType(), ex.StackTrace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public async Task ClearCacheAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
DeleteDir(CrossCurrentActivity.Current.Activity.CacheDir);
|
||||
await _stateService.SetLastFileCacheClearAsync(DateTime.UtcNow);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
|
||||
public Task SelectFileAsync()
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
var hasStorageWritePermission = !_cameraPermissionsDenied &&
|
||||
HasPermission(Manifest.Permission.WriteExternalStorage);
|
||||
var additionalIntents = new List<IParcelable>();
|
||||
if (activity.PackageManager.HasSystemFeature(PackageManager.FeatureCamera))
|
||||
{
|
||||
var hasCameraPermission = !_cameraPermissionsDenied && HasPermission(Manifest.Permission.Camera);
|
||||
if (!_cameraPermissionsDenied && !hasStorageWritePermission)
|
||||
{
|
||||
AskPermission(Manifest.Permission.WriteExternalStorage);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
if (!_cameraPermissionsDenied && !hasCameraPermission)
|
||||
{
|
||||
AskPermission(Manifest.Permission.Camera);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
if (!_cameraPermissionsDenied && hasCameraPermission && hasStorageWritePermission)
|
||||
{
|
||||
try
|
||||
{
|
||||
var file = new Java.IO.File(activity.FilesDir, "temp_camera_photo.jpg");
|
||||
if (!file.Exists())
|
||||
{
|
||||
file.ParentFile.Mkdirs();
|
||||
file.CreateNewFile();
|
||||
}
|
||||
var outputFileUri = FileProvider.GetUriForFile(activity,
|
||||
"com.x8bit.bitwarden.fileprovider", file);
|
||||
additionalIntents.AddRange(GetCameraIntents(outputFileUri));
|
||||
}
|
||||
catch (Java.IO.IOException) { }
|
||||
}
|
||||
}
|
||||
|
||||
var docIntent = new Intent(Intent.ActionOpenDocument);
|
||||
docIntent.AddCategory(Intent.CategoryOpenable);
|
||||
docIntent.SetType("*/*");
|
||||
var chooserIntent = Intent.CreateChooser(docIntent, AppResources.FileSource);
|
||||
if (additionalIntents.Count > 0)
|
||||
{
|
||||
chooserIntent.PutExtra(Intent.ExtraInitialIntents, additionalIntents.ToArray());
|
||||
}
|
||||
activity.StartActivityForResult(chooserIntent, Core.Constants.SelectFileRequestCode);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
private bool DeleteDir(Java.IO.File dir)
|
||||
{
|
||||
if (dir is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dir.IsDirectory)
|
||||
{
|
||||
var children = dir.List();
|
||||
for (int i = 0; i < children.Length; i++)
|
||||
{
|
||||
var success = DeleteDir(new Java.IO.File(dir, children[i]));
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return dir.Delete();
|
||||
}
|
||||
|
||||
if (dir.IsFile)
|
||||
{
|
||||
return dir.Delete();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool HasPermission(string permission)
|
||||
{
|
||||
return ContextCompat.CheckSelfPermission(
|
||||
CrossCurrentActivity.Current.Activity, permission) == Permission.Granted;
|
||||
}
|
||||
|
||||
private void AskPermission(string permission)
|
||||
{
|
||||
ActivityCompat.RequestPermissions(CrossCurrentActivity.Current.Activity, new string[] { permission },
|
||||
Core.Constants.SelectFilePermissionRequestCode);
|
||||
}
|
||||
|
||||
private List<IParcelable> GetCameraIntents(Android.Net.Uri outputUri)
|
||||
{
|
||||
var intents = new List<IParcelable>();
|
||||
var pm = CrossCurrentActivity.Current.Activity.PackageManager;
|
||||
var captureIntent = new Intent(MediaStore.ActionImageCapture);
|
||||
var listCam = pm.QueryIntentActivities(captureIntent, 0);
|
||||
foreach (var res in listCam)
|
||||
{
|
||||
var packageName = res.ActivityInfo.PackageName;
|
||||
var intent = new Intent(captureIntent);
|
||||
intent.SetComponent(new ComponentName(packageName, res.ActivityInfo.Name));
|
||||
intent.SetPackage(packageName);
|
||||
intent.PutExtra(MediaStore.ExtraOutput, outputUri);
|
||||
intents.Add(intent);
|
||||
}
|
||||
return intents;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,5 +9,6 @@ namespace Bit.App.Abstractions
|
||||
void Init(Func<AppOptions> getOptionsFunc, IAccountsManagerHost accountsManagerHost);
|
||||
Task NavigateOnAccountChangeAsync(bool? isAuthed = null);
|
||||
Task LogOutAsync(string userId, bool userInitiated, bool expired);
|
||||
Task PromptToSwitchToExistingAccountAsync(string userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
@@ -8,46 +7,36 @@ namespace Bit.App.Abstractions
|
||||
{
|
||||
string DeviceUserAgent { get; }
|
||||
DeviceType DeviceType { get; }
|
||||
int SystemMajorVersion();
|
||||
string SystemModel();
|
||||
string GetBuildNumber();
|
||||
|
||||
void Toast(string text, bool longDuration = false);
|
||||
bool LaunchApp(string appName);
|
||||
Task ShowLoadingAsync(string text);
|
||||
Task HideLoadingAsync();
|
||||
bool OpenFile(byte[] fileData, string id, string fileName);
|
||||
bool SaveFile(byte[] fileData, string id, string fileName, string contentUri);
|
||||
bool CanOpenFile(string fileName);
|
||||
Task ClearCacheAsync();
|
||||
Task SelectFileAsync();
|
||||
Task<string> DisplayPromptAync(string title = null, string description = null, string text = null,
|
||||
string okButtonText = null, string cancelButtonText = null, bool numericKeyboard = false,
|
||||
bool autofocus = true, bool password = false);
|
||||
void RateApp();
|
||||
Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons);
|
||||
Task<string> DisplayActionSheetAsync(string title, string cancel, string destruction, params string[] buttons);
|
||||
|
||||
bool SupportsFaceBiometric();
|
||||
Task<bool> SupportsFaceBiometricAsync();
|
||||
bool SupportsNfc();
|
||||
bool SupportsCamera();
|
||||
bool SupportsAutofillService();
|
||||
int SystemMajorVersion();
|
||||
string SystemModel();
|
||||
Task<string> DisplayAlertAsync(string title, string message, string cancel, params string[] buttons);
|
||||
Task<string> DisplayActionSheetAsync(string title, string cancel, string destruction, params string[] buttons);
|
||||
void Autofill(CipherView cipher);
|
||||
void CloseAutofill();
|
||||
void Background();
|
||||
bool AutofillAccessibilityServiceRunning();
|
||||
bool AutofillAccessibilityOverlayPermitted();
|
||||
bool HasAutofillService();
|
||||
bool AutofillServiceEnabled();
|
||||
void DisableAutofillService();
|
||||
bool AutofillServicesEnabled();
|
||||
string GetBuildNumber();
|
||||
bool SupportsFido2();
|
||||
|
||||
bool LaunchApp(string appName);
|
||||
void RateApp();
|
||||
void OpenAccessibilitySettings();
|
||||
void OpenAccessibilityOverlayPermissionSettings();
|
||||
void OpenAutofillSettings();
|
||||
long GetActiveTime();
|
||||
void CloseMainApp();
|
||||
bool SupportsFido2();
|
||||
float GetSystemFontSizeScale();
|
||||
Task OnAccountSwitchCompleteAsync();
|
||||
Task SetScreenCaptureAllowedAsync();
|
||||
void OpenAppSettings();
|
||||
void CloseExtensionPopUp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
@@ -9,6 +10,8 @@ namespace Bit.App.Abstractions
|
||||
Task OnRegisteredAsync(string token, string device);
|
||||
void OnUnregistered(string device);
|
||||
void OnError(string message, string device);
|
||||
Task OnNotificationTapped(BaseNotificationData data);
|
||||
Task OnNotificationDismissed(BaseNotificationData data);
|
||||
bool ShouldShowNotification();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
|
||||
namespace Bit.App.Abstractions
|
||||
{
|
||||
public interface IPushNotificationService
|
||||
{
|
||||
bool IsRegisteredForPush { get; }
|
||||
Task<bool> AreNotificationsSettingsEnabledAsync();
|
||||
Task<string> GetTokenAsync();
|
||||
Task RegisterAsync();
|
||||
Task UnregisterAsync();
|
||||
void SendLocalNotification(string title, string message, BaseNotificationData data);
|
||||
void DismissLocalNotification(string notificationId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2515" />
|
||||
<PackageReference Include="ZXing.Net.Mobile" Version="2.4.1" />
|
||||
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.4.1" />
|
||||
<PackageReference Include="Xamarin.CommunityToolkit" Version="1.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -123,6 +122,12 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Remove="Pages\Accounts\AccountsPopupPage.xaml.cs" />
|
||||
<Compile Update="Pages\Accounts\LoginPasswordlessPage.xaml.cs">
|
||||
<DependentUpon>LoginPasswordlessPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Pages\Accounts\LoginPasswordlessRequestPage.xaml.cs">
|
||||
<DependentUpon>LoginPasswordlessRequestPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -137,6 +142,7 @@
|
||||
<Folder Include="Controls\AccountSwitchingOverlay\" />
|
||||
<Folder Include="Utilities\AccountManagement\" />
|
||||
<Folder Include="Controls\DateTime\" />
|
||||
<Folder Include="Controls\IconLabelButton\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -428,5 +434,6 @@
|
||||
<None Remove="Controls\AccountSwitchingOverlay\" />
|
||||
<None Remove="Utilities\AccountManagement\" />
|
||||
<None Remove="Controls\DateTime\" />
|
||||
<None Remove="Controls\IconLabelButton\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
@@ -7,9 +8,11 @@ using Bit.App.Resources;
|
||||
using Bit.App.Services;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.App.Utilities.AccountManagement;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Response;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
@@ -25,13 +28,15 @@ namespace Bit.App
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
private readonly ISyncService _syncService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IAuthService _authService;
|
||||
private readonly IStorageService _secureStorageService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly IAccountsManager _accountsManager;
|
||||
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
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;
|
||||
private static object _processingLoginRequestLock = new object();
|
||||
|
||||
public App(AppOptions appOptions)
|
||||
{
|
||||
@@ -47,10 +52,10 @@ namespace Bit.App
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
|
||||
_authService = ServiceContainer.Resolve<IAuthService>("authService");
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_secureStorageService = ServiceContainer.Resolve<IStorageService>("secureStorageService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_accountsManager = ServiceContainer.Resolve<IAccountsManager>("accountsManager");
|
||||
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
|
||||
|
||||
_accountsManager.Init(() => Options, this);
|
||||
|
||||
@@ -140,6 +145,17 @@ namespace Bit.App
|
||||
new NavigationPage(new RemoveMasterPasswordPage()));
|
||||
});
|
||||
}
|
||||
else if (message.Command == Constants.PasswordlessLoginRequestKey
|
||||
|| message.Command == "unlocked"
|
||||
|| message.Command == "syncCompleted"
|
||||
|| message.Command == AccountsManagerMessageCommands.ACCOUNT_SWITCH_COMPLETED)
|
||||
{
|
||||
lock (_processingLoginRequestLock)
|
||||
{
|
||||
// lock doesn't allow for async execution
|
||||
CheckPasswordlessLoginRequestsAsync().Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -148,11 +164,91 @@ namespace Bit.App
|
||||
});
|
||||
}
|
||||
|
||||
private async Task CheckPasswordlessLoginRequestsAsync()
|
||||
{
|
||||
if (!_isResumed)
|
||||
{
|
||||
_pendingCheckPasswordlessLoginRequests = true;
|
||||
return;
|
||||
}
|
||||
_pendingCheckPasswordlessLoginRequests = false;
|
||||
if (await _vaultTimeoutService.IsLockedAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var notification = await _stateService.GetPasswordlessLoginNotificationAsync();
|
||||
if (notification == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (await CheckShouldSwitchActiveUserAsync(notification))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay to wait for the vault page to appear
|
||||
await Task.Delay(2000);
|
||||
// if there is a request modal opened ignore all incoming requests
|
||||
if (App.Current.MainPage.Navigation.ModalStack.Any(p => p is NavigationPage navPage && navPage.CurrentPage is LoginPasswordlessPage))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var loginRequestData = await _authService.GetPasswordlessLoginRequestByIdAsync(notification.Id);
|
||||
var page = new LoginPasswordlessPage(new LoginPasswordlessDetails()
|
||||
{
|
||||
PubKey = loginRequestData.PublicKey,
|
||||
Id = loginRequestData.Id,
|
||||
IpAddress = loginRequestData.RequestIpAddress,
|
||||
Email = await _stateService.GetEmailAsync(),
|
||||
FingerprintPhrase = loginRequestData.RequestFingerprint,
|
||||
RequestDate = loginRequestData.CreationDate,
|
||||
DeviceType = loginRequestData.RequestDeviceType,
|
||||
Origin = loginRequestData.Origin,
|
||||
});
|
||||
await _stateService.SetPasswordlessLoginNotificationAsync(null);
|
||||
_pushNotificationService.DismissLocalNotification(Constants.PasswordlessNotificationId);
|
||||
if (loginRequestData.CreationDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes) > DateTime.UtcNow)
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page)));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CheckShouldSwitchActiveUserAsync(PasswordlessRequestNotification notification)
|
||||
{
|
||||
var activeUserId = await _stateService.GetActiveUserIdAsync();
|
||||
if (notification.UserId == activeUserId)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var notificationUserEmail = await _stateService.GetEmailAsync(notification.UserId);
|
||||
Device.BeginInvokeOnMainThread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _deviceActionService.DisplayAlertAsync(AppResources.LogInRequested, string.Format(AppResources.LoginAttemptFromXDoYouWantToSwitchToThisAccount, notificationUserEmail), AppResources.Cancel, AppResources.Ok);
|
||||
if (result == AppResources.Ok)
|
||||
{
|
||||
await _stateService.SetActiveUserAsync(notification.UserId);
|
||||
_messagingService.Send(AccountsManagerMessageCommands.SWITCHED_ACCOUNT);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
public AppOptions Options { get; private set; }
|
||||
|
||||
protected async override void OnStart()
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("XF App: OnStart");
|
||||
_isResumed = true;
|
||||
await ClearCacheIfNeededAsync();
|
||||
Prime();
|
||||
if (string.IsNullOrWhiteSpace(Options.Uri))
|
||||
@@ -164,6 +260,10 @@ namespace Bit.App
|
||||
SyncIfNeeded();
|
||||
}
|
||||
}
|
||||
if (_pendingCheckPasswordlessLoginRequests)
|
||||
{
|
||||
_messagingService.Send(Constants.PasswordlessLoginRequestKey);
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
await _vaultTimeoutService.CheckVaultTimeoutAsync();
|
||||
@@ -196,6 +296,10 @@ namespace Bit.App
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine("XF App: OnResume");
|
||||
_isResumed = true;
|
||||
if (_pendingCheckPasswordlessLoginRequests)
|
||||
{
|
||||
_messagingService.Send(Constants.PasswordlessLoginRequestKey);
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
ResumedAsync().FireAndForget();
|
||||
@@ -245,7 +349,7 @@ namespace Bit.App
|
||||
var lastClear = await _stateService.GetLastFileCacheClearAsync();
|
||||
if ((DateTime.UtcNow - lastClear.GetValueOrDefault(DateTime.MinValue)).TotalDays >= 1)
|
||||
{
|
||||
var task = Task.Run(() => _deviceActionService.ClearCacheAsync());
|
||||
var task = Task.Run(() => _fileService.ClearCacheAsync());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +460,14 @@ namespace Bit.App
|
||||
switch (navTarget)
|
||||
{
|
||||
case NavigationTarget.HomeLogin:
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options));
|
||||
if (navParams is HomeNavigationParams homeParams)
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options, homeParams.ShouldCheckRememberEmail));
|
||||
}
|
||||
else
|
||||
{
|
||||
Current.MainPage = new NavigationPage(new HomePage(Options));
|
||||
}
|
||||
break;
|
||||
case NavigationTarget.Login:
|
||||
if (navParams is LoginNavigationParams loginParams)
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
AccountView = accountView;
|
||||
AvatarImageSource = ServiceContainer.Resolve<IAvatarImageSourcePool>("avatarImageSourcePool")
|
||||
?.GetOrCreateAvatar(AccountView.Name, AccountView.Email);
|
||||
?.GetOrCreateAvatar(AccountView.UserId, AccountView.Name, AccountView.Email);
|
||||
}
|
||||
|
||||
public AccountView AccountView
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Utilities;
|
||||
using SkiaSharp;
|
||||
using Xamarin.Forms;
|
||||
|
||||
@@ -10,7 +11,8 @@ namespace Bit.App.Controls
|
||||
{
|
||||
public class AvatarImageSource : StreamImageSource
|
||||
{
|
||||
private string _data;
|
||||
private readonly string _text;
|
||||
private readonly string _id;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
@@ -21,20 +23,21 @@ namespace Bit.App.Controls
|
||||
|
||||
if (obj is AvatarImageSource avatar)
|
||||
{
|
||||
return avatar._data == _data;
|
||||
return avatar._id == _id && avatar._text == _text;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode() => _data?.GetHashCode() ?? -1;
|
||||
public override int GetHashCode() => _id?.GetHashCode() ?? _text?.GetHashCode() ?? -1;
|
||||
|
||||
public AvatarImageSource(string name = null, string email = null)
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null)
|
||||
{
|
||||
_data = name;
|
||||
if (string.IsNullOrWhiteSpace(_data))
|
||||
_id = userId;
|
||||
_text = name;
|
||||
if (string.IsNullOrWhiteSpace(_text))
|
||||
{
|
||||
_data = email;
|
||||
_text = email;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,24 +55,24 @@ namespace Bit.App.Controls
|
||||
private Stream Draw()
|
||||
{
|
||||
string chars;
|
||||
string upperData = null;
|
||||
string upperCaseText = null;
|
||||
|
||||
if (string.IsNullOrEmpty(_data))
|
||||
if (string.IsNullOrEmpty(_text))
|
||||
{
|
||||
chars = "..";
|
||||
}
|
||||
else if (_data?.Length > 1)
|
||||
else if (_text?.Length > 1)
|
||||
{
|
||||
upperData = _data.ToUpper();
|
||||
chars = GetFirstLetters(upperData, 2);
|
||||
upperCaseText = _text.ToUpper();
|
||||
chars = GetFirstLetters(upperCaseText, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
chars = upperData = _data.ToUpper();
|
||||
chars = upperCaseText = _text.ToUpper();
|
||||
}
|
||||
|
||||
var bgColor = StringToColor(upperData);
|
||||
var textColor = Color.White;
|
||||
var bgColor = CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var textColor = CoreHelpers.TextColorFromBgColor(bgColor);
|
||||
var size = 50;
|
||||
|
||||
using (var bitmap = new SKBitmap(size * 2,
|
||||
@@ -85,7 +88,7 @@ namespace Bit.App.Controls
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(bgColor.ToHex())
|
||||
Color = SKColor.Parse(bgColor)
|
||||
})
|
||||
{
|
||||
var midX = canvas.LocalClipBounds.Size.ToSizeI().Width / 2;
|
||||
@@ -97,7 +100,7 @@ namespace Bit.App.Controls
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
StrokeJoin = SKStrokeJoin.Miter,
|
||||
Color = SKColor.Parse(bgColor.ToHex())
|
||||
Color = SKColor.Parse(bgColor)
|
||||
})
|
||||
{
|
||||
canvas.DrawCircle(midX, midY, radius, circlePaint);
|
||||
@@ -108,7 +111,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
IsAntialias = true,
|
||||
Style = SKPaintStyle.Fill,
|
||||
Color = SKColor.Parse(textColor.ToHex()),
|
||||
Color = SKColor.Parse(textColor),
|
||||
TextSize = textSize,
|
||||
TextAlign = SKTextAlign.Center,
|
||||
Typeface = typeface
|
||||
|
||||
@@ -5,19 +5,19 @@ namespace Bit.App.Controls
|
||||
{
|
||||
public interface IAvatarImageSourcePool
|
||||
{
|
||||
AvatarImageSource GetOrCreateAvatar(string name, string email);
|
||||
AvatarImageSource GetOrCreateAvatar(string userId, string name, string email);
|
||||
}
|
||||
|
||||
public class AvatarImageSourcePool : IAvatarImageSourcePool
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, AvatarImageSource> _cache = new ConcurrentDictionary<string, AvatarImageSource>();
|
||||
|
||||
public AvatarImageSource GetOrCreateAvatar(string name, string email)
|
||||
public AvatarImageSource GetOrCreateAvatar(string userId, string name, string email)
|
||||
{
|
||||
var key = $"{name}{email}";
|
||||
var key = $"{userId}{name}{email}";
|
||||
if (!_cache.TryGetValue(key, out var avatar))
|
||||
{
|
||||
avatar = new AvatarImageSource(name, email);
|
||||
avatar = new AvatarImageSource(userId, name, email);
|
||||
if (!_cache.TryAdd(key, avatar)
|
||||
&&
|
||||
!_cache.TryGetValue(key, out avatar)) // If add fails another thread created the avatar in between the first try get and the try add.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Xamarin.Forms;
|
||||
using Bit.App.Effects;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
@@ -16,6 +17,8 @@ namespace Bit.App.Controls
|
||||
FontFamily = "bwi-font.ttf#bwi-font";
|
||||
break;
|
||||
}
|
||||
|
||||
Effects.Add(new RemoveFontPaddingEffect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Xamarin.Forms;
|
||||
using Bit.App.Effects;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
@@ -17,6 +18,8 @@ namespace Bit.App.Controls
|
||||
FontFamily = "bwi-font.ttf#bwi-font";
|
||||
break;
|
||||
}
|
||||
|
||||
Effects.Add(new RemoveFontPaddingEffect());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
src/App/Controls/IconLabelButton/IconLabelButton.xaml
Normal file
42
src/App/Controls/IconLabelButton/IconLabelButton.xaml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Frame xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Controls.IconLabelButton"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
x:Name="_iconLabelButton"
|
||||
HeightRequest="45"
|
||||
Padding="1"
|
||||
StyleClass="btn-icon-secondary"
|
||||
BackgroundColor="{Binding IconLabelBorderColor, Source={x:Reference _iconLabelButton}}"
|
||||
BorderColor="Transparent"
|
||||
HasShadow="False">
|
||||
<Frame.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding ButtonCommand, Source={x:Reference _iconLabelButton}}" />
|
||||
</Frame.GestureRecognizers>
|
||||
<Frame
|
||||
Margin="0"
|
||||
Padding="0"
|
||||
CornerRadius="{Binding CornerRadius, Source={x:Reference _iconLabelButton}}"
|
||||
BackgroundColor="{Binding IconLabelBackgroundColor, Source={x:Reference _iconLabelButton}}"
|
||||
BorderColor="Transparent"
|
||||
IsClippedToBounds="True"
|
||||
HasShadow="False">
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
HorizontalOptions="Center">
|
||||
<controls:IconLabel
|
||||
VerticalOptions="Center"
|
||||
HorizontalTextAlignment="Center"
|
||||
FontSize="Large"
|
||||
TextColor="{Binding IconLabelColor, Source={x:Reference _iconLabelButton}}"
|
||||
Text="{Binding Icon, Source={x:Reference _iconLabelButton}}">
|
||||
</controls:IconLabel>
|
||||
<Label
|
||||
VerticalOptions="Center"
|
||||
HorizontalTextAlignment="Center"
|
||||
TextColor="{Binding IconLabelColor, Source={x:Reference _iconLabelButton}}"
|
||||
FontSize="Medium"
|
||||
Text="{Binding Label, Source={x:Reference _iconLabelButton}}"/>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</Frame>
|
||||
75
src/App/Controls/IconLabelButton/IconLabelButton.xaml.cs
Normal file
75
src/App/Controls/IconLabelButton/IconLabelButton.xaml.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class IconLabelButton : Frame
|
||||
{
|
||||
public static readonly BindableProperty IconProperty = BindableProperty.Create(
|
||||
nameof(Icon), typeof(string), typeof(IconLabelButton));
|
||||
|
||||
public static readonly BindableProperty LabelProperty = BindableProperty.Create(
|
||||
nameof(Label), typeof(string), typeof(IconLabelButton));
|
||||
|
||||
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
|
||||
nameof(ButtonCommand), typeof(ICommand), typeof(IconLabelButton));
|
||||
|
||||
public static readonly BindableProperty IconLabelColorProperty = BindableProperty.Create(
|
||||
nameof(IconLabelColor), typeof(Color), typeof(IconLabelButton), Color.White);
|
||||
|
||||
public static readonly BindableProperty IconLabelBackgroundColorProperty = BindableProperty.Create(
|
||||
nameof(IconLabelBackgroundColor), typeof(Color), typeof(IconLabelButton), Color.White);
|
||||
|
||||
public static readonly BindableProperty IconLabelBorderColorProperty = BindableProperty.Create(
|
||||
nameof(IconLabelBorderColor), typeof(Color), typeof(IconLabelButton), Color.White);
|
||||
|
||||
public IconLabelButton()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public string Icon
|
||||
{
|
||||
get => GetValue(IconProperty) as string;
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
|
||||
public string Label
|
||||
{
|
||||
get => GetValue(LabelProperty) as string;
|
||||
set => SetValue(LabelProperty, value);
|
||||
}
|
||||
|
||||
public ICommand ButtonCommand
|
||||
{
|
||||
get => GetValue(ButtonCommandProperty) as ICommand;
|
||||
set => SetValue(ButtonCommandProperty, value);
|
||||
}
|
||||
|
||||
public Color IconLabelColor
|
||||
{
|
||||
get { return (Color)GetValue(IconLabelColorProperty); }
|
||||
set { SetValue(IconLabelColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color IconLabelBackgroundColor
|
||||
{
|
||||
get { return (Color)GetValue(IconLabelBackgroundColorProperty); }
|
||||
set { SetValue(IconLabelBackgroundColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color IconLabelBorderColor
|
||||
{
|
||||
get { return (Color)GetValue(IconLabelBorderColorProperty); }
|
||||
set { SetValue(IconLabelBorderColorProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
src/App/Effects/RemoveFontPaddingEffect.cs
Normal file
13
src/App/Effects/RemoveFontPaddingEffect.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Effects
|
||||
{
|
||||
public class RemoveFontPaddingEffect : RoutingEffect
|
||||
{
|
||||
public RemoveFontPaddingEffect()
|
||||
: base("Bitwarden.RemoveFontPaddingEffect")
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
23
src/App/Models/NotificationData.cs
Normal file
23
src/App/Models/NotificationData.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
namespace Bit.App.Models
|
||||
{
|
||||
public abstract class BaseNotificationData
|
||||
{
|
||||
public abstract string Type { get; }
|
||||
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
public class PasswordlessNotificationData : BaseNotificationData
|
||||
{
|
||||
public const string TYPE = "passwordlessNotificationData";
|
||||
|
||||
public override string Type => TYPE;
|
||||
|
||||
public int TimeoutInMinutes { get; set; }
|
||||
|
||||
public string UserEmail { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ namespace Bit.App.Pages
|
||||
{
|
||||
private HintPageViewModel _vm;
|
||||
|
||||
public HintPage()
|
||||
public HintPage(string email = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as HintPageViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.Email = email;
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
ToolbarItems.RemoveAt(0);
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace Bit.App.Pages
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly ILogger _logger;
|
||||
private string _email;
|
||||
|
||||
public HintPageViewModel()
|
||||
{
|
||||
@@ -34,7 +35,12 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
public ICommand SubmitCommand { get; }
|
||||
public string Email { get; set; }
|
||||
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
set => SetProperty(ref _email, value);
|
||||
}
|
||||
|
||||
public async Task SubmitAsync()
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
UseOriginalImage="True"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n Account}" />
|
||||
<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"
|
||||
@@ -32,30 +33,66 @@
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<StackLayout x:Name="_mainLayout" x:Key="mainLayout" Spacing="0" Padding="10, 5">
|
||||
<StackLayout VerticalOptions="CenterAndExpand" Spacing="20">
|
||||
<Image
|
||||
x:Name="_logo"
|
||||
Source="logo.png"
|
||||
VerticalOptions="Center" />
|
||||
<Label Text="{u:I18n LoginOrCreateNewAccount}"
|
||||
StyleClass="text-lg"
|
||||
HorizontalTextAlignment="Center">
|
||||
</Label>
|
||||
<StackLayout Spacing="5">
|
||||
<Button Text="{u:I18n LogIn}"
|
||||
StyleClass="btn-primary"
|
||||
Clicked="LogIn_Clicked" />
|
||||
<Button Text="{u:I18n CreateAccount}"
|
||||
Clicked="Register_Clicked" />
|
||||
<Button Text="{u:I18n LogInSso}"
|
||||
Clicked="LogInSso_Clicked" />
|
||||
<Button Text="{u:I18n Cancel}"
|
||||
IsVisible="{Binding ShowCancelButton}"
|
||||
Margin="0,10,0,0"
|
||||
Clicked="Cancel_Clicked" />
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<StackLayout x:Name="_mainLayout" x:Key="mainLayout" Spacing="30" Padding="20, 50, 20, 0">
|
||||
<Image
|
||||
x:Name="_logo"
|
||||
Source="logo.png"
|
||||
VerticalOptions="Center" />
|
||||
<Label Text="{u:I18n LoginOrCreateNewAccount}"
|
||||
StyleClass="text-lg"
|
||||
HorizontalTextAlignment="Center"/>
|
||||
<StackLayout
|
||||
StyleClass="box-row">
|
||||
<Label
|
||||
Text="{u:I18n EmailAddress}"
|
||||
StyleClass="box-label" />
|
||||
<Entry
|
||||
x:Name="_email"
|
||||
Text="{Binding Email}"
|
||||
Keyboard="Email"
|
||||
StyleClass="box-value">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{DynamicResource MutedColor}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Entry>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0, 16, 0 ,0">
|
||||
<StackLayout.GestureRecognizers>
|
||||
<TapGestureRecognizer
|
||||
Command="{Binding RememberEmailCommand}" />
|
||||
</StackLayout.GestureRecognizers>
|
||||
<Label
|
||||
Text="{u:I18n RememberMe}"
|
||||
StyleClass="text-sm"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="Center"
|
||||
VerticalTextAlignment="Center"/>
|
||||
<Switch
|
||||
Scale="0.8"
|
||||
IsToggled="{Binding RememberEmail}"
|
||||
VerticalOptions="Center"/>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
<Button Text="{u:I18n Continue}"
|
||||
StyleClass="btn-primary"
|
||||
IsEnabled="{Binding CanContinue}"
|
||||
Command="{Binding ContinueCommand}" />
|
||||
|
||||
<Label FormattedText="{Binding CreateAccountText}"
|
||||
Margin="0, 10"
|
||||
StyleClass="box-footer-label">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding CreateAccountCommand}" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</StackLayout>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
@@ -10,28 +10,35 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public partial class HomePage : BaseContentPage
|
||||
{
|
||||
private bool _checkRememberedEmail;
|
||||
private readonly HomeViewModel _vm;
|
||||
private readonly AppOptions _appOptions;
|
||||
private IBroadcasterService _broadcasterService;
|
||||
|
||||
public HomePage(AppOptions appOptions = null)
|
||||
public HomePage(AppOptions appOptions = null, bool shouldCheckRememberEmail = true)
|
||||
{
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_appOptions = appOptions;
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as HomeViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.StartLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartLoginAsync());
|
||||
_vm.ShouldCheckRememberEmail = shouldCheckRememberEmail;
|
||||
_vm.ShowCancelButton = _appOptions?.IosExtension ?? false;
|
||||
_vm.StartLoginAction = async () => await StartLoginAsync();
|
||||
_vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
|
||||
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
|
||||
_vm.StartEnvironmentAction = () => Device.BeginInvokeOnMainThread(async () => await StartEnvironmentAsync());
|
||||
_vm.CloseAction = async () =>
|
||||
{
|
||||
await _accountListOverlay.HideAsync();
|
||||
await Navigation.PopModalAsync();
|
||||
};
|
||||
UpdateLogo();
|
||||
|
||||
if (_appOptions?.IosExtension ?? false)
|
||||
if (!_vm.ShowCancelButton)
|
||||
{
|
||||
_vm.ShowCancelButton = true;
|
||||
ToolbarItems.Remove(_closeButton);
|
||||
}
|
||||
|
||||
if (_appOptions?.HideAccountSwitcher ?? false)
|
||||
{
|
||||
ToolbarItems.Remove(_accountAvatar);
|
||||
@@ -52,7 +59,7 @@ namespace Bit.App.Pages
|
||||
|
||||
if (!_appOptions?.HideAccountSwitcher ?? false)
|
||||
{
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync(false);
|
||||
}
|
||||
_broadcasterService.Subscribe(nameof(HomePage), (message) =>
|
||||
{
|
||||
@@ -64,6 +71,8 @@ namespace Bit.App.Pages
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
_vm.CheckNavigateLoginStep();
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
@@ -96,28 +105,12 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private void LogIn_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.StartLoginAction();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartLoginAsync()
|
||||
{
|
||||
var page = new LoginPage(null, _appOptions);
|
||||
var page = new LoginPage(_vm.Email, _appOptions);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
private void Register_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.StartRegisterAction();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartRegisterAsync()
|
||||
{
|
||||
var page = new RegisterPage(this);
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -12,19 +19,37 @@ namespace Bit.App.Pages
|
||||
private readonly IMessagingService _messagingService;
|
||||
|
||||
private bool _showCancelButton;
|
||||
private bool _rememberEmail;
|
||||
private string _email;
|
||||
private bool _isEmailEnabled;
|
||||
private bool _canLogin;
|
||||
private IPlatformUtilsService _platformUtilsService;
|
||||
private ILogger _logger;
|
||||
private IEnvironmentService _environmentService;
|
||||
private IAccountsManager _accountManager;
|
||||
|
||||
public HomeViewModel()
|
||||
{
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
var logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
_accountManager = ServiceContainer.Resolve<IAccountsManager>();
|
||||
|
||||
PageTitle = AppResources.Bitwarden;
|
||||
|
||||
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, logger)
|
||||
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
|
||||
{
|
||||
AllowActiveAccountSelection = true
|
||||
};
|
||||
RememberEmailCommand = new Command(() => RememberEmail = !RememberEmail);
|
||||
ContinueCommand = new AsyncCommand(ContinueToLoginStepAsync, allowsMultipleExecutions: false);
|
||||
CreateAccountCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(StartRegisterAction),
|
||||
onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
CloseCommand = new AsyncCommand(async () => await Device.InvokeOnMainThreadAsync(CloseAction),
|
||||
onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
InitAsync().FireAndForget();
|
||||
}
|
||||
|
||||
public bool ShowCancelButton
|
||||
@@ -33,11 +58,102 @@ namespace Bit.App.Pages
|
||||
set => SetProperty(ref _showCancelButton, value);
|
||||
}
|
||||
|
||||
public bool RememberEmail
|
||||
{
|
||||
get => _rememberEmail;
|
||||
set => SetProperty(ref _rememberEmail, value);
|
||||
}
|
||||
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
set => SetProperty(ref _email, value,
|
||||
additionalPropertyNames: new[] { nameof(CanContinue) });
|
||||
}
|
||||
|
||||
public bool CanContinue => !string.IsNullOrEmpty(Email);
|
||||
|
||||
public bool ShouldCheckRememberEmail { get; set; }
|
||||
|
||||
public FormattedString CreateAccountText
|
||||
{
|
||||
get
|
||||
{
|
||||
var fs = new FormattedString();
|
||||
fs.Spans.Add(new Span
|
||||
{
|
||||
Text = $"{AppResources.NewAroundHere} "
|
||||
});
|
||||
fs.Spans.Add(new Span
|
||||
{
|
||||
Text = AppResources.CreateAccount,
|
||||
TextColor = ThemeManager.GetResourceColor("PrimaryColor")
|
||||
});
|
||||
return fs;
|
||||
}
|
||||
}
|
||||
|
||||
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
|
||||
public Action StartLoginAction { get; set; }
|
||||
public Action StartRegisterAction { get; set; }
|
||||
public Action StartSsoLoginAction { get; set; }
|
||||
public Action StartEnvironmentAction { get; set; }
|
||||
public Action CloseAction { get; set; }
|
||||
public Command RememberEmailCommand { get; set; }
|
||||
public AsyncCommand ContinueCommand { get; }
|
||||
public AsyncCommand CloseCommand { get; }
|
||||
public AsyncCommand CreateAccountCommand { get; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
Email = await _stateService.GetRememberedEmailAsync();
|
||||
RememberEmail = !string.IsNullOrEmpty(Email);
|
||||
}
|
||||
|
||||
public void CheckNavigateLoginStep()
|
||||
{
|
||||
if (ShouldCheckRememberEmail && RememberEmail)
|
||||
{
|
||||
StartLoginAction();
|
||||
}
|
||||
ShouldCheckRememberEmail = false;
|
||||
}
|
||||
|
||||
public async Task ContinueToLoginStepAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Email))
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(
|
||||
string.Format(AppResources.ValidationFieldRequired, AppResources.EmailAddress),
|
||||
AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
if (!Email.Contains("@"))
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.InvalidEmail, AppResources.AnErrorHasOccurred,
|
||||
AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
await _stateService.SetRememberedEmailAsync(RememberEmail ? Email : null);
|
||||
var userId = await _stateService.GetUserIdAsync(Email);
|
||||
if (!string.IsNullOrWhiteSpace(userId))
|
||||
{
|
||||
var userEnvUrls = await _stateService.GetEnvironmentUrlsAsync(userId);
|
||||
if (userEnvUrls?.Base == _environmentService.BaseUrl)
|
||||
{
|
||||
await _accountManager.PromptToSwitchToExistingAccountAsync(userId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
StartLoginAction();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage, AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.LoginPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:LoginPageViewModel"
|
||||
@@ -46,33 +47,13 @@
|
||||
Order="Secondary" />
|
||||
|
||||
<ScrollView x:Name="_mainLayout" x:Key="mainLayout">
|
||||
<StackLayout Spacing="20">
|
||||
<StackLayout Spacing="0">
|
||||
<StackLayout StyleClass="box">
|
||||
<StackLayout StyleClass="box-row">
|
||||
<Label
|
||||
Text="{u:I18n EmailAddress}"
|
||||
StyleClass="box-label" />
|
||||
<Entry
|
||||
x:Name="_email"
|
||||
Text="{Binding Email}"
|
||||
IsEnabled="{Binding IsEmailEnabled}"
|
||||
Keyboard="Email"
|
||||
StyleClass="box-value">
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Property="TextColor" Value="{DynamicResource MutedColor}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Entry>
|
||||
</StackLayout>
|
||||
<Grid StyleClass="box-row">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
@@ -81,6 +62,7 @@
|
||||
<Label
|
||||
Text="{u:I18n MasterPassword}"
|
||||
StyleClass="box-label"
|
||||
Padding="0, 10, 0, 0"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0" />
|
||||
<controls:MonoEntry
|
||||
@@ -98,21 +80,60 @@
|
||||
StyleClass="box-row-button, box-row-button-platform"
|
||||
Text="{Binding ShowPasswordIcon}"
|
||||
Command="{Binding TogglePasswordCommand}"
|
||||
Grid.Row="0"
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Grid.RowSpan="2"
|
||||
Grid.RowSpan="1"
|
||||
AutomationProperties.IsInAccessibleTree="True"
|
||||
AutomationProperties.Name="{u:I18n ToggleVisibility}"
|
||||
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"/>
|
||||
<Label
|
||||
Text="{u:I18n GetMasterPasswordwordHint}"
|
||||
StyleClass="box-footer-label"
|
||||
TextColor="{DynamicResource HyperlinkColor}"
|
||||
Padding="0,5,0,0"
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="Hint_Clicked" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</Grid>
|
||||
</StackLayout>
|
||||
<StackLayout Padding="10, 0">
|
||||
<Button Text="{u:I18n LogIn}"
|
||||
<StackLayout Padding="10, 10">
|
||||
<Button x:Name="_loginWithMasterPassword"
|
||||
Text="{u:I18n LogInWithMasterPassword}"
|
||||
StyleClass="btn-primary"
|
||||
Clicked="LogIn_Clicked" />
|
||||
<Button Text="{u:I18n Cancel}"
|
||||
IsVisible="{Binding ShowCancelButton}"
|
||||
Clicked="Cancel_Clicked" />
|
||||
<controls:IconLabelButton
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Icon="{Binding Source={x:Static core:BitwardenIcons.Device}}"
|
||||
Label="{u:I18n LogInWithAnotherDevice}"
|
||||
ButtonCommand="{Binding LogInWithDeviceCommand}"
|
||||
IsVisible="{Binding IsKnownDevice}"/>
|
||||
<controls:IconLabelButton
|
||||
HorizontalOptions="Fill"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Icon="{Binding Source={x:Static core:BitwardenIcons.Suitcase}}"
|
||||
Label="{u:I18n LogInSso}">
|
||||
<controls:IconLabelButton.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="LogInSSO_Clicked" />
|
||||
</controls:IconLabelButton.GestureRecognizers>
|
||||
</controls:IconLabelButton>
|
||||
<Label
|
||||
Text="{Binding LoggingInAsText}"
|
||||
StyleClass="text-sm"
|
||||
Margin="0,40,0,0"/>
|
||||
<Label
|
||||
Text="{u:I18n NotYou}"
|
||||
StyleClass="text-md"
|
||||
HorizontalOptions="Start"
|
||||
TextColor="{DynamicResource HyperlinkColor}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Tapped="Cancel_Clicked" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
@@ -3,7 +3,9 @@ using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -25,8 +27,9 @@ namespace Bit.App.Pages
|
||||
_vm.Page = this;
|
||||
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
|
||||
_vm.UpdateTempPasswordAction =
|
||||
() => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
_vm.LogInWithDeviceAction = () => StartLoginWithDeviceAsync().FireAndForget();
|
||||
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
|
||||
_vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
_vm.CloseAction = async () =>
|
||||
{
|
||||
await _accountListOverlay.HideAsync();
|
||||
@@ -42,9 +45,6 @@ namespace Bit.App.Pages
|
||||
_vm.Email = email;
|
||||
MasterPasswordEntry = _masterPassword;
|
||||
|
||||
_email.ReturnType = ReturnType.Next;
|
||||
_email.ReturnCommand = new Command(() => _masterPassword.Focus());
|
||||
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
ToolbarItems.Add(_moreItem);
|
||||
@@ -54,11 +54,6 @@ namespace Bit.App.Pages
|
||||
ToolbarItems.Add(_getPasswordHint);
|
||||
}
|
||||
|
||||
if (Device.RuntimePlatform == Device.Android && !_vm.IsEmailEnabled)
|
||||
{
|
||||
ToolbarItems.Add(_removeAccount);
|
||||
}
|
||||
|
||||
if (_appOptions?.IosExtension ?? false)
|
||||
{
|
||||
_vm.ShowCancelButton = true;
|
||||
@@ -78,16 +73,20 @@ namespace Bit.App.Pages
|
||||
_mainContent.Content = _mainLayout;
|
||||
_accountAvatar?.OnAppearing();
|
||||
|
||||
await _vm.InitAsync();
|
||||
if (!_appOptions?.HideAccountSwitcher ?? false)
|
||||
{
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync(_vm.EmailIsInSavedAccounts);
|
||||
}
|
||||
await _vm.InitAsync();
|
||||
if (!_inputFocused)
|
||||
{
|
||||
RequestFocus(string.IsNullOrWhiteSpace(_vm.Email) ? _email : _masterPassword);
|
||||
RequestFocus(_masterPassword);
|
||||
_inputFocused = true;
|
||||
}
|
||||
if (Device.RuntimePlatform == Device.Android && !_vm.CanRemoveAccount)
|
||||
{
|
||||
ToolbarItems.Add(_removeAccount);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnBackButtonPressed()
|
||||
@@ -115,11 +114,31 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private void LogInSSO_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.StartSsoLoginAction();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartLoginWithDeviceAsync()
|
||||
{
|
||||
var page = new LoginPasswordlessRequestPage(_vm.Email, _appOptions);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
private async Task StartSsoLoginAsync()
|
||||
{
|
||||
var page = new LoginSsoPage(_appOptions);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
private void Hint_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
Navigation.PushModalAsync(new NavigationPage(new HintPage()));
|
||||
_vm.ShowMasterPasswordHintAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.App.Utilities.AccountManagement;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
@@ -25,12 +31,15 @@ namespace Bit.App.Pages
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly IApiService _apiService;
|
||||
private readonly IAppIdService _appIdService;
|
||||
private readonly IAccountsManager _accountManager;
|
||||
private bool _showPassword;
|
||||
private bool _showCancelButton;
|
||||
private string _email;
|
||||
private string _masterPassword;
|
||||
private bool _isEmailEnabled;
|
||||
private bool _isKnownDevice;
|
||||
|
||||
public LoginPageViewModel()
|
||||
{
|
||||
@@ -43,11 +52,15 @@ namespace Bit.App.Pages
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
_apiService = ServiceContainer.Resolve<IApiService>();
|
||||
_appIdService = ServiceContainer.Resolve<IAppIdService>();
|
||||
_accountManager = ServiceContainer.Resolve<IAccountsManager>();
|
||||
|
||||
PageTitle = AppResources.Bitwarden;
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
LogInCommand = new Command(async () => await LogInAsync());
|
||||
MoreCommand = new AsyncCommand(MoreAsync, onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
LogInWithDeviceCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(LogInWithDeviceAction), onException: _logger.Exception, allowsMultipleExecutions: false);
|
||||
|
||||
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
|
||||
{
|
||||
@@ -76,7 +89,11 @@ namespace Bit.App.Pages
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
set => SetProperty(ref _email, value);
|
||||
set => SetProperty(ref _email, value,
|
||||
additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(LoggingInAsText)
|
||||
});
|
||||
}
|
||||
|
||||
public string MasterPassword
|
||||
@@ -91,20 +108,31 @@ namespace Bit.App.Pages
|
||||
set => SetProperty(ref _isEmailEnabled, value);
|
||||
}
|
||||
|
||||
public bool IsIosExtension { get; set; }
|
||||
public bool IsKnownDevice
|
||||
{
|
||||
get => _isKnownDevice;
|
||||
set => SetProperty(ref _isKnownDevice, value);
|
||||
}
|
||||
|
||||
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
|
||||
|
||||
public Command LogInCommand { get; }
|
||||
public Command TogglePasswordCommand { get; }
|
||||
public ICommand MoreCommand { get; internal set; }
|
||||
public ICommand LogInWithDeviceCommand { get; }
|
||||
public string ShowPasswordIcon => ShowPassword ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
|
||||
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
|
||||
public string LoggingInAsText => string.Format(AppResources.LoggingInAsX, Email);
|
||||
public bool IsIosExtension { get; set; }
|
||||
public bool CanRemoveAccount { get; set; }
|
||||
public Action StartTwoFactorAction { get; set; }
|
||||
public Action LogInSuccessAction { get; set; }
|
||||
public Action LogInWithDeviceAction { get; set; }
|
||||
public Action UpdateTempPasswordAction { get; set; }
|
||||
public Action StartSsoLoginAction { get; set; }
|
||||
public Action CloseAction { get; set; }
|
||||
|
||||
public bool EmailIsInSavedAccounts => _stateService.AccountViews != null && _stateService.AccountViews.Any(e => e.Email == Email);
|
||||
|
||||
protected override II18nService i18nService => _i18nService;
|
||||
protected override IEnvironmentService environmentService => _environmentService;
|
||||
protected override IDeviceActionService deviceActionService => _deviceActionService;
|
||||
@@ -112,9 +140,22 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Email))
|
||||
try
|
||||
{
|
||||
Email = await _stateService.GetRememberedEmailAsync();
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
|
||||
await AccountSwitchingOverlayViewModel.RefreshAccountViewsAsync();
|
||||
if (string.IsNullOrWhiteSpace(Email))
|
||||
{
|
||||
Email = await _stateService.GetRememberedEmailAsync();
|
||||
}
|
||||
var deviceIdentifier = await _appIdService.GetAppIdAsync();
|
||||
IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier);
|
||||
CanRemoveAccount = await _stateService.GetActiveUserEmailAsync() != Email;
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +199,7 @@ namespace Bit.App.Pages
|
||||
var userEnvUrls = await _stateService.GetEnvironmentUrlsAsync(userId);
|
||||
if (userEnvUrls?.Base == _environmentService.BaseUrl)
|
||||
{
|
||||
await PromptToSwitchToExistingAccountAsync(userId);
|
||||
await _accountManager.PromptToSwitchToExistingAccountAsync(userId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -170,7 +211,6 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
var response = await _authService.LogInAsync(Email, MasterPassword, _captchaToken);
|
||||
await _stateService.SetRememberedEmailAsync(Email);
|
||||
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
|
||||
|
||||
if (response.CaptchaNeeded)
|
||||
@@ -216,19 +256,14 @@ namespace Bit.App.Pages
|
||||
|
||||
private async Task MoreAsync()
|
||||
{
|
||||
var buttons = IsEmailEnabled
|
||||
var buttons = IsEmailEnabled || CanRemoveAccount
|
||||
? new[] { AppResources.GetPasswordHint }
|
||||
: new[] { AppResources.GetPasswordHint, AppResources.RemoveAccount };
|
||||
var selection = await _deviceActionService.DisplayActionSheetAsync(AppResources.Options, AppResources.Cancel, null, buttons);
|
||||
|
||||
if (selection == AppResources.GetPasswordHint)
|
||||
{
|
||||
var hintNavigationPage = new NavigationPage(new HintPage());
|
||||
if (IsIosExtension)
|
||||
{
|
||||
ThemeManager.ApplyResourcesTo(hintNavigationPage);
|
||||
}
|
||||
await Page.Navigation.PushModalAsync(hintNavigationPage);
|
||||
await ShowMasterPasswordHintAsync();
|
||||
}
|
||||
else if (selection == AppResources.RemoveAccount)
|
||||
{
|
||||
@@ -236,6 +271,16 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ShowMasterPasswordHintAsync()
|
||||
{
|
||||
var hintNavigationPage = new NavigationPage(new HintPage(Email));
|
||||
if (IsIosExtension)
|
||||
{
|
||||
ThemeManager.ApplyResourcesTo(hintNavigationPage);
|
||||
}
|
||||
await Page.Navigation.PushModalAsync(hintNavigationPage);
|
||||
}
|
||||
|
||||
public void TogglePassword()
|
||||
{
|
||||
ShowPassword = !ShowPassword;
|
||||
@@ -261,16 +306,14 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PromptToSwitchToExistingAccountAsync(string userId)
|
||||
private void HandleException(Exception ex)
|
||||
{
|
||||
var switchToAccount = await _platformUtilsService.ShowDialogAsync(
|
||||
AppResources.SwitchToAlreadyAddedAccountConfirmation,
|
||||
AppResources.AccountAlreadyAdded, AppResources.Yes, AppResources.Cancel);
|
||||
if (switchToAccount)
|
||||
Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
await _stateService.SetActiveUserAsync(userId);
|
||||
_messagingService.Send("switchedAccount");
|
||||
}
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage);
|
||||
}).FireAndForget();
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
85
src/App/Pages/Accounts/LoginPasswordlessPage.xaml
Normal file
85
src/App/Pages/Accounts/LoginPasswordlessPage.xaml
Normal file
@@ -0,0 +1,85 @@
|
||||
<?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.LoginPasswordlessPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:LoginPasswordlessViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
|
||||
<ContentPage.BindingContext>
|
||||
<pages:LoginPasswordlessViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
|
||||
x:Name="_closeItem" x:Key="closeItem" />
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
<StackLayout
|
||||
Padding="7, 0, 7, 20">
|
||||
<ScrollView
|
||||
VerticalOptions="FillAndExpand">
|
||||
<StackLayout>
|
||||
<Label
|
||||
Text="{u:I18n AreYouTryingToLogIn}"
|
||||
FontSize="Title"
|
||||
FontAttributes="Bold"
|
||||
Margin="0,14,0,21"/>
|
||||
<Label
|
||||
Text="{Binding LogInAttemptByLabel}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,24"/>
|
||||
<Label
|
||||
Text="{u:I18n FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
<controls:MonoLabel
|
||||
FormattedText="{Binding LoginRequest.FingerprintPhrase}"
|
||||
FontSize="Medium"
|
||||
TextColor="{DynamicResource FingerprintPhrase}"
|
||||
Margin="0,0,0,27"/>
|
||||
<Label
|
||||
Text="{u:I18n DeviceType}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
<Label
|
||||
Text="{Binding LoginRequest.DeviceType}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,21"/>
|
||||
<Label
|
||||
Text="{u:I18n IpAddress}"
|
||||
IsVisible="{Binding ShowIpAddress}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
<Label
|
||||
Text="{Binding LoginRequest.IpAddress}"
|
||||
IsVisible="{Binding ShowIpAddress}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,21"/>
|
||||
<Label
|
||||
Text="{u:I18n Time}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
<Label
|
||||
Text="{Binding TimeOfRequestText}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,57"/>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
|
||||
<Button
|
||||
Text="{u:I18n ConfirmLogIn}"
|
||||
Command="{Binding AcceptRequestCommand}"
|
||||
Margin="0,0,0,17"
|
||||
StyleClass="btn-primary"/>
|
||||
<Button
|
||||
Text="{u:I18n DenyLogIn}"
|
||||
Command="{Binding RejectRequestCommand}"
|
||||
StyleClass="btn-secundary"/>
|
||||
|
||||
</StackLayout>
|
||||
</pages:BaseContentPage>
|
||||
40
src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs
Normal file
40
src/App/Pages/Accounts/LoginPasswordlessPage.xaml.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class LoginPasswordlessPage : BaseContentPage
|
||||
{
|
||||
private LoginPasswordlessViewModel _vm;
|
||||
|
||||
public LoginPasswordlessPage(LoginPasswordlessDetails loginPasswordlessDetails)
|
||||
{
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as LoginPasswordlessViewModel;
|
||||
_vm.Page = this;
|
||||
|
||||
_vm.LoginRequest = loginPasswordlessDetails;
|
||||
|
||||
ToolbarItems.Add(_closeItem);
|
||||
}
|
||||
|
||||
private async void Close_Clicked(object sender, System.EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
await Navigation.PopModalAsync();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
_vm.StartRequestTimeUpdater();
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
_vm.StopRequestTimeUpdater();
|
||||
}
|
||||
}
|
||||
}
|
||||
76
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml
Normal file
76
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<pages:BaseContentPage
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="Bit.App.Pages.LoginPasswordlessRequestPage"
|
||||
xmlns:pages="clr-namespace:Bit.App.Pages"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="pages:LoginPasswordlessRequestViewModel"
|
||||
Title="{Binding PageTitle}">
|
||||
|
||||
<ContentPage.BindingContext>
|
||||
<pages:LoginPasswordlessRequestViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
<ContentPage.ToolbarItems>
|
||||
<ToolbarItem Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1" x:Name="_closeItem"/>
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout
|
||||
Padding="7, 0, 7, 20">
|
||||
<Label
|
||||
Text="{u:I18n LogInInitiated}"
|
||||
FontSize="Title"
|
||||
FontAttributes="Bold"
|
||||
Margin="0,14,0,21"/>
|
||||
<Label
|
||||
Text="{u:I18n ANotificationHasBeenSentToYourDevice}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,10"/>
|
||||
<Label
|
||||
Text="{u:I18n PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice}"
|
||||
FontSize="Small"
|
||||
Margin="0,0,0,24"/>
|
||||
<Label
|
||||
Text="{u:I18n FingerprintPhrase}"
|
||||
FontSize="Small"
|
||||
FontAttributes="Bold"/>
|
||||
<controls:MonoLabel
|
||||
FormattedText="{Binding FingerprintPhrase}"
|
||||
FontSize="Medium"
|
||||
TextColor="{DynamicResource FingerprintPhrase}"/>
|
||||
<Label
|
||||
Text="{u:I18n ResendNotification}"
|
||||
StyleClass="text-md"
|
||||
HorizontalOptions="Start"
|
||||
Margin="0,40,0,0"
|
||||
TextColor="{DynamicResource HyperlinkColor}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding CreatePasswordlessLoginCommand}" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
<StackLayout
|
||||
Orientation="Horizontal"
|
||||
Margin="0,30,0,0">
|
||||
<Label
|
||||
Text="{u:I18n NeedAnotherOption}"
|
||||
FontSize="Small"
|
||||
VerticalTextAlignment="End"/>
|
||||
<Label
|
||||
Text="{u:I18n ViewAllLoginOptions}"
|
||||
StyleClass="text-md"
|
||||
VerticalTextAlignment="End"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
Margin="5, 0"
|
||||
TextColor="{DynamicResource HyperlinkColor}">
|
||||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding CloseCommand}" />
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</StackLayout>
|
||||
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</pages:BaseContentPage>
|
||||
65
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs
Normal file
65
src/App/Pages/Accounts/LoginPasswordlessRequestPage.xaml.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public partial class LoginPasswordlessRequestPage : BaseContentPage
|
||||
{
|
||||
private LoginPasswordlessRequestViewModel _vm;
|
||||
private readonly AppOptions _appOptions;
|
||||
|
||||
public LoginPasswordlessRequestPage(string email, AppOptions appOptions = null)
|
||||
{
|
||||
InitializeComponent();
|
||||
_appOptions = appOptions;
|
||||
_vm = BindingContext as LoginPasswordlessRequestViewModel;
|
||||
_vm.Page = this;
|
||||
_vm.Email = email;
|
||||
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
|
||||
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
|
||||
_vm.UpdateTempPasswordAction = () => Device.BeginInvokeOnMainThread(async () => await UpdateTempPasswordAsync());
|
||||
_vm.CloseAction = () => { Navigation.PopModalAsync(); };
|
||||
|
||||
_vm.CreatePasswordlessLoginCommand.Execute(null);
|
||||
}
|
||||
|
||||
protected override void OnAppearing()
|
||||
{
|
||||
base.OnAppearing();
|
||||
_vm.StartCheckLoginRequestStatus();
|
||||
}
|
||||
|
||||
protected override void OnDisappearing()
|
||||
{
|
||||
base.OnDisappearing();
|
||||
_vm.StopCheckLoginRequestStatus();
|
||||
}
|
||||
|
||||
private async Task StartTwoFactorAsync()
|
||||
{
|
||||
var page = new TwoFactorPage(false, _appOptions);
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
private async Task LogInSuccessAsync()
|
||||
{
|
||||
if (AppHelpers.SetAlternateMainPage(_appOptions))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var previousPage = await AppHelpers.ClearPreviousPage();
|
||||
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
|
||||
}
|
||||
|
||||
private async Task UpdateTempPasswordAsync()
|
||||
{
|
||||
var page = new UpdateTempPasswordPage();
|
||||
await Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
194
src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs
Normal file
194
src/App/Pages/Accounts/LoginPasswordlessRequestViewModel.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class LoginPasswordlessRequestViewModel : CaptchaProtectedViewModel
|
||||
{
|
||||
private const int REQUEST_TIME_UPDATE_PERIOD_IN_SECONDS = 4;
|
||||
|
||||
private IDeviceActionService _deviceActionService;
|
||||
private IAuthService _authService;
|
||||
private ISyncService _syncService;
|
||||
private II18nService _i18nService;
|
||||
private IStateService _stateService;
|
||||
private IPlatformUtilsService _platformUtilsService;
|
||||
private IEnvironmentService _environmentService;
|
||||
private ILogger _logger;
|
||||
|
||||
protected override II18nService i18nService => _i18nService;
|
||||
protected override IEnvironmentService environmentService => _environmentService;
|
||||
protected override IDeviceActionService deviceActionService => _deviceActionService;
|
||||
protected override IPlatformUtilsService platformUtilsService => _platformUtilsService;
|
||||
|
||||
private CancellationTokenSource _checkLoginRequestStatusCts;
|
||||
private Task _checkLoginRequestStatusTask;
|
||||
private string _fingerprintPhrase;
|
||||
private string _email;
|
||||
private string _requestId;
|
||||
private string _requestAccessCode;
|
||||
// Item1 publicKey, Item2 privateKey
|
||||
private Tuple<byte[], byte[]> _requestKeyPair;
|
||||
|
||||
public LoginPasswordlessRequestViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>();
|
||||
_authService = ServiceContainer.Resolve<IAuthService>();
|
||||
_syncService = ServiceContainer.Resolve<ISyncService>();
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>();
|
||||
_stateService = ServiceContainer.Resolve<IStateService>();
|
||||
_logger = ServiceContainer.Resolve<ILogger>();
|
||||
|
||||
PageTitle = AppResources.LogInWithAnotherDevice;
|
||||
|
||||
CreatePasswordlessLoginCommand = new AsyncCommand(CreatePasswordlessLoginAsync,
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
CloseCommand = new AsyncCommand(() => Device.InvokeOnMainThreadAsync(CloseAction),
|
||||
onException: _logger.Exception,
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public Action StartTwoFactorAction { get; set; }
|
||||
public Action LogInSuccessAction { get; set; }
|
||||
public Action UpdateTempPasswordAction { get; set; }
|
||||
public Action CloseAction { get; set; }
|
||||
|
||||
public ICommand CreatePasswordlessLoginCommand { get; }
|
||||
public ICommand CloseCommand { get; }
|
||||
|
||||
public string FingerprintPhrase
|
||||
{
|
||||
get => _fingerprintPhrase;
|
||||
set => SetProperty(ref _fingerprintPhrase, value);
|
||||
}
|
||||
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
set => SetProperty(ref _email, value);
|
||||
}
|
||||
|
||||
public void StartCheckLoginRequestStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
_checkLoginRequestStatusCts?.Cancel();
|
||||
_checkLoginRequestStatusCts = new CancellationTokenSource();
|
||||
_checkLoginRequestStatusTask = new TimerTask(_logger, CheckLoginRequestStatus, _checkLoginRequestStatusCts).RunPeriodic(TimeSpan.FromSeconds(REQUEST_TIME_UPDATE_PERIOD_IN_SECONDS));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void StopCheckLoginRequestStatus()
|
||||
{
|
||||
try
|
||||
{
|
||||
_checkLoginRequestStatusCts?.Cancel();
|
||||
_checkLoginRequestStatusCts?.Dispose();
|
||||
_checkLoginRequestStatusCts = null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CheckLoginRequestStatus()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_requestId) || string.IsNullOrEmpty(_requestAccessCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var response = await _authService.GetPasswordlessLoginResponseAsync(_requestId, _requestAccessCode);
|
||||
|
||||
if (!response.RequestApproved)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StopCheckLoginRequestStatus();
|
||||
|
||||
var authResult = await _authService.LogInPasswordlessAsync(Email, _requestAccessCode, _requestId, _requestKeyPair.Item2, response.Key, response.MasterPasswordHash);
|
||||
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
|
||||
|
||||
if (await HandleCaptchaAsync(authResult.CaptchaSiteKey, authResult.CaptchaNeeded, CheckLoginRequestStatus))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (authResult.TwoFactor)
|
||||
{
|
||||
StartTwoFactorAction?.Invoke();
|
||||
}
|
||||
else if (authResult.ForcePasswordReset)
|
||||
{
|
||||
UpdateTempPasswordAction?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
_syncService.FullSyncAsync(true).FireAndForget();
|
||||
LogInSuccessAction?.Invoke();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
StartCheckLoginRequestStatus();
|
||||
HandleException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CreatePasswordlessLoginAsync()
|
||||
{
|
||||
await Device.InvokeOnMainThreadAsync(() => _deviceActionService.ShowLoadingAsync(AppResources.Loading));
|
||||
|
||||
var response = await _authService.PasswordlessCreateLoginRequestAsync(_email);
|
||||
if (response != null)
|
||||
{
|
||||
FingerprintPhrase = response.RequestFingerprint;
|
||||
_requestId = response.Id;
|
||||
_requestAccessCode = response.RequestAccessCode;
|
||||
_requestKeyPair = response.RequestKeyPair;
|
||||
}
|
||||
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
}
|
||||
|
||||
private void HandleException(Exception ex)
|
||||
{
|
||||
Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage);
|
||||
}).FireAndForget();
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
175
src/App/Pages/Accounts/LoginPasswordlessViewModel.cs
Normal file
175
src/App/Pages/Accounts/LoginPasswordlessViewModel.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class LoginPasswordlessViewModel : BaseViewModel
|
||||
{
|
||||
private IDeviceActionService _deviceActionService;
|
||||
private IAuthService _authService;
|
||||
private IPlatformUtilsService _platformUtilsService;
|
||||
private ILogger _logger;
|
||||
private LoginPasswordlessDetails _resquest;
|
||||
private CancellationTokenSource _requestTimeCts;
|
||||
private Task _requestTimeTask;
|
||||
|
||||
private const int REQUEST_TIME_UPDATE_PERIOD_IN_MINUTES = 5;
|
||||
|
||||
public LoginPasswordlessViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_authService = ServiceContainer.Resolve<IAuthService>("authService");
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
PageTitle = AppResources.LogInRequested;
|
||||
|
||||
AcceptRequestCommand = new AsyncCommand(() => PasswordlessLoginAsync(true),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
RejectRequestCommand = new AsyncCommand(() => PasswordlessLoginAsync(false),
|
||||
onException: ex => HandleException(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public ICommand AcceptRequestCommand { get; }
|
||||
|
||||
public ICommand RejectRequestCommand { get; }
|
||||
|
||||
public string LogInAttemptByLabel => LoginRequest != null ? string.Format(AppResources.LogInAttemptByXOnY, LoginRequest.Email, LoginRequest.Origin) : string.Empty;
|
||||
|
||||
public string TimeOfRequestText => CreateRequestDate(LoginRequest?.RequestDate);
|
||||
|
||||
public bool ShowIpAddress => !string.IsNullOrEmpty(LoginRequest?.IpAddress);
|
||||
|
||||
public LoginPasswordlessDetails LoginRequest
|
||||
{
|
||||
get => _resquest;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _resquest, value, additionalPropertyNames: new string[]
|
||||
{
|
||||
nameof(LogInAttemptByLabel),
|
||||
nameof(TimeOfRequestText),
|
||||
nameof(ShowIpAddress),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void StopRequestTimeUpdater()
|
||||
{
|
||||
try
|
||||
{
|
||||
_requestTimeCts?.Cancel();
|
||||
_requestTimeCts?.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void StartRequestTimeUpdater()
|
||||
{
|
||||
try
|
||||
{
|
||||
_requestTimeCts?.Cancel();
|
||||
_requestTimeCts = new CancellationTokenSource();
|
||||
_requestTimeTask = new TimerTask(_logger, UpdateRequestTime, _requestTimeCts).RunPeriodic(TimeSpan.FromMinutes(REQUEST_TIME_UPDATE_PERIOD_IN_MINUTES));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UpdateRequestTime()
|
||||
{
|
||||
TriggerPropertyChanged(nameof(TimeOfRequestText));
|
||||
if (DateTime.UtcNow > LoginRequest?.RequestDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes))
|
||||
{
|
||||
StopRequestTimeUpdater();
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.LoginRequestHasAlreadyExpired);
|
||||
await Page.Navigation.PopModalAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task PasswordlessLoginAsync(bool approveRequest)
|
||||
{
|
||||
if (LoginRequest.RequestDate.ToUniversalTime().AddMinutes(Constants.PasswordlessNotificationTimeoutInMinutes) <= DateTime.UtcNow)
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.LoginRequestHasAlreadyExpired);
|
||||
await Page.Navigation.PopModalAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
|
||||
await _authService.PasswordlessLoginAsync(LoginRequest.Id, LoginRequest.PubKey, approveRequest);
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
await Page.Navigation.PopModalAsync();
|
||||
_platformUtilsService.ShowToast("info", null, approveRequest ? AppResources.LogInAccepted : AppResources.LogInDenied);
|
||||
|
||||
StopRequestTimeUpdater();
|
||||
}
|
||||
|
||||
private string CreateRequestDate(DateTime? requestDate)
|
||||
{
|
||||
if (!requestDate.HasValue)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
if (DateTime.UtcNow < requestDate.Value.ToUniversalTime().AddMinutes(REQUEST_TIME_UPDATE_PERIOD_IN_MINUTES))
|
||||
{
|
||||
return AppResources.JustNow;
|
||||
}
|
||||
|
||||
return string.Format(AppResources.XMinutesAgo, DateTime.UtcNow.Minute - requestDate.Value.ToUniversalTime().Minute);
|
||||
}
|
||||
|
||||
private void HandleException(Exception ex)
|
||||
{
|
||||
Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.GenericErrorMessage);
|
||||
}).FireAndForget();
|
||||
_logger.Exception(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public class LoginPasswordlessDetails
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Key { get; set; }
|
||||
|
||||
public string PubKey { get; set; }
|
||||
|
||||
public string Origin { get; set; }
|
||||
|
||||
public string Email { get; set; }
|
||||
|
||||
public string FingerprintPhrase { get; set; }
|
||||
|
||||
public DateTime RequestDate { get; set; }
|
||||
|
||||
public string DeviceType { get; set; }
|
||||
|
||||
public string IpAddress { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -129,7 +129,8 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (useCurrentActiveAccount)
|
||||
{
|
||||
return new AvatarImageSource(await _stateService.GetNameAsync(), await _stateService.GetEmailAsync());
|
||||
return new AvatarImageSource(await _stateService.GetActiveUserIdAsync(),
|
||||
await _stateService.GetNameAsync(), await _stateService.GetEmailAsync());
|
||||
}
|
||||
return new AvatarImageSource();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,22 @@ namespace Bit.App.Pages
|
||||
protected abstract IPlatformUtilsService platformUtilsService { get; }
|
||||
protected string _captchaToken = null;
|
||||
|
||||
protected async Task<bool> HandleCaptchaAsync(string captchaSiteKey, bool needsCaptcha, Func<Task> onSuccess)
|
||||
{
|
||||
if (!needsCaptcha)
|
||||
{
|
||||
_captchaToken = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (await HandleCaptchaAsync(captchaSiteKey))
|
||||
{
|
||||
await onSuccess();
|
||||
_captchaToken = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected async Task<bool> HandleCaptchaAsync(string CaptchaSiteKey)
|
||||
{
|
||||
var callbackUri = "bitwarden://captcha-callback";
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<u:InverseBoolConverter x:Key="inverseBool" />
|
||||
<u:LocalizableEnumConverter x:Key="localizableEnum" />
|
||||
<xct:EnumToBoolConverter x:Key="enumToBool"/>
|
||||
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
|
||||
<ToolbarItem Text="{u:I18n Cancel}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1"
|
||||
x:Name="_closeItem" x:Key="closeItem" />
|
||||
<ToolbarItem Text="{u:I18n Select}"
|
||||
Clicked="Select_Clicked"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Styles;
|
||||
using Bit.Core.Abstractions;
|
||||
@@ -18,11 +19,11 @@ namespace Bit.App.Pages
|
||||
private readonly Action<string> _selectAction;
|
||||
private readonly TabsPage _tabsPage;
|
||||
|
||||
public GeneratorPage(bool fromTabPage, Action<string> selectAction = null, TabsPage tabsPage = null, bool isUsernameGenerator = false, string emailWebsite = null, bool editMode = false)
|
||||
public GeneratorPage(bool fromTabPage, Action<string> selectAction = null, TabsPage tabsPage = null, bool isUsernameGenerator = false, string emailWebsite = null, bool editMode = false, AppOptions appOptions = null)
|
||||
{
|
||||
_tabsPage = tabsPage;
|
||||
InitializeComponent();
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
|
||||
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
|
||||
_vm = BindingContext as GeneratorPageViewModel;
|
||||
_vm.Page = this;
|
||||
_fromTabPage = fromTabPage;
|
||||
@@ -31,6 +32,7 @@ namespace Bit.App.Pages
|
||||
_vm.IsUsername = isUsernameGenerator;
|
||||
_vm.EmailWebsite = emailWebsite;
|
||||
_vm.EditMode = editMode;
|
||||
_vm.IosExtension = appOptions?.IosExtension ?? false;
|
||||
var isIos = Device.RuntimePlatform == Device.iOS;
|
||||
if (selectAction != null)
|
||||
{
|
||||
@@ -134,14 +136,6 @@ namespace Bit.App.Pages
|
||||
await _vm.SliderChangedAsync();
|
||||
}
|
||||
|
||||
private async void Close_Clicked(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
await Navigation.PopModalAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task UpdateOnThemeChanged()
|
||||
{
|
||||
await base.UpdateOnThemeChanged();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
@@ -20,6 +21,8 @@ namespace Bit.App.Pages
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly IUsernameGenerationService _usernameGenerationService;
|
||||
private readonly ITokenService _tokenService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
|
||||
|
||||
private PasswordGenerationOptions _options;
|
||||
@@ -49,8 +52,6 @@ namespace Bit.App.Pages
|
||||
private bool _showFirefoxRelayApiAccessToken;
|
||||
private bool _showAnonAddyApiAccessToken;
|
||||
private bool _showSimpleLoginApiKey;
|
||||
private UsernameEmailType _catchAllEmailTypeSelected;
|
||||
private UsernameEmailType _plusAddressedEmailTypeSelected;
|
||||
private bool _editMode;
|
||||
|
||||
public GeneratorPageViewModel()
|
||||
@@ -59,6 +60,8 @@ namespace Bit.App.Pages
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
|
||||
_clipboardService = ServiceContainer.Resolve<IClipboardService>();
|
||||
_usernameGenerationService = ServiceContainer.Resolve<IUsernameGenerationService>();
|
||||
_tokenService = ServiceContainer.Resolve<ITokenService>();
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
|
||||
|
||||
PageTitle = AppResources.Generator;
|
||||
GeneratorTypeOptions = new List<GeneratorType> {
|
||||
@@ -89,8 +92,9 @@ 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 => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
CopyCommand = new AsyncCommand(CopyAsync, onException: ex => OnSubmitException(ex), allowsMultipleExecutions: false);
|
||||
ToggleForwardedEmailHiddenValueCommand = new AsyncCommand(ToggleForwardedEmailHiddenValueAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
CopyCommand = new AsyncCommand(CopyAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
CloseCommand = new AsyncCommand(CloseAsync, onException: ex => _logger.Value.Exception(ex), allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
public List<GeneratorType> GeneratorTypeOptions { get; set; }
|
||||
@@ -104,6 +108,7 @@ namespace Bit.App.Pages
|
||||
public ICommand RegenerateUsernameCommand { get; set; }
|
||||
public ICommand ToggleForwardedEmailHiddenValueCommand { get; set; }
|
||||
public ICommand CopyCommand { get; set; }
|
||||
public ICommand CloseCommand { get; set; }
|
||||
|
||||
public string Password
|
||||
{
|
||||
@@ -140,6 +145,8 @@ namespace Bit.App.Pages
|
||||
set => SetProperty(ref _isUsername, value);
|
||||
}
|
||||
|
||||
public bool IosExtension { get; set; }
|
||||
|
||||
public bool ShowTypePicker
|
||||
{
|
||||
get => _showTypePicker;
|
||||
@@ -157,7 +164,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public bool ShowUsernameEmailType
|
||||
{
|
||||
get => !string.IsNullOrWhiteSpace(EmailWebsite) || EditMode;
|
||||
get => !string.IsNullOrWhiteSpace(EmailWebsite);
|
||||
}
|
||||
|
||||
public int Length
|
||||
@@ -367,7 +374,7 @@ namespace Bit.App.Pages
|
||||
IsUsername = value == GeneratorType.Username;
|
||||
TriggerPropertyChanged(nameof(GeneratorTypeSelected));
|
||||
SaveOptionsAsync().FireAndForget();
|
||||
SaveUsernameOptionsAsync(false).FireAndForget();
|
||||
SaveUsernameOptionsAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,6 +389,7 @@ namespace Bit.App.Pages
|
||||
IsPassword = value == 0;
|
||||
TriggerPropertyChanged(nameof(PasswordTypeSelectedIndex));
|
||||
SaveOptionsAsync().FireAndForget();
|
||||
SaveUsernameOptionsAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,7 +404,7 @@ namespace Bit.App.Pages
|
||||
_usernameOptions.Type = value;
|
||||
Username = Constants.DefaultUsernameGenerated;
|
||||
TriggerPropertyChanged(nameof(UsernameTypeSelected), new string[] { nameof(UsernameTypeDescriptionLabel) });
|
||||
SaveUsernameOptionsAsync(false).FireAndForget();
|
||||
SaveUsernameOptionsAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -564,26 +572,28 @@ namespace Bit.App.Pages
|
||||
|
||||
public UsernameEmailType PlusAddressedEmailTypeSelected
|
||||
{
|
||||
get => _plusAddressedEmailTypeSelected;
|
||||
get => _usernameOptions.PlusAddressedEmailType;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _plusAddressedEmailTypeSelected, value))
|
||||
if (_usernameOptions.PlusAddressedEmailType != value)
|
||||
{
|
||||
_usernameOptions.PlusAddressedEmailType = value;
|
||||
SaveUsernameOptionsAsync(false).FireAndForget();
|
||||
TriggerPropertyChanged(nameof(PlusAddressedEmailTypeSelected));
|
||||
SaveUsernameOptionsAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UsernameEmailType CatchAllEmailTypeSelected
|
||||
{
|
||||
get => _catchAllEmailTypeSelected;
|
||||
get => _usernameOptions.CatchAllEmailType;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _catchAllEmailTypeSelected, value))
|
||||
if (_usernameOptions.CatchAllEmailType != value)
|
||||
{
|
||||
_usernameOptions.CatchAllEmailType = value;
|
||||
SaveUsernameOptionsAsync(false).FireAndForget();
|
||||
TriggerPropertyChanged(nameof(CatchAllEmailTypeSelected));
|
||||
SaveUsernameOptionsAsync().FireAndForget();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,16 +611,29 @@ namespace Bit.App.Pages
|
||||
{
|
||||
(_options, EnforcedPolicyOptions) = await _passwordGenerationService.GetOptionsAsync();
|
||||
LoadFromOptions();
|
||||
await RegenerateAsync();
|
||||
|
||||
_usernameOptions = await _usernameGenerationService.GetOptionsAsync();
|
||||
await _tokenService.PrepareTokenForDecodingAsync();
|
||||
_usernameOptions.PlusAddressedEmail = _tokenService.GetEmail();
|
||||
_usernameOptions.EmailWebsite = EmailWebsite;
|
||||
_usernameOptions.CatchAllEmailType = _usernameOptions.PlusAddressedEmailType = string.IsNullOrWhiteSpace(EmailWebsite) || !EditMode ? UsernameEmailType.Random : UsernameEmailType.Website;
|
||||
|
||||
if (!EditMode)
|
||||
if (!IsUsername)
|
||||
{
|
||||
_usernameOptions.CatchAllEmailType = _usernameOptions.PlusAddressedEmailType = UsernameEmailType.Random;
|
||||
await RegenerateAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UsernameTypeSelected != UsernameType.ForwardedEmailAlias)
|
||||
{
|
||||
await RegenerateUsernameAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Username = Constants.DefaultUsernameGenerated;
|
||||
}
|
||||
}
|
||||
TriggerUsernamePropertiesChanged();
|
||||
Username = Constants.DefaultUsernameGenerated;
|
||||
|
||||
_doneIniting = true;
|
||||
}
|
||||
@@ -666,12 +689,17 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
|
||||
_usernameOptions.EmailWebsite = EmailWebsite;
|
||||
await _usernameGenerationService.SaveOptionsAsync(_usernameOptions);
|
||||
|
||||
if (regenerate)
|
||||
if (regenerate && UsernameTypeSelected != UsernameType.ForwardedEmailAlias)
|
||||
{
|
||||
await RegenerateUsernameAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
Username = Constants.DefaultUsernameGenerated;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SliderChangedAsync()
|
||||
@@ -710,6 +738,18 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
public async Task CloseAsync()
|
||||
{
|
||||
if (IosExtension)
|
||||
{
|
||||
_deviceActionService.CloseExtensionPopUp();
|
||||
}
|
||||
else
|
||||
{
|
||||
await Page.Navigation.PopModalAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadFromOptions()
|
||||
{
|
||||
AllowAmbiguousChars = _options.AllowAmbiguousChar.GetValueOrDefault();
|
||||
@@ -746,6 +786,7 @@ namespace Bit.App.Pages
|
||||
TriggerPropertyChanged(nameof(PlusAddressedEmail));
|
||||
TriggerPropertyChanged(nameof(GeneratorTypeSelected));
|
||||
TriggerPropertyChanged(nameof(UsernameTypeDescriptionLabel));
|
||||
TriggerPropertyChanged(nameof(EmailWebsite));
|
||||
}
|
||||
|
||||
private void SetOptions()
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Bit.App.Pages
|
||||
public class SendAddEditPageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IStateService _stateService;
|
||||
@@ -51,6 +52,7 @@ namespace Bit.App.Pages
|
||||
public SendAddEditPageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
@@ -292,7 +294,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public async Task ChooseFileAsync()
|
||||
{
|
||||
await _deviceActionService.SelectFileAsync();
|
||||
await _fileService.SelectFileAsync();
|
||||
}
|
||||
|
||||
public void ClearExpirationDate()
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
await LoadDataAsync();
|
||||
|
||||
var uppercaseGroupNames = _deviceActionService.DeviceType == DeviceType.iOS;
|
||||
var uppercaseGroupNames = Device.RuntimePlatform == Device.iOS;
|
||||
if (MainPage)
|
||||
{
|
||||
groupedSends.Add(new SendGroupingsPageListGroup(
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
StyleClass="box-value"
|
||||
HorizontalOptions="End" />
|
||||
<Button
|
||||
Clicked="ToggleAccessibility"
|
||||
Command="{Binding ToggleAccessibilityCommand}"
|
||||
StyleClass="box-overlay"
|
||||
RelativeLayout.XConstraint="0"
|
||||
RelativeLayout.YConstraint="0"
|
||||
|
||||
@@ -55,14 +55,6 @@ namespace Bit.App.Pages
|
||||
_vm.ToggleInlineAutofill();
|
||||
}
|
||||
|
||||
private void ToggleAccessibility(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
{
|
||||
_vm.ToggleAccessibility();
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleDrawOver(object sender, EventArgs e)
|
||||
{
|
||||
if (DoOnce())
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Services;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class AutofillServicesPageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly MobileI18nService _i18nService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
readonly LazyResolve<ILogger> _logger = new LazyResolve<ILogger>("logger");
|
||||
|
||||
private bool _autofillServiceToggled;
|
||||
private bool _inlineAutofillToggled;
|
||||
@@ -22,9 +27,14 @@ namespace Bit.App.Pages
|
||||
public AutofillServicesPageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService;
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
PageTitle = AppResources.AutofillServices;
|
||||
ToggleAccessibilityCommand = new AsyncCommand(ToggleAccessibilityAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
}
|
||||
|
||||
#region Autofill Service
|
||||
@@ -74,6 +84,8 @@ namespace Bit.App.Pages
|
||||
|
||||
#region Accessibility
|
||||
|
||||
public ICommand ToggleAccessibilityCommand { get; }
|
||||
|
||||
public string AccessibilityDescriptionLabel
|
||||
{
|
||||
get
|
||||
@@ -163,7 +175,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
else
|
||||
{
|
||||
_deviceActionService.DisableAutofillService();
|
||||
_autofillHandler.DisableAutofillService();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,8 +188,18 @@ namespace Bit.App.Pages
|
||||
InlineAutofillToggled = !InlineAutofillToggled;
|
||||
}
|
||||
|
||||
public void ToggleAccessibility()
|
||||
public async Task ToggleAccessibilityAsync()
|
||||
{
|
||||
if (!_autofillHandler.AutofillAccessibilityServiceRunning())
|
||||
{
|
||||
var accept = await _platformUtilsService.ShowDialogAsync(AppResources.AccessibilityDisclosureText,
|
||||
AppResources.AccessibilityServiceDisclosure, AppResources.Accept,
|
||||
AppResources.Decline);
|
||||
if (!accept)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
_deviceActionService.OpenAccessibilitySettings();
|
||||
}
|
||||
|
||||
@@ -193,9 +215,9 @@ namespace Bit.App.Pages
|
||||
public void UpdateEnabled()
|
||||
{
|
||||
AutofillServiceToggled =
|
||||
_deviceActionService.HasAutofillService() && _deviceActionService.AutofillServiceEnabled();
|
||||
AccessibilityToggled = _deviceActionService.AutofillAccessibilityServiceRunning();
|
||||
DrawOverToggled = _deviceActionService.AutofillAccessibilityOverlayPermitted();
|
||||
_autofillHandler.SupportsAutofillService() && _autofillHandler.AutofillServiceEnabled();
|
||||
AccessibilityToggled = _autofillHandler.AutofillAccessibilityServiceRunning();
|
||||
DrawOverToggled = _autofillHandler.AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
|
||||
private async Task UpdateInlineAutofillToggledAsync()
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace Bit.App.Pages
|
||||
public class ExportVaultPageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly IExportService _exportService;
|
||||
@@ -39,6 +40,7 @@ namespace Bit.App.Pages
|
||||
public ExportVaultPageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_exportService = ServiceContainer.Resolve<IExportService>("exportService");
|
||||
@@ -182,7 +184,7 @@ namespace Bit.App.Pages
|
||||
_defaultFilename = _exportService.GetFileName(null, fileFormat);
|
||||
_exportResult = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
if (!_deviceActionService.SaveFile(_exportResult, null, _defaultFilename, null))
|
||||
if (!_fileService.SaveFile(_exportResult, null, _defaultFilename, null))
|
||||
{
|
||||
ClearResult();
|
||||
await _platformUtilsService.ShowDialogAsync(_i18nService.T("ExportVaultFailure"));
|
||||
@@ -220,7 +222,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public async void SaveFileSelected(string contentUri, string filename)
|
||||
{
|
||||
if (_deviceActionService.SaveFile(_exportResult, null, filename ?? _defaultFilename, contentUri))
|
||||
if (_fileService.SaveFile(_exportResult, null, filename ?? _defaultFilename, contentUri))
|
||||
{
|
||||
ClearResult();
|
||||
_platformUtilsService.ShowToast("success", null, _i18nService.T("ExportVaultSuccess"));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.PlatformConfiguration;
|
||||
@@ -9,12 +10,12 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public partial class OptionsPage : BaseContentPage
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
private readonly OptionsPageViewModel _vm;
|
||||
|
||||
public OptionsPage()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
InitializeComponent();
|
||||
_vm = BindingContext as OptionsPageViewModel;
|
||||
_vm.Page = this;
|
||||
@@ -25,7 +26,7 @@ namespace Bit.App.Pages
|
||||
if (Device.RuntimePlatform == Device.Android)
|
||||
{
|
||||
ToolbarItems.RemoveAt(0);
|
||||
_vm.ShowAndroidAutofillSettings = _deviceActionService.SupportsAutofillService();
|
||||
_vm.ShowAndroidAutofillSettings = _autofillHandler.SupportsAutofillService();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -56,12 +56,14 @@ namespace Bit.App.Pages
|
||||
new KeyValuePair<string, string>(ThemeManager.Dark, AppResources.Dark),
|
||||
new KeyValuePair<string, string>(ThemeManager.Black, AppResources.Black),
|
||||
new KeyValuePair<string, string>(ThemeManager.Nord, AppResources.Nord),
|
||||
new KeyValuePair<string, string>(ThemeManager.SolarizedDark, AppResources.SolarizedDark),
|
||||
};
|
||||
AutoDarkThemeOptions = new List<KeyValuePair<string, string>>
|
||||
{
|
||||
new KeyValuePair<string, string>(ThemeManager.Dark, AppResources.Dark),
|
||||
new KeyValuePair<string, string>(ThemeManager.Black, AppResources.Black),
|
||||
new KeyValuePair<string, string>(ThemeManager.Nord, AppResources.Nord),
|
||||
new KeyValuePair<string, string>(ThemeManager.SolarizedDark, AppResources.SolarizedDark),
|
||||
};
|
||||
UriMatchOptions = new List<KeyValuePair<UriMatchType?, string>>
|
||||
{
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Bit.App.Pages
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
private readonly IEnvironmentService _environmentService;
|
||||
private readonly IMessagingService _messagingService;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
@@ -30,7 +31,7 @@ namespace Bit.App.Pages
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly ILogger _loggerService;
|
||||
|
||||
private readonly IPushNotificationService _pushNotificationService;
|
||||
private const int CustomVaultTimeoutValue = -100;
|
||||
|
||||
private bool _supportsBiometric;
|
||||
@@ -42,6 +43,7 @@ namespace Bit.App.Pages
|
||||
private string _vaultTimeoutActionDisplayValue;
|
||||
private bool _showChangeMasterPassword;
|
||||
private bool _reportLoggingEnabled;
|
||||
private bool _approvePasswordlessLoginRequests;
|
||||
|
||||
private List<KeyValuePair<string, int?>> _vaultTimeouts =
|
||||
new List<KeyValuePair<string, int?>>
|
||||
@@ -73,6 +75,7 @@ namespace Bit.App.Pages
|
||||
_cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
@@ -83,6 +86,7 @@ namespace Bit.App.Pages
|
||||
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
|
||||
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
|
||||
_loggerService = ServiceContainer.Resolve<ILogger>("logger");
|
||||
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
|
||||
|
||||
GroupedItems = new ObservableRangeCollection<ISettingsPageListItem>();
|
||||
PageTitle = AppResources.Settings;
|
||||
@@ -133,6 +137,7 @@ namespace Bit.App.Pages
|
||||
_showChangeMasterPassword = IncludeLinksWithSubscriptionInfo() &&
|
||||
!await _keyConnectorService.GetUsesKeyConnector();
|
||||
_reportLoggingEnabled = await _loggerService.IsEnabled();
|
||||
_approvePasswordlessLoginRequests = await _stateService.GetApprovePasswordlessLoginsAsync();
|
||||
BuildList();
|
||||
}
|
||||
|
||||
@@ -326,6 +331,38 @@ namespace Bit.App.Pages
|
||||
BuildList();
|
||||
}
|
||||
|
||||
public async Task ApproveLoginRequestsAsync()
|
||||
{
|
||||
var options = new[]
|
||||
{
|
||||
CreateSelectableOption(AppResources.Yes, _approvePasswordlessLoginRequests),
|
||||
CreateSelectableOption(AppResources.No, !_approvePasswordlessLoginRequests),
|
||||
};
|
||||
|
||||
var selection = await Page.DisplayActionSheet(AppResources.UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices, AppResources.Cancel, null, options);
|
||||
|
||||
if (selection == null || selection == AppResources.Cancel)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_approvePasswordlessLoginRequests = CompareSelection(selection, AppResources.Yes);
|
||||
await _stateService.SetApprovePasswordlessLoginsAsync(_approvePasswordlessLoginRequests);
|
||||
|
||||
BuildList();
|
||||
|
||||
if (!_approvePasswordlessLoginRequests || await _pushNotificationService.AreNotificationsSettingsEnabledAsync())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var openAppSettingsResult = await _platformUtilsService.ShowDialogAsync(AppResources.ReceivePushNotificationsForNewLoginRequests, title: string.Empty, confirmText: AppResources.Settings, cancelText: AppResources.NoThanks);
|
||||
if (openAppSettingsResult)
|
||||
{
|
||||
_deviceActionService.OpenAppSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task VaultTimeoutActionAsync()
|
||||
{
|
||||
var options = _vaultTimeoutActions.Select(o =>
|
||||
@@ -419,7 +456,7 @@ namespace Bit.App.Pages
|
||||
else if (await _platformUtilsService.SupportsBiometricAsync())
|
||||
{
|
||||
_biometric = await _platformUtilsService.AuthenticateBiometricAsync(null,
|
||||
_deviceActionService.DeviceType == Core.Enums.DeviceType.Android ? "." : null);
|
||||
Device.RuntimePlatform == Device.Android ? "." : null);
|
||||
}
|
||||
if (_biometric == current)
|
||||
{
|
||||
@@ -450,7 +487,7 @@ namespace Bit.App.Pages
|
||||
autofillItems.Add(new SettingsPageListItem
|
||||
{
|
||||
Name = AppResources.AutofillServices,
|
||||
SubLabel = _deviceActionService.AutofillServicesEnabled() ? AppResources.On : AppResources.Off,
|
||||
SubLabel = _autofillHandler.AutofillServicesEnabled() ? AppResources.On : AppResources.Off,
|
||||
ExecuteAsync = () => Page.Navigation.PushModalAsync(new NavigationPage(new AutofillServicesPage(Page as SettingsPage)))
|
||||
});
|
||||
}
|
||||
@@ -504,6 +541,12 @@ namespace Bit.App.Pages
|
||||
ExecuteAsync = () => UpdatePinAsync()
|
||||
},
|
||||
new SettingsPageListItem
|
||||
{
|
||||
Name = AppResources.ApproveLoginRequests,
|
||||
SubLabel = _approvePasswordlessLoginRequests ? AppResources.On : AppResources.Off,
|
||||
ExecuteAsync = () => ApproveLoginRequestsAsync()
|
||||
},
|
||||
new SettingsPageListItem
|
||||
{
|
||||
Name = AppResources.LockNow,
|
||||
ExecuteAsync = () => LockAsync()
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace Bit.App.Pages
|
||||
public class AttachmentsPageViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IFileService _fileService;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IStateService _stateService;
|
||||
@@ -34,6 +35,7 @@ namespace Bit.App.Pages
|
||||
public AttachmentsPageViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
_cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
@@ -156,7 +158,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_vaultTimeoutService.DelayLockAndLogoutMs = 60000;
|
||||
}
|
||||
await _deviceActionService.SelectFileAsync();
|
||||
await _fileService.SelectFileAsync();
|
||||
}
|
||||
|
||||
private async void DeleteAsync(AttachmentView attachment)
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IPasswordRepromptService _passwordRepromptService;
|
||||
@@ -37,6 +38,7 @@ namespace Bit.App.Pages
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
|
||||
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
|
||||
@@ -232,7 +234,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
if (autofillResponse == AppResources.Yes || autofillResponse == AppResources.YesAndSave)
|
||||
{
|
||||
_deviceActionService.Autofill(cipher);
|
||||
_autofillHandler.Autofill(cipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
private readonly IAuditService _auditService;
|
||||
protected readonly IDeviceActionService _deviceActionService;
|
||||
protected readonly IFileService _fileService;
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly IPlatformUtilsService _platformUtilsService;
|
||||
private CipherView _cipher;
|
||||
@@ -22,6 +23,7 @@ namespace Bit.App.Pages
|
||||
public BaseCipherViewModel()
|
||||
{
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_fileService = ServiceContainer.Resolve<IFileService>();
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_auditService = ServiceContainer.Resolve<IAuditService>("auditService");
|
||||
_logger = ServiceContainer.Resolve<ILogger>("logger");
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace Bit.App.Pages
|
||||
private readonly AppOptions _appOptions;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
private readonly IVaultTimeoutService _vaultTimeoutService;
|
||||
private readonly IKeyConnectorService _keyConnectorService;
|
||||
|
||||
@@ -40,6 +41,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
|
||||
|
||||
@@ -350,8 +352,8 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
else if (Device.RuntimePlatform == Device.Android &&
|
||||
!_deviceActionService.AutofillAccessibilityServiceRunning() &&
|
||||
!_deviceActionService.AutofillServiceEnabled())
|
||||
!_autofillHandler.AutofillAccessibilityServiceRunning() &&
|
||||
!_autofillHandler.AutofillServiceEnabled())
|
||||
{
|
||||
await DisplayAlert(AppResources.BitwardenAutofillService,
|
||||
AppResources.BitwardenAutofillServiceAlert2, AppResources.Ok);
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Bit.App.Pages
|
||||
private readonly IPolicyService _policyService;
|
||||
private readonly ICustomFieldItemFactory _customFieldItemFactory;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
|
||||
private bool _showNotesSeparator;
|
||||
private bool _showPassword;
|
||||
@@ -78,6 +79,7 @@ namespace Bit.App.Pages
|
||||
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
_customFieldItemFactory = ServiceContainer.Resolve<ICustomFieldItemFactory>("customFieldItemFactory");
|
||||
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
|
||||
GeneratePasswordCommand = new Command(GeneratePassword);
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
@@ -508,7 +510,7 @@ namespace Bit.App.Pages
|
||||
if (Page is CipherAddEditPage page && page.FromAutofillFramework)
|
||||
{
|
||||
// Close and go back to app
|
||||
_deviceActionService.CloseAutofill();
|
||||
_autofillHandler.CloseAutofill();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -605,6 +607,8 @@ namespace Bit.App.Pages
|
||||
return;
|
||||
}
|
||||
|
||||
var website = Cipher?.Login?.Uris?.FirstOrDefault()?.Host;
|
||||
|
||||
var page = new GeneratorPage(false, async (username) =>
|
||||
{
|
||||
try
|
||||
@@ -617,7 +621,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
OnGenerateUsernameException(ex);
|
||||
}
|
||||
}, isUsernameGenerator: true, emailWebsite: Cipher?.Name, editMode: true);
|
||||
}, isUsernameGenerator: true, emailWebsite: website, editMode: true);
|
||||
await Page.Navigation.PushModalAsync(new NavigationPage(page));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace Bit.App.Pages
|
||||
private string _totpCode;
|
||||
private string _totpCodeFormatted;
|
||||
private string _totpSec;
|
||||
private double _totpInterval = Constants.TotpDefaultTimer;
|
||||
private bool _totpLow;
|
||||
private DateTime? _totpInterval = null;
|
||||
private string _previousCipherId;
|
||||
private byte[] _attachmentData;
|
||||
private string _attachmentFilename;
|
||||
@@ -241,7 +241,7 @@ namespace Bit.App.Pages
|
||||
Page.Resources["textTotp"] = ThemeManager.Resources()[value ? "text-danger" : "text-default"];
|
||||
}
|
||||
}
|
||||
public double TotpProgress => string.IsNullOrEmpty(TotpSec) ? 0 : double.Parse(TotpSec) * 100 / 30;
|
||||
public double TotpProgress => string.IsNullOrEmpty(TotpSec) ? 0 : double.Parse(TotpSec) * 100 / _totpInterval;
|
||||
public bool IsDeleted => Cipher.IsDeleted;
|
||||
public bool CanEdit => !Cipher.IsDeleted;
|
||||
|
||||
@@ -265,6 +265,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_totpTickHelper = new TotpHelper(Cipher);
|
||||
_totpTickCancellationToken?.Cancel();
|
||||
_totpInterval = _totpTickHelper.Interval;
|
||||
_totpTickCancellationToken = new CancellationTokenSource();
|
||||
_totpTickTask = new TimerTask(_logger, StartCiphersTotpTick, _totpTickCancellationToken).RunPeriodic();
|
||||
}
|
||||
@@ -284,6 +285,7 @@ namespace Bit.App.Pages
|
||||
await _totpTickHelper.GenerateNewTotpValues();
|
||||
TotpSec = _totpTickHelper.TotpSec;
|
||||
TotpCodeFormatted = _totpTickHelper.TotpCodeFormatted;
|
||||
_totpInterval = _totpTickHelper.Interval;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -429,7 +431,6 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (Cipher == null || Cipher.Type != Core.Enums.CipherType.Login || Cipher.Login.Totp == null)
|
||||
{
|
||||
_totpInterval = null;
|
||||
return;
|
||||
}
|
||||
_totpCode = await _totpService.GetCodeAsync(Cipher.Login.Totp);
|
||||
@@ -449,7 +450,6 @@ namespace Bit.App.Pages
|
||||
else
|
||||
{
|
||||
TotpCodeFormatted = null;
|
||||
_totpInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
var canOpenFile = true;
|
||||
if (!_deviceActionService.CanOpenFile(attachment.FileName))
|
||||
if (!_fileService.CanOpenFile(attachment.FileName))
|
||||
{
|
||||
if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
@@ -562,7 +562,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public async void OpenAttachment(byte[] data, AttachmentView attachment)
|
||||
{
|
||||
if (!_deviceActionService.OpenFile(data, attachment.Id, attachment.FileName))
|
||||
if (!_fileService.OpenFile(data, attachment.Id, attachment.FileName))
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.UnableToOpenFile);
|
||||
return;
|
||||
@@ -573,7 +573,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
_attachmentData = data;
|
||||
_attachmentFilename = attachment.FileName;
|
||||
if (!_deviceActionService.SaveFile(_attachmentData, null, _attachmentFilename, null))
|
||||
if (!_fileService.SaveFile(_attachmentData, null, _attachmentFilename, null))
|
||||
{
|
||||
ClearAttachmentData();
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.UnableToSaveAttachment);
|
||||
@@ -582,7 +582,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public async void SaveFileSelected(string contentUri, string filename)
|
||||
{
|
||||
if (_deviceActionService.SaveFile(_attachmentData, null, filename ?? _attachmentFilename, contentUri))
|
||||
if (_fileService.SaveFile(_attachmentData, null, filename ?? _attachmentFilename, contentUri))
|
||||
{
|
||||
ClearAttachmentData();
|
||||
_platformUtilsService.ShowToast("success", null, AppResources.SaveAttachmentSuccess);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
@@ -12,7 +12,7 @@ namespace Bit.App.Pages
|
||||
public partial class CiphersPage : BaseContentPage
|
||||
{
|
||||
private readonly string _autofillUrl;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
|
||||
private CiphersPageViewModel _vm;
|
||||
private bool _hasFocused;
|
||||
@@ -48,7 +48,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
NavigationPage.SetTitleView(this, _titleLayout);
|
||||
}
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
}
|
||||
|
||||
public SearchBar SearchBar => _searchBar;
|
||||
@@ -107,7 +107,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
else
|
||||
{
|
||||
_deviceActionService.CloseAutofill();
|
||||
_autofillHandler.CloseAutofill();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Bit.App.Pages
|
||||
private readonly ICipherService _cipherService;
|
||||
private readonly ISearchService _searchService;
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly IAutofillHandler _autofillHandler;
|
||||
private readonly IStateService _stateService;
|
||||
private readonly IPasswordRepromptService _passwordRepromptService;
|
||||
private readonly IOrganizationService _organizationService;
|
||||
@@ -37,6 +38,7 @@ namespace Bit.App.Pages
|
||||
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
_searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
|
||||
_organizationService = ServiceContainer.Resolve<IOrganizationService>("organizationService");
|
||||
@@ -196,7 +198,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
else
|
||||
{
|
||||
_deviceActionService.Autofill(cipher);
|
||||
_autofillHandler.Autofill(cipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ namespace Bit.App.Pages
|
||||
private bool _websiteIconsEnabled;
|
||||
private string _iconImageSource = string.Empty;
|
||||
|
||||
public int interval { get; set; }
|
||||
private double _progress;
|
||||
private string _totpSec;
|
||||
private string _totpCodeFormatted;
|
||||
@@ -37,7 +36,6 @@ namespace Bit.App.Pages
|
||||
|
||||
Cipher = cipherView;
|
||||
WebsiteIconsEnabled = websiteIconsEnabled;
|
||||
interval = _totpService.GetTimeInterval(Cipher.Login.Totp);
|
||||
CopyCommand = new AsyncCommand(CopyToClipboardAsync,
|
||||
onException: ex => _logger.Value.Exception(ex),
|
||||
allowsMultipleExecutions: false);
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace Bit.App.Pages
|
||||
NestedFolders = NestedFolders.GetRange(0, NestedFolders.Count - 1);
|
||||
}
|
||||
|
||||
var uppercaseGroupNames = _deviceActionService.DeviceType == DeviceType.iOS;
|
||||
var uppercaseGroupNames = Device.RuntimePlatform == Device.iOS;
|
||||
var hasFavorites = FavoriteCiphers?.Any() ?? false;
|
||||
if (hasFavorites)
|
||||
{
|
||||
@@ -400,7 +400,7 @@ namespace Bit.App.Pages
|
||||
|
||||
private void CreateCipherGroupedItems(List<GroupingsPageListGroup> groupedItems)
|
||||
{
|
||||
var uppercaseGroupNames = _deviceActionService.DeviceType == DeviceType.iOS;
|
||||
var uppercaseGroupNames = Device.RuntimePlatform == Device.iOS;
|
||||
_totpTickCts?.Cancel();
|
||||
if (ShowTotp)
|
||||
{
|
||||
|
||||
10502
src/App/Resources/AppResources.Designer.cs
generated
10502
src/App/Resources/AppResources.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -300,7 +300,7 @@
|
||||
<comment>The title for the vault page.</comment>
|
||||
</data>
|
||||
<data name="Authenticator" xml:space="preserve">
|
||||
<value>Authenticator</value>
|
||||
<value>Waarmerker</value>
|
||||
<comment>Authenticator TOTP feature</comment>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
@@ -900,8 +900,8 @@
|
||||
<value>Kan nie waarmerksleutel lees nie.</value>
|
||||
</data>
|
||||
<data name="PointYourCameraAtTheQRCode" xml:space="preserve">
|
||||
<value>Point your camera at the QR Code.
|
||||
Scanning will happen automatically.</value>
|
||||
<value>Rig u kamera op die QR-kode.
|
||||
Skandering gebeur outomaties.</value>
|
||||
</data>
|
||||
<data name="ScanQrTitle" xml:space="preserve">
|
||||
<value>Skandeer QR-kode</value>
|
||||
@@ -1575,6 +1575,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Versperde URI’s vir outovul</value>
|
||||
</data>
|
||||
@@ -2265,35 +2269,35 @@ Scanning will happen automatically.</value>
|
||||
<value>TOTP</value>
|
||||
</data>
|
||||
<data name="VerificationCodes" xml:space="preserve">
|
||||
<value>Verification Codes</value>
|
||||
<value>Bevestigingskodes</value>
|
||||
</data>
|
||||
<data name="PremiumSubscriptionRequired" xml:space="preserve">
|
||||
<value>Premium subscription required</value>
|
||||
<value>Premie-intekening word vereis</value>
|
||||
</data>
|
||||
<data name="CannotAddAuthenticatorKey" xml:space="preserve">
|
||||
<value>Cannot add authenticator key? </value>
|
||||
<value>Kan nie waarmerksleutel toevoeg nie? </value>
|
||||
</data>
|
||||
<data name="ScanQRCode" xml:space="preserve">
|
||||
<value>Scan QR Code</value>
|
||||
<value>Skandeer QR-kode</value>
|
||||
</data>
|
||||
<data name="CannotScanQRCode" xml:space="preserve">
|
||||
<value>Cannot scan QR Code? </value>
|
||||
<value>Kan nie QR-kode skandeer nie? </value>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyScanner" xml:space="preserve">
|
||||
<value>Authenticator Key</value>
|
||||
<value>Waarmerksleutel</value>
|
||||
</data>
|
||||
<data name="EnterKeyManually" xml:space="preserve">
|
||||
<value>Enter Key Manually</value>
|
||||
<value>Voer sleutel handmatig in</value>
|
||||
</data>
|
||||
<data name="AddTotp" xml:space="preserve">
|
||||
<value>Add TOTP</value>
|
||||
<value>Voeg TOTP toe</value>
|
||||
</data>
|
||||
<data name="SetupTotp" xml:space="preserve">
|
||||
<value>Set up TOTP</value>
|
||||
<value>Stel TOTP op</value>
|
||||
</data>
|
||||
<data name="OnceTheKeyIsSuccessfullyEntered" xml:space="preserve">
|
||||
<value>Once the key is successfully entered,
|
||||
select Add TOTP to store the key safely</value>
|
||||
<value>Sodra u die sleutel reg ingevoer het,
|
||||
kies u Voeg TOTP toe om die sleutel veilig te bewaar</value>
|
||||
</data>
|
||||
<data name="SelectAddTotpToStoreTheKeySafely" xml:space="preserve">
|
||||
<value></value>
|
||||
@@ -2313,38 +2317,98 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Is u seker u wil skermopname aktiveer?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Aantekening versoek</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Probeer u aanteken?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Aantekenversoek deir {0} op {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Toesteltipe</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP-adres</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Tyd</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Naby</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Bevestig aantekening</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Weier aantekening</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Sopas</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minute gelede</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Aantekening bevestig</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Aantekening geweier</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Keur aantekenversoeke goed</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Gebruik hierdie toestel vir die goedkeur van aantekenversoeke van ander toestelle.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Laat kennisgewings toe</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Ontvang stootkennisgewings vir nuwe aantekenversoeke</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Nee dankie</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Bevestig aantekeningspoging vir {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Alle kennisgewings</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password Type</value>
|
||||
<value>Wagwoordtipe</value>
|
||||
</data>
|
||||
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
|
||||
<value>What would you like to generate?</value>
|
||||
<value>Wat wil u genereer?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Username Type</value>
|
||||
<value>Gebruikersnaamtipe</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus Addressed Email</value>
|
||||
<value>E-posadres met plus</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all Email</value>
|
||||
<value>Allesomvattende e-pos</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded Email Alias</value>
|
||||
<value>E-posalias vir aanstuur</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Random Word</value>
|
||||
<value>Lukrake woord</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>Email (required)</value>
|
||||
<value>E-pos (vereis)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Domain Name (required)</value>
|
||||
<value>Domeinnaam (vereis)</value>
|
||||
</data>
|
||||
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
|
||||
<value>API Key (required)</value>
|
||||
<value>API-sleutel (vereis)</value>
|
||||
</data>
|
||||
<data name="Service" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
<value>Diens</value>
|
||||
</data>
|
||||
<data name="AnonAddy" xml:space="preserve">
|
||||
<value>AnonAddy</value>
|
||||
@@ -2359,33 +2423,89 @@ select Add TOTP to store the key safely</value>
|
||||
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="APIAccessToken" xml:space="preserve">
|
||||
<value>API Access Token</value>
|
||||
<value>API-toegangsteken</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
|
||||
<value>Are you sure you want to overwrite the current username?</value>
|
||||
<value>Is u seker u wil oor die huidige gebruikersnaam skryf?</value>
|
||||
</data>
|
||||
<data name="GenerateUsername" xml:space="preserve">
|
||||
<value>Generate Username</value>
|
||||
<value>Genereer gebruikersnaam</value>
|
||||
</data>
|
||||
<data name="EmailType" xml:space="preserve">
|
||||
<value>Email Type</value>
|
||||
<value>E-postipe</value>
|
||||
</data>
|
||||
<data name="WebsiteRequired" xml:space="preserve">
|
||||
<value>Website (required)</value>
|
||||
<value>Webwerf (vereis)</value>
|
||||
</data>
|
||||
<data name="UnknownXErrorMessage" xml:space="preserve">
|
||||
<value>Unknown {0} error occurred.</value>
|
||||
<value>Onbekende {0} fout het voorgekom.</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmailDescription" xml:space="preserve">
|
||||
<value>Use your email provider's subaddress capabilities</value>
|
||||
<value>Gebruik u e-posverskaffer se subadresvermoëns</value>
|
||||
</data>
|
||||
<data name="CatchAllEmailDescription" xml:space="preserve">
|
||||
<value>Use your domain's configured catch-all inbox.</value>
|
||||
<value>Gebruik u domein se opgestelde allesomvattende inmandjie.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Generate an email alias with an external forwarding service.</value>
|
||||
<value>Genereer ’n e-posalias met ’n eksterne aanstuurdiens.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
<value>Lukraak</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Toeganklikheidsdiensopenbaarmaking</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden gebruik die Toeganklikheidsdiens om na aantekenvelde in toeps en webwerwe te soek en dan die geskikte veld-ID’s om ’n gebruikersnaam en wagwoord in te voer wanner ’n ooreenstemming vir die toep of webwerf gevind is. Ons bewaar geen van die inligting wat deur die diens gebied word nie en ons poog ook nie om enige op-skerm-elemente buiten teksinvoer van velde te beheer nie.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Aanvaar</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Wys af</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Aantekenversoek het reeds verstryk.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1575,6 +1575,10 @@
|
||||
<value>نورد</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>تعبئة العناوين المحجوبة تلقائياً</value>
|
||||
</data>
|
||||
@@ -2314,6 +2318,66 @@
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>هل أنت متأكد من أنك تريد تمكين التقاط الشاشة؟</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>طلب تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>هل تحاول تسجيل الدخول؟</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>محاولة تسجيل الدخول بواسطة {0} في {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>نوع الجهاز</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>عنوان IP</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>الوقت</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>قريب</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>تأكيد تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>رفض تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>للتو</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>منذ {0} دقائق</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>تم تأكيد تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>تم رفض تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>الموافقة على طلبات تسجيل الدخول</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>استخدم هذا الجهاز للموافقة على طلبات تسجيل الدخول من الأجهزة الأخرى.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>السماح بالإشعارات</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>تلقي إشعارات دفع لطلبات تسجيل الدخول الجديدة</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>ﻻ، شكرًا</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>تأكيد محاولة تسجيل الدخول لـ {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>جميع الإشعارات</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>نوع كلمة المرور</value>
|
||||
</data>
|
||||
@@ -2389,4 +2453,60 @@
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>عشوائي</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>كشف خدمة إمكانية الوصول</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden يستخدم خدمة إمكانية الوصول للبحث عن حقول تسجيل الدخول في التطبيقات ومواقع الويب، ثم يقوم بإنشاء معرفات الحقل المناسب لإدخال اسم المستخدم وكلمة المرور عند العثور على تطابق للتطبيق أو الموقع. ونحن لا نخزن أيا من المعلومات التي قدمتها لنا الخدمة، كما أننا لا نحاول السيطرة على أي عناصر على الشاشة تتجاوز إدخال نصوص وثائق التفويض.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>قبول</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>رفض</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>انتهت صلاحية طلب تسجيل الدخول.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>محاولة تسجيل الدخول من:
|
||||
{0}
|
||||
هل تريد التبديل إلى هذا الحساب؟</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>جديد هنا؟</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>احصل على تلميح كلمة المرور الرئيسية</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>تسجيل الدخول كـ {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>ليس أنت؟</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>تسجيل الدخول باستخدام كلمة المرور الرئيسية</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>تسجيل الدخول باستخدام جهاز آخر</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1575,6 +1575,10 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Günəşli tünd</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Əngəllənən URI-lərin avto-doldurulması</value>
|
||||
</data>
|
||||
@@ -2312,6 +2316,66 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Ekranın çəkilməsini fəallaşdırmaq istədiyinizə əminsiniz?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Giriş tələb olundu</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Giriş etməyə çalışırsınız?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>{0} tərəfindən {1} tarixində giriş cəhdi</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Cihaz növü</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP ünvan</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Vaxt</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Yaxın</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Girişi təsdiqlə</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Girişi rədd et</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>İndicə</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} dəqiqə əvvəl</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Giriş təsdiqləndi</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Giriş rədd edildi</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Giriş tələblərini təsdiqlə</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Digər cihazlardan edilən giriş tələblərini təsdiqləmək üçün bu cihazı istifadə edin.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Bildirişlərə icazə ver</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Yeni giriş tələbləri üçün ani bildirişlər alın</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Xeyr təşəkkürlər</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>{0} üçün giriş cəhdini təsdiqlə</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Bütün bildirişlər</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Parol növü</value>
|
||||
</data>
|
||||
@@ -2387,4 +2451,60 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Təsadüfi</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Əlçatımlılıq Xidməti açıqlaması</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden, tətbiqlərdə və veb saytlarda giriş sahələrini axtarmaq üçün Əlçatımlılıq Xidmətini istifadə edir, daha sonra tətbiq və ya sayt üçün uyğunluq aşkar etdikdə istifadəçi adı və parolun daxil edilməsi üçün müvafiq sahə kimliklərini yaradır. Xidmət tərəfindən bizə təqdim edilən məlumatların heç birini saxlamırıq, kimlik məlumatlarının daxil edilməsindən kənar ekrandakı hər hansısa elementə nəzarət etməyə cəhd etmirik.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Qəbul et</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Rədd et</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Giriş tələbinin müddəti artıq bitib.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Giriş cəhdi:
|
||||
{0}
|
||||
Bu hesaba keçmək istəyirsiniz?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Burada yenisiniz?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Siz deyilsiniz?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Ana parolla giriş et</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Başqa cihazla giriş et</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Giriş etmə başladıldı</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Cihazınıza bir bildiriş göndərildi.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Zəhmət olmasa anbarınızın kilidinin açıq olduğuna və Barmaq izi ifadəsinin digər cihazda uyğun gəldiyinə əmin olun.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Bildirişi təkrar göndər</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Başqa bir seçimə ehtiyacınız var?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Bütün giriş etmə seçimlərinə bax</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -273,13 +273,13 @@
|
||||
<comment>The log out button text (verb).</comment>
|
||||
</data>
|
||||
<data name="LogoutConfirmation" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце выйсці?</value>
|
||||
<value>Вы сапраўды хочаце выйсці?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Выдаліць уліковы запіс</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце выдаліць уліковы запіс?</value>
|
||||
<value>Вы сапраўды хочаце выдаліць уліковы запіс?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Уліковы запіс ужо дададзены</value>
|
||||
@@ -375,7 +375,7 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} скапіявана.</value>
|
||||
<value>{0} скапіяваны</value>
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
@@ -559,7 +559,7 @@
|
||||
<value>Дзеянне пасля заканчэння часу чакання сховішча</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
|
||||
<value>Выхад з сістэмы скасуе ўсе магчымасці доступу да сховішча і запатрабуе аўтэнтыфікацыю праз інтэрнэт пасля завяршэння часу чакання. Вы ўпэўнены, што хочаце выкарыстоўваць гэты параметр?</value>
|
||||
<value>Выхад з сістэмы скасуе ўсе магчымасці доступу да сховішча і запатрабуе аўтэнтыфікацыю праз інтэрнэт пасля завяршэння часу чакання. Вы сапраўды хочаце выкарыстоўваць гэты параметр?</value>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>Уваход...</value>
|
||||
@@ -644,7 +644,7 @@
|
||||
<value>Мы адправілі вам на электронную пошту падказку да асноўнага пароля.</value>
|
||||
</data>
|
||||
<data name="PasswordOverrideAlert" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце перазапісаць бягучы пароль?</value>
|
||||
<value>Вы сапраўды хочаце перазапісаць бягучы пароль?</value>
|
||||
</data>
|
||||
<data name="PushNotificationAlert" xml:space="preserve">
|
||||
<value>Bitwarden дазваляе аўтаматычна сінхранізаваць сховішча пры дапамозе push-апавяшчэнняў. Для максімальнай зручнасці, выберыце "Дазволіць" пры з'яўленні прапановы ўключыць push-апавяшчэнні.</value>
|
||||
@@ -708,7 +708,7 @@
|
||||
<value>Двухэтапны ўваход</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>Двухэтапны ўваход робіць ваш уліковы запіс больш бяспечным, патрабуючы пацвярджэнне ўваходу на іншай прыладзе з выкарыстаннем ключа бяспекі, праграмы аўтэнтыфікацыі, SMS, тэлефоннага званка або электроннай пошты. Двухэтапны ўваход уключаецца на bitwarden.com. Перайсці на сайт, каб зрабіць гэта?</value>
|
||||
<value>Двухэтапны ўваход робіць ваш уліковы запіс больш бяспечным, патрабуючы пацвярджэнне ўваходу на іншай прыладзе з выкарыстаннем ключа бяспекі, праграмы аўтэнтыфікацыі, SMS, тэлефоннага званка або электроннай пошты. Двухэтапны ўваход уключаецца на bitwarden.com. Перайсці на вэб-сайт, каб зрабіць гэта?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Разблакіраваць з {0}</value>
|
||||
@@ -793,7 +793,7 @@
|
||||
<value>Вы сапраўды хочаце аўтазапоўніць або паглядзець гэты элемент?</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceMatchConfirm" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце выкарыстоўваць для аўтазапаўнення гэты элемент? Ён не дакладна адпавядае "{0}".</value>
|
||||
<value>Вы сапраўды хочаце выкарыстоўваць для аўтазапаўнення гэты элемент? Ён не дакладна адпавядае "{0}".</value>
|
||||
</data>
|
||||
<data name="MatchingItems" xml:space="preserve">
|
||||
<value>Адпаведныя элементы</value>
|
||||
@@ -883,7 +883,7 @@
|
||||
<comment>Message shown when downloading a file</comment>
|
||||
</data>
|
||||
<data name="AttachmentLargeWarning" xml:space="preserve">
|
||||
<value>Гэта далучэнне мае памер {0}. Вы ўпэўнены, што хочаце спампаваць яго на сваю прыладу?</value>
|
||||
<value>Гэта далучэнне мае памер {0}. Вы сапраўды хочаце спампаваць яго на сваю прыладу?</value>
|
||||
<comment>The placeholder will show the file size of the attachment. Ex "25 MB"</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorKey" xml:space="preserve">
|
||||
@@ -1498,7 +1498,7 @@
|
||||
<value>Ваша сховішча заблакіравана. Увядзіце PIN-код для працягу.</value>
|
||||
</data>
|
||||
<data name="VaultLockedIdentity" xml:space="preserve">
|
||||
<value>Ваша сховішча заблакіравана. Пацвердзіце сваю асобу, каб працягнуць.</value>
|
||||
<value>Ваша сховішча заблакіравана. Каб працягнуць, пацвердзіце сваю асобу.</value>
|
||||
</data>
|
||||
<data name="Dark" xml:space="preserve">
|
||||
<value>Цёмная</value>
|
||||
@@ -1561,7 +1561,7 @@
|
||||
<value>Выхад</value>
|
||||
</data>
|
||||
<data name="ExitConfirmation" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце выйсці з Bitwarden?</value>
|
||||
<value>Вы сапраўды хочаце выйсці з Bitwarden?</value>
|
||||
</data>
|
||||
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
|
||||
<value>Вы сапраўды хочаце, каб пасля перазапуску праграма патрабавала асноўны пароль для разблакіроўкі?</value>
|
||||
@@ -1574,6 +1574,10 @@
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Цёмная Solarized</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Аўтазапаўненне заблакіраваных URI</value>
|
||||
</data>
|
||||
@@ -1959,7 +1963,7 @@
|
||||
<value>Выдаліць пароль</value>
|
||||
</data>
|
||||
<data name="AreYouSureRemoveSendPassword" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце выдаліць пароль?</value>
|
||||
<value>Вы сапраўды хочаце выдаліць пароль?</value>
|
||||
</data>
|
||||
<data name="RemovingSendPassword" xml:space="preserve">
|
||||
<value>Выдаленне пароля</value>
|
||||
@@ -2006,7 +2010,7 @@
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AreYouSureDeleteSend" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце выдаліць гэты Send?</value>
|
||||
<value>Вы сапраўды хочаце выдаліць гэты Send?</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDeleted" xml:space="preserve">
|
||||
@@ -2059,7 +2063,7 @@
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendFilePremiumRequired" xml:space="preserve">
|
||||
<value>У бясплатных уліковых запісах можна адпраўляць толькі тэкст. Для адпраўкі файлаў праз Send, патрабуецца платная падпіска.</value>
|
||||
<value>У бясплатных уліковых запісах можна адпраўляць толькі тэкст. Для адпраўкі файлаў праз Send, патрабуецца прэміяльны статус.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendFileEmailVerificationRequired" xml:space="preserve">
|
||||
@@ -2172,7 +2176,7 @@
|
||||
<value>Выдаленне вашага ўліковага запісу з'яўляецца незваротным дзеяннем</value>
|
||||
</data>
|
||||
<data name="DeleteAccountExplanation" xml:space="preserve">
|
||||
<value>Ваш уліковы запіс і ўсе даныя сховішча будуць выдалены без магчымасці аднаўлення. Вы ўпэўнены, што хочаце працягнуць?</value>
|
||||
<value>Ваш уліковы запіс і ўсе даныя сховішча будуць выдалены без магчымасці аднаўлення. Вы сапраўды хочаце працягнуць?</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccount" xml:space="preserve">
|
||||
<value>Выдаленне вашага ўліковага запісу</value>
|
||||
@@ -2311,7 +2315,67 @@
|
||||
<value>Дазволіць здымкі экрана</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце дазволіць здымкі экрана?</value>
|
||||
<value>Вы сапраўды хочаце дазволіць здымкі экрана?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Выкананы запыт уваходу</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Вы спрабуеце ўвайсці?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Спроба ўваходу {0} у {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Тып прылады</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP-адрас</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Час</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Побач</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Пацвердзіць уваход</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Адхіліць уваход</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Толькі што</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} хвілін таму</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Уваход пацверджаны</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Уваход адхілены</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Ухваліць запыт уваходу</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Выкарыстоўваць гэту прыладу для ўхвалення запытаў на ўваход, якія зроблены з іншых прылад.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Дазволіць апавяшчэнні</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Атрымліваць push-апавяшчэнні пра новыя запыты на ўваход</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Не, дзякуй</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Пацвердзіць спробу ўваходу для {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Усе апавяшчэннi</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Тып пароля</value>
|
||||
@@ -2362,7 +2426,7 @@
|
||||
<value>Токен доступу да API</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
|
||||
<value>Вы ўпэўнены, што хочаце перазапісаць бягучае імя карыстальніка?</value>
|
||||
<value>Вы сапраўды хочаце перазапісаць бягучае імя карыстальніка?</value>
|
||||
</data>
|
||||
<data name="GenerateUsername" xml:space="preserve">
|
||||
<value>Генерыраваць імя карыстальніка</value>
|
||||
@@ -2388,4 +2452,60 @@
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Выпадкова</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Апісанне службы спецыяльных магчымасцей</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden выкарыстоўвае службу спецыяльных магчымасцей для пошуку палёў уваходу ў праграмах і вэб-сайтах, пасля чаго вызначае належныя ідэнтыфікатары палёў для таго, каб увесці імя карыстальніка і пароль, які адпавядае знойдзенай праграме або вэб-сайту. Мы ніколі не захоўваем ніякай інфармацыі, якая забяспечвае нам служба, і ніколі не прыкладаем намаганняў па кантролі любых элементаў на экране за выключэннем увядзення ўліковых даных у тэкставым выглядзе.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Прыняць</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Адхіліць</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Запыт на ўваход пратэрмінаваны.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Спроба ўваходу з:
|
||||
{0}
|
||||
Вы сапраўды хочаце перайсці на гэты ўліковы запіс?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Упершыню тут?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Атрымаць падказку да асноўнага пароля</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Увайсці як {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Не вы?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Увайсці з асноўным паролем</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Увайсці з іншай прылады</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Ініцыяваны ўваход</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Апавяшчэнне было адпраўлена на вашу прыладу.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Пераканайцеся, што ваша сховішча разблакіравана, а фраза адбітка пальца супадае з іншай прыладай.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Адправіць апавяшчэнне паўторна</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Неабходны іншы варыянт?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Паглядзець усе варыянты ўваходу</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1575,6 +1575,10 @@
|
||||
<value>Норд</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Преекспонирано тъмен</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Блокирани за авт. попълване адреси</value>
|
||||
</data>
|
||||
@@ -2076,7 +2080,7 @@
|
||||
<value>Това действие е защитено. За да продължите, въведете отново главната си парола, за да потвърдите самоличността си.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Captcha Required</value>
|
||||
<value>Captcha required</value>
|
||||
</data>
|
||||
<data name="CaptchaFailed" xml:space="preserve">
|
||||
<value>
|
||||
@@ -2116,7 +2120,7 @@
|
||||
<value>FIDO2 WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2Instruction" xml:space="preserve">
|
||||
<value>To continue, have your FIDO2 WebAuthn enabled security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
<value>To continue, have your FIDO2 WebAuthn compatible security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
</data>
|
||||
<data name="Fido2Desc" xml:space="preserve">
|
||||
<value>Идентификация чрез FIDO2 WebAuthn – можете да се идентифицирате чрез външен ключ за сигурност.</value>
|
||||
@@ -2314,6 +2318,66 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Наистина ли искате да разрешите заснемането на екрана?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Направена е заявка за вписване</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Опитвате се да се впишете ли?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Опит за вписване от {0} в {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Вид устройство</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP адрес</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Време</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Потвърждаване на вписването</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Отказване на вписването</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Току-що</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>Преди {0} минути</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Вписването е потвърдено</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Вписването е отказано</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Одобряване на заявки за вписване</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Използвайте това устройство за одобряване на заявки за вписване направени от други устройства.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Разрешаване на известията</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Получаване на известия при нови заявки за вписване</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Не, благодаря</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Потвърждаване на заявката за вписване за {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Всички известия</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Тип парола</value>
|
||||
</data>
|
||||
@@ -2324,13 +2388,13 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Тип потребителско име</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus Addressed Email</value>
|
||||
<value>Plus addressed email</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all Email</value>
|
||||
<value>Catch-all email</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded Email Alias</value>
|
||||
<value>Forwarded email alias</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Произволна дума</value>
|
||||
@@ -2389,4 +2453,60 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Произволно</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Използване на услугата за достъпност</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Битуорден използва услугата за достъпност, за да разпознава полета за вписване в приложенията и уеб сайтовете и, ако в трезора има съвпадение, да попълва потребителското име и паролата. Никаква информация, предоставена ни от услугата, не се запазва, както и не правим опити да контролираме елементите на екрана, освен въвеждането на данните за идентификация.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Приемане</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Отказване</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Заявката за вписване вече е изтекла.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Опит за вписване от:
|
||||
{0}
|
||||
Искате ли да превключите към тази регистрация?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>За пръв път ли сте тук?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Получете подсказване за главната парола</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Вписване като {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Това не сте Вие?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Вписване с главната парола</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Вписване с друго устройство</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Вписването е стартирано</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Към устройството Ви е изпратено известие.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Уверете се, че трезорът Ви е отключен и че Уникалната фраза съвпада с другото устройство.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Повторно изпращане на известието</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Предпочитате друг вариант?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Вижте всички възможности за вписване</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
<comment>Full label for a email address.</comment>
|
||||
</data>
|
||||
<data name="EmailUs" xml:space="preserve">
|
||||
<value>Email Us</value>
|
||||
<value>Email us</value>
|
||||
</data>
|
||||
<data name="EmailUsDescription" xml:space="preserve">
|
||||
<value>Email us directly to get help or leave feedback.</value>
|
||||
@@ -203,7 +203,7 @@
|
||||
<comment>Title for your favorite items in the vault.</comment>
|
||||
</data>
|
||||
<data name="FileBugReport" xml:space="preserve">
|
||||
<value>File a Bug Report</value>
|
||||
<value>File a bug report</value>
|
||||
</data>
|
||||
<data name="FileBugReportDescription" xml:space="preserve">
|
||||
<value>Open an issue at our GitHub repository.</value>
|
||||
@@ -247,11 +247,11 @@
|
||||
<comment>Description message for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
|
||||
<value>Internet Connection Required</value>
|
||||
<value>Internet connection required</value>
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
<value>Invalid Master Password. Try again.</value>
|
||||
<value>Invalid master password. Try again.</value>
|
||||
</data>
|
||||
<data name="InvalidPIN" xml:space="preserve">
|
||||
<value>Invalid PIN. Try again.</value>
|
||||
@@ -276,13 +276,13 @@
|
||||
<value>আপনি লগ আউট করতে চান?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Remove account</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Account already added</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Item has been deleted.</value>
|
||||
<value>Item deleted</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -353,7 +353,7 @@
|
||||
<comment>The title for the sync page.</comment>
|
||||
</data>
|
||||
<data name="ThankYou" xml:space="preserve">
|
||||
<value>Thank You</value>
|
||||
<value>Thank you</value>
|
||||
</data>
|
||||
<data name="Tools" xml:space="preserve">
|
||||
<value>Tools</value>
|
||||
@@ -364,7 +364,7 @@
|
||||
<comment>Label for a uri/url.</comment>
|
||||
</data>
|
||||
<data name="UseFingerprintToUnlock" xml:space="preserve">
|
||||
<value>Use Fingerprint to Unlock</value>
|
||||
<value>Use fingerprint to unlock</value>
|
||||
</data>
|
||||
<data name="Username" xml:space="preserve">
|
||||
<value>Username</value>
|
||||
@@ -375,11 +375,11 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} has been copied.</value>
|
||||
<value>{0} copied</value>
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
<value>Verify Fingerprint</value>
|
||||
<value>Verify fingerprint</value>
|
||||
</data>
|
||||
<data name="VerifyMasterPassword" xml:space="preserve">
|
||||
<value>প্রধান পাসওয়ার্ড যাচাইকরণ</value>
|
||||
@@ -394,7 +394,7 @@
|
||||
<value>View</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsite" xml:space="preserve">
|
||||
<value>Visit Our Website</value>
|
||||
<value>Visit our website</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>
|
||||
@@ -425,13 +425,13 @@
|
||||
<value>Auto-fill service</value>
|
||||
</data>
|
||||
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
|
||||
<value>Avoid Ambiguous Characters</value>
|
||||
<value>Avoid ambiguous characters</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtension" xml:space="preserve">
|
||||
<value>Bitwarden App Extension</value>
|
||||
<value>Bitwarden app extension</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
|
||||
<value>The easiest way to add new logins to your vault is from the Bitwarden App Extension. Learn more about using the Bitwarden App Extension by navigating to the "Settings" screen.</value>
|
||||
<value>The easiest way to add new logins to your vault is from the Bitwarden app extension. Learn more about using the Bitwarden app extension by navigating to the "Settings" screen.</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionDescription" xml:space="preserve">
|
||||
<value>Use Bitwarden in Safari and other apps to auto-fill your logins.</value>
|
||||
@@ -443,7 +443,7 @@
|
||||
<value>Use the Bitwarden accessibility service to auto-fill your logins.</value>
|
||||
</data>
|
||||
<data name="ChangeEmail" xml:space="preserve">
|
||||
<value>Change Email</value>
|
||||
<value>Change email</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>
|
||||
@@ -471,19 +471,19 @@
|
||||
<value>বস্তু সম্পাদনা</value>
|
||||
</data>
|
||||
<data name="EnableAutomaticSyncing" xml:space="preserve">
|
||||
<value>Enable Automatic Syncing</value>
|
||||
<value>Allow automatic syncing</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>আপনার প্রধান পাসওয়ার্ডের ইঙ্গিতটি পেতে আপনার অ্যাকাউন্টের ইমেল ঠিকানা প্রবেশ করুন।</value>
|
||||
</data>
|
||||
<data name="ExntesionReenable" xml:space="preserve">
|
||||
<value>Re-enable app extension</value>
|
||||
<value>Reactivate app extension</value>
|
||||
</data>
|
||||
<data name="ExtensionAlmostDone" xml:space="preserve">
|
||||
<value>Almost done!</value>
|
||||
</data>
|
||||
<data name="ExtensionEnable" xml:space="preserve">
|
||||
<value>Enable app extension</value>
|
||||
<value>Activate app extension</value>
|
||||
</data>
|
||||
<data name="ExtensionInSafari" xml:space="preserve">
|
||||
<value>In Safari, find Bitwarden using the share icon (hint: scroll to the right on the bottom row of the menu).</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>More settings</value>
|
||||
</data>
|
||||
<data name="MustLogInMainApp" xml:space="preserve">
|
||||
<value>You must log into the main Bitwarden app before you can use the extension.</value>
|
||||
@@ -604,7 +604,7 @@
|
||||
<value>কখনই না</value>
|
||||
</data>
|
||||
<data name="NewItemCreated" xml:space="preserve">
|
||||
<value>New item created.</value>
|
||||
<value>Item added</value>
|
||||
</data>
|
||||
<data name="NoFavorites" xml:space="preserve">
|
||||
<value>There are no favorites in your vault.</value>
|
||||
@@ -647,7 +647,7 @@
|
||||
<value>আপনি কি নিশ্চিত যে আপনি বর্তমান পাসওয়ার্ডটি ওভাররাইট করতে চান?</value>
|
||||
</data>
|
||||
<data name="PushNotificationAlert" xml:space="preserve">
|
||||
<value>Bitwarden keeps your vault automatically synced by using push notifications. For the best possible experience, please select "Allow" on the following prompt when asked to enable push notifications.</value>
|
||||
<value>Bitwarden keeps your vault automatically synced by using push notifications. For the best possible experience, please select "Allow" on the following prompt when asked to allow push notifications.</value>
|
||||
<comment>Push notifications for apple products</comment>
|
||||
</data>
|
||||
<data name="RateTheApp" xml:space="preserve">
|
||||
@@ -678,10 +678,10 @@
|
||||
<value>Enter a 4 digit PIN code to unlock the app with.</value>
|
||||
</data>
|
||||
<data name="ItemInformation" xml:space="preserve">
|
||||
<value>Item Information</value>
|
||||
<value>Item information</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Item updated.</value>
|
||||
<value>Item saved</value>
|
||||
</data>
|
||||
<data name="Submitting" xml:space="preserve">
|
||||
<value>Submitting...</value>
|
||||
@@ -692,10 +692,10 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="SyncingComplete" xml:space="preserve">
|
||||
<value>Syncing complete.</value>
|
||||
<value>Syncing complete</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Syncing failed.</value>
|
||||
<value>Syncing failed</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Sync vault now</value>
|
||||
@@ -708,7 +708,7 @@
|
||||
<value>Two-step login</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>Two-step login makes your account more secure by requiring you to verify your login with another device such as a security key, authenticator app, SMS, phone call, or email. Two-step login can be enabled on the bitwarden.com web vault. Do you want to visit the website now?</value>
|
||||
<value>Two-step login makes your account more secure by requiring you to verify your login with another device such as a security key, authenticator app, SMS, phone call, or email. Two-step login can be set up on the bitwarden.com web vault. Do you want to visit the website now?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Unlock with {0}</value>
|
||||
@@ -721,10 +721,10 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="VerificationCode" xml:space="preserve">
|
||||
<value>Verification Code</value>
|
||||
<value>Verification code</value>
|
||||
</data>
|
||||
<data name="ViewItem" xml:space="preserve">
|
||||
<value>View Item</value>
|
||||
<value>View item</value>
|
||||
</data>
|
||||
<data name="WebVault" xml:space="preserve">
|
||||
<value>Bitwarden web vault</value>
|
||||
@@ -796,10 +796,10 @@
|
||||
<value>Are you sure you want to auto-fill this item? It is not a complete match for "{0}".</value>
|
||||
</data>
|
||||
<data name="MatchingItems" xml:space="preserve">
|
||||
<value>Matching Items</value>
|
||||
<value>Matching items</value>
|
||||
</data>
|
||||
<data name="PossibleMatchingItems" xml:space="preserve">
|
||||
<value>Possible Matching Items</value>
|
||||
<value>Possible matching items</value>
|
||||
</data>
|
||||
<data name="Search" xml:space="preserve">
|
||||
<value>অনুসন্ধান</value>
|
||||
@@ -815,7 +815,7 @@
|
||||
<comment>Message shown when trying to launch an app that does not exist on the user's device.</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorAppTitle" xml:space="preserve">
|
||||
<value>Authenticator App</value>
|
||||
<value>Authenticator app</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="EnterVerificationCodeApp" xml:space="preserve">
|
||||
@@ -827,11 +827,11 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="LoginUnavailable" xml:space="preserve">
|
||||
<value>Login Unavailable</value>
|
||||
<value>Login unavailable</value>
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>This account has two-step login enabled, however, none of the configured two-step providers are supported on this device. Please use a supported device and/or add additional providers that are better supported across devices (such as an authenticator app).</value>
|
||||
<value>This account has two-step login set up, however, none of the configured two-step providers are supported on this device. Please use a supported device and/or add additional providers that are better supported across devices (such as an authenticator app).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>পুনরুদ্ধার কোড</value>
|
||||
@@ -887,10 +887,10 @@
|
||||
<comment>The placeholder will show the file size of the attachment. Ex "25 MB"</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorKey" xml:space="preserve">
|
||||
<value>Authenticator Key (TOTP)</value>
|
||||
<value>Authenticator key (TOTP)</value>
|
||||
</data>
|
||||
<data name="VerificationCodeTotp" xml:space="preserve">
|
||||
<value>Verification Code (TOTP)</value>
|
||||
<value>Verification code (TOTP)</value>
|
||||
<comment>Totp code label</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyAdded" xml:space="preserve">
|
||||
@@ -931,7 +931,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Attachment deleted</value>
|
||||
</data>
|
||||
<data name="ChooseFile" xml:space="preserve">
|
||||
<value>Choose File</value>
|
||||
<value>Choose file</value>
|
||||
</data>
|
||||
<data name="File" xml:space="preserve">
|
||||
<value>File</value>
|
||||
@@ -1080,7 +1080,7 @@ Scanning will happen automatically.</value>
|
||||
<value>নামের শেষাংশ</value>
|
||||
</data>
|
||||
<data name="FullName" xml:space="preserve">
|
||||
<value>Full Name</value>
|
||||
<value>Full name</value>
|
||||
</data>
|
||||
<data name="LicenseNumber" xml:space="preserve">
|
||||
<value>লাইসেন্স নম্বর</value>
|
||||
@@ -1110,7 +1110,7 @@ Scanning will happen automatically.</value>
|
||||
<value>October</value>
|
||||
</data>
|
||||
<data name="PassportNumber" xml:space="preserve">
|
||||
<value>Passport Number</value>
|
||||
<value>Passport number</value>
|
||||
</data>
|
||||
<data name="Phone" xml:space="preserve">
|
||||
<value>Phone</value>
|
||||
@@ -1119,7 +1119,7 @@ Scanning will happen automatically.</value>
|
||||
<value>September</value>
|
||||
</data>
|
||||
<data name="SSN" xml:space="preserve">
|
||||
<value>Social Security Number</value>
|
||||
<value>Social Security number</value>
|
||||
</data>
|
||||
<data name="StateProvince" xml:space="preserve">
|
||||
<value>State / Province</value>
|
||||
@@ -1128,7 +1128,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Title</value>
|
||||
</data>
|
||||
<data name="ZipPostalCode" xml:space="preserve">
|
||||
<value>Zip / Postal Code</value>
|
||||
<value>Zip / Postal code</value>
|
||||
</data>
|
||||
<data name="Address" xml:space="preserve">
|
||||
<value>Address</value>
|
||||
@@ -1143,7 +1143,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Show a recognizable image next to each login.</value>
|
||||
</data>
|
||||
<data name="IconsUrl" xml:space="preserve">
|
||||
<value>Icons Server URL</value>
|
||||
<value>Icons server URL</value>
|
||||
</data>
|
||||
<data name="AutofillWithBitwarden" xml:space="preserve">
|
||||
<value>Auto-fill with Bitwarden</value>
|
||||
@@ -1198,7 +1198,7 @@ Scanning will happen automatically.</value>
|
||||
<value>We were unable to automatically open the Android autofill settings menu for you. You can navigate to the autofill settings menu manually from Android Settings > System > Languages and input > Advanced > Autofill service.</value>
|
||||
</data>
|
||||
<data name="CustomFieldName" xml:space="preserve">
|
||||
<value>Custom Field Name</value>
|
||||
<value>Custom field name</value>
|
||||
</data>
|
||||
<data name="FieldTypeBoolean" xml:space="preserve">
|
||||
<value>Boolean</value>
|
||||
@@ -1213,7 +1213,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Text</value>
|
||||
</data>
|
||||
<data name="NewCustomField" xml:space="preserve">
|
||||
<value>New Custom Field</value>
|
||||
<value>New custom field</value>
|
||||
</data>
|
||||
<data name="SelectTypeField" xml:space="preserve">
|
||||
<value>What type of custom field do you want to add?</value>
|
||||
@@ -1249,14 +1249,14 @@ Scanning will happen automatically.</value>
|
||||
<value>Starts with</value>
|
||||
</data>
|
||||
<data name="URIMatchDetection" xml:space="preserve">
|
||||
<value>URI Match Detection</value>
|
||||
<value>URI match detection</value>
|
||||
</data>
|
||||
<data name="MatchDetection" xml:space="preserve">
|
||||
<value>মিল সনাক্তকরণ</value>
|
||||
<comment>URI match detection for auto-fill.</comment>
|
||||
</data>
|
||||
<data name="YesAndSave" xml:space="preserve">
|
||||
<value>Yes, and Save</value>
|
||||
<value>Yes, and save</value>
|
||||
</data>
|
||||
<data name="AutofillAndSave" xml:space="preserve">
|
||||
<value>Auto-fill and save</value>
|
||||
@@ -1286,7 +1286,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>ex. Date this item was updated</comment>
|
||||
</data>
|
||||
<data name="AutofillActivated" xml:space="preserve">
|
||||
<value>AutoFill Activated!</value>
|
||||
<value>AutoFill activated!</value>
|
||||
</data>
|
||||
<data name="MustLogInMainAppAutofill" xml:space="preserve">
|
||||
<value>You must log into the main Bitwarden app before you can use AutoFill.</value>
|
||||
@@ -1301,7 +1301,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Access your vault directly from your keyboard to quickly autofill passwords.</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn" xml:space="preserve">
|
||||
<value>To enable password autofill on your device, follow these instructions:</value>
|
||||
<value>To set up password auto-fill on your device, follow these instructions:</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn1" xml:space="preserve">
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
@@ -1381,10 +1381,10 @@ Scanning will happen automatically.</value>
|
||||
<value>সংগ্রহ অনুসন্ধান</value>
|
||||
</data>
|
||||
<data name="SearchFileSends" xml:space="preserve">
|
||||
<value>Search File Sends</value>
|
||||
<value>Search file Sends</value>
|
||||
</data>
|
||||
<data name="SearchTextSends" xml:space="preserve">
|
||||
<value>Search Text Sends</value>
|
||||
<value>Search text Sends</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Search {0}</value>
|
||||
@@ -1437,13 +1437,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Choose an organization that you wish to move this item to. Moving to an organization transfers ownership of the item to that organization. You will no longer be the direct owner of this item once it has been moved.</value>
|
||||
</data>
|
||||
<data name="NumberOfWords" xml:space="preserve">
|
||||
<value>Number of Words</value>
|
||||
<value>Number of words</value>
|
||||
</data>
|
||||
<data name="Passphrase" xml:space="preserve">
|
||||
<value>Passphrase</value>
|
||||
</data>
|
||||
<data name="WordSeparator" xml:space="preserve">
|
||||
<value>Word Separator</value>
|
||||
<value>Word separator</value>
|
||||
</data>
|
||||
<data name="Clear" xml:space="preserve">
|
||||
<value>Clear</value>
|
||||
@@ -1480,7 +1480,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Unlock</value>
|
||||
</data>
|
||||
<data name="UnlockVault" xml:space="preserve">
|
||||
<value>Unlock Vault</value>
|
||||
<value>Unlock vault</value>
|
||||
</data>
|
||||
<data name="ThirtyMinutes" xml:space="preserve">
|
||||
<value>30 minutes</value>
|
||||
@@ -1553,10 +1553,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Default dark theme</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescription" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is enabled.</value>
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is in use.</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Copy Note</value>
|
||||
<value>Copy note</value>
|
||||
</data>
|
||||
<data name="Exit" xml:space="preserve">
|
||||
<value>প্রস্থান</value>
|
||||
@@ -1575,6 +1575,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Auto-fill blocked URIs</value>
|
||||
</data>
|
||||
@@ -1591,7 +1595,7 @@ Scanning will happen automatically.</value>
|
||||
<value>On app restart</value>
|
||||
</data>
|
||||
<data name="AutofillServiceNotEnabled" xml:space="preserve">
|
||||
<value>Auto-fill makes it easy to securely access your Bitwarden vault from other websites and apps. It looks like you have not enabled an auto-fill service for Bitwarden. Enable auto-fill for Bitwarden from the "Settings" screen.</value>
|
||||
<value>Auto-fill makes it easy to securely access your Bitwarden vault from other websites and apps. It looks like you have not set up an auto-fill service for Bitwarden. Set up auto-fill for Bitwarden from the "Settings" screen.</value>
|
||||
</data>
|
||||
<data name="ThemeAppliedOnRestart" xml:space="preserve">
|
||||
<value>Your theme changes will apply when the app is restarted.</value>
|
||||
@@ -1601,7 +1605,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>ex. Uppercase the first character of a word.</comment>
|
||||
</data>
|
||||
<data name="IncludeNumber" xml:space="preserve">
|
||||
<value>Include Number</value>
|
||||
<value>Include number</value>
|
||||
</data>
|
||||
<data name="Download" xml:space="preserve">
|
||||
<value>Download</value>
|
||||
@@ -1610,25 +1614,25 @@ Scanning will happen automatically.</value>
|
||||
<value>Shared</value>
|
||||
</data>
|
||||
<data name="ToggleVisibility" xml:space="preserve">
|
||||
<value>Toggle Visibility</value>
|
||||
<value>Toggle visibility</value>
|
||||
</data>
|
||||
<data name="LoginExpired" xml:space="preserve">
|
||||
<value>Your login session has expired.</value>
|
||||
</data>
|
||||
<data name="BiometricsDirection" xml:space="preserve">
|
||||
<value>Biometric Verification</value>
|
||||
<value>Biometric verification</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Biometrics</value>
|
||||
</data>
|
||||
<data name="UseBiometricsToUnlock" xml:space="preserve">
|
||||
<value>Use Biometrics To Unlock</value>
|
||||
<value>Use biometrics to unlock</value>
|
||||
</data>
|
||||
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden needs attention - See "Auto-fill Accessibility Service" from Bitwarden Settings</value>
|
||||
<value>Bitwarden needs attention - See "Auto-fill Accessibility Service" from Bitwarden settings</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
|
||||
<value>3. On the Android App Settings screen for Bitwarden, go to the "Display over other apps" options (under Advanced) and tap the toggle to enable overlay support.</value>
|
||||
<value>3. On the Android App Settings screen for Bitwarden, go to the "Display over other apps" options (under Advanced) and tap the toggle to allow overlay support.</value>
|
||||
</data>
|
||||
<data name="OverlayPermission" xml:space="preserve">
|
||||
<value>অনুমতি</value>
|
||||
@@ -1655,7 +1659,7 @@ 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>Code sent!</value>
|
||||
</data>
|
||||
<data name="ConfirmYourIdentity" xml:space="preserve">
|
||||
<value>Confirm your identity to continue.</value>
|
||||
@@ -1700,7 +1704,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Attachment saved successfully</value>
|
||||
</data>
|
||||
<data name="AutofillTileAccessibilityRequired" xml:space="preserve">
|
||||
<value>Please enable "Auto-fill Accessibility Service" from Bitwarden Settings to use the Auto-fill tile.</value>
|
||||
<value>Please turn on "Auto-fill Accessibility Service" from Bitwarden Settings to use the Auto-fill tile.</value>
|
||||
</data>
|
||||
<data name="AutofillTileUriNotFound" xml:space="preserve">
|
||||
<value>No password fields detected</value>
|
||||
@@ -1722,7 +1726,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>Item has been restored.</value>
|
||||
<value>Item restored</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -1752,19 +1756,19 @@ Scanning will happen automatically.</value>
|
||||
<value>Biometric unlock for autofill disabled pending verification of master password.</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefresh" xml:space="preserve">
|
||||
<value>Enable sync on refresh</value>
|
||||
<value>Allow sync on refresh</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
|
||||
<value>Syncing vault with pull down gesture.</value>
|
||||
</data>
|
||||
<data name="LogInSso" xml:space="preserve">
|
||||
<value>Enterprise Single Sign-On</value>
|
||||
<value>Enterprise single sign-on</value>
|
||||
</data>
|
||||
<data name="LogInSsoSummary" xml:space="preserve">
|
||||
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
|
||||
</data>
|
||||
<data name="OrgIdentifier" xml:space="preserve">
|
||||
<value>Organization Identifier</value>
|
||||
<value>Organization identifier</value>
|
||||
</data>
|
||||
<data name="LoginSsoError" xml:space="preserve">
|
||||
<value>Currently unable to login with SSO</value>
|
||||
@@ -1797,7 +1801,7 @@ Scanning will happen automatically.</value>
|
||||
<value>নিম্নলিখিত বিশেষ অক্ষরগুলির একটি বা একাধিক রয়েছে: {0}</value>
|
||||
</data>
|
||||
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
|
||||
<value>Invalid Password</value>
|
||||
<value>Invalid password</value>
|
||||
</data>
|
||||
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
|
||||
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
|
||||
@@ -1819,7 +1823,7 @@ Scanning will happen automatically.</value>
|
||||
<value>গোপনীয়তা নীতি</value>
|
||||
</data>
|
||||
<data name="AccessibilityDrawOverPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden needs attention - Enable "Draw-Over" in "Auto-fill Services" from Bitwarden Settings</value>
|
||||
<value>Bitwarden needs attention - Turn on "Draw-Over" in "Auto-fill Services" from Bitwarden Settings</value>
|
||||
</data>
|
||||
<data name="AutofillServices" xml:space="preserve">
|
||||
<value>Auto-fill services</value>
|
||||
@@ -1828,34 +1832,34 @@ Scanning will happen automatically.</value>
|
||||
<value>Use inline autofill</value>
|
||||
</data>
|
||||
<data name="InlineAutofillDescription" xml:space="preserve">
|
||||
<value>Use inline autofill if your selected IME (keyboard) supports it. If your configuration is not supported (or this option is disabled), the default Autofill overlay will be used.</value>
|
||||
<value>Use inline autofill if your selected IME (keyboard) supports it. If your configuration is not supported (or this option is turned off), the default Autofill overlay will be used.</value>
|
||||
</data>
|
||||
<data name="Accessibility" xml:space="preserve">
|
||||
<value>Use accessibility</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription" xml:space="preserve">
|
||||
<value>Use the Bitwarden Accessibility Service to auto-fill your logins across apps and the web. When enabled, we'll display a popup when login fields are selected.</value>
|
||||
<value>Use the Bitwarden Accessibility Service to auto-fill your logins across apps and the web. When set up, we'll display a popup when login fields are selected.</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription2" xml:space="preserve">
|
||||
<value>Use the Bitwarden Accessibility Service to auto-fill your logins across apps and the web. (Requires Draw-Over to be enabled as well)</value>
|
||||
<value>Use the Bitwarden Accessibility Service to auto-fill your logins across apps and the web. (Requires Draw-Over to be turned on as well)</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription3" xml:space="preserve">
|
||||
<value>Use the Bitwarden Accessibility Service to use the Autofill Quick-Action Tile, and/or show a popup using Draw-Over (if enabled).</value>
|
||||
<value>Use the Bitwarden Accessibility Service to use the Autofill Quick-Action Tile, and/or show a popup using Draw-Over (if turned on).</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription4" xml:space="preserve">
|
||||
<value>Required to use the Autofill Quick-Action Tile, or to augment the Autofill Service by using Draw-Over (if enabled).</value>
|
||||
<value>Required to use the Autofill Quick-Action Tile, or to augment the Autofill Service by using Draw-Over (if turned on).</value>
|
||||
</data>
|
||||
<data name="DrawOver" xml:space="preserve">
|
||||
<value>Use draw-over</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription" xml:space="preserve">
|
||||
<value>When enabled, allows the Bitwarden Accessibility Service to display a popup when login fields are selected.</value>
|
||||
<value>Allows the Bitwarden Accessibility Service to display a popup when login fields are selected.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription2" xml:space="preserve">
|
||||
<value>If enabled, the Bitwarden Accessibility Service will display a popup when login fields are selected to assist with auto-filling your logins.</value>
|
||||
<value>If turned on, the Bitwarden Accessibility Service will display a popup when login fields are selected to assist with auto-filling your logins.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription3" xml:space="preserve">
|
||||
<value>If enabled, accessibility will show a popup to augment the Autofill Service for older apps that don't support the Android Autofill Framework.</value>
|
||||
<value>If turned on, accessibility will show a popup to augment the Autofill Service for older apps that don't support the Android Autofill Framework.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
|
||||
<value>একটি এন্টারপ্রাইজ নীতির কারণে, আপনি আপনার ব্যক্তিগত ভল্টে বস্তুসমূহ সংরক্ষণ করা থেকে সীমাবদ্ধ। একটি প্রতিষ্ঠানের মালিকানা বিকল্পটি পরিবর্তন করুন এবং উপলভ্য সংগ্রহগুলি থেকে চয়ন করুন।</value>
|
||||
@@ -1911,10 +1915,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Text type is not selected, tap to select.</value>
|
||||
</data>
|
||||
<data name="DeletionDate" xml:space="preserve">
|
||||
<value>Deletion Date</value>
|
||||
<value>Deletion date</value>
|
||||
</data>
|
||||
<data name="DeletionTime" xml:space="preserve">
|
||||
<value>Deletion Time</value>
|
||||
<value>Deletion time</value>
|
||||
</data>
|
||||
<data name="DeletionDateInfo" xml:space="preserve">
|
||||
<value>The Send will be permanently deleted on the specified date and time.</value>
|
||||
@@ -1924,10 +1928,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Pending deletion</value>
|
||||
</data>
|
||||
<data name="ExpirationDate" xml:space="preserve">
|
||||
<value>Expiration Date</value>
|
||||
<value>Expiration date</value>
|
||||
</data>
|
||||
<data name="ExpirationTime" xml:space="preserve">
|
||||
<value>Expiration Time</value>
|
||||
<value>Expiration time</value>
|
||||
</data>
|
||||
<data name="ExpirationDateInfo" xml:space="preserve">
|
||||
<value>If set, access to this Send will expire on the specified date and time.</value>
|
||||
@@ -1937,7 +1941,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Expired</value>
|
||||
</data>
|
||||
<data name="MaximumAccessCount" xml:space="preserve">
|
||||
<value>Maximum Access Count</value>
|
||||
<value>Maximum access count</value>
|
||||
</data>
|
||||
<data name="MaximumAccessCountInfo" xml:space="preserve">
|
||||
<value>If set, users will no longer be able to access this Send once the maximum access count is reached.</value>
|
||||
@@ -1947,17 +1951,17 @@ Scanning will happen automatically.</value>
|
||||
<value>Max access count reached</value>
|
||||
</data>
|
||||
<data name="CurrentAccessCount" xml:space="preserve">
|
||||
<value>Current Access Count</value>
|
||||
<value>Current access count</value>
|
||||
</data>
|
||||
<data name="NewPassword" xml:space="preserve">
|
||||
<value>New Password</value>
|
||||
<value>New password</value>
|
||||
</data>
|
||||
<data name="PasswordInfo" xml:space="preserve">
|
||||
<value>Optionally require a password for users to access this Send.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="RemovePassword" xml:space="preserve">
|
||||
<value>Remove Password</value>
|
||||
<value>Remove password</value>
|
||||
</data>
|
||||
<data name="AreYouSureRemoveSendPassword" xml:space="preserve">
|
||||
<value>Are you sure you want to remove the password?</value>
|
||||
@@ -1973,7 +1977,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="DisableSend" xml:space="preserve">
|
||||
<value>Disable this Send so that no one can access it</value>
|
||||
<value>Deactivate this Send so that no one can access it</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
@@ -1985,10 +1989,10 @@ 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="CopyLink" xml:space="preserve">
|
||||
<value>Copy Link</value>
|
||||
<value>Copy link</value>
|
||||
</data>
|
||||
<data name="ShareLink" xml:space="preserve">
|
||||
<value>Share Link</value>
|
||||
<value>Share link</value>
|
||||
</data>
|
||||
<data name="SendLink" xml:space="preserve">
|
||||
<value>Send link</value>
|
||||
@@ -2003,7 +2007,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="AddSend" xml:space="preserve">
|
||||
<value>Add Send</value>
|
||||
<value>New Send</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AreYouSureDeleteSend" xml:space="preserve">
|
||||
@@ -2011,15 +2015,15 @@ 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="SendDeleted" xml:space="preserve">
|
||||
<value>Send has been deleted.</value>
|
||||
<value>Send deleted</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
<value>Send updated.</value>
|
||||
<value>Send saved</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
<value>New send created.</value>
|
||||
<value>Send created</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="OneDay" xml:space="preserve">
|
||||
@@ -2077,37 +2081,37 @@ Scanning will happen automatically.</value>
|
||||
<value>This action is protected, to continue please re-enter your master password to verify your identity.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Captcha Required</value>
|
||||
<value>Captcha required</value>
|
||||
</data>
|
||||
<data name="CaptchaFailed" xml:space="preserve">
|
||||
<value>Captcha Failed. Please try again.</value>
|
||||
<value>Captcha failed. Please try again.</value>
|
||||
</data>
|
||||
<data name="UpdatedMasterPassword" xml:space="preserve">
|
||||
<value>Updated Master Password</value>
|
||||
<value>Updated master password</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPassword" xml:space="preserve">
|
||||
<value>Update Master Password</value>
|
||||
<value>Update master password</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update your Master Password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
|
||||
<value>Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Updating Password</value>
|
||||
<value>Updating password</value>
|
||||
</data>
|
||||
<data name="UpdatePasswordError" xml:space="preserve">
|
||||
<value>Currently unable to update password</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPassword" xml:space="preserve">
|
||||
<value>Remove Master Password</value>
|
||||
<value>Remove master password</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning" xml:space="preserve">
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your Master Password from your account and require SSO to login.</value>
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your master password from your account and require SSO to login.</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning2" xml:space="preserve">
|
||||
<value>If you do not want to remove your Master Password, you may leave this organization.</value>
|
||||
<value>If you do not want to remove your master password, you may leave this organization.</value>
|
||||
</data>
|
||||
<data name="LeaveOrganization" xml:space="preserve">
|
||||
<value>Leave Organization</value>
|
||||
<value>Leave organization</value>
|
||||
</data>
|
||||
<data name="LeaveOrganizationName" xml:space="preserve">
|
||||
<value>Leave {0}?</value>
|
||||
@@ -2116,7 +2120,7 @@ Scanning will happen automatically.</value>
|
||||
<value>FIDO2 WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2Instruction" xml:space="preserve">
|
||||
<value>To continue, have your FIDO2 WebAuthn enabled security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
<value>To continue, have your FIDO2 WebAuthn compatible security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
</data>
|
||||
<data name="Fido2Desc" xml:space="preserve">
|
||||
<value>Authentication using FIDO2 WebAuthn, you can authenticate using an external security key.</value>
|
||||
@@ -2125,7 +2129,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Authenticate WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2ReturnToApp" xml:space="preserve">
|
||||
<value>Return to App</value>
|
||||
<value>Return to app</value>
|
||||
</data>
|
||||
<data name="Fido2CheckBrowser" xml:space="preserve">
|
||||
<value>Please make sure your default browser supports WebAuthn and try again.</value>
|
||||
@@ -2134,16 +2138,16 @@ Scanning will happen automatically.</value>
|
||||
<value>This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed Vault Timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Your vault timeout exceeds the restrictions set by your organization.</value>
|
||||
</data>
|
||||
<data name="DisablePersonalVaultExportPolicyInEffect">
|
||||
<value>One or more organization policies prevents your from exporting your personal vault.</value>
|
||||
<value>One or more organization policies prevents your from exporting your individual vault.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Add account</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
@@ -2152,13 +2156,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Logged out</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
<value>Account locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
@@ -2182,13 +2186,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Your account has been permanently deleted</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Invalid Verification Code.</value>
|
||||
<value>Invalid verification code</value>
|
||||
</data>
|
||||
<data name="RequestOTP" xml:space="preserve">
|
||||
<value>Request one-time password</value>
|
||||
</data>
|
||||
<data name="SendCode" xml:space="preserve">
|
||||
<value>Send Code</value>
|
||||
<value>Send code</value>
|
||||
</data>
|
||||
<data name="Sending" xml:space="preserve">
|
||||
<value>Sending</value>
|
||||
@@ -2203,7 +2207,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Verifying</value>
|
||||
</data>
|
||||
<data name="ResendCode" xml:space="preserve">
|
||||
<value>Resend Code</value>
|
||||
<value>Resend code</value>
|
||||
</data>
|
||||
<data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve">
|
||||
<value>A verification code was sent to your email</value>
|
||||
@@ -2236,7 +2240,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Numbers (0 to 9)</value>
|
||||
</data>
|
||||
<data name="SpecialCharacters" xml:space="preserve">
|
||||
<value>Special Characters (!@#$%^&*)</value>
|
||||
<value>Special characters (!@#$%^&*)</value>
|
||||
</data>
|
||||
<data name="TapToGoBack" xml:space="preserve">
|
||||
<value>Tap to go back</value>
|
||||
@@ -2251,7 +2255,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Filter items by vault</value>
|
||||
</data>
|
||||
<data name="AllVaults" xml:space="preserve">
|
||||
<value>All Vaults</value>
|
||||
<value>All vaults</value>
|
||||
</data>
|
||||
<data name="Vaults" xml:space="preserve">
|
||||
<value>Vaults</value>
|
||||
@@ -2266,7 +2270,7 @@ Scanning will happen automatically.</value>
|
||||
<value>TOTP</value>
|
||||
</data>
|
||||
<data name="VerificationCodes" xml:space="preserve">
|
||||
<value>Verification Codes</value>
|
||||
<value>Verification codes</value>
|
||||
</data>
|
||||
<data name="PremiumSubscriptionRequired" xml:space="preserve">
|
||||
<value>Premium subscription required</value>
|
||||
@@ -2281,10 +2285,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Cannot scan QR Code? </value>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyScanner" xml:space="preserve">
|
||||
<value>Authenticator Key</value>
|
||||
<value>Authenticator key</value>
|
||||
</data>
|
||||
<data name="EnterKeyManually" xml:space="preserve">
|
||||
<value>Enter Key Manually</value>
|
||||
<value>Enter key manually</value>
|
||||
</data>
|
||||
<data name="AddTotp" xml:space="preserve">
|
||||
<value>Add TOTP</value>
|
||||
@@ -2312,37 +2316,97 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Allow screen capture</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Are you sure you want to enable Screen Capture?</value>
|
||||
<value>Are you sure you want to turn on screen capture?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Login requested</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Are you trying to log in?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Login attempt by {0} on {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Device type</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP address</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Time</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirm login</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Deny login</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Just now</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minutes ago</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Login confirmed</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Login denied</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Approve login requests</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use this device to approve login requests made from other devices.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Allow notifications</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Receive push notifications for new login requests</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>No thanks</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Confirm login attempt for {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>All notifications</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password Type</value>
|
||||
<value>Password type</value>
|
||||
</data>
|
||||
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
|
||||
<value>What would you like to generate?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Username Type</value>
|
||||
<value>Username type</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus Addressed Email</value>
|
||||
<value>Plus addressed email</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all Email</value>
|
||||
<value>Catch-all email</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded Email Alias</value>
|
||||
<value>Forwarded email alias</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Random Word</value>
|
||||
<value>Random word</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>Email (required)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Domain Name (required)</value>
|
||||
<value>Domain name (required)</value>
|
||||
</data>
|
||||
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
|
||||
<value>API Key (required)</value>
|
||||
<value>API key (required)</value>
|
||||
</data>
|
||||
<data name="Service" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
@@ -2360,13 +2424,13 @@ select Add TOTP to store the key safely</value>
|
||||
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="APIAccessToken" xml:space="preserve">
|
||||
<value>API Access Token</value>
|
||||
<value>API access token</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
|
||||
<value>Are you sure you want to overwrite the current username?</value>
|
||||
</data>
|
||||
<data name="GenerateUsername" xml:space="preserve">
|
||||
<value>Generate Username</value>
|
||||
<value>Generate username</value>
|
||||
</data>
|
||||
<data name="EmailType" xml:space="preserve">
|
||||
<value>Email Type</value>
|
||||
@@ -2389,4 +2453,60 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accept</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Decline</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -1553,7 +1553,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Zadana tamna tema</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescription" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is enabled.</value>
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is in use.</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Kopiraj bilješke</value>
|
||||
@@ -1575,6 +1575,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Auto-fill blocked URIs</value>
|
||||
</data>
|
||||
@@ -2235,7 +2239,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Numbers (0 to 9)</value>
|
||||
</data>
|
||||
<data name="SpecialCharacters" xml:space="preserve">
|
||||
<value>Special Characters (!@#$%^&*)</value>
|
||||
<value>Special characters (!@#$%^&*)</value>
|
||||
</data>
|
||||
<data name="TapToGoBack" xml:space="preserve">
|
||||
<value>Tap to go back</value>
|
||||
@@ -2250,7 +2254,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Filter items by vault</value>
|
||||
</data>
|
||||
<data name="AllVaults" xml:space="preserve">
|
||||
<value>All Vaults</value>
|
||||
<value>All vaults</value>
|
||||
</data>
|
||||
<data name="Vaults" xml:space="preserve">
|
||||
<value>Vaults</value>
|
||||
@@ -2265,7 +2269,7 @@ Scanning will happen automatically.</value>
|
||||
<value>TOTP</value>
|
||||
</data>
|
||||
<data name="VerificationCodes" xml:space="preserve">
|
||||
<value>Verification Codes</value>
|
||||
<value>Verification codes</value>
|
||||
</data>
|
||||
<data name="PremiumSubscriptionRequired" xml:space="preserve">
|
||||
<value>Premium subscription required</value>
|
||||
@@ -2280,10 +2284,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Cannot scan QR Code? </value>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyScanner" xml:space="preserve">
|
||||
<value>Authenticator Key</value>
|
||||
<value>Authenticator key</value>
|
||||
</data>
|
||||
<data name="EnterKeyManually" xml:space="preserve">
|
||||
<value>Enter Key Manually</value>
|
||||
<value>Enter key manually</value>
|
||||
</data>
|
||||
<data name="AddTotp" xml:space="preserve">
|
||||
<value>Add TOTP</value>
|
||||
@@ -2311,37 +2315,97 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Allow screen capture</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Are you sure you want to enable Screen Capture?</value>
|
||||
<value>Are you sure you want to turn on screen capture?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Login requested</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Are you trying to log in?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Login attempt by {0} on {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Device type</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP address</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Time</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirm login</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Deny login</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Just now</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minutes ago</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Login confirmed</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Login denied</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Approve login requests</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use this device to approve login requests made from other devices.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Allow notifications</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Receive push notifications for new login requests</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>No thanks</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Confirm login attempt for {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>All notifications</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password Type</value>
|
||||
<value>Password type</value>
|
||||
</data>
|
||||
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
|
||||
<value>What would you like to generate?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Username Type</value>
|
||||
<value>Username type</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus Addressed Email</value>
|
||||
<value>Plus addressed email</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all Email</value>
|
||||
<value>Catch-all email</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded Email Alias</value>
|
||||
<value>Forwarded email alias</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Random Word</value>
|
||||
<value>Random word</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>Email (required)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Domain Name (required)</value>
|
||||
<value>Domain name (required)</value>
|
||||
</data>
|
||||
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
|
||||
<value>API Key (required)</value>
|
||||
<value>API key (required)</value>
|
||||
</data>
|
||||
<data name="Service" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
@@ -2359,13 +2423,13 @@ select Add TOTP to store the key safely</value>
|
||||
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="APIAccessToken" xml:space="preserve">
|
||||
<value>API Access Token</value>
|
||||
<value>API access token</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
|
||||
<value>Are you sure you want to overwrite the current username?</value>
|
||||
</data>
|
||||
<data name="GenerateUsername" xml:space="preserve">
|
||||
<value>Generate Username</value>
|
||||
<value>Generate username</value>
|
||||
</data>
|
||||
<data name="EmailType" xml:space="preserve">
|
||||
<value>Email Type</value>
|
||||
@@ -2388,4 +2452,60 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accept</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Decline</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
<comment>Title for your favorite items in the vault.</comment>
|
||||
</data>
|
||||
<data name="FileBugReport" xml:space="preserve">
|
||||
<value>Presenta un informe d'error</value>
|
||||
<value>Envieu un informe d'error</value>
|
||||
</data>
|
||||
<data name="FileBugReportDescription" xml:space="preserve">
|
||||
<value>Obri una incidéncia al nostre dipòsit de GitHub.</value>
|
||||
@@ -229,7 +229,7 @@
|
||||
<value>Carpetes</value>
|
||||
</data>
|
||||
<data name="FolderUpdated" xml:space="preserve">
|
||||
<value>Carpeta actualitzada.</value>
|
||||
<value>Carpeta guardada</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Vés al lloc web</value>
|
||||
@@ -296,7 +296,7 @@
|
||||
<comment>Text to define that there are more options things to see.</comment>
|
||||
</data>
|
||||
<data name="MyVault" xml:space="preserve">
|
||||
<value>La meua caixa forta</value>
|
||||
<value>Caixa forta</value>
|
||||
<comment>The title for the vault page.</comment>
|
||||
</data>
|
||||
<data name="Authenticator" xml:space="preserve">
|
||||
@@ -587,7 +587,7 @@
|
||||
<value>La contrasenya ha de contenir almenys 8 caràcters.</value>
|
||||
</data>
|
||||
<data name="MinNumbers" xml:space="preserve">
|
||||
<value>Mínim de caràcters númerics</value>
|
||||
<value>Mínim de caràcters numèrics</value>
|
||||
<comment>Minimum numeric characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MinSpecial" xml:space="preserve">
|
||||
@@ -604,7 +604,7 @@
|
||||
<value>Mai</value>
|
||||
</data>
|
||||
<data name="NewItemCreated" xml:space="preserve">
|
||||
<value>S'ha creat un element nou.</value>
|
||||
<value>S'ha afegit un element</value>
|
||||
</data>
|
||||
<data name="NoFavorites" xml:space="preserve">
|
||||
<value>No hi ha cap preferit a la vostra caixa forta.</value>
|
||||
@@ -681,7 +681,7 @@
|
||||
<value>Informació de l'element</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Element actualitzat.</value>
|
||||
<value>Element guardat</value>
|
||||
</data>
|
||||
<data name="Submitting" xml:space="preserve">
|
||||
<value>S'està enviant...</value>
|
||||
@@ -856,7 +856,7 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="VerificationEmailSent" xml:space="preserve">
|
||||
<value>Correu de verificació enviat.</value>
|
||||
<value>Correu de verificació enviat</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="YubiKeyInstruction" xml:space="preserve">
|
||||
@@ -1256,7 +1256,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<comment>URI match detection for auto-fill.</comment>
|
||||
</data>
|
||||
<data name="YesAndSave" xml:space="preserve">
|
||||
<value>Si, i guarda</value>
|
||||
<value>Sí, i guarda</value>
|
||||
</data>
|
||||
<data name="AutofillAndSave" xml:space="preserve">
|
||||
<value>Ompli automàticament i guarda</value>
|
||||
@@ -1575,6 +1575,10 @@ L'escaneig es farà automàticament.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solaritzat fosc</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Emplena automàticament els URI bloquejats</value>
|
||||
</data>
|
||||
@@ -1616,7 +1620,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<value>La vostra sessió ha caducat.</value>
|
||||
</data>
|
||||
<data name="BiometricsDirection" xml:space="preserve">
|
||||
<value>Utilitzeu dades biomètriques per verificar.</value>
|
||||
<value>Utilitzeu dades biomètriques per verificar</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Dades biomètriques</value>
|
||||
@@ -1722,7 +1726,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>L'element s'ha restaurat.</value>
|
||||
<value>L'element s'ha restaurat</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -1836,7 +1840,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<value>Utilitzeu el servei d’accessibilitat Bitwarden per omplir els vostres inicis de sessió automàticament a través d’aplicacions i del web. Quan estiga activat, mostrarem una finestra emergent quan se seleccionen els camps d'inici de sessió.</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription2" xml:space="preserve">
|
||||
<value>Utilitzeu el servei d’accessibilitat Bitwarden per omplir els vostres inicis de sessió automàticament a través d’aplicacions i del web. (Cal que també estigui habilitat el Dibuixa-sobre)</value>
|
||||
<value>Utilitzeu el servei d’accessibilitat Bitwarden per omplir els vostres inicis de sessió automàticament a través d’aplicacions i del web. (Cal que també estiga habilitat el Dibuixa-sobre)</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription3" xml:space="preserve">
|
||||
<value>Utilitzeu el servei d’accessibilitat Bitwarden per utilitzar el mosaic d’acció ràpida d’emplenament automàtic o mostrar una finestra emergent mitjançant Dibuixa-sobre (si està activat).</value>
|
||||
@@ -1972,7 +1976,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSend" xml:space="preserve">
|
||||
<value>Deshabiliteu aquest Send perquè ningú no hi puga accedir.</value>
|
||||
<value>Deshabiliteu aquest Send perquè ningú no hi puga accedir</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
@@ -2014,11 +2018,11 @@ L'escaneig es farà automàticament.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
<value>S'ha actualitzat el Send</value>
|
||||
<value>S'ha guardat el Send</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
<value>S'ha creat un enviament nou.</value>
|
||||
<value>S'ha creat un Send nou</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="OneDay" xml:space="preserve">
|
||||
@@ -2124,7 +2128,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<value>Autentica WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2ReturnToApp" xml:space="preserve">
|
||||
<value>Tornar a l'aplicació</value>
|
||||
<value>Torna a l'aplicació</value>
|
||||
</data>
|
||||
<data name="Fido2CheckBrowser" xml:space="preserve">
|
||||
<value>Assegureu-vos que el vostre navegador predeterminat admeta WebAuthn i torneu-ho a provar.</value>
|
||||
@@ -2133,7 +2137,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<value>Aquesta organització té una política empresarial que us inscriurà automàticament al restabliment de la contrasenya. La inscripció permetrà als administradors de l’organització canviar la vostra contrasenya mestra.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Les polítiques de l'organització afecten el temps d'espera de la caixa forta. El temps d'espera màxim permès d'aquesta és de $HOURS$ hores i $MINUTES$ minuts</value>
|
||||
<value>Les polítiques de la vostra organització afecten el temps d'espera de la vostra caixa forta. El temps d'espera màxim permès de la caixa forta és de {0} hores i {1} minuts</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>El temps d'espera de la caixa forta supera les restriccions establertes per la vostra organització.</value>
|
||||
@@ -2151,7 +2155,7 @@ L'escaneig es farà automàticament.</value>
|
||||
<value>Bloquejat</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Sessió tancada</value>
|
||||
<value>S'ha tancat sessió</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>S'ha canviat al següent compte disponible</value>
|
||||
@@ -2313,6 +2317,66 @@ seleccioneu Afegeix TOTP per emmagatzemar la clau de manera segura</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Segur que voleu activar la captura de pantalla?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>S'ha sol·licitat inici de sessió</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Esteu intentant iniciar sessió?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Intent d'inici de sessió de {0} en {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Tipus de dispositiu</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>Adreça IP</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Hora</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>A prop</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirmeu l'inici de sessió</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Denegueu l'inici de sessió</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Ara mateix</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>Fa {0} minuts</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>S'ha confirmat l'inici de sessió</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>S'ha denegat l'inici de sessió</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Aprova les sol·licituds d'inici de sessió</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Utilitzeu aquest dispositiu per aprovar les sol·licituds d'inici de sessió fetes des d'altres dispositius.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Permet notificacions</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Rebeu notificacions push per a noves sol·licituds d'inici de sessió</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>No, gràcies</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Confirmeu l'intent d'inici de sessió per a {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Totes les notificacions</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Tipus de contrasenya</value>
|
||||
</data>
|
||||
@@ -2388,4 +2452,60 @@ seleccioneu Afegeix TOTP per emmagatzemar la clau de manera segura</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Aleatori</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Divulgació del servei d'accessibilitat</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden utilitza el Servei d'Accessibilitat per cercar camps d'inici de sessió en aplicacions i llocs web i, a continuació, establir els ID de camp adequats per introduir un nom d'usuari i una contrasenya quan es trobe una coincidència per a l'aplicació o el lloc. No emmagatzemem cap de la informació que ens presenta el servei, ni intentem controlar cap element de la pantalla més enllà de l'entrada de text de les credencials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accepta</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Rebutja</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>La sol·licitud d'inici de sessió ja ha caducat.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Intent d'inici de sessió des de:
|
||||
{0}
|
||||
Voleu canviar a aquest compte?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Nou per ací?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>No sou vosaltres?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Inicia sessió amb la teua contrasenya mestra</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Inicia sessió amb un altre dispositiu</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>S'ha iniciat la sessió</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>S'ha enviat una notificació al vostre dispositiu.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Assegureu-vos que la vostra caixa forta estiga desbloquejada i que la frase d'empremta digital coincidisca amb l'altre dispositiu.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Torna a enviar la notificació</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Necessiteu una altra opció?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Veure totes les opcions d'inici de sessió</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
<comment>Short label for an email address.</comment>
|
||||
</data>
|
||||
<data name="EmailAddress" xml:space="preserve">
|
||||
<value>E-mailová adresa</value>
|
||||
<value>Emailová adresa</value>
|
||||
<comment>Full label for a email address.</comment>
|
||||
</data>
|
||||
<data name="EmailUs" xml:space="preserve">
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Položka byla smazána</value>
|
||||
<value>Položka byla odstraněna.</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -394,7 +394,7 @@
|
||||
<value>Zobrazit</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsite" xml:space="preserve">
|
||||
<value>Navštivit naší webovou stránku</value>
|
||||
<value>Navštívit naší webovou stránku</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsiteDescription" xml:space="preserve">
|
||||
<value>Navštivte náš web pro získání nápovědy, novinek, kontaktu, nebo návodů, jak používat Bitwarden.</value>
|
||||
@@ -428,7 +428,7 @@
|
||||
<value>Použít nezaměnitelné znaky</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtension" xml:space="preserve">
|
||||
<value>Rozšíření aplikace Bitwarden</value>
|
||||
<value>Rozšíření aplikace bitwarden</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
|
||||
<value>Nejjednodušší způsob přidání nových přihlášení do trezoru je z rozšíření Bitwarden. Další informace o používání rozšíření Bitwarden získáte klepnutím na obrazovku Nastavení.</value>
|
||||
@@ -443,7 +443,7 @@
|
||||
<value>Použijte službu přístupnosti pro automatické vyplňování přihlašovacích údajů.</value>
|
||||
</data>
|
||||
<data name="ChangeEmail" xml:space="preserve">
|
||||
<value>Změnit e-mail</value>
|
||||
<value>Změnit email</value>
|
||||
</data>
|
||||
<data name="ChangeEmailConfirmation" xml:space="preserve">
|
||||
<value>E-mailovou adresu si můžete změnit na webové stránce bitwarden.com. Chcete tuto stránku nyní otevřít?</value>
|
||||
@@ -604,7 +604,7 @@
|
||||
<value>Nikdy</value>
|
||||
</data>
|
||||
<data name="NewItemCreated" xml:space="preserve">
|
||||
<value>Položka byla přidána</value>
|
||||
<value>Nová položka byla vytvořena.</value>
|
||||
</data>
|
||||
<data name="NoFavorites" xml:space="preserve">
|
||||
<value>Žádné oblíbené přihlašovací údaje.</value>
|
||||
@@ -647,7 +647,7 @@
|
||||
<value>Opravdu chcete přepsat aktuální heslo?</value>
|
||||
</data>
|
||||
<data name="PushNotificationAlert" xml:space="preserve">
|
||||
<value>Bitwarden udržuje váš trezor automaticky synchronizovaný pomocí nabízených oznámení. Pro nejlepší možný zážitek klikněte prosím na následující výzvě na "Ok", pokud budete požádáni o jejich povolení.</value>
|
||||
<value>bitwarden udržuje váš trezor automaticky synchronizovaný pomocí nabízených oznámení. Pro nejlepší možný zážitek klikněte prosím na následující výzvě na "Ok", pokud budete požádáni o jejich povolení.</value>
|
||||
<comment>Push notifications for apple products</comment>
|
||||
</data>
|
||||
<data name="RateTheApp" xml:space="preserve">
|
||||
@@ -708,7 +708,7 @@
|
||||
<value>Dvoufázové přihlášení</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>Dvoufázové přihlášení činí váš účet mnohem bezpečnějším díky nutnosti po každém úspěšném přihlášení zadat ověřovací kód získaný z aplikace, SMS, e-mailu nebo telefonního hovoru. Dvoufázové přihlášení lze aktivovat na webové stránce bitwarden.com. Chcete tuto stránku nyní otevřít?</value>
|
||||
<value>Dvoufázové přihlášení činí váš účet mnohem bezpečnější díky nutnosti po každém úspěšném přihlášení zadat ověřovací kód získaný z aplikace, SMS, emailu nebo telefonního hovoru. Dvoufázové přihlášení lze aktivovat na webové stránce bitwarden.com. Chcete tuto stránku nyní otevřít?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Odemknout pomocí {0}</value>
|
||||
@@ -775,10 +775,10 @@
|
||||
<value>Povoleno</value>
|
||||
</data>
|
||||
<data name="Off" xml:space="preserve">
|
||||
<value>Off</value>
|
||||
<value>Vypnuto</value>
|
||||
</data>
|
||||
<data name="On" xml:space="preserve">
|
||||
<value>On</value>
|
||||
<value>Zapnuto</value>
|
||||
</data>
|
||||
<data name="Status" xml:space="preserve">
|
||||
<value>Stav</value>
|
||||
@@ -900,8 +900,8 @@
|
||||
<value>Nelze přečíst ověřovací klíč.</value>
|
||||
</data>
|
||||
<data name="PointYourCameraAtTheQRCode" xml:space="preserve">
|
||||
<value>Point your camera at the QR Code.
|
||||
Scanning will happen automatically.</value>
|
||||
<value>Nasměrujte kameru na QR Kód.
|
||||
Načtení proběhne automaticky.</value>
|
||||
</data>
|
||||
<data name="ScanQrTitle" xml:space="preserve">
|
||||
<value>Načíst QR kód</value>
|
||||
@@ -916,10 +916,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Zkopírovat ověřovací kód (TOTP)</value>
|
||||
</data>
|
||||
<data name="CopyTotpAutomaticallyDescription" xml:space="preserve">
|
||||
<value>If a login has an authenticator key, copy the TOTP verification code to your clip-board when you auto-fill the login.</value>
|
||||
<value>Zkopírujte si TOTP ověřovací kód do schránky, pokud používáte autentizační klíč k přihlašování, před použitím automatického vyplňování.</value>
|
||||
</data>
|
||||
<data name="CopyTotpAutomatically" xml:space="preserve">
|
||||
<value>Copy TOTP automatically</value>
|
||||
<value>Automaticky kopírovat TOTP</value>
|
||||
</data>
|
||||
<data name="PremiumRequired" xml:space="preserve">
|
||||
<value>Pro použití této funkce je potřebné prémiové členství.</value>
|
||||
@@ -958,7 +958,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Dozvědět se více</value>
|
||||
</data>
|
||||
<data name="ApiUrl" xml:space="preserve">
|
||||
<value>URL API serveru</value>
|
||||
<value>URL serveru API</value>
|
||||
</data>
|
||||
<data name="CustomEnvironment" xml:space="preserve">
|
||||
<value>Vlastní prostředí</value>
|
||||
@@ -1137,10 +1137,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Expirace</value>
|
||||
</data>
|
||||
<data name="ShowWebsiteIcons" xml:space="preserve">
|
||||
<value>Show website icons</value>
|
||||
<value>Zobrazit ikony webových stránek</value>
|
||||
</data>
|
||||
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
|
||||
<value>Show a recognizable image next to each login.</value>
|
||||
<value>Zobrazí rozeznatelné ikony vedle každého záznamu.</value>
|
||||
</data>
|
||||
<data name="IconsUrl" xml:space="preserve">
|
||||
<value>URL serveru ikonek</value>
|
||||
@@ -1381,10 +1381,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Vyledat v kolekci</value>
|
||||
</data>
|
||||
<data name="SearchFileSends" xml:space="preserve">
|
||||
<value>Search File Sends</value>
|
||||
<value>Search file Sends</value>
|
||||
</data>
|
||||
<data name="SearchTextSends" xml:space="preserve">
|
||||
<value>Search Text Sends</value>
|
||||
<value>Search text Sends</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Hledat {0}</value>
|
||||
@@ -1550,10 +1550,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Výchozí (Systémový)</value>
|
||||
</data>
|
||||
<data name="DefaultDarkTheme" xml:space="preserve">
|
||||
<value>Default dark theme</value>
|
||||
<value>Výchozí tmavý motiv</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescription" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is enabled.</value>
|
||||
<value>Zvolte motiv, který se bude zobrazovat po aktivování tmavého motivu v systému.</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Kopírovat poznámky</value>
|
||||
@@ -1575,6 +1575,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Automatické vyplňování blokovaných URI</value>
|
||||
</data>
|
||||
@@ -1898,16 +1902,16 @@ Scanning will happen automatically.</value>
|
||||
<value>Soubor, který chcete odeslat.</value>
|
||||
</data>
|
||||
<data name="FileTypeIsSelected" xml:space="preserve">
|
||||
<value>File type is selected.</value>
|
||||
<value>Je vybrán typ souboru.</value>
|
||||
</data>
|
||||
<data name="FileTypeIsNotSelected" xml:space="preserve">
|
||||
<value>File type is not selected, tap to select.</value>
|
||||
<value>Není vybrán typ souboru, klepněte pro výběr.</value>
|
||||
</data>
|
||||
<data name="TextTypeIsSelected" xml:space="preserve">
|
||||
<value>Text type is selected.</value>
|
||||
<value>Je vybrán typ textu.</value>
|
||||
</data>
|
||||
<data name="TextTypeIsNotSelected" xml:space="preserve">
|
||||
<value>Text type is not selected, tap to select.</value>
|
||||
<value>Není vybrán typ textu, klepněte pro výběr.</value>
|
||||
</data>
|
||||
<data name="DeletionDate" xml:space="preserve">
|
||||
<value>Datum odstranění</value>
|
||||
@@ -1972,7 +1976,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="DisableSend" xml:space="preserve">
|
||||
<value>Zakažte tento Send, aby k němu nikdo neměl přístup.</value>
|
||||
<value>Vypnout tento Send, aby k němu nikdo neměl přístup</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
@@ -2040,7 +2044,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Vlastní</value>
|
||||
</data>
|
||||
<data name="ShareOnSave" xml:space="preserve">
|
||||
<value>Sdílet tento Send po uložení.</value>
|
||||
<value>Sdílet tento Send po uložení</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDisabledWarning" xml:space="preserve">
|
||||
@@ -2052,7 +2056,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="HideEmail" xml:space="preserve">
|
||||
<value>Skrýt mou e-mailovou adresu před příjemci.</value>
|
||||
<value>Skrýt mou e-mailovou adresu před příjemci</value>
|
||||
</data>
|
||||
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||
<value>Jedna nebo více zásad organizace ovlivňuje nastavení Send.</value>
|
||||
@@ -2088,7 +2092,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Aktualizovat hlavní heslo</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update your Master Password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
|
||||
<value>Administrátor v organizaci nedávno změnil vaše hlavní heslo. Pro přístup k trezoru jej nyní musíte změnit. Pokračování vás odhlásí z vaší aktuální relace a bude nutné se znovu přihlásit. Aktivní relace na jiných zařízeních mohou zůstat aktivní až po dobu jedné hodiny.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Aktualizace hesla</value>
|
||||
@@ -2100,22 +2104,22 @@ Scanning will happen automatically.</value>
|
||||
<value>Odstranit hlavní heslo</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning" xml:space="preserve">
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your Master Password from your account and require SSO to login.</value>
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your master password from your account and require SSO to login.</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning2" xml:space="preserve">
|
||||
<value>If you do not want to remove your Master Password, you may leave this organization.</value>
|
||||
<value>If you do not want to remove your master password, you may leave this organization.</value>
|
||||
</data>
|
||||
<data name="LeaveOrganization" xml:space="preserve">
|
||||
<value>Opustit organizaci</value>
|
||||
</data>
|
||||
<data name="LeaveOrganizationName" xml:space="preserve">
|
||||
<value>Leave {0}?</value>
|
||||
<value>Opustit {0}?</value>
|
||||
</data>
|
||||
<data name="Fido2Title" xml:space="preserve">
|
||||
<value>FIDO2 WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2Instruction" xml:space="preserve">
|
||||
<value>To continue, have your FIDO2 WebAuthn enabled security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
<value>To continue, have your FIDO2 WebAuthn compatible security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
</data>
|
||||
<data name="Fido2Desc" xml:space="preserve">
|
||||
<value>Authentication using FIDO2 WebAuthn, you can authenticate using an external security key.</value>
|
||||
@@ -2133,7 +2137,7 @@ Scanning will happen automatically.</value>
|
||||
<value>This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed Vault Timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Your vault timeout exceeds the restrictions set by your organization.</value>
|
||||
@@ -2157,13 +2161,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Přepnuto na další dostupný účet</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
<value>Účet uzamčen</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Odhlášení proběhlo úspěšně</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
<value>Účet byl úspěšně odstraněn</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Odstranit účet</value>
|
||||
@@ -2214,10 +2218,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Zadejte ověřovací kód, který byl odeslán na %@</value>
|
||||
</data>
|
||||
<data name="SubmitCrashLogs" xml:space="preserve">
|
||||
<value>Submit crash logs</value>
|
||||
<value>Odesílat záznamy o pádech</value>
|
||||
</data>
|
||||
<data name="SubmitCrashLogsDescription" xml:space="preserve">
|
||||
<value>Help Bitwarden improve app stability by submitting crash reports.</value>
|
||||
<value>Pomozte zlepšovat stabilitu aplikace odesíláním hlášení o selháních.</value>
|
||||
</data>
|
||||
<data name="OptionsExpanded" xml:space="preserve">
|
||||
<value>Options are expanded, tap to collapse.</value>
|
||||
@@ -2226,19 +2230,19 @@ Scanning will happen automatically.</value>
|
||||
<value>Options are collapsed, tap to expand.</value>
|
||||
</data>
|
||||
<data name="UppercaseAtoZ" xml:space="preserve">
|
||||
<value>Uppercase (A to Z)</value>
|
||||
<value>Velká písmena (A-Z)</value>
|
||||
</data>
|
||||
<data name="LowercaseAtoZ" xml:space="preserve">
|
||||
<value>Lowercase (A to Z)</value>
|
||||
<value>Malá písmena (A-Z)</value>
|
||||
</data>
|
||||
<data name="NumbersZeroToNine" xml:space="preserve">
|
||||
<value>Numbers (0 to 9)</value>
|
||||
<value>Čísla (0-9)</value>
|
||||
</data>
|
||||
<data name="SpecialCharacters" xml:space="preserve">
|
||||
<value>Special Characters (!@#$%^&*)</value>
|
||||
<value>Speciální znaky (!@#$%^&*)</value>
|
||||
</data>
|
||||
<data name="TapToGoBack" xml:space="preserve">
|
||||
<value>Tap to go back</value>
|
||||
<value>Klepnutím se vrátíte zpět</value>
|
||||
</data>
|
||||
<data name="PasswordIsVisibleTapToHide" xml:space="preserve">
|
||||
<value>Heslo je viditelné, klepněte pro skrytí</value>
|
||||
@@ -2247,49 +2251,49 @@ Scanning will happen automatically.</value>
|
||||
<value>Heslo není viditelné, klepněte pro zobrazení.</value>
|
||||
</data>
|
||||
<data name="FilterByVault" xml:space="preserve">
|
||||
<value>Filter items by vault</value>
|
||||
<value>Filtrovat položky podle trezoru</value>
|
||||
</data>
|
||||
<data name="AllVaults" xml:space="preserve">
|
||||
<value>All Vaults</value>
|
||||
<value>Všechny trezory</value>
|
||||
</data>
|
||||
<data name="Vaults" xml:space="preserve">
|
||||
<value>Vaults</value>
|
||||
<value>Trezory</value>
|
||||
</data>
|
||||
<data name="VaultFilterDescription" xml:space="preserve">
|
||||
<value>Vault: {0}</value>
|
||||
<value>Trezor: {0}</value>
|
||||
</data>
|
||||
<data name="All" xml:space="preserve">
|
||||
<value>All</value>
|
||||
<value>Všechny</value>
|
||||
</data>
|
||||
<data name="Totp" xml:space="preserve">
|
||||
<value>TOTP</value>
|
||||
</data>
|
||||
<data name="VerificationCodes" xml:space="preserve">
|
||||
<value>Verification Codes</value>
|
||||
<value>Ověřovací kódy</value>
|
||||
</data>
|
||||
<data name="PremiumSubscriptionRequired" xml:space="preserve">
|
||||
<value>Premium subscription required</value>
|
||||
</data>
|
||||
<data name="CannotAddAuthenticatorKey" xml:space="preserve">
|
||||
<value>Cannot add authenticator key? </value>
|
||||
<value>Nelze přidat autentizační klíč? </value>
|
||||
</data>
|
||||
<data name="ScanQRCode" xml:space="preserve">
|
||||
<value>Scan QR Code</value>
|
||||
<value>Načíst QR kód</value>
|
||||
</data>
|
||||
<data name="CannotScanQRCode" xml:space="preserve">
|
||||
<value>Cannot scan QR Code? </value>
|
||||
<value>Nelze načíst QR Kód? </value>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyScanner" xml:space="preserve">
|
||||
<value>Authenticator Key</value>
|
||||
<value>Autentizační klíč</value>
|
||||
</data>
|
||||
<data name="EnterKeyManually" xml:space="preserve">
|
||||
<value>Enter Key Manually</value>
|
||||
<value>Enter key manually</value>
|
||||
</data>
|
||||
<data name="AddTotp" xml:space="preserve">
|
||||
<value>Add TOTP</value>
|
||||
<value>Přidat TOTP</value>
|
||||
</data>
|
||||
<data name="SetupTotp" xml:space="preserve">
|
||||
<value>Set up TOTP</value>
|
||||
<value>Nastavit TOTP</value>
|
||||
</data>
|
||||
<data name="OnceTheKeyIsSuccessfullyEntered" xml:space="preserve">
|
||||
<value>Once the key is successfully entered,
|
||||
@@ -2299,7 +2303,7 @@ select Add TOTP to store the key safely</value>
|
||||
<value></value>
|
||||
</data>
|
||||
<data name="NeverLockWarning" xml:space="preserve">
|
||||
<value>Setting your lock options to “Never” keeps your vault available to anyone with access to your device. If you use this option, you should ensure that you keep your device properly protected.</value>
|
||||
<value>Nastavení zámku na „Nikdy“ ponechá váš trezor k dispozici komukoliv s přístupem k vašemu zařízení. Používáte-li tuto možnost, měli byste zajistit, aby vaše zařízení bylo náležitě chráněno.</value>
|
||||
</data>
|
||||
<data name="EnvironmentPageUrlsError" xml:space="preserve">
|
||||
<value>One or more of the URLs entered are invalid. Please revise it and try to save again.</value>
|
||||
@@ -2308,43 +2312,103 @@ select Add TOTP to store the key safely</value>
|
||||
<value>We were unable to process your request. Please try again or contact us.</value>
|
||||
</data>
|
||||
<data name="AllowScreenCapture" xml:space="preserve">
|
||||
<value>Allow screen capture</value>
|
||||
<value>Povolit záznam obrazovky</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Are you sure you want to enable Screen Capture?</value>
|
||||
<value>Opravdu chcete zapnout záznam obrazovky?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Požadavek k přihlášení</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Pokoušíte se přihlásit?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Pokus o přihlášení od {0} na {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Typ zařízení</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP adresa</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Čas</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Poblíž</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Potvrdit přihlášení</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Zamítnout přihlášení</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Právě teď</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>před {0} minutami</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Přihlášení potvrzeno</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Přihlášení zamítnuto</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Schválit žádosti o přihlášení</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Použijte toto zařízení pro schvalování žádostí o přihlášení z jiných zařízení.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Povolit oznámení</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Dostávat oznámení ohledně nových žádostí o přihlášení</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Ne, děkuji</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Potvrdit pokus o přihlášení pro {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Všechna oznámení</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password Type</value>
|
||||
<value>Typ hesla</value>
|
||||
</data>
|
||||
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
|
||||
<value>What would you like to generate?</value>
|
||||
<value>Co chcete vygenerovat?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Username Type</value>
|
||||
<value>Typ uživatelského jména</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus Addressed Email</value>
|
||||
<value>E-mailová adresa s plusem</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all Email</value>
|
||||
<value>Catch-all email</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded Email Alias</value>
|
||||
<value>Alias přeposílaného e-mailu</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Random Word</value>
|
||||
<value>Náhodné slovo</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>Email (required)</value>
|
||||
<value>E-mail (povinný)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Domain Name (required)</value>
|
||||
<value>Název domény (povinný)</value>
|
||||
</data>
|
||||
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
|
||||
<value>API Key (required)</value>
|
||||
<value>API klíč (povinný)</value>
|
||||
</data>
|
||||
<data name="Service" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
<value>Služba</value>
|
||||
</data>
|
||||
<data name="AnonAddy" xml:space="preserve">
|
||||
<value>AnonAddy</value>
|
||||
@@ -2359,33 +2423,89 @@ select Add TOTP to store the key safely</value>
|
||||
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="APIAccessToken" xml:space="preserve">
|
||||
<value>API Access Token</value>
|
||||
<value>Přístupový token API</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
|
||||
<value>Are you sure you want to overwrite the current username?</value>
|
||||
<value>Opravdu chcete přepsat aktuální uživatelské jméno?</value>
|
||||
</data>
|
||||
<data name="GenerateUsername" xml:space="preserve">
|
||||
<value>Generate Username</value>
|
||||
<value>Generovat uživatelské jméno</value>
|
||||
</data>
|
||||
<data name="EmailType" xml:space="preserve">
|
||||
<value>Email Type</value>
|
||||
<value>Typ e-mailu</value>
|
||||
</data>
|
||||
<data name="WebsiteRequired" xml:space="preserve">
|
||||
<value>Website (required)</value>
|
||||
<value>Webová stránka (povinná)</value>
|
||||
</data>
|
||||
<data name="UnknownXErrorMessage" xml:space="preserve">
|
||||
<value>Unknown {0} error occurred.</value>
|
||||
<value>Vyskytla se neznámá chyba: {0}.</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmailDescription" xml:space="preserve">
|
||||
<value>Use your email provider's subaddress capabilities</value>
|
||||
<value>Použijte funkce podadres Vašeho poskytovatele e-mailu</value>
|
||||
</data>
|
||||
<data name="CatchAllEmailDescription" xml:space="preserve">
|
||||
<value>Use your domain's configured catch-all inbox.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Generate an email alias with an external forwarding service.</value>
|
||||
<value>Vygeneruje alias e-mailu pomocí externí přeposílací služby.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
<value>Náhodně</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Potvrdit</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Zamítnout</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Požadavek na přihlášení již vypršel.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -232,7 +232,7 @@
|
||||
<value>Mappe opdateret.</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Gå til hjemmeside</value>
|
||||
<value>Gå til websted</value>
|
||||
<comment>The button text that allows user to launch the website to their web browser.</comment>
|
||||
</data>
|
||||
<data name="HelpAndFeedback" xml:space="preserve">
|
||||
@@ -251,7 +251,7 @@
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
<value>Ugyldig hovedadgangskode. Prøv igen.</value>
|
||||
<value>Ugyldig hovedadgangskode. Forsøg igen.</value>
|
||||
</data>
|
||||
<data name="InvalidPIN" xml:space="preserve">
|
||||
<value>Ugyldig pinkode. Prøv igen.</value>
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Element er blevet slettet.</value>
|
||||
<value>Element slettet</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -364,7 +364,7 @@
|
||||
<comment>Label for a uri/url.</comment>
|
||||
</data>
|
||||
<data name="UseFingerprintToUnlock" xml:space="preserve">
|
||||
<value>Lås op med dit fingeraftryk</value>
|
||||
<value>Brug fingeraftryk til at låse op</value>
|
||||
</data>
|
||||
<data name="Username" xml:space="preserve">
|
||||
<value>Brugernavn</value>
|
||||
@@ -375,7 +375,7 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} er blevet kopieret.</value>
|
||||
<value>{0} kopieret</value>
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
@@ -394,7 +394,7 @@
|
||||
<value>Vis</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsite" xml:space="preserve">
|
||||
<value>Besøg vores hjemmeside</value>
|
||||
<value>Besøg vores websted</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsiteDescription" xml:space="preserve">
|
||||
<value>Besøg vores hjemmeside for at få hjælp, nyheder, e-maile os og/eller få mere at vide om, hvordan du benytter Bitwarden.</value>
|
||||
@@ -471,7 +471,7 @@
|
||||
<value>Redigér element</value>
|
||||
</data>
|
||||
<data name="EnableAutomaticSyncing" xml:space="preserve">
|
||||
<value>Aktivér automatisk synkronisering</value>
|
||||
<value>Tillad automatisk synkronisering</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>Angiv din kontos e-mailadresse for at modtage dit hovedadgangskodetip.</value>
|
||||
@@ -587,11 +587,11 @@
|
||||
<value>Hovedadgangskode skal være på minimum 8 tegn.</value>
|
||||
</data>
|
||||
<data name="MinNumbers" xml:space="preserve">
|
||||
<value>Minimum cifre</value>
|
||||
<value>Mindste antal cifre</value>
|
||||
<comment>Minimum numeric characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MinSpecial" xml:space="preserve">
|
||||
<value>Minimum specialtegn</value>
|
||||
<value>Mindste antal specialtegn</value>
|
||||
<comment>Minimum special characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MoreSettings" xml:space="preserve">
|
||||
@@ -604,7 +604,7 @@
|
||||
<value>Aldrig</value>
|
||||
</data>
|
||||
<data name="NewItemCreated" xml:space="preserve">
|
||||
<value>Nyt element oprettet.</value>
|
||||
<value>Element tilføjet</value>
|
||||
</data>
|
||||
<data name="NoFavorites" xml:space="preserve">
|
||||
<value>Der er ingen favoritter i din boks.</value>
|
||||
@@ -681,7 +681,7 @@
|
||||
<value>Elementinformation</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Element opdateret.</value>
|
||||
<value>Element gemt</value>
|
||||
</data>
|
||||
<data name="Submitting" xml:space="preserve">
|
||||
<value>Indsender...</value>
|
||||
@@ -695,7 +695,7 @@
|
||||
<value>Synkronisering fuldført.</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Synkronisering mislykkedes.</value>
|
||||
<value>Synkronisering mislykkedes</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Synkronisér boks nu</value>
|
||||
@@ -708,7 +708,7 @@
|
||||
<value>To-trins login</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>To-trins login øger din kontosikkerhed, ved at kræve at du verificerer dit login med en anden enhed, såsom en sikkerhedsnøgle, autentificerings app, SMS, telefonopkald eller e-mail. To-trins login kan aktiveres i bitwarden.com web-boksen. Vil du besøge hjemmesiden nu?</value>
|
||||
<value>To-trins login gør din konto mere sikker ved at kræve, at du verificerer dit login med en anden enhed, såsom en sikkerhedsnøgle, autentificeringsapp, SMS, telefonopkald eller e-mail. To-trins login kan aktiveres i bitwarden.com web-boksen. Vil du besøge hjemmesiden nu?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Lås op med {0}</value>
|
||||
@@ -815,7 +815,7 @@
|
||||
<comment>Message shown when trying to launch an app that does not exist on the user's device.</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorAppTitle" xml:space="preserve">
|
||||
<value>Autentificerings app</value>
|
||||
<value>Autentificerings-app</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="EnterVerificationCodeApp" xml:space="preserve">
|
||||
@@ -831,7 +831,7 @@
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>Denne konto har to-trins login aktiveret, men ingen af de konfigurerede to-trins-udbydere understøttes på denne enhed. Du skal bruge en understøttet enhed og/eller tilføje ekstra udbydere, der understøttes bedre på tværs af enheder (såsom en autentificeringsapp).</value>
|
||||
<value>Denne konto har to-trins login aktiveret, men ingen af de konfigurerede to-trins-udbydere understøttes på denne enhed. Brug venligst en understøttet enhed og/eller tilføj yderligere udbydere, der bedre understøttes på tværs af enheder (såsom en autentificeringsapp).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>Gendannelseskode</value>
|
||||
@@ -1017,7 +1017,7 @@ Skanning vil ske automatisk.</value>
|
||||
<value>Login</value>
|
||||
</data>
|
||||
<data name="TypeSecureNote" xml:space="preserve">
|
||||
<value>Sikret notat</value>
|
||||
<value>Sikkert notat</value>
|
||||
</data>
|
||||
<data name="Address1" xml:space="preserve">
|
||||
<value>Adresse 1</value>
|
||||
@@ -1553,7 +1553,7 @@ Skanning vil ske automatisk.</value>
|
||||
<value>Standard mørkt tema</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescription" xml:space="preserve">
|
||||
<value>Vælg det mørke tema, der skal bruges, når Standard (system) temaet bruges, mens din enheds mørke tilstand er aktiveret.</value>
|
||||
<value>Vælg det mørke tema, der skal bruges, når Standard (System) temaet bruges, mens din enheds mørke tilstand er aktiveret.</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Kopiér notat</value>
|
||||
@@ -1575,6 +1575,10 @@ Skanning vil ske automatisk.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Autoudfyld blokerede URI'er</value>
|
||||
</data>
|
||||
@@ -1625,7 +1629,7 @@ Skanning vil ske automatisk.</value>
|
||||
<value>Benyt biometri til oplåsning</value>
|
||||
</data>
|
||||
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden har brug for din opmærksomhed - se "Autoudfyld hjælpefunktion" i Bitwarden-indstillinger</value>
|
||||
<value>Bitwarden har brug for opmærksomhed - se "Autoudfyld hjælpefunktion" i Bitwarden-indstillinger</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
|
||||
<value>3. På Android-appindstillinger for Bitwarden, gå til indstillingen "Vis oven på andre apps" (under Avanceret) og tryk på knappen for at aktivere overlejringsunderstøttelse.</value>
|
||||
@@ -1722,7 +1726,7 @@ Skanning vil ske automatisk.</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>Element er gendannet.</value>
|
||||
<value>Element gendannet</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -1752,7 +1756,7 @@ Skanning vil ske automatisk.</value>
|
||||
<value>Biometrisk oplåsning til autoudfyldning deaktiveret - afventer verifikation af hovedadgangskoden.</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefresh" xml:space="preserve">
|
||||
<value>Aktivér synk ved opfriskning</value>
|
||||
<value>Tillad synk ved opfriskning</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
|
||||
<value>Synkronisering af boks med træk nedad-gestus.</value>
|
||||
@@ -1848,7 +1852,7 @@ Skanning vil ske automatisk.</value>
|
||||
<value>Brug "Tegn over"</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription" xml:space="preserve">
|
||||
<value>Når aktiveret, tillades Bitwarden-tilgængelighedstjenesten at vise en popup, når login-felter vælges.</value>
|
||||
<value>Tillader Bitwarden-tilgængelighedstjenesten at vise en popup, når login-felter vælges.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription2" xml:space="preserve">
|
||||
<value>Hvis aktiveret, vil Bitwarden-tilgængelighedstjenesten vise en popup, når login-felter vælges for at hjælpe med autoudfyldning af logins.</value>
|
||||
@@ -2002,7 +2006,7 @@ Skanning vil ske automatisk.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AddSend" xml:space="preserve">
|
||||
<value>Tilføj Send</value>
|
||||
<value>Ny Send</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AreYouSureDeleteSend" xml:space="preserve">
|
||||
@@ -2010,15 +2014,15 @@ Skanning vil ske automatisk.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDeleted" xml:space="preserve">
|
||||
<value>Send er blevet slettet.</value>
|
||||
<value>Send slettet</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
<value>Send opdateret.</value>
|
||||
<value>Send gemt</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
<value>Ny Send oprettet.</value>
|
||||
<value>Send oprettet</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="OneDay" xml:space="preserve">
|
||||
@@ -2313,6 +2317,66 @@ vælg Tilføj TOTP for at gemme nøglen sikkert</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Er du sikker på, at du vil aktivere skærmoptagelse?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Login anmodet</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Forsøger du at logge ind?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Loginforsøg af {0} på {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Enhedstype</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP-adresse</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Tid</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>I nærheden af</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Bekræft login</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Afvis login</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Netop nu</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minutter siden</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Login bekræftet</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Login afvist</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Godkend loginanmodninger</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Brug denne enhed til at godkende loginanmodninger fra andre enheder.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Tillad notifikationer</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Modtag push-notifikationer om nye login-anmodninger</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Nej tak</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Bekræft loginforsøg for {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Alle notifikationer</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Adgangskodetype</value>
|
||||
</data>
|
||||
@@ -2323,7 +2387,7 @@ vælg Tilføj TOTP for at gemme nøglen sikkert</value>
|
||||
<value>Brugernavnstype</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus adresseret e-mail</value>
|
||||
<value>Plus-adresseret e-mail</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Fang-alle e-mail</value>
|
||||
@@ -2388,4 +2452,60 @@ vælg Tilføj TOTP for at gemme nøglen sikkert</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Tilfældig</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Oplysninger om tilgængelighedstjeneste</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden bruger tilgængelighedstjenesten til at søge efter login-felter i apps og på websteder, for derefter at oprette relevante felt-ID'er til angivelse af brugernavn og adgangskode, når et match findes. Vi gemmer ikke nogen af de oplysninger, som tjenesten giver os, og vi gør heller ikke noget forsøg på at styre skærmelementer ud over tekstindtastning af legitimationsoplysninger.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Acceptér</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Afvis</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Loginanmodning er allerede udløbet.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login-forsøg fra:
|
||||
{0}
|
||||
Vil du skifte til denne konto?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Ny her?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Få hovedadgangskodetip</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logger ind som {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Ikke dig?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log ind med hovedadgangskoden</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log ind med en anden enhed</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Indlogning påbegyndt</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>En notifikation er sendt til din enhed.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Sørg for, at din boks er oplåst, samt at Fingeraftrykssætningen på den anden enhed matcher.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Gensend notifikation</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Behov for en anden mulighed?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Vis alle indlogningsmuligheder</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -186,7 +186,7 @@
|
||||
<comment>Short label for an email address.</comment>
|
||||
</data>
|
||||
<data name="EmailAddress" xml:space="preserve">
|
||||
<value>E-Mail Adresse</value>
|
||||
<value>E-Mail-Adresse</value>
|
||||
<comment>Full label for a email address.</comment>
|
||||
</data>
|
||||
<data name="EmailUs" xml:space="preserve">
|
||||
@@ -229,7 +229,7 @@
|
||||
<value>Ordner</value>
|
||||
</data>
|
||||
<data name="FolderUpdated" xml:space="preserve">
|
||||
<value>Ordner wurde aktualisiert.</value>
|
||||
<value>Ordner wurde aktualisiert</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Webseite besuchen</value>
|
||||
@@ -251,7 +251,7 @@
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
<value>Ungültiges Masterpasswort. Bitte erneut versuchen.</value>
|
||||
<value>Ungültiges Master-Passwort. Bitte erneut versuchen.</value>
|
||||
</data>
|
||||
<data name="InvalidPIN" xml:space="preserve">
|
||||
<value>Ungültiger PIN. Bitte erneut versuchen.</value>
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Eintrag wurde gelöscht.</value>
|
||||
<value>Eintrag wurde gelöscht</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -375,7 +375,7 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} wurde kopiert.</value>
|
||||
<value>{0} wurde kopiert</value>
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
@@ -394,7 +394,7 @@
|
||||
<value>Ansicht</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsite" xml:space="preserve">
|
||||
<value>Besuche unsere Website</value>
|
||||
<value>Besuchen Sie unsere Website</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsiteDescription" xml:space="preserve">
|
||||
<value>Besuche unsere Webseite um Hilfe zu erhalten, Neuigkeiten zu erfahren, Kontakt aufzunehmen und mehr über die Verwendung von Bitwarden zu lernen.</value>
|
||||
@@ -431,7 +431,7 @@
|
||||
<value>Bitwarden App Erweiterung</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
|
||||
<value>Die einfachste Möglichkeit, neue Anmeldedaten zu deinemTresor hinzuzufügen, ist die Bitwarden App Erweiterung. Erfahre mehr über die Bitwarden App Erweiterung, indem du zu den "Einstellungen" wechselst.</value>
|
||||
<value>Die einfachste Möglichkeit, neue Anmeldedaten zu Ihrem Tresor hinzuzufügen, ist die Bitwarden App Erweiterung. Erfahren Sie mehr über die Bitwarden App Erweiterung, indem Sie zu dem "Einstellungen"-Bildschirm navigieren.</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionDescription" xml:space="preserve">
|
||||
<value>Nutze Bitwarden in Safari und anderen Apps, um Zugangsdaten automatisch einzufügen.</value>
|
||||
@@ -566,7 +566,7 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="LoginOrCreateNewAccount" xml:space="preserve">
|
||||
<value>Du musst dich anmelden oder einen neuen Account erstellen um auf den Tresor zuzugreifen.</value>
|
||||
<value>Melde dich an oder erstelle einen neuen Account, um auf Deinen Tresor zuzugreifen.</value>
|
||||
</data>
|
||||
<data name="Manage" xml:space="preserve">
|
||||
<value>Verwalten</value>
|
||||
@@ -578,7 +578,7 @@
|
||||
<value>Das Master-Passwort wird verwendet, um den Tresor zu öffnen. Es ist sehr wichtig, dass du das Passwort nicht vergisst, da es keine Möglichkeit gibt es zurückzusetzen.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHint" xml:space="preserve">
|
||||
<value>Masterpassworthinweis (optional)</value>
|
||||
<value>Master-Passwort-Hinweis (optional)</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHintDescription" xml:space="preserve">
|
||||
<value>Ein Hinweis auf dein Master-Passwort kann dir helfen, dich an das Passwort zu erinnern, solltest du es vergessen.</value>
|
||||
@@ -604,7 +604,7 @@
|
||||
<value>Niemals</value>
|
||||
</data>
|
||||
<data name="NewItemCreated" xml:space="preserve">
|
||||
<value>Eintrag erstellt.</value>
|
||||
<value>Eintrag erstellt</value>
|
||||
</data>
|
||||
<data name="NoFavorites" xml:space="preserve">
|
||||
<value>Es befinden sich keine Favoriten in deinem Tresor.</value>
|
||||
@@ -632,7 +632,7 @@
|
||||
<value>Sonstige</value>
|
||||
</data>
|
||||
<data name="PasswordGenerated" xml:space="preserve">
|
||||
<value>Passwort generiert.</value>
|
||||
<value>Passwort generiert</value>
|
||||
</data>
|
||||
<data name="PasswordGenerator" xml:space="preserve">
|
||||
<value>Passwortgenerator</value>
|
||||
@@ -660,7 +660,7 @@
|
||||
<value>Passwort neu generieren</value>
|
||||
</data>
|
||||
<data name="RetypeMasterPassword" xml:space="preserve">
|
||||
<value>Masterpasswort wiederholen</value>
|
||||
<value>Master-Passwort wiederholen</value>
|
||||
</data>
|
||||
<data name="SearchVault" xml:space="preserve">
|
||||
<value>Tresor durchsuchen</value>
|
||||
@@ -681,7 +681,7 @@
|
||||
<value>Eintrags-Information</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Eintrag aktualisiert.</value>
|
||||
<value>Eintrag aktualisiert</value>
|
||||
</data>
|
||||
<data name="Submitting" xml:space="preserve">
|
||||
<value>Wird übermittelt...</value>
|
||||
@@ -692,10 +692,10 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="SyncingComplete" xml:space="preserve">
|
||||
<value>Synchronisierung abgeschlossen.</value>
|
||||
<value>Synchronisierung abgeschlossen</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Synchronisierung fehlgeschlagen.</value>
|
||||
<value>Synchronisierung fehlgeschlagen</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Tresor jetzt synchronisieren</value>
|
||||
@@ -721,7 +721,7 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="VerificationCode" xml:space="preserve">
|
||||
<value>Bestätigungscode</value>
|
||||
<value>Verifizierungscode </value>
|
||||
</data>
|
||||
<data name="ViewItem" xml:space="preserve">
|
||||
<value>Eintrag anzeigen</value>
|
||||
@@ -831,7 +831,7 @@
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>Dieses Konto hat eine aktive Zwei-Faktor Authentifizierung, allerdings wird keiner der konfigurierten Zwei-Faktor Anbieter von diesem Gerät unterstützt. Bitte nutze ein unterstütztes Gerät und / oder füge zusätzliche Anbieter hinzu, die von mehr Geräten unterstützt werden (wie eine Authentifizierungs-App).</value>
|
||||
<value>Dieses Konto hat eine aktive Zwei-Faktor Authentifizierung, allerdings wird keiner der konfigurierten Zwei-Faktor Anbieter von diesem Gerät unterstützt. Bitte nutzen Sie ein unterstütztes Gerät und / oder fügen Sie zusätzliche Anbieter hinzu, die von mehr Geräten unterstützt werden (wie eine Authentifizierungs-App).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>Wiederherstellungscode</value>
|
||||
@@ -856,7 +856,7 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="VerificationEmailSent" xml:space="preserve">
|
||||
<value>Bestätigungsmail wurde gesendet.</value>
|
||||
<value>Bestätigungsmail wurde gesendet</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="YubiKeyInstruction" xml:space="preserve">
|
||||
@@ -890,7 +890,7 @@
|
||||
<value>Authentifizierungsschlüssel (TOTP)</value>
|
||||
</data>
|
||||
<data name="VerificationCodeTotp" xml:space="preserve">
|
||||
<value>Bestätigungscode (TOTP)</value>
|
||||
<value>Verifizierungscode (TOTP)</value>
|
||||
<comment>Totp code label</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyAdded" xml:space="preserve">
|
||||
@@ -1443,7 +1443,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Passphrase</value>
|
||||
</data>
|
||||
<data name="WordSeparator" xml:space="preserve">
|
||||
<value>Trennzeichen</value>
|
||||
<value>Worttrennzeichen</value>
|
||||
</data>
|
||||
<data name="Clear" xml:space="preserve">
|
||||
<value>Leeren</value>
|
||||
@@ -1575,6 +1575,10 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Blockierte URIs automatisch ausfüllen</value>
|
||||
</data>
|
||||
@@ -1616,7 +1620,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Deine Sitzung ist abgelaufen.</value>
|
||||
</data>
|
||||
<data name="BiometricsDirection" xml:space="preserve">
|
||||
<value>Biometrische Verifizierung</value>
|
||||
<value>Biometrische Daten zur Verifizierung nutzen.</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Biometrie</value>
|
||||
@@ -1625,7 +1629,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Biometrische Daten zum Entsperren verwenden</value>
|
||||
</data>
|
||||
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden braucht Aufmerksamkeit - Siehe "Auto-Ausfüllen-Bedienungshilfe" in den Bitwarden-Einstellungen</value>
|
||||
<value>Bitwarden braucht Aufmerksamkeit - Siehe "Auto-Fill-Bedienungshilfe" in den Bitwarden-Einstellungen</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
|
||||
<value>3. Gehe unter Android in den App-Einstellungen für Bitwarden zur Option "Über anderen Apps einblenden" (unter Erweitert) und tippe auf den Schalter, um die Overlay-Unterstützung zu aktivieren.</value>
|
||||
@@ -1700,7 +1704,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Anhang erfolgreich gespeichert</value>
|
||||
</data>
|
||||
<data name="AutofillTileAccessibilityRequired" xml:space="preserve">
|
||||
<value>Bitte aktiviere "Auto-Ausfüllen-Bedienungshilfe" in den Bitwarden-Einstellungen, um die Auto-Ausfüllen-Kachel zu verwenden.</value>
|
||||
<value>Bitte aktivieren Sie "Auto-Fill-Bedienungshilfe" in den Bitwarden-Einstellungen, um die Auto-Fill-Kachel zu verwenden.</value>
|
||||
</data>
|
||||
<data name="AutofillTileUriNotFound" xml:space="preserve">
|
||||
<value>Keine Passwortfelder erkannt</value>
|
||||
@@ -1722,7 +1726,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>Eintrag wurde wiederhergestellt.</value>
|
||||
<value>Eintrag wurde wiederhergestellt</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -1972,7 +1976,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSend" xml:space="preserve">
|
||||
<value>Dieses Send deaktivieren, damit niemand darauf zugreifen kann.</value>
|
||||
<value>Dieses Send deaktivieren, damit niemand darauf zugreifen kann</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
@@ -2010,15 +2014,15 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDeleted" xml:space="preserve">
|
||||
<value>Send wurde gelöscht.</value>
|
||||
<value>Send wurde gelöscht</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
<value>Send aktualisiert.</value>
|
||||
<value>Send aktualisiert</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
<value>Neues Send erstellt.</value>
|
||||
<value>Neues Send erstellt</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="OneDay" xml:space="preserve">
|
||||
@@ -2040,7 +2044,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Benutzerdefiniert</value>
|
||||
</data>
|
||||
<data name="ShareOnSave" xml:space="preserve">
|
||||
<value>Dieses Send beim Speichern teilen.</value>
|
||||
<value>Dieses Send beim Speichern teilen</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDisabledWarning" xml:space="preserve">
|
||||
@@ -2052,7 +2056,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="HideEmail" xml:space="preserve">
|
||||
<value>Meine E-Mail-Adresse vor den Empfängern verstecken.</value>
|
||||
<value>Meine E-Mail-Adresse vor den Empfängern verstecken</value>
|
||||
</data>
|
||||
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||
<value>Eine oder mehrere Organisationsrichtlinien beeinflussen deine Send Einstellungen.</value>
|
||||
@@ -2178,10 +2182,10 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Löschen deines Kontos</value>
|
||||
</data>
|
||||
<data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve">
|
||||
<value>Dein Konto wurde unwiderruflich gelöscht.</value>
|
||||
<value>Dein Konto wurde unwiderruflich gelöscht</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Ungültiger Bestätigungscode.</value>
|
||||
<value>Ungültiger Verifizierungscode</value>
|
||||
</data>
|
||||
<data name="RequestOTP" xml:space="preserve">
|
||||
<value>Einmalpasswort anfordern</value>
|
||||
@@ -2205,7 +2209,7 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<value>Code erneut senden</value>
|
||||
</data>
|
||||
<data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve">
|
||||
<value>Ein Bestätigungscode wurde an deine E-Mail-Adresse gesendet.</value>
|
||||
<value>Ein Bestätigungscode wurde an deine E-Mail-Adresse gesendet</value>
|
||||
</data>
|
||||
<data name="AnErrorOccurredWhileSendingAVerificationCodeToYourEmailPleaseTryAgain" xml:space="preserve">
|
||||
<value>Beim Senden des Bestätigungscodes an deine E-Mail-Adresse ist ein Fehler aufgetreten. Bitte versuche es erneut</value>
|
||||
@@ -2312,6 +2316,66 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Bist du sicher, dass du die Bildschirmaufnahme aktivieren möchtest?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Zugangsdaten angefordert</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Versuchst du dich anzumelden?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Anmeldeversuch von {0} am {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Gerätetyp</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP-Adresse</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Zeit</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Nahe</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Anmeldung bestätigen</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Anmeldung verweigern</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Gerade eben</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>vor {0} Minute(n)</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Anmeldung bestätigt</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Anmeldung verweigert</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Anmeldeanfragen genehmigen</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Benutze dieses Gerät, um Anmeldeanfragen von anderen Geräten zu genehmigen.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Benachrichtigungen zulassen</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Push-Benachrichtigungen für neue Anmeldeanfragen erhalten</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Nein, danke</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Anmeldeversuch für {0} bestätigen</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Alle Benachrichtigungen</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Passworttyp</value>
|
||||
</data>
|
||||
@@ -2387,4 +2451,60 @@ Das Scannen erfolgt automatisch.</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Zufällig</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Bedienungshilfen Offenlegung</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden verwendet die Bedienungshilfen, um nach Anmeldefeldern in Apps und Webseiten zu suchen und legt dann die entsprechenden Feld-IDs fest, um Benutzername und Passwort einzugeben, wenn eine Übereinstimmung mit der App oder der Seite gefunden wird. Wir speichern keine der Informationen, die uns der Dienst zur Verfügung stellt. Ebenso wenig versuchen wir beliebige Elemente auf dem Bildschirm außer der Texteingabe von Anmeldedaten zu kontrollieren.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Akzeptieren</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Ablehnen</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Anmeldeanfrage ist bereits abgelaufen.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Anmeldeversuch von:
|
||||
{0}
|
||||
Möchtest du zu diesem Konto wechseln?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Neu hier?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Nicht du?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Mit Master-Passwort anmelden</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Mit einem anderen Gerät anmelden</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Anmeldung initiiert</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Eine Benachrichtigung wurde an dein Gerät gesendet.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Bitte stelle sicher, dass dein Tresor entsperrt ist und die Fingerabdruck-Phrase mit dem anderen Gerät übereinstimmt.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Benachrichtigung erneut senden</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Brauchst du eine andere Option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Alle Anmelde-Optionen anzeigen</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -289,7 +289,7 @@
|
||||
<value>Θα θέλατε να το αλλάξετε τώρα?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Κύριος Κωδικός</value>
|
||||
<value>Κύριος κωδικός</value>
|
||||
<comment>Label for a master password.</comment>
|
||||
</data>
|
||||
<data name="More" xml:space="preserve">
|
||||
@@ -1575,6 +1575,10 @@
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Αυτόματη συμπλήρωση μπλοκαρισμένων URIs</value>
|
||||
</data>
|
||||
@@ -1610,7 +1614,7 @@
|
||||
<value>Κοινοποιήθηκε</value>
|
||||
</data>
|
||||
<data name="ToggleVisibility" xml:space="preserve">
|
||||
<value>Εναλλαγή Ορατότητας</value>
|
||||
<value>Εναλλαγή ορατότητας</value>
|
||||
</data>
|
||||
<data name="LoginExpired" xml:space="preserve">
|
||||
<value>Η περίοδος σύνδεσης σας έχει λήξει.</value>
|
||||
@@ -2313,6 +2317,66 @@
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε την καταγραφή οθόνης;</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Απαιτείται σύνδεση</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Προσπαθείτε να συνδεθείτε;</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Προσπάθεια σύνδεσης από τον/την {0} στο {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Τύπος συσκευής</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>Διεύθυνση IP</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Ώρα</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Κοντά</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Επιβεβαίωση σύνδεσης</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Άρνηση σύνδεσης</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Μόλις τώρα</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} λεπτά πριν</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Η σύνδεση επιβεβαιώθηκε</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Η σύνδεση απορρίφθηκε</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Έγκριση αιτήσεων σύνδεσης</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Χρησιμοποιήστε αυτήν τη συσκευή για να εγκρίνετε αιτήματα σύνδεσης από άλλες συσκευές.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Να επιτρέπονται οι ειδοποιήσεις</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Λάβετε ειδοποιήσεις push για νέα αιτήματα σύνδεσης</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Όχι ευχαριστώ</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Επιβεβαίωση προσπάθειας σύνδεσης για {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Όλες οι ειδοποιήσεις</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Τύπος Κωδικού</value>
|
||||
</data>
|
||||
@@ -2388,4 +2452,60 @@
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Τυχαίο</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Γνωστοποίηση Υπηρεσίας Προσβασιμότητας</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accept</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Decline</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
<value>Folders</value>
|
||||
</data>
|
||||
<data name="FolderUpdated" xml:space="preserve">
|
||||
<value>Folder updated.</value>
|
||||
<value>Folder saved</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Go to website</value>
|
||||
@@ -276,13 +276,13 @@
|
||||
<value>Are you sure you want to log out?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Remove account</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Account already added</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Item has been deleted.</value>
|
||||
<value>Item deleted</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -375,7 +375,7 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} has been copied.</value>
|
||||
<value>{0} copied</value>
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
@@ -1286,7 +1286,7 @@ Scanning will happen automatically.</value>
|
||||
<comment>ex. Date this item was updated</comment>
|
||||
</data>
|
||||
<data name="AutofillActivated" xml:space="preserve">
|
||||
<value>Auto-fill activated!</value>
|
||||
<value>AutoFill activated!</value>
|
||||
</data>
|
||||
<data name="MustLogInMainAppAutofill" xml:space="preserve">
|
||||
<value>You must log into the main Bitwarden app before you can use auto-fill.</value>
|
||||
@@ -1575,6 +1575,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Auto-fill blocked URIs</value>
|
||||
</data>
|
||||
@@ -2322,6 +2326,66 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Are you sure you want to enable Screen Capture?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Login requested</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Are you trying to log in?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Login attempt by {0} on {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Device type</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP address</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Time</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirm login</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Deny login</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Just now</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minutes ago</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Login confirmed</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Login denied</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Approve login requests</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use this device to approve login requests made from other devices.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Allow notifications</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Receive push notifications for new login requests</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>No thanks</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Confirm login attempt for {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>All notifications</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password Type</value>
|
||||
</data>
|
||||
@@ -2397,4 +2461,60 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accept</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Decline</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Are you new here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log in with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -276,13 +276,13 @@
|
||||
<value>Are you sure you want to log out?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Remove account</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Account already added</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
@@ -1080,7 +1080,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Last name</value>
|
||||
</data>
|
||||
<data name="FullName" xml:space="preserve">
|
||||
<value>Full Name</value>
|
||||
<value>Full name</value>
|
||||
</data>
|
||||
<data name="LicenseNumber" xml:space="preserve">
|
||||
<value>Licence number</value>
|
||||
@@ -1381,10 +1381,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Search collection</value>
|
||||
</data>
|
||||
<data name="SearchFileSends" xml:space="preserve">
|
||||
<value>Search File Sends</value>
|
||||
<value>Search file Sends</value>
|
||||
</data>
|
||||
<data name="SearchTextSends" xml:space="preserve">
|
||||
<value>Search Text Sends</value>
|
||||
<value>Search text Sends</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Search {0}</value>
|
||||
@@ -1480,7 +1480,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Unlock</value>
|
||||
</data>
|
||||
<data name="UnlockVault" xml:space="preserve">
|
||||
<value>Unlock Vault</value>
|
||||
<value>Unlock vault</value>
|
||||
</data>
|
||||
<data name="ThirtyMinutes" xml:space="preserve">
|
||||
<value>30 minutes</value>
|
||||
@@ -1553,7 +1553,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Default dark theme</value>
|
||||
</data>
|
||||
<data name="DefaultDarkThemeDescription" xml:space="preserve">
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is enabled.</value>
|
||||
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is in use.</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Copy notes</value>
|
||||
@@ -1575,6 +1575,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Auto-fill blocked URIs</value>
|
||||
</data>
|
||||
@@ -1655,7 +1659,7 @@ 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>Code sent!</value>
|
||||
</data>
|
||||
<data name="ConfirmYourIdentity" xml:space="preserve">
|
||||
<value>Confirm your identity to continue.</value>
|
||||
@@ -2090,37 +2094,37 @@ Scanning will happen automatically.</value>
|
||||
<value>This action is protected, to continue please re-enter your master password to verify your identity.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Captcha Required</value>
|
||||
<value>Captcha required</value>
|
||||
</data>
|
||||
<data name="CaptchaFailed" xml:space="preserve">
|
||||
<value>Captcha Failed. Please try again.</value>
|
||||
<value>Captcha failed. Please try again.</value>
|
||||
</data>
|
||||
<data name="UpdatedMasterPassword" xml:space="preserve">
|
||||
<value>Updated Master Password</value>
|
||||
<value>Updated master password</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPassword" xml:space="preserve">
|
||||
<value>Update Master Password</value>
|
||||
<value>Update master password</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Your Master Password was recently changed by an administrator in your organization. In order to access the vault, you must update your Master Password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
|
||||
<value>Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Updating Password</value>
|
||||
<value>Updating password</value>
|
||||
</data>
|
||||
<data name="UpdatePasswordError" xml:space="preserve">
|
||||
<value>Currently unable to update password</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPassword" xml:space="preserve">
|
||||
<value>Remove Master Password</value>
|
||||
<value>Remove master password</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning" xml:space="preserve">
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your Master Password from your account and require SSO to login.</value>
|
||||
<value>{0} is using SSO with customer-managed encryption. Continuing will remove your master password from your account and require SSO to login.</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning2" xml:space="preserve">
|
||||
<value>If you do not want to remove your Master Password, you may leave this organization.</value>
|
||||
<value>If you do not want to remove your master password, you may leave this organization.</value>
|
||||
</data>
|
||||
<data name="LeaveOrganization" xml:space="preserve">
|
||||
<value>Leave Organization</value>
|
||||
<value>Leave organization</value>
|
||||
</data>
|
||||
<data name="LeaveOrganizationName" xml:space="preserve">
|
||||
<value>Leave {0}?</value>
|
||||
@@ -2129,7 +2133,7 @@ Scanning will happen automatically.</value>
|
||||
<value>FIDO2 WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2Instruction" xml:space="preserve">
|
||||
<value>To continue, have your FIDO2 WebAuthn enabled security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
<value>To continue, have your FIDO2 WebAuthn compatible security key ready, then follow the instructions after clicking 'Authenticate WebAuthn' on the next screen.</value>
|
||||
</data>
|
||||
<data name="Fido2Desc" xml:space="preserve">
|
||||
<value>Authentication using FIDO2 WebAuthn, you can authenticate using an external security key.</value>
|
||||
@@ -2138,7 +2142,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Authenticate WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2ReturnToApp" xml:space="preserve">
|
||||
<value>Return to App</value>
|
||||
<value>Return to app</value>
|
||||
</data>
|
||||
<data name="Fido2CheckBrowser" xml:space="preserve">
|
||||
<value>Please make sure your default browser supports WebAuthn and try again.</value>
|
||||
@@ -2147,16 +2151,16 @@ Scanning will happen automatically.</value>
|
||||
<value>This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed Vault Timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Your vault timeout exceeds the restrictions set by your organization.</value>
|
||||
</data>
|
||||
<data name="DisablePersonalVaultExportPolicyInEffect">
|
||||
<value>One or more organization policies prevents your from exporting your personal vault.</value>
|
||||
<value>One or more organization policies prevents your from exporting your individual vault.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Add account</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
@@ -2165,13 +2169,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Logged out</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
<value>Account locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
@@ -2195,13 +2199,13 @@ Scanning will happen automatically.</value>
|
||||
<value>Your account has been permanently deleted</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Invalid Verification Code.</value>
|
||||
<value>Invalid verification code</value>
|
||||
</data>
|
||||
<data name="RequestOTP" xml:space="preserve">
|
||||
<value>Request one-time password</value>
|
||||
</data>
|
||||
<data name="SendCode" xml:space="preserve">
|
||||
<value>Send Code</value>
|
||||
<value>Send code</value>
|
||||
</data>
|
||||
<data name="Sending" xml:space="preserve">
|
||||
<value>Sending</value>
|
||||
@@ -2216,7 +2220,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Verifying</value>
|
||||
</data>
|
||||
<data name="ResendCode" xml:space="preserve">
|
||||
<value>Resend Code</value>
|
||||
<value>Resend code</value>
|
||||
</data>
|
||||
<data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve">
|
||||
<value>A verification code was sent to your email</value>
|
||||
@@ -2249,7 +2253,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Numbers (0 to 9)</value>
|
||||
</data>
|
||||
<data name="SpecialCharacters" xml:space="preserve">
|
||||
<value>Special Characters (!@#$%^&*)</value>
|
||||
<value>Special characters (!@#$%^&*)</value>
|
||||
</data>
|
||||
<data name="TapToGoBack" xml:space="preserve">
|
||||
<value>Tap to go back</value>
|
||||
@@ -2264,7 +2268,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Filter items by vault</value>
|
||||
</data>
|
||||
<data name="AllVaults" xml:space="preserve">
|
||||
<value>All Vaults</value>
|
||||
<value>All vaults</value>
|
||||
</data>
|
||||
<data name="Vaults" xml:space="preserve">
|
||||
<value>Vaults</value>
|
||||
@@ -2279,7 +2283,7 @@ Scanning will happen automatically.</value>
|
||||
<value>TOTP</value>
|
||||
</data>
|
||||
<data name="VerificationCodes" xml:space="preserve">
|
||||
<value>Verification Codes</value>
|
||||
<value>Verification codes</value>
|
||||
</data>
|
||||
<data name="PremiumSubscriptionRequired" xml:space="preserve">
|
||||
<value>Premium subscription required</value>
|
||||
@@ -2294,10 +2298,10 @@ Scanning will happen automatically.</value>
|
||||
<value>Cannot scan QR Code? </value>
|
||||
</data>
|
||||
<data name="AuthenticatorKeyScanner" xml:space="preserve">
|
||||
<value>Authenticator Key</value>
|
||||
<value>Authenticator key</value>
|
||||
</data>
|
||||
<data name="EnterKeyManually" xml:space="preserve">
|
||||
<value>Enter Key Manually</value>
|
||||
<value>Enter key manually</value>
|
||||
</data>
|
||||
<data name="AddTotp" xml:space="preserve">
|
||||
<value>Add TOTP</value>
|
||||
@@ -2325,37 +2329,97 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Allow screen capture</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Are you sure you want to enable Screen Capture?</value>
|
||||
<value>Are you sure you want to turn on screen capture?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Login requested</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Are you trying to log in?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Login attempt by {0} on {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Device type</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP address</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Time</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirm login</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Deny login</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Just now</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minutes ago</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Login confirmed</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Login denied</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Approve login requests</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use this device to approve login requests made from other devices.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Allow notifications</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Receive push notifications for new login requests</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>No thanks</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Confirm login attempt for {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>All notifications</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Password Type</value>
|
||||
<value>Password type</value>
|
||||
</data>
|
||||
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
|
||||
<value>What would you like to generate?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Username Type</value>
|
||||
<value>Username type</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus Addressed Email</value>
|
||||
<value>Plus addressed email</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all Email</value>
|
||||
<value>Catch-all email</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded Email Alias</value>
|
||||
<value>Forwarded email alias</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Random Word</value>
|
||||
<value>Random word</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>Email (required)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Domain Name (required)</value>
|
||||
<value>Domain name (required)</value>
|
||||
</data>
|
||||
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
|
||||
<value>API Key (required)</value>
|
||||
<value>API key (required)</value>
|
||||
</data>
|
||||
<data name="Service" xml:space="preserve">
|
||||
<value>Service</value>
|
||||
@@ -2373,13 +2437,13 @@ select Add TOTP to store the key safely</value>
|
||||
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
|
||||
</data>
|
||||
<data name="APIAccessToken" xml:space="preserve">
|
||||
<value>API Access Token</value>
|
||||
<value>API access token</value>
|
||||
</data>
|
||||
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
|
||||
<value>Are you sure you want to overwrite the current username?</value>
|
||||
</data>
|
||||
<data name="GenerateUsername" xml:space="preserve">
|
||||
<value>Generate Username</value>
|
||||
<value>Generate username</value>
|
||||
</data>
|
||||
<data name="EmailType" xml:space="preserve">
|
||||
<value>Email Type</value>
|
||||
@@ -2402,4 +2466,60 @@ select Add TOTP to store the key safely</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Random</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Accept</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Decline</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Login request has already expired.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
<value>Contraseña maestra no válida. Prueba de nuevo.</value>
|
||||
<value>Contraseña maestra no válida. Inténtelo de nuevo.</value>
|
||||
</data>
|
||||
<data name="InvalidPIN" xml:space="preserve">
|
||||
<value>PIN no válido. Prueba de nuevo.</value>
|
||||
@@ -471,7 +471,7 @@
|
||||
<value>Editar elemento</value>
|
||||
</data>
|
||||
<data name="EnableAutomaticSyncing" xml:space="preserve">
|
||||
<value>Habilitar sincronizacion automatica</value>
|
||||
<value>Habilitar sincronización automática</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>Introduce el correo electrónico de tu cuenta para recibir la pista de tu contraseña maestra.</value>
|
||||
@@ -987,7 +987,7 @@ El escaneo se realizará automáticamente.</value>
|
||||
<value>URL del servidor</value>
|
||||
</data>
|
||||
<data name="WebVaultUrl" xml:space="preserve">
|
||||
<value>URL del servidor de la caja fuerte web</value>
|
||||
<value>URL del servidor de la bóveda web</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceNotificationContentOld" xml:space="preserve">
|
||||
<value>Pulsa en esta notificación para ver las entradas de tu caja fuerte.</value>
|
||||
@@ -1575,6 +1575,10 @@ El escaneo se realizará automáticamente.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Oscuro Solar</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Autorellenar URIs bloqueadas</value>
|
||||
</data>
|
||||
@@ -2314,6 +2318,66 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>¿Estás seguro de que quieres activar captura de pantalla?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Inicio de sesión solicitado</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>¿Estás tratando de iniciar sesión?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Intento de inicio de sesión por {0} en {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Tipo de dispositivo</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>Dirección IP</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Hora</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Cerca</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Confirmar inicio de sesión</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Denegar inicio de sesión</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Justo ahora</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>Hace {0} minutos</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Inicio de sesión confirmado</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Inicio de sesión denegado</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Aprobar solicitudes de inicio de sesión</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use este dispositivo para aprovar solicitudes de incio de sesión realizadas desde otros dispositivos.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Permitir notificaciones</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Recibir notificaciones push para nuevas solicitudes de iniciar sesión</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>No, gracias</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Confirmar intento de inicio de sesión para {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Todas las notificaciones</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Tipo de contraseña</value>
|
||||
</data>
|
||||
@@ -2389,4 +2453,60 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Aleatorio</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Revelación del servicio de accesibilidad</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden utiliza el Servicio de Accesibilidad para buscar campos de inicio de sesión en aplicaciones y sitios web, establecer los identificadores de campo apropiados para introducir un nombre de usuario y contraseña cuando se encuentre una coincidencia para la aplicación o el sitio. No almacenamos ninguna de las informaciones presentadas por el servicio, tampoco intentamos controlar ningún elemento en pantalla más allá de la introducción de credenciales de texto.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Aceptar</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Rechazar</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>La solicitud de acceso ya ha caducado.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Intento de inicio de sesión desde:
|
||||
{0}
|
||||
¿Desea cambiar a esta cuenta?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>¿Nuevo por aquí?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>¿No eres tú?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Iniciar sesión con contraseña maestra</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Iniciar sesión con otro dispositivo</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Inicio de sesión en proceso</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Se ha enviado una notificación a tu dispositivo.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Por favor, asegúrese de que su bóveda está desbloqueada y la frase de huella dactilar coincide en el otro dispositivo.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Enviar nueva notificación</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>¿Necesitas otra opción?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Ver todas las opciones de inicio de sesión</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -978,7 +978,7 @@ Skaneerimine toimub automaatselt.</value>
|
||||
<comment>"Identity" refers to an identity server. See more context here https://en.wikipedia.org/wiki/Identity_management</comment>
|
||||
</data>
|
||||
<data name="SelfHostedEnvironment" xml:space="preserve">
|
||||
<value>Self-hosted Environment</value>
|
||||
<value>Enda majutatud keskkond</value>
|
||||
</data>
|
||||
<data name="SelfHostedEnvironmentFooter" xml:space="preserve">
|
||||
<value>Sisesta baas URL, kus sinu või ettevõtte majutatud Bitwarden asub.</value>
|
||||
@@ -1575,6 +1575,10 @@ Skaneerimine toimub automaatselt.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized tume</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Täida blokeeritud URId automaatselt</value>
|
||||
</data>
|
||||
@@ -1610,7 +1614,7 @@ Skaneerimine toimub automaatselt.</value>
|
||||
<value>Jagatud</value>
|
||||
</data>
|
||||
<data name="ToggleVisibility" xml:space="preserve">
|
||||
<value>Toggle Visiblity</value>
|
||||
<value>Näita sisu</value>
|
||||
</data>
|
||||
<data name="LoginExpired" xml:space="preserve">
|
||||
<value>Sessioon on aegunud.</value>
|
||||
@@ -2313,6 +2317,66 @@ Skaneerimine toimub automaatselt.</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Oled kindel, et soovid lubada ekraanikuva salvestamist?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Sisselogimise päring</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Oled sisse logimas?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Sisselogimise päring kontolt {0} kuupäeval {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Seadme tüüp</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP aadress</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Aeg</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Asukoht</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Kinnita sisselogimine</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Tühista sisselogimine</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Just praegu</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minuti eest</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Sisselogimine on kinnitatud</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Sisselogimine on tühistatud</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Sisselogimise päringute kinnitamine</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Kasuta seda seadet, et kinnitada teistes seadmetes tehtavad sisselogimised.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Luba teavitused</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Saa uute sisselogimise päringute kohta teavitusi</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Ei soovi</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Kinnita sisselogimise katse kontole {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Kõik teavitused</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Parooli tüüp</value>
|
||||
</data>
|
||||
@@ -2388,4 +2452,60 @@ Skaneerimine toimub automaatselt.</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Juhuslik</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Accessibility Service Disclosure</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username & password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Nõustu</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Keeldu</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Sisselogimise päring on juba aegunud.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Sisselogimise päring:
|
||||
{0}
|
||||
Soovid selle konto peale lülituda?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Oled siin uus?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Pole sina?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Logi sisse ülemparooliga</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Logi sisse läbi teise seadme</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -918,7 +918,7 @@
|
||||
<value>Saio hasiera batek autentifikazio-gakoa badu, TOTP egiaztatze-kodea arbelean automatikoki kopiatuko da saio hasiera bat auto-betetzean.</value>
|
||||
</data>
|
||||
<data name="CopyTotpAutomatically" xml:space="preserve">
|
||||
<value>Kopiatu TOTO automatikoki</value>
|
||||
<value>Kopiatu TOTP automatikoki</value>
|
||||
</data>
|
||||
<data name="PremiumRequired" xml:space="preserve">
|
||||
<value>Premium bazkidetza beharrezkoa da ezaugarri hau erabiltzeko.</value>
|
||||
@@ -1574,6 +1574,10 @@
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized iluna</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Auto-bete blokeatutako URI-ak</value>
|
||||
</data>
|
||||
@@ -2312,6 +2316,66 @@
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Ziur al zaude pantaila-argazkia gaitu nahi duzula?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Saio hasiera eskatu da</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Saioa hasten saiatzen ari zara?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>{0} saioa hasten saiatu da {1}-n</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Gailu mota</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP helbidea</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Ordua</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Gertu</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Berretsi saio hasiera</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Sarrera ukatu</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Oraintxe bertan</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>Orain dela {0} minutu</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Saio hasiera onartua</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Saio hasiera ukatua</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Saio hasiera eskaerak onartu</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Erabili gailu hau beste gailu batzuetatik egindako saio hasiera eskaerak onartzeko.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Baimendu jakinarazpenak</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Jaso push jakinarazpenak saio hasiera eskaera berrietarako</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Ez, eskerrik asko</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Onartu {0}-ren saio hasiera eskaera</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Jakinarazpen guztiak</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Pasahitz mota</value>
|
||||
</data>
|
||||
@@ -2387,4 +2451,60 @@
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Ausazkoa</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Zabaldu irisgarritasun zerbitzua</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwardenek irisgarritasun zerbitzua erabiltzen du aplikazioetan eta webguneetan sarbide-eremuak bilatzeko; ondoren, eremu-ID egokiak ezartzen ditu, aplikaziorako edo gunerako eremu bat aurkitzen denean erabiltzaile-izena eta pasahitza sartzeko. Zerbitzuak ematen digun informazioa ez dugu gordeko, eta ez gara saiatuko pantailan kredentzialen testutik haratagoko elementurik zelatatzen.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Onartu</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Baztertu</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Sarbide eskaera iraungi da.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Saio hasiera saiakera hemendik:
|
||||
{0}
|
||||
Kontu honetara aldatu nahi duzu?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Berria hemendik?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Ez zara zu?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Hasi saioa pasahitz nagusiarekin</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Hasi saioa beste gailu batekin</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Saioa hastea martxan da</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Jakinarazpen bat bidali da zure gailura.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Mesedez, ziurtatu kutxa gotorra desblokeatuta dagoela eta hatz-marka digitalaren esaldia bat datorrela beste gailuarekin.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Berbidali jakinarazpena</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Beste aukerarik behar al duzu?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Ikusi erregistro guztiak ezarpenetan</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
<comment>The button text that allows a user to copy the login's password to their clipboard.</comment>
|
||||
</data>
|
||||
<data name="CopyUsername" xml:space="preserve">
|
||||
<value>رونوشت نام کاربری</value>
|
||||
<value>کپی نام کاربری</value>
|
||||
<comment>The button text that allows a user to copy the login's username to their clipboard.</comment>
|
||||
</data>
|
||||
<data name="Credits" xml:space="preserve">
|
||||
@@ -190,7 +190,7 @@
|
||||
<comment>Full label for a email address.</comment>
|
||||
</data>
|
||||
<data name="EmailUs" xml:space="preserve">
|
||||
<value>به ما رایانامه بزنید</value>
|
||||
<value>ایمیل ما</value>
|
||||
</data>
|
||||
<data name="EmailUsDescription" xml:space="preserve">
|
||||
<value>برای کمک گرفتن و گذاشتن بازخورد بصورت مستقیم به ما رایانامه ارسال کنید.</value>
|
||||
@@ -379,10 +379,10 @@
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
<value>تایید اثر انگشت</value>
|
||||
<value>تأیید اثر انگشت</value>
|
||||
</data>
|
||||
<data name="VerifyMasterPassword" xml:space="preserve">
|
||||
<value>تایید کلمه عبور اصلی</value>
|
||||
<value>تأیید کلمه عبور اصلی</value>
|
||||
</data>
|
||||
<data name="VerifyPIN" xml:space="preserve">
|
||||
<value>تایید پین</value>
|
||||
@@ -394,7 +394,7 @@
|
||||
<value>مشاهده</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsite" xml:space="preserve">
|
||||
<value>از وبسایت ما دیدن کنید</value>
|
||||
<value>از وب سایت ما دیدن کنید</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsiteDescription" xml:space="preserve">
|
||||
<value>برای کمک گرفتن، اخبار، رایانامه ما، و یا آموزش بیشتر برای استفاده از Bitwarden از وب سایت ما دیدن کنید.</value>
|
||||
@@ -425,7 +425,7 @@
|
||||
<value>سرویس پر کردن خودکار</value>
|
||||
</data>
|
||||
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
|
||||
<value>از کاراکترهای مبهم اجتناب کن</value>
|
||||
<value>از کاراکترهای مبهم اجتناب شود</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtension" xml:space="preserve">
|
||||
<value>افزونه برنامه Bitwarden</value>
|
||||
@@ -635,7 +635,7 @@
|
||||
<value>کلمه عبور تولید شد.</value>
|
||||
</data>
|
||||
<data name="PasswordGenerator" xml:space="preserve">
|
||||
<value>تولید کننده کلمه عبور</value>
|
||||
<value>تولیدکننده کلمه عبور</value>
|
||||
</data>
|
||||
<data name="PasswordHint" xml:space="preserve">
|
||||
<value>راهنمای کلمه عبور</value>
|
||||
@@ -856,7 +856,7 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="VerificationEmailSent" xml:space="preserve">
|
||||
<value>رایانامه تایید فرستاده شد.</value>
|
||||
<value>رایانامه تأیید فرستاده شد</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="YubiKeyInstruction" xml:space="preserve">
|
||||
@@ -1575,6 +1575,10 @@
|
||||
<value>نُرد</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>تاریک خورشیدی</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>پر کردن خودکار URI های مسدود شده</value>
|
||||
</data>
|
||||
@@ -2314,6 +2318,66 @@
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>آیا مطمئن هستید که می خواهید ضبط صفحه را فعال کنید؟</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>ورود الزامیست</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>آیا در تلاش برای ورود به سیستم هستید؟</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>تلاش برای ورود به سیستم توسط {0} در {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>نوع دستگاه</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>آدرس IP</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>زمان</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>نزدیک</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>تأیید ورود</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>رَدِ ورود</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>همین الان</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} دقيقه پیش</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>ورود تأیید شد</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>ورود رَد شد</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>درخواست های ورود را تأیید کنید</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>از این دستگاه برای تأیید درخواستهای ورود به سیستم از دستگاههای دیگر استفاده کنید.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>اجازه دادن به اعلانها</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>دریافت اعلانهای پوش برای درخواستهای ورود جدید</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>نه ممنون</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>تأیید تلاش برای ورود به سیستم برای {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>همه اعلانها</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>نوع گذرواژه</value>
|
||||
</data>
|
||||
@@ -2389,4 +2453,60 @@
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>تصادفی</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>افشای سرویس دسترسی</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden از سرویس دسترسپذیری برای جستجوی فیلدهای ورود در برنامهها و وبسایتها استفاده میکند، سپس زمانی که مطابقتی با برنامه یا سایت پیدا شد، شناسههای فیلد مناسب را برای وارد کردن نام کاربری و رمز عبور ایجاد میکند. ما هیچ کدام از اطلاعات ارائه شده توسط سرویس به ما را ذخیره نمی کنیم و هیچ تلاشی برای کنترل عناصر روی صفحه فراتر از ورود متن اعتبارنامه ها انجام نمی دهیم.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>پذیرفتن</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>رَد کردن</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>درخواست ورود قبلاً منقضی شده است.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>تلاش برای ورود از:
|
||||
{0}
|
||||
آیا می خواهید به این حساب تغییر دهید؟</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>اینجا جدیده؟</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>دریافت راهنمای گذرواژه اصلی</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>در حال ورود به عنوان {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>شما نیستید؟</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>با کلمه عبور اصلی وارد شوید</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>با دستگاه دیگری وارد شوید</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
<comment>Title for your favorite items in the vault.</comment>
|
||||
</data>
|
||||
<data name="FileBugReport" xml:space="preserve">
|
||||
<value>Lähetä virheraportti</value>
|
||||
<value>Lähetä virheilmoitus</value>
|
||||
</data>
|
||||
<data name="FileBugReportDescription" xml:space="preserve">
|
||||
<value>Avaa ongelma GitHub-sivullamme.</value>
|
||||
@@ -219,7 +219,7 @@
|
||||
<value>Uusi kansio luotu.</value>
|
||||
</data>
|
||||
<data name="FolderDeleted" xml:space="preserve">
|
||||
<value>Kansio poistettu.</value>
|
||||
<value>Kansio poistettiin</value>
|
||||
</data>
|
||||
<data name="FolderNone" xml:space="preserve">
|
||||
<value>Ei kansiota</value>
|
||||
@@ -229,10 +229,10 @@
|
||||
<value>Kansiot</value>
|
||||
</data>
|
||||
<data name="FolderUpdated" xml:space="preserve">
|
||||
<value>Kansio päivitetty.</value>
|
||||
<value>Kansio tallennettiin</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Mene sivustolle</value>
|
||||
<value>Avaa sivusto</value>
|
||||
<comment>The button text that allows user to launch the website to their web browser.</comment>
|
||||
</data>
|
||||
<data name="HelpAndFeedback" xml:space="preserve">
|
||||
@@ -243,7 +243,7 @@
|
||||
<comment>Hide a secret value that is currently shown (password).</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredMessage" xml:space="preserve">
|
||||
<value>Yhdistä Internetiin jatkaaksesi.</value>
|
||||
<value>Jatka muodostamalla yhteys Internetiin.</value>
|
||||
<comment>Description message for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
|
||||
@@ -308,7 +308,7 @@
|
||||
<comment>Label for an entity name.</comment>
|
||||
</data>
|
||||
<data name="No" xml:space="preserve">
|
||||
<value>En</value>
|
||||
<value>Ei</value>
|
||||
</data>
|
||||
<data name="Notes" xml:space="preserve">
|
||||
<value>Merkinnät</value>
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>Kohde poistettu.</value>
|
||||
<value>Kohde poistettiin</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -364,7 +364,7 @@
|
||||
<comment>Label for a uri/url.</comment>
|
||||
</data>
|
||||
<data name="UseFingerprintToUnlock" xml:space="preserve">
|
||||
<value>Avaa lukitus sormenjäljellä</value>
|
||||
<value>Avaa sormenjäljellä</value>
|
||||
</data>
|
||||
<data name="Username" xml:space="preserve">
|
||||
<value>Käyttäjätunnus</value>
|
||||
@@ -375,7 +375,7 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} kopioitu.</value>
|
||||
<value>{0} kopioitiin</value>
|
||||
<comment>Confirmation message after suceessfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
@@ -397,7 +397,7 @@
|
||||
<value>Käy sivustollamme</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsiteDescription" xml:space="preserve">
|
||||
<value>Käy sivustollamme, jossa voit saada apua Bitwardenin käyttämisessä, lukea palvelun uutisia tai lähettää meille sähköpostia.</value>
|
||||
<value>Käy sivustollamme saadaksesi apua, uutisia, lähettääksesi meille sähköpostia ja/tai saadaksesi lisätietoa Bitwardenin käytöstä.</value>
|
||||
</data>
|
||||
<data name="Website" xml:space="preserve">
|
||||
<value>SIvusto</value>
|
||||
@@ -431,7 +431,7 @@
|
||||
<value>Bitwardenin sovelluslaajennus</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
|
||||
<value>Helpoin tapa lisätä holviisi uusia kirjautumistietoja on käyttää Bitwardenin sovelluslaajennusta. Asetusten "Lisäasetukset" -osiosta löydät lisätietoja laajennuksesta.</value>
|
||||
<value>Helpoin tapa lisätä holviisi uusia kirjautumistietoja on käyttää Bitwardenin sovelluslaajennusta. "Asetukset" -osiosta löydät lisätietoja laajennuksen käytöstä.</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionDescription" xml:space="preserve">
|
||||
<value>Käytä Bitwardenia kirjautumistietojesi automaattiseen täyttöön Safarissa ja muissa sovelluksissa.</value>
|
||||
@@ -440,7 +440,7 @@
|
||||
<value>Bitwardenin automaattisen täytön palvelu</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillAccessibilityServiceDescription" xml:space="preserve">
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua kirjautumistietojesi automaattiseen täyttöön.</value>
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua kirjautumistietojen automaattiseen täyttöön.</value>
|
||||
</data>
|
||||
<data name="ChangeEmail" xml:space="preserve">
|
||||
<value>Vaihda sähköpostiosoite</value>
|
||||
@@ -477,13 +477,13 @@
|
||||
<value>Syötä tilisi sähköpostiosoite saadaksesi pääsalasanan vihjeen.</value>
|
||||
</data>
|
||||
<data name="ExntesionReenable" xml:space="preserve">
|
||||
<value>Ota sovelluslaajennus uudelleen käyttöön</value>
|
||||
<value>Aktivoi sovelluslaajennus uudelleen</value>
|
||||
</data>
|
||||
<data name="ExtensionAlmostDone" xml:space="preserve">
|
||||
<value>Melkein valmis!</value>
|
||||
</data>
|
||||
<data name="ExtensionEnable" xml:space="preserve">
|
||||
<value>Käytä sovelluslaajennusta</value>
|
||||
<value>Aktivoi sovelluslaajennus</value>
|
||||
</data>
|
||||
<data name="ExtensionInSafari" xml:space="preserve">
|
||||
<value>Löydät Bitwardenin Safarista jakokuvaketta käyttäen (vihje: vieritä valikon alimmaista riviä oikealle).</value>
|
||||
@@ -505,7 +505,7 @@
|
||||
<value>Avaa laajennus napauttamalla valikon Bitwarden-kuvaketta.</value>
|
||||
</data>
|
||||
<data name="ExtensionTurnOn" xml:space="preserve">
|
||||
<value>Ottaaksesi Bitwardenin käyttöön Safarissa ja muissa sovelluksissa, napauta valikon alariviltä "Lisää" -kuvaketta.</value>
|
||||
<value>Ottaaksesi Bitwardenin käyttöön Safarissa ja muissa sovelluksissa, paina valikon alarivin "Lisää" -kuvaketta.</value>
|
||||
</data>
|
||||
<data name="Favorite" xml:space="preserve">
|
||||
<value>Suosikki</value>
|
||||
@@ -566,7 +566,7 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="LoginOrCreateNewAccount" xml:space="preserve">
|
||||
<value>Kirjaudu sisään tai luo uusi tili päästäksesi salattuun holviisi.</value>
|
||||
<value>Kirjaudu tai luo uusi tili käyttääksesi salattua holviasi.</value>
|
||||
</data>
|
||||
<data name="Manage" xml:space="preserve">
|
||||
<value>Hallinta</value>
|
||||
@@ -604,7 +604,7 @@
|
||||
<value>Ei koskaan</value>
|
||||
</data>
|
||||
<data name="NewItemCreated" xml:space="preserve">
|
||||
<value>Uusi kohde luotu.</value>
|
||||
<value>Kohde lisättiin</value>
|
||||
</data>
|
||||
<data name="NoFavorites" xml:space="preserve">
|
||||
<value>Holvissasi ei ole suosikkeja.</value>
|
||||
@@ -632,7 +632,7 @@
|
||||
<value>Muut</value>
|
||||
</data>
|
||||
<data name="PasswordGenerated" xml:space="preserve">
|
||||
<value>Salasana generoitu.</value>
|
||||
<value>Salasana luotiin</value>
|
||||
</data>
|
||||
<data name="PasswordGenerator" xml:space="preserve">
|
||||
<value>Salasanageneraattori</value>
|
||||
@@ -647,7 +647,7 @@
|
||||
<value>Haluatko varmasti korvata nykyisen salasanan?</value>
|
||||
</data>
|
||||
<data name="PushNotificationAlert" xml:space="preserve">
|
||||
<value>Bitwarden pitää holvisi automaattisesti synkronoituna push-ilmoitusten avulla. Parhaan mahdollisen kokemuksen takaamiseksi, valitse "Salli", kun sinua pyydetään ottamaan ilmoitukset käyttöön seuraavassa kehotteessa.</value>
|
||||
<value>Bitwarden pitää holvisi automaattisesti synkronoituna push-ilmoitusten avulla. Parhaan mahdollisen kokemuksen takaamiseksi, valitse "Salli", kun sinua pyydetään ottamaan ilmoitukset käyttöön.</value>
|
||||
<comment>Push notifications for apple products</comment>
|
||||
</data>
|
||||
<data name="RateTheApp" xml:space="preserve">
|
||||
@@ -663,7 +663,7 @@
|
||||
<value>Syötä pääsalasana uudelleen</value>
|
||||
</data>
|
||||
<data name="SearchVault" xml:space="preserve">
|
||||
<value>Hae holvista</value>
|
||||
<value>Etsi holvista</value>
|
||||
</data>
|
||||
<data name="Security" xml:space="preserve">
|
||||
<value>Suojaus</value>
|
||||
@@ -681,7 +681,7 @@
|
||||
<value>Kohteen tiedot</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Kohde päivitetty.</value>
|
||||
<value>Kohde tallennettiin</value>
|
||||
</data>
|
||||
<data name="Submitting" xml:space="preserve">
|
||||
<value>Käsitellään…</value>
|
||||
@@ -692,10 +692,10 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="SyncingComplete" xml:space="preserve">
|
||||
<value>Synkronointi on valmis.</value>
|
||||
<value>Synkronointi suoritettiin</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Synkronointi epäonnistui.</value>
|
||||
<value>Synkronointi epäonnistui</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Synkronoi holvi nyt</value>
|
||||
@@ -708,7 +708,7 @@
|
||||
<value>Kaksivaiheinen kirjautuminen</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>Kaksivaiheinen kirjautuminen tekee tilistäsi turvallisemman edellyttämällä salasanan lisäksi kirjautumisen lisätodennusta todennuslaitteen, ‑sovelluksen, tekstiviestin, puhelun tai sähköpostin avulla. Voit ottaa kaksivaiheisen kirjautumisen käyttöön bitwarden.com‑verkkoholvissa. Haluatko käydä sivustolla nyt?</value>
|
||||
<value>Kaksivaiheinen kirjautuminen tekee tilistäsi turvallisemman edellyttämällä salasanan lisäksi kirjautumisen lisätodennusta todennuslaitteen, ‑sovelluksen, tekstiviestin, puhelun tai sähköpostin avulla. Voit ottaa kaksivaiheisen kirjautumisen käyttöön bitwarden.com‑verkkoholvista. Haluatko avata sivuston nyt?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Avaustapa: {0}</value>
|
||||
@@ -769,7 +769,7 @@
|
||||
<value>2. Laita asetus päälle ja paina OK-painiketta hyväksyäksesi.</value>
|
||||
</data>
|
||||
<data name="Disabled" xml:space="preserve">
|
||||
<value>Ei käytössä</value>
|
||||
<value>Poistettu käytöstä</value>
|
||||
</data>
|
||||
<data name="Enabled" xml:space="preserve">
|
||||
<value>Käytössä</value>
|
||||
@@ -831,7 +831,7 @@
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>Tilillä on käytössä kaksivaiheinen kirjautuminen, mutta tämä laite ei tue käytettävissä olevia todentajia. Käytä yhteensopivaa laitetta ja lisää/tai ota käyttöön laajemmin tuettuja todentajia (kuten todennussovellus).</value>
|
||||
<value>Tilillä on käytössä kaksivaiheinen kirjautuminen, mutta tämä laite ei tue käytettävissä olevia todentajia. Käytä yhteensopivaa laitetta ja/tai lisää eri alustoija laajemmin tukevia todentajia (kuten todennussovellus).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>Palautuskoodi</value>
|
||||
@@ -856,11 +856,11 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="VerificationEmailSent" xml:space="preserve">
|
||||
<value>Todennussähköposti lähetetty.</value>
|
||||
<value>Todennussähköposti lähetettiin</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="YubiKeyInstruction" xml:space="preserve">
|
||||
<value>Aseta YubiKey NEO -todenuslaite laitettasi vasten tai kytke YubiKey-todennuslaite laitteesi USB-porttiin ja paina sen painiketta.</value>
|
||||
<value>Jatka asettamalla YubiKey NEO -todenuslaite laitteen takapuolta vasten tai kytke YubiKey-todennuslaite laitteen USB-porttiin ja paina sen painiketta.</value>
|
||||
</data>
|
||||
<data name="YubiKeyTitle" xml:space="preserve">
|
||||
<value>YubiKey-todennuslaite</value>
|
||||
@@ -928,7 +928,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Tiedostoliite lisätty</value>
|
||||
</data>
|
||||
<data name="AttachmentDeleted" xml:space="preserve">
|
||||
<value>Tiedostoliite poistettu</value>
|
||||
<value>Tiedostoliite poistettiin</value>
|
||||
</data>
|
||||
<data name="ChooseFile" xml:space="preserve">
|
||||
<value>Valitse tiedosto</value>
|
||||
@@ -946,7 +946,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Tiedoston lähde</value>
|
||||
</data>
|
||||
<data name="FeatureUnavailable" xml:space="preserve">
|
||||
<value>Toiminto ei ole käytettävissä</value>
|
||||
<value>Ominaisuus ei ole käytettävissä</value>
|
||||
</data>
|
||||
<data name="MaxFileSize" xml:space="preserve">
|
||||
<value>Tiedoston enimmäiskoko on 100 MB.</value>
|
||||
@@ -967,7 +967,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Edistyneille käyttäjille. Voit määrittää jokaiselle palvelulle oman pääverkkotunnuksen.</value>
|
||||
</data>
|
||||
<data name="EnvironmentSaved" xml:space="preserve">
|
||||
<value>Palvelinten URL-osoitteet tallennettu.</value>
|
||||
<value>Palvelinympäristön URL-osoitteet tallennettiin.</value>
|
||||
</data>
|
||||
<data name="FormattedIncorrectly" xml:space="preserve">
|
||||
<value>{0} on muotoiltu virheellisesti.</value>
|
||||
@@ -1092,7 +1092,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Toukokuu</value>
|
||||
</data>
|
||||
<data name="MiddleName" xml:space="preserve">
|
||||
<value>Välinimi</value>
|
||||
<value>Toinen nimi</value>
|
||||
</data>
|
||||
<data name="Mr" xml:space="preserve">
|
||||
<value>Hra</value>
|
||||
@@ -1204,7 +1204,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Totuusarvo</value>
|
||||
</data>
|
||||
<data name="FieldTypeHidden" xml:space="preserve">
|
||||
<value>Piilotettu teksti</value>
|
||||
<value>Piilotettu</value>
|
||||
</data>
|
||||
<data name="FieldTypeLinked" xml:space="preserve">
|
||||
<value>Linkitetty</value>
|
||||
@@ -1256,7 +1256,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>URI match detection for auto-fill.</comment>
|
||||
</data>
|
||||
<data name="YesAndSave" xml:space="preserve">
|
||||
<value>Kyllä ja tallenna</value>
|
||||
<value>Kyllä, ja tallenna</value>
|
||||
</data>
|
||||
<data name="AutofillAndSave" xml:space="preserve">
|
||||
<value>Täytä automaattisesti ja tallenna</value>
|
||||
@@ -1272,21 +1272,21 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Yritä uudelleen</value>
|
||||
</data>
|
||||
<data name="YubiKeyInstructionIos" xml:space="preserve">
|
||||
<value>Jatkaaksesi, pidä YubiKey NEO -todenuslaitettasi laitteen takaosaa vasten.</value>
|
||||
<value>Jatka pitämällä YubiKey NEO -todenuslaitetta laitteen takapuolta vasten.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillAccessibilityServiceDescription2" xml:space="preserve">
|
||||
<value>Esteettömyyspalvelu voi olla hyödyllinen sellaisten sovellusten kanssa, jotka eivät tue tavallista automaattisen täytön palvelua.</value>
|
||||
</data>
|
||||
<data name="DatePasswordUpdated" xml:space="preserve">
|
||||
<value>Salasana päivitetty</value>
|
||||
<value>Salasana päivitettiin</value>
|
||||
<comment>ex. Date this password was updated</comment>
|
||||
</data>
|
||||
<data name="DateUpdated" xml:space="preserve">
|
||||
<value>Päivitetty</value>
|
||||
<value>Päivitettiin</value>
|
||||
<comment>ex. Date this item was updated</comment>
|
||||
</data>
|
||||
<data name="AutofillActivated" xml:space="preserve">
|
||||
<value>Automaattinen täyttö on otettu käyttöön!</value>
|
||||
<value>Automaattinen täyttö on aktivoitu!</value>
|
||||
</data>
|
||||
<data name="MustLogInMainAppAutofill" xml:space="preserve">
|
||||
<value>Sinun on kirjauduttava Bitwardenin pääsovellukseen ennen kuin voit käyttää automaattista täyttöä.</value>
|
||||
@@ -1381,10 +1381,10 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Hae kokoelmasta</value>
|
||||
</data>
|
||||
<data name="SearchFileSends" xml:space="preserve">
|
||||
<value>Hae tiedosto-Sendeistä</value>
|
||||
<value>Etsi tiedosto-Sendeistä</value>
|
||||
</data>
|
||||
<data name="SearchTextSends" xml:space="preserve">
|
||||
<value>Hae teksti-Sendeistä</value>
|
||||
<value>Etsi teksti-Sendeistä</value>
|
||||
</data>
|
||||
<data name="SearchGroup" xml:space="preserve">
|
||||
<value>Hae - {0}</value>
|
||||
@@ -1416,7 +1416,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>ex: Item moved to Organization.</comment>
|
||||
</data>
|
||||
<data name="ItemShared" xml:space="preserve">
|
||||
<value>Kohde jaettu.</value>
|
||||
<value>Kohde on jaettu.</value>
|
||||
</data>
|
||||
<data name="SelectOneCollection" xml:space="preserve">
|
||||
<value>Valitse ainakin yksi kokoelma.</value>
|
||||
@@ -1489,17 +1489,17 @@ 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>Kirjautunut tunnuksella {0} palveluun {1}.</value>
|
||||
<value>Kirjautui tunnuksella {0} palvelimelle {1}.</value>
|
||||
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="VaultLockedMasterPassword" xml:space="preserve">
|
||||
<value>Holvisi on lukittu. Syötä pääsalasana jatkaaksesi.</value>
|
||||
<value>Holvi on lukittu. Jatka vahvistamalla pääsalasanasi.</value>
|
||||
</data>
|
||||
<data name="VaultLockedPIN" xml:space="preserve">
|
||||
<value>Holvisi on lukittu. Vahvista PIN-koodisi jatkaaksesi.</value>
|
||||
<value>Holvi on lukittu. Jatka vahvistamalla PIN-koodisi.</value>
|
||||
</data>
|
||||
<data name="VaultLockedIdentity" xml:space="preserve">
|
||||
<value>Holvisi on lukittu. Vahvista henkilöllisyytesi jatkaaksesi.</value>
|
||||
<value>Holvi on lukittu. Jatka vahvistamalla henkilöllisyytesi.</value>
|
||||
</data>
|
||||
<data name="Dark" xml:space="preserve">
|
||||
<value>Tumma</value>
|
||||
@@ -1575,6 +1575,10 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Nord</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
<value>Täytä estetyt URI:t automaattisesti</value>
|
||||
</data>
|
||||
@@ -1591,7 +1595,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Kun sovellus käynnistetään uudelleen</value>
|
||||
</data>
|
||||
<data name="AutofillServiceNotEnabled" xml:space="preserve">
|
||||
<value>Automaattinen täyttö tekee Bitwarden-holvisi käytöstä sivustoilla ja muissa sovelluksissa helppoa. Näyttää siltä, ettei automaattista täyttöä ole otettu käyttöön. Voit tehdä sen "Asetukset" -ruudusta.</value>
|
||||
<value>Automaattinen täyttö tekee Bitwarden-holvisi käytöstä sivustoilla ja muissa sovelluksissa helppoa. Näyttää siltä, ettei Bitwardenille ole määritetty automaattisen täytön palvelua. Määritys onnistuu "Asetukset" -ruudusta.</value>
|
||||
</data>
|
||||
<data name="ThemeAppliedOnRestart" xml:space="preserve">
|
||||
<value>Teema vaihtuu kun sovellus käynnistetään uudelleen.</value>
|
||||
@@ -1625,10 +1629,10 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Avaa biometrialla</value>
|
||||
</data>
|
||||
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden vaatii huomiota - Katso "Automaattisen täytön esteettömyyspalvelu" Bitwardenin asetuksissa</value>
|
||||
<value>Bitwarden vaatii huomiota - Katso Bitwardenin asetuksista "Automaattisen täytön esteettömyyspalvelu"</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
|
||||
<value>3. Androidin sovellusasetuksissa, Bitwardenin ruudulla, siirry "Näkyminen muiden päällä" -asetukseen (lisäasetusten alla) ja ota ominaisuus käyttöön napauttamalla kytkintä.</value>
|
||||
<value>3. Siirry Android-sovellusasetuksien Bitwarden-ruudulta "Näkyminen muiden päällä" -asetukseen (lisäasetusten alla) ja ota ominaisuus kytkinvalinnasta käyttöön.</value>
|
||||
</data>
|
||||
<data name="OverlayPermission" xml:space="preserve">
|
||||
<value>Käyttöoikeus</value>
|
||||
@@ -1637,7 +1641,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Avaa "Näkyminen muiden päällä" -käyttöoikeusasetukset</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceStep3" xml:space="preserve">
|
||||
<value>3. Androidin sovellusasetuksissa, Bitwardenin ruudulla, siirry "Näkyminen muiden päällä" -asetukseen (lisäasetusten alla) ja ota ominaisuus käyttöön napauttamalla kytkintä.</value>
|
||||
<value>3. Androidin sovellusasetuksissa, Bitwardenin ruudulla, siirry "Näkyminen muiden päällä" -asetukseen (lisäasetusten alla) ja ota ominaisuus käyttöön kytkinvalinnasta.</value>
|
||||
</data>
|
||||
<data name="Denied" xml:space="preserve">
|
||||
<value>Hylätty</value>
|
||||
@@ -1655,10 +1659,10 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Lähetä todennuskoodi sähköpostiisi</value>
|
||||
</data>
|
||||
<data name="CodeSent" xml:space="preserve">
|
||||
<value>Koodi lähetetty</value>
|
||||
<value>Koodi lähetettiin!</value>
|
||||
</data>
|
||||
<data name="ConfirmYourIdentity" xml:space="preserve">
|
||||
<value>Vahvista henkilöllisyytesi jatkaaksesi.</value>
|
||||
<value>Jatka vahvistamalla henkilöllisyytesi.</value>
|
||||
</data>
|
||||
<data name="ExportVaultWarning" xml:space="preserve">
|
||||
<value>Tämä vienti sisältää holvisi tiedot salaamattomassa muodossa. Sinun ei tulisi säilyttää tai lähettää vietyä tiedostoa suojaamattomien kanavien (kuten sähköpostin) välityksellä. Poista se välittömästi kun sille ei enää ole käyttöä.</value>
|
||||
@@ -1697,7 +1701,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Liitteen tallennuksessa oli ongelma. Jos ongelma jatkuu, voit tehdä tallennuksen verkkoholvin kautta.</value>
|
||||
</data>
|
||||
<data name="SaveAttachmentSuccess" xml:space="preserve">
|
||||
<value>Tiedostoliitteen tallennus onnistui</value>
|
||||
<value>Tiedostoliite tallennettiin</value>
|
||||
</data>
|
||||
<data name="AutofillTileAccessibilityRequired" xml:space="preserve">
|
||||
<value>Ota "Automaattisen täytön esteettömyyspalvelu" käyttöön Bitwardenin asetuksista käyttääksesi automaattisen täytön pikavalintapalkkia.</value>
|
||||
@@ -1722,7 +1726,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>Kohde palautettu.</value>
|
||||
<value>Kohde palautettiin</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -1809,16 +1813,16 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Aktivoimalla tämän valinnan hyväksyt seuraavat: </value>
|
||||
</data>
|
||||
<data name="AcceptPoliciesError" xml:space="preserve">
|
||||
<value>Käyttöehtoja ja tietosuojakäytäntöä ei ole vahvistettu.</value>
|
||||
<value>Palveluehtoja ja tietosuojakäytäntöä ei ole vahvistettu.</value>
|
||||
</data>
|
||||
<data name="TermsOfService" xml:space="preserve">
|
||||
<value>Käyttöehdot</value>
|
||||
<value>Palveluehdot</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicy" xml:space="preserve">
|
||||
<value>Tietosuojakäytäntö</value>
|
||||
</data>
|
||||
<data name="AccessibilityDrawOverPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden tarvitsee huomiota - Katso "Näkyminen muiden päällä" Bitwardenin asetusten kohdasta "Automaattisen täytön palvelut"</value>
|
||||
<value>Bitwarden edellyttää toimenpiteitä - Kytke "Näkyminen muiden päällä" -asetus käyttöön Bitwardenin asetusten kohdasta "Automaattisen täytön palvelut"</value>
|
||||
</data>
|
||||
<data name="AutofillServices" xml:space="preserve">
|
||||
<value>Automaattisen täytön palvelut</value>
|
||||
@@ -1827,16 +1831,16 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Tekstinsisäinen täyttö</value>
|
||||
</data>
|
||||
<data name="InlineAutofillDescription" xml:space="preserve">
|
||||
<value>Käytä tekstinsisäistä automaattista täyttöä, jos käyttämäsi IME (näppäimistö) tukee sitä. Jos käyttämäsi alusta ei ole tuettu (tai tämä valinta ei ole käytössä), käytetään normaalia automaattisen täytön pikavalintapalkkia.</value>
|
||||
<value>Käytä tekstinsisäistä automaattista täyttöä, jos käyttämäsi IME (näppäimistö) tukee sitä. Jos käyttämiääsi alustaa ei tueta (tai valinta on poistettu käytöstä), käytetään normaalia automaattisen täytön pikavalintapalkkia.</value>
|
||||
</data>
|
||||
<data name="Accessibility" xml:space="preserve">
|
||||
<value>Esteettömyyspalvelu</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription" xml:space="preserve">
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua kirjautumistietojen automaattiseen täyttöön sovelluksissa ja verkossa. Kun tämä on käytössä, näytetään aktiivisten kirjautumiskenttien ohessa pikavalintapalkki.</value>
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua kirjautumistietojen automaattiseen täyttöön sovelluksissa ja verkkosivustoilla. Kun määritetty, näytetään aktiivisten kirjautumiskenttien ohessa pikavalintapalkki.</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription2" xml:space="preserve">
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua kirjautumistietojen automaattiseen täyttöön sovelluksissa ja verkossa (myös "Näkyminen muiden päällä" -asetuksen on oltava käytössä).</value>
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua kirjautumistietojen automaattiseen täyttöön sovelluksissa ja verkkosivustoilla (myös "Näkyminen muiden päällä" -asetuksen on oltava käytössä).</value>
|
||||
</data>
|
||||
<data name="AccessibilityDescription3" xml:space="preserve">
|
||||
<value>Käytä Bitwardenin esteettömyyspalvelua käyttääksesi Automaattisen täytön pikavalintapalkkia ja/tai näytä palkki käyttäen "Näkyminen muiden päällä" -asetusta.</value>
|
||||
@@ -1848,16 +1852,16 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Näkyminen muiden päällä</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription" xml:space="preserve">
|
||||
<value>Kun käytössä, sallii Bitwardenin esteettömyyspalvelun näyttää pikavalintapalkki aktiivisten kirjautumiskenttien ohessa.</value>
|
||||
<value>Sallii Bitwardenin esteettömyyspalvelun näyttää pikavalintapalkin aktiivisten kirjautumiskenttien ohessa.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription2" xml:space="preserve">
|
||||
<value>Kun käytössä, Bitwardenin esteettömyyspalvelu näyttää aktiivisten kirjautumiskenttien ohessa pikavalintapalkin helpottaakseen kirjautumistietojesi automaattista täyttöä.</value>
|
||||
<value>Kun käytössä, Bitwardenin esteettömyyspalvelu näyttää aktiivisten kirjautumiskenttien ohessa pikavalintapalkin helpottaakseen kirjautumistietojen automaattista täyttöä.</value>
|
||||
</data>
|
||||
<data name="DrawOverDescription3" xml:space="preserve">
|
||||
<value>Jos käytössä, esteettömyyspalvelu näyttää pikavalintapalkin laajentaakseen automaattisen täytön palvelun toiminnan kattamaan myös vanhemmat sovellukset, jotka eivät tue Android Autofill Framework -rajapintaa.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
|
||||
<value>Yrityksen asettaman käytännön johdosta kohteiden tallennus omaan holviisi ei ole mahdollista. Muuta omistusasetus organisaatiolle ja valitse käytettävissä olevista kokoelmista.</value>
|
||||
<value>Yrityskäytännön johdosta kohteiden tallennus henkilökohtaiseen holviin ei ole mahdollista. Muuta omistusasetus organisaatiolle ja valitse käytettävissä olevista kokoelmista.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipPolicyInEffect" xml:space="preserve">
|
||||
<value>Organisaatiokäytäntö vaikuttaa omistajuusvalintoihisi.</value>
|
||||
@@ -1901,13 +1905,13 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Tiedostotyyppi on valittu.</value>
|
||||
</data>
|
||||
<data name="FileTypeIsNotSelected" xml:space="preserve">
|
||||
<value>Tiedostotyyppiä ei ole valittu, valitse napauttamalla.</value>
|
||||
<value>Tiedostotyyppiä ei ole valittu. Valitse napauttamalla.</value>
|
||||
</data>
|
||||
<data name="TextTypeIsSelected" xml:space="preserve">
|
||||
<value>Tekstityyppi on valittu.</value>
|
||||
</data>
|
||||
<data name="TextTypeIsNotSelected" xml:space="preserve">
|
||||
<value>Tekstityyppiä ei ole valittu, valitse napauttamalla.</value>
|
||||
<value>Tekstityyppiä ei ole valittu. Valitse napauttamalla.</value>
|
||||
</data>
|
||||
<data name="DeletionDate" xml:space="preserve">
|
||||
<value>Poistoajankohta</value>
|
||||
@@ -1923,7 +1927,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Odottaa poistoa</value>
|
||||
</data>
|
||||
<data name="ExpirationDate" xml:space="preserve">
|
||||
<value>Erääntymisajankohta</value>
|
||||
<value>Erääntymispäivä</value>
|
||||
</data>
|
||||
<data name="ExpirationTime" xml:space="preserve">
|
||||
<value>Erääntymisaika</value>
|
||||
@@ -1943,10 +1947,10 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="MaximumAccessCountReached" xml:space="preserve">
|
||||
<value>Käyttökertojen enimmäismäärä saavutettu</value>
|
||||
<value>Käyttökertojen enimmäismäärä on saavutettu</value>
|
||||
</data>
|
||||
<data name="CurrentAccessCount" xml:space="preserve">
|
||||
<value>Nykyinen käyttökertojen määrä</value>
|
||||
<value>Käyttökertojen nykyinen määrä</value>
|
||||
</data>
|
||||
<data name="NewPassword" xml:space="preserve">
|
||||
<value>Uusi salasana</value>
|
||||
@@ -1965,7 +1969,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Poistetaan salasana</value>
|
||||
</data>
|
||||
<data name="SendPasswordRemoved" xml:space="preserve">
|
||||
<value>Salasana on poistettu.</value>
|
||||
<value>Salasana poistettiin</value>
|
||||
</data>
|
||||
<data name="NotesInfo" xml:space="preserve">
|
||||
<value>Yksityisiä merkintöjä tästä Sendistä.</value>
|
||||
@@ -2002,7 +2006,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AddSend" xml:space="preserve">
|
||||
<value>Lisää Send</value>
|
||||
<value>Uusi Send</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AreYouSureDeleteSend" xml:space="preserve">
|
||||
@@ -2010,15 +2014,15 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDeleted" xml:space="preserve">
|
||||
<value>Send on poistettu.</value>
|
||||
<value>Send poistettiin</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
<value>Send on päivitetty.</value>
|
||||
<value>Send tallennettiin</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
<value>Uusi Send on luotu.</value>
|
||||
<value>Send luotiin</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="OneDay" xml:space="preserve">
|
||||
@@ -2044,7 +2048,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDisabledWarning" xml:space="preserve">
|
||||
<value>Yrityksen käytännön vuoksi voit poistaa vain olemassa olevan Sendin.</value>
|
||||
<value>Yrityskäytännön vuoksi voit poistaa vain olemassa olevan Sendin.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AboutSend" xml:space="preserve">
|
||||
@@ -2073,7 +2077,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Pääsalasanan vahvistus</value>
|
||||
</data>
|
||||
<data name="PasswordConfirmationDesc" xml:space="preserve">
|
||||
<value>Toiminto on suojattu. Jatkaaksesi, syötä pääsalasanasi uudelleen vahvistaaksesi henkilöllisyytesi.</value>
|
||||
<value>Toiminto on suojattu. Jatka vahvistamalla henkilöllisyytesi syöttämällä pääsalasanasi uudelleen.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Captcha-vahvistus vaaditaan</value>
|
||||
@@ -2082,16 +2086,16 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Captcha-vahvistus epäonnistui. Yritä uudelleen.</value>
|
||||
</data>
|
||||
<data name="UpdatedMasterPassword" xml:space="preserve">
|
||||
<value>Pääsalasana on päivitetty</value>
|
||||
<value>Pääsalasana päivitettiin</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPassword" xml:space="preserve">
|
||||
<value>Päivitä pääsalasana</value>
|
||||
<value>Vaihda pääsalasana</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Organisaatiosi ylläpito on hiljattain vaihtanut pääsalasanasi. Käyttääksesi holvia, on sinun päivitettävä se nyt. Tämä uloskirjaa kaikki nykyiset istunnot pakottaen uudelleenkirjautumisen. Muiden laitteiden aktiiviset istunnot saattavat toimia vielä tunnin ajan.</value>
|
||||
<value>Organisaatiosi ylläpito on hiljattain vaihtanut pääsalasanasi. Käyttääksesi holvia, 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="UpdatingPassword" xml:space="preserve">
|
||||
<value>Salasanaa päivitetään</value>
|
||||
<value>Salasanaa vaihdetaan</value>
|
||||
</data>
|
||||
<data name="UpdatePasswordError" xml:space="preserve">
|
||||
<value>Salasanan päivitys ei tällä hetkellä onnistu</value>
|
||||
@@ -2100,7 +2104,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Poista pääsalasana</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning" xml:space="preserve">
|
||||
<value>{0} käyttää SSO:ta asiakkaan hallitsemalla salauksella. Jos jatkat, poistetaan tilitäsi pääsalasana ja jatkossa on käytettävä SSO-kirjautumista.</value>
|
||||
<value>{0} käyttää SSO:ta asiakkaan hallitsemalla salauksella. Jos jatkat, tilisi pääsalasana poistetaan, jonka jälkeen on käytettävä SSO-kirjautumista.</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning2" xml:space="preserve">
|
||||
<value>Jollet halua poistaa pääsalasanaasi, voit poistua tästä organisaatiosta.</value>
|
||||
@@ -2115,7 +2119,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>FIDO2 WebAuthn</value>
|
||||
</data>
|
||||
<data name="Fido2Instruction" xml:space="preserve">
|
||||
<value>Jatkaaksesi, pidä FIDO2 WebAuthn -todennuslaitteesi valmiina ja seuraa ohjeita napautettuasi seuraavasta näytöstä 'WebAuthn-todennus'.</value>
|
||||
<value>Jatka valmistelemalla FIDO2 WebAuthn -todennuslaitteesi ja seuraa ohjeita valittuasi seuraavasta näytöstä "WebAuthn-todennus" -valinnan.</value>
|
||||
</data>
|
||||
<data name="Fido2Desc" xml:space="preserve">
|
||||
<value>FIDO2 WebAuthn -tunnistautumisen voi todentaa ulkoisella todennuslaitteella.</value>
|
||||
@@ -2133,13 +2137,13 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Organisaatiolla on käytäntö, joka liittää tilisi automaattisesti salasanan palautusapuun. Liitos sallii organisaation ylläpitäjien vaihtaa pääsalasanasi.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Organisaatiosi käytännöt vaikuttavat holvisi aikakatkaisuun. Suurin sallittu aika on {0} tunti(a) ja {1} minuutti(a)</value>
|
||||
<value>Organisaatiokäytännöt vaikuttavat holvin aikakatkaisuun. Suurin sallittu aika on {0} tunti(a) ja {1} minuutti(a)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Holvisi aikakatkaisu ylittää organisaatiosi asettamat rajoitukset.</value>
|
||||
</data>
|
||||
<data name="DisablePersonalVaultExportPolicyInEffect">
|
||||
<value>Yksi tai useampi organisaation käytäntö estää henkilökohtaisen holvisi viennin.</value>
|
||||
<value>Yksi tai useampi organisaatiokäytäntö estää henkilökohtaisen holvisi viennin.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Lisää tili</value>
|
||||
@@ -2157,7 +2161,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Vaihdettu seuraavaan käytettävissä olevaan tiliin</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Tili lukittu</value>
|
||||
<value>Tili lukittiin</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Tilin uloskirjaus onnistui</value>
|
||||
@@ -2181,7 +2185,7 @@ Koodi luetaan automaattisesti.</value>
|
||||
<value>Tilisi on poistettu pysyvästi</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Virheellinen todennuskoodi.</value>
|
||||
<value>Virheellinen todennuskoodi</value>
|
||||
</data>
|
||||
<data name="RequestOTP" xml:space="preserve">
|
||||
<value>Pyydä kertakäyttöinen salasana</value>
|
||||
@@ -2313,6 +2317,66 @@ turvallisesti valitsemalla "Lisää TOTP"</value>
|
||||
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
|
||||
<value>Haluatko varmasti sallia kuvankaappauksen?</value>
|
||||
</data>
|
||||
<data name="LogInRequested" xml:space="preserve">
|
||||
<value>Kirjautumista pyydetty</value>
|
||||
</data>
|
||||
<data name="AreYouTryingToLogIn" xml:space="preserve">
|
||||
<value>Yritätkö kirjautua sisään?</value>
|
||||
</data>
|
||||
<data name="LogInAttemptByXOnY" xml:space="preserve">
|
||||
<value>Kirjautumisyritys tunnuksella {0} laitteella {1}</value>
|
||||
</data>
|
||||
<data name="DeviceType" xml:space="preserve">
|
||||
<value>Laitteen tyyppi</value>
|
||||
</data>
|
||||
<data name="IpAddress" xml:space="preserve">
|
||||
<value>IP-osoite</value>
|
||||
</data>
|
||||
<data name="Time" xml:space="preserve">
|
||||
<value>Aika</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Lähellä</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Vahvista kirjautuminen</value>
|
||||
</data>
|
||||
<data name="DenyLogIn" xml:space="preserve">
|
||||
<value>Estä kirjautuminen</value>
|
||||
</data>
|
||||
<data name="JustNow" xml:space="preserve">
|
||||
<value>Juuri nyt</value>
|
||||
</data>
|
||||
<data name="XMinutesAgo" xml:space="preserve">
|
||||
<value>{0} minuuttia sitten</value>
|
||||
</data>
|
||||
<data name="LogInAccepted" xml:space="preserve">
|
||||
<value>Kirjautuminen vahvistettu</value>
|
||||
</data>
|
||||
<data name="LogInDenied" xml:space="preserve">
|
||||
<value>Kirjautuminen estetty</value>
|
||||
</data>
|
||||
<data name="ApproveLoginRequests" xml:space="preserve">
|
||||
<value>Hyväksy kirjautumispyyntöjä</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Hyväksy muiden laitteiden kirjautumispyyntöjä tällä laitteelta.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Salli ilmoitukset</value>
|
||||
</data>
|
||||
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
|
||||
<value>Vastaanota push-ilmoitus uusista kirjautumispyynnöistä</value>
|
||||
</data>
|
||||
<data name="NoThanks" xml:space="preserve">
|
||||
<value>Ei kiitos</value>
|
||||
</data>
|
||||
<data name="ConfimLogInAttempForX" xml:space="preserve">
|
||||
<value>Vahvista kirjautuminen kohteessa {0}</value>
|
||||
</data>
|
||||
<data name="AllNotifications" xml:space="preserve">
|
||||
<value>Kaikki ilmoitukset</value>
|
||||
</data>
|
||||
<data name="PasswordType" xml:space="preserve">
|
||||
<value>Salasanan tyyppi</value>
|
||||
</data>
|
||||
@@ -2388,4 +2452,60 @@ turvallisesti valitsemalla "Lisää TOTP"</value>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Satunnainen</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Esteettömyyspalvelun kuvaus</value>
|
||||
</data>
|
||||
<data name="AccessibilityDisclosureText" xml:space="preserve">
|
||||
<value>Bitwarden käyttää esteettömyyspalvelua kirjautumiskenttien etsintään sovelluksista ja verkkosivustoilta. Löydetyille kentille luodaan asianmukaiset tunnisteet tunnusten ja salasanojen syöttöön sopivan sovelluksen tai sivuston löytyessä. Mitään palvelun paljastamia tietoja ei tallenneta, eikä mitään näytöllä esitettäviä kohteita pyritä hallitsemaan kirjautumistietojen tekstinsyöttöä lukuun ottamatta.</value>
|
||||
</data>
|
||||
<data name="Accept" xml:space="preserve">
|
||||
<value>Hyväksy</value>
|
||||
</data>
|
||||
<data name="Decline" xml:space="preserve">
|
||||
<value>Älä hyväksy</value>
|
||||
</data>
|
||||
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
|
||||
<value>Kirjautumispyyntö on jo erääntynyt.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Kirjautumisyritys tunnuksella:
|
||||
{0}
|
||||
Haluatko vaihtaa tähän tiliin?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>Oletko uusi täällä?</value>
|
||||
</data>
|
||||
<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>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Etkö se ollut sinä?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Kirjaudu pääsalasanalla</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Kirjaudu toisella laitteella</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Kirjautuminen aloitettu</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>Laitteellesi on lähetetty ilmoitus.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Varmista, että holvisi on avattu ja tunnistelauseke täsmää toisella laitteella.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Lähetä ilmoitus uudelleen</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Tarvitsetko toisen vaihtoehdon?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>Näytä kaikki kirjautumisvalinnat</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user