mirror of
https://github.com/bitwarden/mobile
synced 2025-12-05 23:53:33 +00:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43b7782872 | ||
|
|
8f66e2a315 | ||
|
|
8e333e6d14 | ||
|
|
ac7a680a1b | ||
|
|
88f6b60b97 | ||
|
|
1f58b0cabe | ||
|
|
284d728023 | ||
|
|
0796bf17ce | ||
|
|
4bd06d2393 | ||
|
|
a3a508eb83 | ||
|
|
f10307c72d | ||
|
|
840925c479 | ||
|
|
fdcb2d76c9 | ||
|
|
4734fe4e43 | ||
|
|
383eee6ec7 | ||
|
|
1d9671bc5c | ||
|
|
22b00bcb33 | ||
|
|
c1748acf39 | ||
|
|
507c3faea1 | ||
|
|
020a5c072d | ||
|
|
c47aad0412 | ||
|
|
7c83d7b37b | ||
|
|
4d4e246a47 | ||
|
|
612e458071 | ||
|
|
a2ec263116 | ||
|
|
5ade10d1fe | ||
|
|
5008e1daa8 | ||
|
|
ad7c656868 | ||
|
|
bdd0ea007b | ||
|
|
bf33f23c12 | ||
|
|
c043528a16 | ||
|
|
fd74164f82 |
85
.github/workflows/build.yml
vendored
85
.github/workflows/build.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Set up CLOC
|
||||
run: |
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }}
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Check if special branches exist
|
||||
id: branch-check
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
echo "::set-output name=rc_branch_exists::0"
|
||||
fi
|
||||
|
||||
if [[ $(git ls-remote --heads origin hotfix) ]]; then
|
||||
if [[ $(git ls-remote --heads origin hotfix-rc) ]]; then
|
||||
echo "::set-output name=hotfix_branch_exists::1"
|
||||
else
|
||||
echo "::set-output name=hotfix_branch_exists::0"
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
needs: setup
|
||||
steps:
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@c26a08ba26249b81327e26f6ef381897b6a8754d # v1
|
||||
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Decrypt secrets
|
||||
env:
|
||||
@@ -167,14 +167,14 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload Play Store .aab artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.4
|
||||
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
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.4
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden.apk
|
||||
path: ./com.x8bit.bitwarden.apk
|
||||
@@ -186,7 +186,7 @@ jobs:
|
||||
&& 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'
|
||||
|| 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"
|
||||
@@ -202,7 +202,7 @@ jobs:
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@c26a08ba26249b81327e26f6ef381897b6a8754d # v1
|
||||
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
@@ -213,7 +213,7 @@ jobs:
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Decrypt secrets
|
||||
env:
|
||||
@@ -241,6 +241,7 @@ jobs:
|
||||
run: |
|
||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||
$appPath = $($env:GITHUB_WORKSPACE + "/src/App/App.csproj");
|
||||
$corePath = $($env:GITHUB_WORKSPACE + "/src/Core/Core.csproj");
|
||||
|
||||
$androidManifest = $($env:GITHUB_WORKSPACE + "/src/Android/Properties/AndroidManifest.xml");
|
||||
|
||||
@@ -306,6 +307,18 @@ jobs:
|
||||
$appCenterNode.ParentNode.RemoveChild($appCenterNode);
|
||||
|
||||
$xml.Save($appPath);
|
||||
|
||||
Write-Output "########################################"
|
||||
Write-Output "##### Uninstall from Core.csproj"
|
||||
Write-Output "########################################"
|
||||
|
||||
$xml=New-Object XML;
|
||||
$xml.Load($corePath);
|
||||
|
||||
$appCenterNode=$xml.SelectSingleNode("/Project/ItemGroup/PackageReference[@Include='Microsoft.AppCenter.Crashes']");
|
||||
$appCenterNode.ParentNode.RemoveChild($appCenterNode);
|
||||
|
||||
$xml.Save($corePath);
|
||||
shell: pwsh
|
||||
|
||||
- name: Restore packages
|
||||
@@ -347,7 +360,7 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Upload F-Droid .apk artifact
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.4
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: com.x8bit.bitwarden-fdroid.apk
|
||||
path: ./com.x8bit.bitwarden-fdroid.apk
|
||||
@@ -368,16 +381,16 @@ jobs:
|
||||
echo "GitHub event: $GITHUB_EVENT"
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Login to Azure - Prod Subscription
|
||||
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
|
||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
|
||||
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "appcenter-ios-token"
|
||||
@@ -399,7 +412,8 @@ jobs:
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output $HOME/secrets/dist_extension.mobileprovision ./.github/secrets/dist_extension.mobileprovision.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output $HOME/secrets/dist_share_extension.mobileprovision ./.github/secrets/dist_share_extension.mobileprovision.gpg
|
||||
--output $HOME/secrets/dist_share_extension.mobileprovision \
|
||||
./.github/secrets/dist_share_extension.mobileprovision.gpg
|
||||
shell: bash
|
||||
|
||||
- name: Increment version
|
||||
@@ -495,7 +509,7 @@ jobs:
|
||||
-exportOptionsPlist $EXPORT_OPTIONS_PATH
|
||||
shell: bash
|
||||
|
||||
- name: Copy all dSYMs files to upload
|
||||
- name: Copy all dSYMs files to upload
|
||||
run: |
|
||||
ARCHIVE_DSYMS_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive/dSYMs"
|
||||
EXPORT_PATH="./bitwarden-export"
|
||||
@@ -504,7 +518,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Upload App Store .ipa & dSYMs artifacts
|
||||
uses: actions/upload-artifact@ee69f02b3dfdecd58bb31b4d133da38ba6fe3700 # v2.2.4
|
||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
||||
with:
|
||||
name: Bitwarden iOS
|
||||
path: |
|
||||
@@ -514,15 +528,12 @@ jobs:
|
||||
|
||||
- name: Install AppCenter CLI
|
||||
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'
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- run: npm install -g appcenter-cli
|
||||
(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: npm install -g appcenter-cli
|
||||
|
||||
- name: Upload dSYMs to App Center
|
||||
if: |
|
||||
@@ -530,10 +541,10 @@ jobs:
|
||||
&& 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'
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
env:
|
||||
APPCENTER_IOS_TOKEN: ${{ steps.retrieve-secrets.outputs.appcenter-ios-token }}
|
||||
run: appcenter crashes upload-symbols -a kspearrin/bitwarden -s "./bitwarden-export/dSYMs" --token $APPCENTER_IOS_TOKEN
|
||||
run: appcenter crashes upload-symbols -a bitwarden/bitwarden -s "./bitwarden-export/dSYMs" --token $APPCENTER_IOS_TOKEN
|
||||
shell: bash
|
||||
|
||||
- name: Deploy to App Store
|
||||
@@ -542,7 +553,7 @@ jobs:
|
||||
&& 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'
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
@@ -564,22 +575,22 @@ jobs:
|
||||
_CROWDIN_PROJECT_ID: "269690"
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
|
||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
||||
|
||||
- name: Login to Azure
|
||||
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
|
||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
|
||||
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "crowdin-api-token"
|
||||
|
||||
- name: Upload Sources
|
||||
uses: crowdin/github-action@e39093fd75daae7859c68eded4b43d42ec78d8ea # v1.3.2
|
||||
uses: crowdin/github-action@9237b4cb361788dfce63feb2e2f15c09e2fe7415
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
|
||||
@@ -605,7 +616,7 @@ jobs:
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master')
|
||||
|| (github.ref == 'refs/heads/rc')
|
||||
|| (github.ref == 'refs/heads/hotfix')
|
||||
|| (github.ref == 'refs/heads/hotfix-rc')
|
||||
env:
|
||||
CLOC_STATUS: ${{ needs.cloc.result }}
|
||||
ANDROID_STATUS: ${{ needs.android.result }}
|
||||
@@ -626,21 +637,21 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Login to Azure - Prod Subscription
|
||||
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
|
||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
||||
if: failure()
|
||||
with:
|
||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
||||
|
||||
- name: Retrieve secrets
|
||||
id: retrieve-secrets
|
||||
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
|
||||
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
|
||||
if: failure()
|
||||
with:
|
||||
keyvault: "bitwarden-prod-kv"
|
||||
secrets: "devops-alerts-slack-webhook-url"
|
||||
|
||||
- name: Notify Slack on failure
|
||||
uses: act10ns/slack@e4e71685b9b239384b0f676a63c32367f59c2522 # v1.2.2
|
||||
uses: act10ns/slack@da3191ebe2e67f49b46880b4633f5591a96d1d33
|
||||
if: failure()
|
||||
env:
|
||||
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
|
||||
|
||||
12
.github/workflows/release.yml
vendored
12
.github/workflows/release.yml
vendored
@@ -12,7 +12,7 @@ on:
|
||||
options:
|
||||
- Initial Release
|
||||
- Redeploy
|
||||
- dry-run
|
||||
- Dry Run
|
||||
|
||||
jobs:
|
||||
release:
|
||||
@@ -22,11 +22,11 @@ jobs:
|
||||
branch-name: ${{ steps.branch.outputs.branch-name }}
|
||||
steps:
|
||||
- name: Branch check
|
||||
if: github.event.inputs.release_type != 'dry-run'
|
||||
if: github.event.inputs.release_type != 'Dry Run'
|
||||
run: |
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix" ]]; then
|
||||
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
|
||||
echo "==================================="
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix' branches"
|
||||
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||
echo "==================================="
|
||||
exit 1
|
||||
fi
|
||||
@@ -75,7 +75,7 @@ jobs:
|
||||
run: zip -r Bitwarden\ iOS.zip Bitwarden\ iOS
|
||||
|
||||
- name: Create release
|
||||
if: github.event.inputs.release_type != 'dry-run'
|
||||
if: github.event.inputs.release_type != 'Dry Run'
|
||||
uses: ncipollo/release-action@40bb172bd05f266cf9ba4ff965cb61e9ee5f6d01 # v1.9.0
|
||||
with:
|
||||
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
|
||||
@@ -171,5 +171,5 @@ jobs:
|
||||
cd $GITHUB_WORKSPACE
|
||||
|
||||
- name: Deploy to gh-pages
|
||||
if: github.event.inputs.release_type != 'dry-run'
|
||||
if: github.event.inputs.release_type != 'Dry Run'
|
||||
run: npm run deploy
|
||||
|
||||
42
SECURITY.md
42
SECURITY.md
@@ -1,39 +1,11 @@
|
||||
Bitwarden believes that working with security researchers across the globe is crucial to keeping our
|
||||
users safe. If you believe you've found a security issue in our product or service, we encourage you to
|
||||
notify us. We welcome working with you to resolve the issue promptly. Thanks in advance!
|
||||
Bitwarden believes that working with security researchers across the globe is crucial to keeping our users safe. If you believe you've found a security issue in our product or service, we encourage you to please submit a report through our [HackerOne Program](https://hackerone.com/bitwarden/). We welcome working with you to resolve the issue promptly. Thanks in advance!
|
||||
|
||||
# Disclosure Policy
|
||||
|
||||
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every
|
||||
effort to quickly resolve the issue.
|
||||
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a
|
||||
third-party. We may publicly disclose the issue before resolving it, if appropriate.
|
||||
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or
|
||||
degradation of our service. Only interact with accounts you own or with explicit permission of the
|
||||
account holder.
|
||||
- If you would like to encrypt your report, please use the PGP key with long ID
|
||||
`0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
|
||||
|
||||
# In-scope
|
||||
|
||||
- Security issues in any current release of Bitwarden. This includes the web vault, browser extension,
|
||||
and mobile apps (iOS and Android). Product downloads are available at https://bitwarden.com. Source
|
||||
code is available at https://github.com/bitwarden.
|
||||
|
||||
# Exclusions
|
||||
|
||||
The following bug classes are out-of scope:
|
||||
|
||||
- Bugs that are already reported on any of Bitwarden's issue trackers (https://github.com/bitwarden),
|
||||
or that we already know of. Note that some of our issue tracking is private.
|
||||
- Issues in an upstream software dependency (ex: Xamarin, ASP.NET) which are already reported to the
|
||||
upstream maintainer.
|
||||
- Attacks requiring physical access to a user's device.
|
||||
- Self-XSS
|
||||
- Issues related to software or protocols not under Bitwarden's control
|
||||
- Vulnerabilities in outdated versions of Bitwarden
|
||||
- Missing security best practices that do not directly lead to a vulnerability
|
||||
- Issues that do not have any impact on the general public
|
||||
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every effort to quickly resolve the issue.
|
||||
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a third-party. We may publicly disclose the issue before resolving it, if appropriate.
|
||||
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our service. Only interact with accounts you own or with explicit permission of the account holder.
|
||||
- If you would like to encrypt your report, please use the PGP key with long ID `0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
|
||||
|
||||
While researching, we'd like to ask you to refrain from:
|
||||
|
||||
@@ -42,4 +14,8 @@ While researching, we'd like to ask you to refrain from:
|
||||
- Social engineering (including phishing) of Bitwarden staff or contractors
|
||||
- Any physical attempts against Bitwarden property or data centers
|
||||
|
||||
# We want to help you!
|
||||
|
||||
If you have something that you feel is close to exploitation, or if you'd like some information regarding the internal API, or generally have any questions regarding the app that would help in your efforts, please email us at https://bitwarden.com/contact and ask for that information. As stated above, Bitwarden wants to help you find issues, and is more than willing to help.
|
||||
|
||||
Thank you for helping keep Bitwarden and our users safe!
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.2.5.2" />
|
||||
<PackageReference Include="Xamarin.AndroidX.Migration" Version="1.0.8" />
|
||||
<PackageReference Include="Xamarin.Essentials">
|
||||
<Version>1.7.1</Version>
|
||||
<Version>1.7.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Xamarin.Firebase.Messaging">
|
||||
<Version>122.0.0</Version>
|
||||
|
||||
@@ -74,6 +74,12 @@ namespace Bit.Droid
|
||||
var appCenterTask = appCenterHelper.InitAsync();
|
||||
#endif
|
||||
|
||||
var toplayout = Window?.DecorView?.RootView;
|
||||
if (toplayout != null)
|
||||
{
|
||||
toplayout.FilterTouchesWhenObscured = true;
|
||||
}
|
||||
|
||||
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
|
||||
Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
||||
_appOptions = GetOptions();
|
||||
|
||||
@@ -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="2.16.3" 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="2.18.0" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30"/>
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Android.OS;
|
||||
using Android.Security.Keystore;
|
||||
using Bit.Core.Abstractions;
|
||||
using Java.Security;
|
||||
using Javax.Crypto;
|
||||
#if !FDROID
|
||||
using Microsoft.AppCenter.Crashes;
|
||||
#endif
|
||||
|
||||
namespace Bit.Droid.Services
|
||||
{
|
||||
@@ -43,23 +43,22 @@ namespace Bit.Droid.Services
|
||||
|
||||
public Task<bool> ValidateIntegrityAsync(string bioIntegrityKey = null)
|
||||
{
|
||||
// bioIntegrityKey used in iOS only
|
||||
if (Build.VERSION.SdkInt < BuildVersionCodes.M)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
_keystore.Load(null);
|
||||
IKey key = _keystore.GetKey(KeyName, null);
|
||||
Cipher cipher = Cipher.GetInstance(Transformation);
|
||||
|
||||
if (key == null || cipher == null)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_keystore.Load(null);
|
||||
var key = _keystore.GetKey(KeyName, null);
|
||||
var cipher = Cipher.GetInstance(Transformation);
|
||||
|
||||
if (key == null || cipher == null)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
cipher.Init(CipherMode.EncryptMode, key);
|
||||
}
|
||||
catch (KeyPermanentlyInvalidatedException e)
|
||||
@@ -75,6 +74,9 @@ namespace Bit.Droid.Services
|
||||
catch (InvalidKeyException e)
|
||||
{
|
||||
// Fallback for old bitwarden users without a key
|
||||
#if !FDROID
|
||||
Crashes.TrackError(e);
|
||||
#endif
|
||||
CreateKey();
|
||||
}
|
||||
|
||||
@@ -95,10 +97,13 @@ namespace Bit.Droid.Services
|
||||
keyGen.Init(keyGenSpec);
|
||||
keyGen.GenerateKey();
|
||||
}
|
||||
catch
|
||||
catch (Exception e)
|
||||
{
|
||||
// Catch silently to allow biometrics to function on devices that are in a state where key generation
|
||||
// is not functioning
|
||||
#if !FDROID
|
||||
Crashes.TrackError(e);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ namespace Bit.Droid.Services
|
||||
else
|
||||
{
|
||||
var data = new Intent();
|
||||
if (cipher == null)
|
||||
if (cipher?.Login == null)
|
||||
{
|
||||
data.PutExtra("canceled", "true");
|
||||
}
|
||||
@@ -734,6 +734,11 @@ namespace Bit.Droid.Services
|
||||
return Accessibility.AccessibilityHelpers.OverlayPermitted();
|
||||
}
|
||||
|
||||
public bool HasAutofillService()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OpenAccessibilityOverlayPermissionSettings()
|
||||
{
|
||||
var activity = (MainActivity)CrossCurrentActivity.Current.Activity;
|
||||
@@ -943,5 +948,10 @@ namespace Bit.Droid.Services
|
||||
var activity = CrossCurrentActivity.Current?.Activity as MainActivity;
|
||||
return activity?.Resources?.Configuration?.FontScale ?? 1;
|
||||
}
|
||||
|
||||
public async Task OnAccountSwitchCompleteAsync()
|
||||
{
|
||||
// for any Android-specific cleanup required after switching accounts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace Bit.App.Abstractions
|
||||
void Background();
|
||||
bool AutofillAccessibilityServiceRunning();
|
||||
bool AutofillAccessibilityOverlayPermitted();
|
||||
bool HasAutofillService();
|
||||
bool AutofillServiceEnabled();
|
||||
void DisableAutofillService();
|
||||
bool AutofillServicesEnabled();
|
||||
@@ -46,5 +47,6 @@ namespace Bit.App.Abstractions
|
||||
void CloseMainApp();
|
||||
bool SupportsFido2();
|
||||
float GetSystemFontSizeScale();
|
||||
Task OnAccountSwitchCompleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.4.0" />
|
||||
<PackageReference Include="Plugin.Fingerprint" Version="2.1.4" />
|
||||
<PackageReference Include="SkiaSharp.Views.Forms" Version="2.80.3" />
|
||||
<PackageReference Include="Xamarin.CommunityToolkit" Version="2.0.0" />
|
||||
<PackageReference Include="Xamarin.Essentials" Version="1.7.1" />
|
||||
<PackageReference Include="Xamarin.CommunityToolkit" Version="2.0.1" />
|
||||
<PackageReference Include="Xamarin.Essentials" Version="1.7.2" />
|
||||
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.11.982" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2337" />
|
||||
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2401" />
|
||||
<PackageReference Include="ZXing.Net.Mobile" Version="2.4.1" />
|
||||
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -73,8 +73,9 @@ namespace Bit.App
|
||||
}
|
||||
else if (message.Command == "locked")
|
||||
{
|
||||
var (userId, userInitiated) =
|
||||
message.Data as Tuple<string, bool> ?? new Tuple<string, bool>(null, false);
|
||||
var extras = message.Data as Tuple<string, bool>;
|
||||
var userId = extras?.Item1;
|
||||
var userInitiated = extras?.Item2 ?? false;
|
||||
Device.BeginInvokeOnMainThread(async () => await LockedAsync(userId, userInitiated));
|
||||
}
|
||||
else if (message.Command == "lockVault")
|
||||
@@ -83,8 +84,10 @@ namespace Bit.App
|
||||
}
|
||||
else if (message.Command == "logout")
|
||||
{
|
||||
var (userId, userInitiated, expired) =
|
||||
message.Data as Tuple<string, bool, bool> ?? new Tuple<string, bool, bool>(null, true, false);
|
||||
var extras = message.Data as Tuple<string, bool, bool>;
|
||||
var userId = extras?.Item1;
|
||||
var userInitiated = extras?.Item2 ?? true;
|
||||
var expired = extras?.Item3 ?? false;
|
||||
Device.BeginInvokeOnMainThread(async () => await LogOutAsync(userId, userInitiated, expired));
|
||||
}
|
||||
else if (message.Command == "loggedOut")
|
||||
@@ -425,7 +428,7 @@ namespace Bit.App
|
||||
});
|
||||
}
|
||||
|
||||
private async Task LockedAsync(string userId, bool autoPromptBiometric)
|
||||
private async Task LockedAsync(string userId, bool userInitiated)
|
||||
{
|
||||
if (!await _stateService.IsActiveAccountAsync(userId))
|
||||
{
|
||||
@@ -433,6 +436,7 @@ namespace Bit.App
|
||||
return;
|
||||
}
|
||||
|
||||
var autoPromptBiometric = !userInitiated;
|
||||
if (autoPromptBiometric && Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
var vaultTimeout = await _stateService.GetVaultTimeoutAsync();
|
||||
|
||||
@@ -59,26 +59,26 @@
|
||||
Grid.Row="0"
|
||||
Text="{Binding AccountView.Email}"
|
||||
IsVisible="{Binding IsActive}"
|
||||
StyleClass="list-title"
|
||||
StyleClass="accountlist-title, accountlist-title-platform"
|
||||
LineBreakMode="TailTruncation" />
|
||||
<Label
|
||||
Grid.Row="0"
|
||||
Text="{Binding AccountView.Email}"
|
||||
IsVisible="{Binding IsActive, Converter={StaticResource inverseBool}}"
|
||||
StyleClass="list-title"
|
||||
StyleClass="accountlist-title, accountlist-title-platform"
|
||||
TextColor="{DynamicResource MutedColor}"
|
||||
LineBreakMode="TailTruncation" />
|
||||
<Label
|
||||
Grid.Row="1"
|
||||
IsVisible="{Binding ShowHostname}"
|
||||
Text="{Binding AccountView.Hostname}"
|
||||
StyleClass="list-sub"
|
||||
StyleClass="accountlist-sub, accountlist-sub-platform"
|
||||
LineBreakMode="TailTruncation" />
|
||||
<Label
|
||||
Grid.Row="2"
|
||||
Text="{u:I18n AccountUnlocked}"
|
||||
IsVisible="{Binding IsUnlockedAndNotActive}"
|
||||
StyleClass="list-sub"
|
||||
StyleClass="accountlist-sub, accountlist-sub-platform"
|
||||
FontAttributes="Italic"
|
||||
TextTransform="Lowercase"
|
||||
LineBreakMode="TailTruncation" />
|
||||
@@ -86,7 +86,7 @@
|
||||
Grid.Row="2"
|
||||
Text="{u:I18n AccountLocked}"
|
||||
IsVisible="{Binding IsLockedAndNotActive}"
|
||||
StyleClass="list-sub"
|
||||
StyleClass="accountlist-sub, accountlist-sub-platform"
|
||||
FontAttributes="Italic"
|
||||
TextTransform="Lowercase"
|
||||
LineBreakMode="TailTruncation" />
|
||||
@@ -94,7 +94,7 @@
|
||||
Grid.Row="2"
|
||||
Text="{u:I18n AccountLoggedOut}"
|
||||
IsVisible="{Binding IsLoggedOutAndNotActive}"
|
||||
StyleClass="list-sub"
|
||||
StyleClass="accountlist-sub, accountlist-sub-platform"
|
||||
FontAttributes="Italic"
|
||||
TextTransform="Lowercase"
|
||||
LineBreakMode="TailTruncation" />
|
||||
@@ -144,7 +144,7 @@
|
||||
AutomationProperties.IsInAccessibleTree="False" />
|
||||
<Label
|
||||
Text="{u:I18n AddAccount}"
|
||||
StyleClass="list-title"
|
||||
StyleClass="accountlist-title, accountlist-title-platform"
|
||||
LineBreakMode="TailTruncation"
|
||||
VerticalOptions="Center"
|
||||
Grid.Column="1" />
|
||||
|
||||
@@ -62,6 +62,10 @@ namespace Bit.App.Controls
|
||||
upperData = _data.ToUpper();
|
||||
chars = GetFirstLetters(upperData, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
chars = upperData = _data.ToUpper();
|
||||
}
|
||||
|
||||
var bgColor = StringToColor(upperData);
|
||||
var textColor = Color.White;
|
||||
@@ -122,7 +126,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
return data.Substring(0, 2);
|
||||
}
|
||||
return null;
|
||||
return data;
|
||||
}
|
||||
|
||||
private Color StringToColor(string str)
|
||||
|
||||
@@ -41,8 +41,11 @@ namespace Bit.App.Pages
|
||||
public async Task InitAsync()
|
||||
{
|
||||
var history = await _passwordGenerationService.GetHistoryAsync();
|
||||
History.ResetWithRange(history ?? new List<GeneratedPasswordHistory>());
|
||||
ShowNoData = History.Count == 0;
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
History.ResetWithRange(history ?? new List<GeneratedPasswordHistory>());
|
||||
ShowNoData = History.Count == 0;
|
||||
});
|
||||
}
|
||||
|
||||
public async Task ClearAsync()
|
||||
|
||||
@@ -256,23 +256,24 @@
|
||||
x:Name="_btnOptions"
|
||||
StyleClass="box-row-button"
|
||||
TextColor="{DynamicResource PrimaryColor}"
|
||||
Margin="0" />
|
||||
Margin="0"
|
||||
Clicked="ToggleOptions_Clicked"/>
|
||||
<controls:IconButton
|
||||
x:Name="_btnOptionsUp"
|
||||
Text="{Binding Source={x:Static core:BitwardenIcons.ChevronUp}}"
|
||||
StyleClass="box-row-button"
|
||||
TextColor="{DynamicResource PrimaryColor}"
|
||||
Clicked="ToggleOptions_Clicked"
|
||||
IsVisible="False" />
|
||||
IsVisible="{Binding ShowOptions}" />
|
||||
<controls:IconButton
|
||||
x:Name="_btnOptionsDown"
|
||||
Text="{Binding Source={x:Static core:BitwardenIcons.AngleDown}}"
|
||||
StyleClass="box-row-button"
|
||||
TextColor="{DynamicResource PrimaryColor}"
|
||||
Clicked="ToggleOptions_Clicked"
|
||||
IsVisible="False" />
|
||||
IsVisible="{Binding ShowOptions, Converter={StaticResource inverseBool}}" />
|
||||
</StackLayout>
|
||||
<StackLayout IsVisible="True">
|
||||
<StackLayout IsVisible="{Binding ShowOptions}">
|
||||
<StackLayout
|
||||
StyleClass="box-row"
|
||||
Margin="0,10,0,0">
|
||||
|
||||
@@ -53,10 +53,9 @@ namespace Bit.App.Pages
|
||||
_vm.SegmentedButtonFontSize = 13;
|
||||
_vm.SegmentedButtonMargins = new Thickness(0, 10, 0, 0);
|
||||
_vm.EditorMargins = new Thickness(0, 5, 0, 0);
|
||||
// Review this when https://github.com/bitwarden/mobile/pull/1454 workaround can be reverted
|
||||
//_btnOptions.WidthRequest = 70;
|
||||
//_btnOptionsDown.WidthRequest = 30;
|
||||
//_btnOptionsUp.WidthRequest = 30;
|
||||
_btnOptions.WidthRequest = 70;
|
||||
_btnOptionsDown.WidthRequest = 30;
|
||||
_btnOptionsUp.WidthRequest = 30;
|
||||
}
|
||||
else if (Device.RuntimePlatform == Device.iOS)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public interface ISendGroupingsPageListItem
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,29 @@
|
||||
</controls:ExtendedStackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate
|
||||
x:Key="headerTemplate"
|
||||
x:DataType="pages:SendGroupingsPageHeaderListItem">
|
||||
<StackLayout
|
||||
Spacing="0" Padding="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Title}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<pages:SendGroupingsPageListItemSelector x:Key="sendListItemDataTemplateSelector"
|
||||
HeaderTemplate="{StaticResource headerTemplate}"
|
||||
SendTemplate="{StaticResource sendTemplate}"
|
||||
GroupTemplate="{StaticResource sendGroupTemplate}" />
|
||||
|
||||
@@ -114,33 +136,9 @@
|
||||
ItemsSource="{Binding GroupedSends}"
|
||||
VerticalOptions="FillAndExpand"
|
||||
ItemTemplate="{StaticResource sendListItemDataTemplateSelector}"
|
||||
IsGrouped="True"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="RowSelected"
|
||||
StyleClass="list, list-platform">
|
||||
|
||||
<CollectionView.GroupHeaderTemplate>
|
||||
<DataTemplate x:DataType="pages:SendGroupingsPageListGroup">
|
||||
<StackLayout
|
||||
Spacing="0" Padding="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform"
|
||||
IsVisible="{Binding First, Converter={StaticResource inverseBool}}" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Name}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
</CollectionView.GroupHeaderTemplate>
|
||||
</controls:ExtendedCollectionView>
|
||||
StyleClass="list, list-platform" />
|
||||
</RefreshView>
|
||||
</StackLayout>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SendGroupingsPageHeaderListItem : ISendGroupingsPageListItem
|
||||
{
|
||||
public SendGroupingsPageHeaderListItem(string title, string itemCount)
|
||||
{
|
||||
Title = title;
|
||||
ItemCount = itemCount;
|
||||
}
|
||||
|
||||
public string Title { get; }
|
||||
public string ItemCount { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Bit.Core.Models.View;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SendGroupingsPageListItem
|
||||
public class SendGroupingsPageListItem : ISendGroupingsPageListItem
|
||||
{
|
||||
private string _icon;
|
||||
private string _name;
|
||||
|
||||
@@ -4,11 +4,17 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public class SendGroupingsPageListItemSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate HeaderTemplate { get; set; }
|
||||
public DataTemplate SendTemplate { get; set; }
|
||||
public DataTemplate GroupTemplate { get; set; }
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
if (item is SendGroupingsPageHeaderListItem)
|
||||
{
|
||||
return HeaderTemplate;
|
||||
}
|
||||
|
||||
if (item is SendGroupingsPageListItem listItem)
|
||||
{
|
||||
return listItem.Send != null ? SendTemplate : GroupTemplate;
|
||||
|
||||
@@ -10,6 +10,7 @@ using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using DeviceType = Bit.Core.Enums.DeviceType;
|
||||
@@ -48,7 +49,7 @@ namespace Bit.App.Pages
|
||||
|
||||
Loading = true;
|
||||
PageTitle = AppResources.Send;
|
||||
GroupedSends = new ExtendedObservableCollection<SendGroupingsPageListGroup>();
|
||||
GroupedSends = new ObservableRangeCollection<ISendGroupingsPageListItem>();
|
||||
RefreshCommand = new Command(async () =>
|
||||
{
|
||||
Refreshing = true;
|
||||
@@ -103,7 +104,7 @@ namespace Bit.App.Pages
|
||||
get => _showList;
|
||||
set => SetProperty(ref _showList, value);
|
||||
}
|
||||
public ExtendedObservableCollection<SendGroupingsPageListGroup> GroupedSends { get; set; }
|
||||
public ObservableRangeCollection<ISendGroupingsPageListItem> GroupedSends { get; set; }
|
||||
public Command RefreshCommand { get; set; }
|
||||
public Command<SendView> SendOptionsCommand { get; set; }
|
||||
public bool LoadedOnce { get; set; }
|
||||
@@ -175,7 +176,49 @@ namespace Bit.App.Pages
|
||||
MainPage ? AppResources.AllSends : AppResources.Sends, sendsListItems.Count,
|
||||
uppercaseGroupNames, !MainPage));
|
||||
}
|
||||
GroupedSends.ResetWithRange(groupedSends);
|
||||
|
||||
// TODO: refactor this
|
||||
if (Device.RuntimePlatform == Device.Android
|
||||
||
|
||||
GroupedSends.Any())
|
||||
{
|
||||
var items = new List<ISendGroupingsPageListItem>();
|
||||
foreach (var itemGroup in groupedSends)
|
||||
{
|
||||
items.Add(new SendGroupingsPageHeaderListItem(itemGroup.Name, itemGroup.ItemCount));
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
GroupedSends.ReplaceRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: we need this on iOS, so that it doesn't crash when adding coming from an empty list
|
||||
var first = true;
|
||||
var items = new List<ISendGroupingsPageListItem>();
|
||||
foreach (var itemGroup in groupedSends)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
items.Add(new SendGroupingsPageHeaderListItem(itemGroup.Name, itemGroup.ItemCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
if (groupedSends.Any())
|
||||
{
|
||||
GroupedSends.ReplaceRange(new List<ISendGroupingsPageListItem> { new SendGroupingsPageHeaderListItem(groupedSends[0].Name, groupedSends[0].ItemCount) });
|
||||
GroupedSends.AddRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
GroupedSends.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -192,7 +192,8 @@ namespace Bit.App.Pages
|
||||
|
||||
public void UpdateEnabled()
|
||||
{
|
||||
AutofillServiceToggled = _deviceActionService.AutofillServiceEnabled();
|
||||
AutofillServiceToggled =
|
||||
_deviceActionService.HasAutofillService() && _deviceActionService.AutofillServiceEnabled();
|
||||
AccessibilityToggled = _deviceActionService.AutofillAccessibilityServiceRunning();
|
||||
DrawOverToggled = _deviceActionService.AutofillAccessibilityOverlayPermitted();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public interface ISettingsPageListItem
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -82,8 +82,26 @@
|
||||
</controls:ExtendedStackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate
|
||||
x:Key="headerTemplate"
|
||||
x:DataType="pages:SettingsPageHeaderListItem">
|
||||
<StackLayout
|
||||
Padding="0" Spacing="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Title}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
</StackLayout>
|
||||
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<pages:SettingsPageListItemSelector
|
||||
x:Key="listItemDataTemplateSelector"
|
||||
HeaderTemplate="{StaticResource headerTemplate}"
|
||||
RegularTemplate="{StaticResource regularTemplate}"
|
||||
TimePickerTemplate="{StaticResource timePickerTemplate}" />
|
||||
</ResourceDictionary>
|
||||
@@ -93,28 +111,8 @@
|
||||
ItemsSource="{Binding GroupedItems}"
|
||||
VerticalOptions="FillAndExpand"
|
||||
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
|
||||
IsGrouped="True"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="RowSelected"
|
||||
StyleClass="list, list-platform">
|
||||
|
||||
<CollectionView.GroupHeaderTemplate>
|
||||
<DataTemplate x:DataType="pages:SettingsPageListGroup">
|
||||
<StackLayout
|
||||
Padding="0" Spacing="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform"
|
||||
IsVisible="{Binding First, Converter={StaticResource inverseBool}}" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Name}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
</StackLayout>
|
||||
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
</CollectionView.GroupHeaderTemplate>
|
||||
</controls:ExtendedCollectionView>
|
||||
StyleClass="list, list-platform" />
|
||||
|
||||
</pages:BaseContentPage>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsPageHeaderListItem : ISettingsPageListItem
|
||||
{
|
||||
public SettingsPageHeaderListItem(string title)
|
||||
{
|
||||
Title = title;
|
||||
}
|
||||
|
||||
public string Title { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
using System;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsPageListItem
|
||||
public class SettingsPageListItem : ISettingsPageListItem
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
@@ -4,21 +4,19 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public class SettingsPageListItemSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate HeaderTemplate { get; set; }
|
||||
public DataTemplate RegularTemplate { get; set; }
|
||||
public DataTemplate TimePickerTemplate { get; set; }
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
if (item is SettingsPageHeaderListItem)
|
||||
{
|
||||
return HeaderTemplate;
|
||||
}
|
||||
if (item is SettingsPageListItem listItem)
|
||||
{
|
||||
if (listItem.ShowTimeInput)
|
||||
{
|
||||
return TimePickerTemplate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return RegularTemplate;
|
||||
}
|
||||
return listItem.ShowTimeInput ? TimePickerTemplate : RegularTemplate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Xamarin.Forms;
|
||||
using ZXing.Client.Result;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
@@ -79,11 +80,11 @@ namespace Bit.App.Pages
|
||||
_keyConnectorService = ServiceContainer.Resolve<IKeyConnectorService>("keyConnectorService");
|
||||
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
|
||||
|
||||
GroupedItems = new ExtendedObservableCollection<SettingsPageListGroup>();
|
||||
GroupedItems = new ObservableRangeCollection<ISettingsPageListItem>();
|
||||
PageTitle = AppResources.Settings;
|
||||
}
|
||||
|
||||
public ExtendedObservableCollection<SettingsPageListGroup> GroupedItems { get; set; }
|
||||
public ObservableRangeCollection<ISettingsPageListItem> GroupedItems { get; set; }
|
||||
|
||||
public async Task InitAsync()
|
||||
{
|
||||
@@ -501,7 +502,9 @@ namespace Bit.App.Pages
|
||||
new SettingsPageListItem { Name = AppResources.RateTheApp },
|
||||
new SettingsPageListItem { Name = AppResources.DeleteAccount }
|
||||
};
|
||||
GroupedItems.ResetWithRange(new List<SettingsPageListGroup>
|
||||
|
||||
// TODO: improve this. Leaving this as is to reduce error possibility on the hotfix.
|
||||
var settingsListGroupItems = new List<SettingsPageListGroup>()
|
||||
{
|
||||
new SettingsPageListGroup(autofillItems, AppResources.Autofill, doUpper, true),
|
||||
new SettingsPageListGroup(manageItems, AppResources.Manage, doUpper),
|
||||
@@ -509,7 +512,50 @@ namespace Bit.App.Pages
|
||||
new SettingsPageListGroup(accountItems, AppResources.Account, doUpper),
|
||||
new SettingsPageListGroup(toolsItems, AppResources.Tools, doUpper),
|
||||
new SettingsPageListGroup(otherItems, AppResources.Other, doUpper)
|
||||
});
|
||||
};
|
||||
|
||||
// TODO: refactor this
|
||||
if (Device.RuntimePlatform == Device.Android
|
||||
||
|
||||
GroupedItems.Any())
|
||||
{
|
||||
var items = new List<ISettingsPageListItem>();
|
||||
foreach (var itemGroup in settingsListGroupItems)
|
||||
{
|
||||
items.Add(new SettingsPageHeaderListItem(itemGroup.Name));
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
GroupedItems.ReplaceRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: we need this on iOS, so that it doesn't crash when adding coming from an empty list
|
||||
var first = true;
|
||||
var items = new List<ISettingsPageListItem>();
|
||||
foreach (var itemGroup in settingsListGroupItems)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
items.Add(new SettingsPageHeaderListItem(itemGroup.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
if (settingsListGroupItems.Any())
|
||||
{
|
||||
GroupedItems.ReplaceRange(new List<ISettingsPageListItem> { new SettingsPageHeaderListItem(settingsListGroupItems[0].Name) });
|
||||
GroupedItems.AddRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
GroupedItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IncludeLinksWithSubscriptionInfo()
|
||||
|
||||
@@ -732,7 +732,6 @@
|
||||
<BoxView StyleClass="box-row-separator" />
|
||||
</StackLayout>
|
||||
<controls:RepeaterView
|
||||
x:Name="_collectionsRepeaterView"
|
||||
ItemsSource="{Binding Collections}"
|
||||
IsVisible="{Binding HasCollections}">
|
||||
<controls:RepeaterView.ItemTemplate>
|
||||
|
||||
@@ -51,7 +51,6 @@ namespace Bit.App.Pages
|
||||
_vm.CipherId = cipherId;
|
||||
_vm.FolderId = folderId == "none" ? null : folderId;
|
||||
_vm.CollectionIds = collectionId != null ? new HashSet<string>(new List<string> { collectionId }) : null;
|
||||
_vm.CollectionsRepeaterView = _collectionsRepeaterView;
|
||||
_vm.Type = type;
|
||||
_vm.DefaultName = name ?? appOptions?.SaveName;
|
||||
_vm.DefaultUri = uri ?? appOptions?.Uri;
|
||||
@@ -171,7 +170,6 @@ namespace Bit.App.Pages
|
||||
{
|
||||
RequestFocus(_nameEntry);
|
||||
}
|
||||
_scrollView.Scrolled += (sender, args) => _vm.HandleScroll();
|
||||
});
|
||||
// Hide password reprompt option if using key connector
|
||||
_passwordPrompt.IsVisible = !await _keyConnectorService.GetUsesKeyConnector();
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Models;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core;
|
||||
@@ -44,7 +43,6 @@ namespace Bit.App.Pages
|
||||
private int _ownershipSelectedIndex;
|
||||
private bool _hasCollections;
|
||||
private string _previousCipherId;
|
||||
private DateTime _lastHandledScrollTime;
|
||||
private List<Core.Models.View.CollectionView> _writeableCollections;
|
||||
private string[] _additionalCipherProperties = new string[]
|
||||
{
|
||||
@@ -168,7 +166,7 @@ namespace Bit.App.Pages
|
||||
public ExtendedObservableCollection<LoginUriView> Uris { get; set; }
|
||||
public ExtendedObservableCollection<AddEditPageFieldViewModel> Fields { get; set; }
|
||||
public ExtendedObservableCollection<CollectionViewModel> Collections { get; set; }
|
||||
public RepeaterView CollectionsRepeaterView { get; set; }
|
||||
|
||||
public int TypeSelectedIndex
|
||||
{
|
||||
get => _typeSelectedIndex;
|
||||
@@ -821,30 +819,13 @@ namespace Bit.App.Pages
|
||||
{
|
||||
var cols = _writeableCollections.Where(c => c.OrganizationId == Cipher.OrganizationId)
|
||||
.Select(c => new CollectionViewModel { Collection = c }).ToList();
|
||||
HasCollections = cols.Any();
|
||||
Collections.ResetWithRange(cols);
|
||||
Collections = new ExtendedObservableCollection<CollectionViewModel>(cols);
|
||||
}
|
||||
else
|
||||
{
|
||||
HasCollections = false;
|
||||
Collections.ResetWithRange(new List<CollectionViewModel>());
|
||||
Collections = new ExtendedObservableCollection<CollectionViewModel>(new List<CollectionViewModel>());
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleScroll()
|
||||
{
|
||||
// workaround for https://github.com/xamarin/Xamarin.Forms/issues/13607
|
||||
// required for org ownership/collections to render properly in XF4.5+
|
||||
if (!HasCollections ||
|
||||
EditMode ||
|
||||
(DateTime.Now - _lastHandledScrollTime < TimeSpan.FromMilliseconds(200)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
CollectionsRepeaterView.ItemsSource = Collections;
|
||||
_lastHandledScrollTime = DateTime.Now;
|
||||
HasCollections = Collections.Any();
|
||||
}
|
||||
|
||||
private void TriggerCipherChanged()
|
||||
|
||||
@@ -29,8 +29,28 @@
|
||||
ButtonCommand="{Binding BindingContext.CipherOptionsCommand, Source={x:Reference _page}}"
|
||||
WebsiteIconsEnabled="{Binding BindingContext.WebsiteIconsEnabled, Source={x:Reference _page}}" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate
|
||||
x:Key="headerTemplate"
|
||||
x:DataType="pages:GroupingsPageHeaderListItem">
|
||||
<StackLayout
|
||||
Spacing="0" Padding="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Title}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<pages:GroupingsPageListItemSelector x:Key="listItemDataTemplateSelector"
|
||||
HeaderTemplate="{StaticResource headerTemplate}"
|
||||
CipherTemplate="{StaticResource cipherTemplate}" />
|
||||
|
||||
<StackLayout x:Key="mainLayout" x:Name="_mainLayout">
|
||||
@@ -52,30 +72,9 @@
|
||||
ItemsSource="{Binding GroupedItems}"
|
||||
VerticalOptions="FillAndExpand"
|
||||
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
|
||||
IsGrouped="True"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="RowSelected"
|
||||
StyleClass="list, list-platform">
|
||||
|
||||
<CollectionView.GroupHeaderTemplate>
|
||||
<DataTemplate x:DataType="pages:GroupingsPageListGroup">
|
||||
<StackLayout
|
||||
Spacing="0" Padding="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Name}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
</CollectionView.GroupHeaderTemplate>
|
||||
</controls:ExtendedCollectionView>
|
||||
StyleClass="list, list-platform" />
|
||||
</StackLayout>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
@@ -11,6 +11,7 @@ using Bit.Core.Utilities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -36,14 +37,14 @@ namespace Bit.App.Pages
|
||||
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
|
||||
|
||||
GroupedItems = new ExtendedObservableCollection<GroupingsPageListGroup>();
|
||||
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
|
||||
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public Command CipherOptionsCommand { get; set; }
|
||||
public ExtendedObservableCollection<GroupingsPageListGroup> GroupedItems { get; set; }
|
||||
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { get; set; }
|
||||
|
||||
public bool ShowList
|
||||
{
|
||||
@@ -65,9 +66,9 @@ namespace Bit.App.Pages
|
||||
public void Init(AppOptions appOptions)
|
||||
{
|
||||
_appOptions = appOptions;
|
||||
Uri = appOptions.Uri;
|
||||
Uri = appOptions?.Uri;
|
||||
string name = null;
|
||||
if (Uri.StartsWith(Constants.AndroidAppProtocol))
|
||||
if (Uri?.StartsWith(Constants.AndroidAppProtocol) ?? false)
|
||||
{
|
||||
name = Uri.Substring(Constants.AndroidAppProtocol.Length);
|
||||
}
|
||||
@@ -105,7 +106,49 @@ namespace Bit.App.Pages
|
||||
new GroupingsPageListGroup(fuzzy, AppResources.PossibleMatchingItems, fuzzy.Count, false,
|
||||
!hasMatching));
|
||||
}
|
||||
GroupedItems.ResetWithRange(groupedItems);
|
||||
|
||||
// TODO: refactor this
|
||||
if (Device.RuntimePlatform == Device.Android
|
||||
||
|
||||
GroupedItems.Any())
|
||||
{
|
||||
var items = new List<IGroupingsPageListItem>();
|
||||
foreach (var itemGroup in groupedItems)
|
||||
{
|
||||
items.Add(new GroupingsPageHeaderListItem(itemGroup.Name, itemGroup.ItemCount));
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
GroupedItems.ReplaceRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: we need this on iOS, so that it doesn't crash when adding coming from an empty list
|
||||
var first = true;
|
||||
var items = new List<IGroupingsPageListItem>();
|
||||
foreach (var itemGroup in groupedItems)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
items.Add(new GroupingsPageHeaderListItem(itemGroup.Name, itemGroup.ItemCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
if (groupedItems.Any())
|
||||
{
|
||||
GroupedItems.ReplaceRange(new List<IGroupingsPageListItem> { new GroupingsPageHeaderListItem(groupedItems[0].Name, groupedItems[0].ItemCount) });
|
||||
GroupedItems.AddRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
GroupedItems.Clear();
|
||||
}
|
||||
}
|
||||
ShowList = groupedItems.Any();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,30 +55,53 @@
|
||||
<DataTemplate x:Key="groupTemplate"
|
||||
x:DataType="pages:GroupingsPageListItem">
|
||||
<controls:ExtendedStackLayout Orientation="Horizontal"
|
||||
StyleClass="list-row, list-row-platform">
|
||||
StyleClass="list-row, list-row-platform">
|
||||
<controls:IconLabel Text="{Binding Icon, Mode=OneWay}"
|
||||
HorizontalOptions="Start"
|
||||
VerticalOptions="Center"
|
||||
StyleClass="list-icon, list-icon-platform"
|
||||
ShouldUpdateFontSizeDynamicallyForAccesibility="True">
|
||||
HorizontalOptions="Start"
|
||||
VerticalOptions="Center"
|
||||
StyleClass="list-icon, list-icon-platform"
|
||||
ShouldUpdateFontSizeDynamicallyForAccesibility="True">
|
||||
<controls:IconLabel.Effects>
|
||||
<effects:FixedSizeEffect />
|
||||
</controls:IconLabel.Effects>
|
||||
</controls:IconLabel>
|
||||
<Label Text="{Binding Name, Mode=OneWay}"
|
||||
LineBreakMode="TailTruncation"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
StyleClass="list-title"/>
|
||||
LineBreakMode="TailTruncation"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
StyleClass="list-title"/>
|
||||
<Label Text="{Binding ItemCount, Mode=OneWay}"
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalTextAlignment="End"
|
||||
StyleClass="list-sub"/>
|
||||
HorizontalOptions="End"
|
||||
VerticalOptions="CenterAndExpand"
|
||||
HorizontalTextAlignment="End"
|
||||
StyleClass="list-sub"/>
|
||||
</controls:ExtendedStackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate
|
||||
x:Key="headerTemplate"
|
||||
x:DataType="pages:GroupingsPageHeaderListItem">
|
||||
<StackLayout
|
||||
Spacing="0"
|
||||
Padding="0"
|
||||
VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Title}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
|
||||
<pages:GroupingsPageListItemSelector x:Key="listItemDataTemplateSelector"
|
||||
HeaderTemplate="{StaticResource headerTemplate}"
|
||||
CipherTemplate="{StaticResource cipherTemplate}"
|
||||
GroupTemplate="{StaticResource groupTemplate}" />
|
||||
|
||||
@@ -105,32 +128,9 @@
|
||||
ItemsSource="{Binding GroupedItems}"
|
||||
VerticalOptions="FillAndExpand"
|
||||
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
|
||||
IsGrouped="True"
|
||||
SelectionMode="Single"
|
||||
SelectionChanged="RowSelected"
|
||||
StyleClass="list, list-platform">
|
||||
|
||||
<CollectionView.GroupHeaderTemplate>
|
||||
<DataTemplate x:DataType="pages:GroupingsPageListGroup">
|
||||
<StackLayout
|
||||
Spacing="0" Padding="0" VerticalOptions="FillAndExpand"
|
||||
StyleClass="list-row-header-container, list-row-header-container-platform">
|
||||
<BoxView
|
||||
StyleClass="list-section-separator-top, list-section-separator-top-platform"
|
||||
IsVisible="{Binding First, Converter={StaticResource inverseBool}}" />
|
||||
<StackLayout StyleClass="list-row-header, list-row-header-platform">
|
||||
<Label
|
||||
Text="{Binding Name}"
|
||||
StyleClass="list-header, list-header-platform" />
|
||||
<Label
|
||||
Text="{Binding ItemCount}"
|
||||
StyleClass="list-header-sub" />
|
||||
</StackLayout>
|
||||
<BoxView StyleClass="list-section-separator-bottom, list-section-separator-bottom-platform" />
|
||||
</StackLayout>
|
||||
</DataTemplate>
|
||||
</CollectionView.GroupHeaderTemplate>
|
||||
</controls:ExtendedCollectionView>
|
||||
StyleClass="list, list-platform" />
|
||||
</RefreshView>
|
||||
</StackLayout>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class GroupingsPageHeaderListItem : IGroupingsPageListItem
|
||||
{
|
||||
public GroupingsPageHeaderListItem(string title, string itemCount)
|
||||
{
|
||||
Title = title;
|
||||
ItemCount = itemCount;
|
||||
}
|
||||
|
||||
public string Title { get; }
|
||||
public string ItemCount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Bit.Core.Models.View;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class GroupingsPageListItem
|
||||
public class GroupingsPageListItem : IGroupingsPageListItem
|
||||
{
|
||||
private string _icon;
|
||||
private string _name;
|
||||
|
||||
@@ -4,11 +4,17 @@ namespace Bit.App.Pages
|
||||
{
|
||||
public class GroupingsPageListItemSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate HeaderTemplate { get; set; }
|
||||
public DataTemplate CipherTemplate { get; set; }
|
||||
public DataTemplate GroupTemplate { get; set; }
|
||||
|
||||
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
|
||||
{
|
||||
if (item is GroupingsPageHeaderListItem)
|
||||
{
|
||||
return HeaderTemplate;
|
||||
}
|
||||
|
||||
if (item is GroupingsPageListItem listItem)
|
||||
{
|
||||
return listItem.Cipher != null ? CipherTemplate : GroupTemplate;
|
||||
|
||||
@@ -11,6 +11,7 @@ using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.CommunityToolkit.ObjectModel;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
@@ -63,7 +64,7 @@ namespace Bit.App.Pages
|
||||
|
||||
Loading = true;
|
||||
PageTitle = AppResources.MyVault;
|
||||
GroupedItems = new ExtendedObservableCollection<GroupingsPageListGroup>();
|
||||
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
|
||||
RefreshCommand = new Command(async () =>
|
||||
{
|
||||
Refreshing = true;
|
||||
@@ -144,7 +145,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
|
||||
|
||||
public ExtendedObservableCollection<GroupingsPageListGroup> GroupedItems { get; set; }
|
||||
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { get; set; }
|
||||
public Command RefreshCommand { get; set; }
|
||||
public Command<CipherView> CipherOptionsCommand { get; set; }
|
||||
public bool LoadedOnce { get; set; }
|
||||
@@ -275,12 +276,54 @@ namespace Bit.App.Pages
|
||||
{
|
||||
new GroupingsPageListItem()
|
||||
{
|
||||
IsTrash = true,
|
||||
IsTrash = true,
|
||||
ItemCount = _deletedCount.ToString("N0")
|
||||
}
|
||||
}, AppResources.Trash, _deletedCount, uppercaseGroupNames, false));
|
||||
}
|
||||
GroupedItems.ResetWithRange(groupedItems);
|
||||
|
||||
// TODO: refactor this
|
||||
if (Device.RuntimePlatform == Device.Android
|
||||
||
|
||||
GroupedItems.Any())
|
||||
{
|
||||
var items = new List<IGroupingsPageListItem>();
|
||||
foreach (var itemGroup in groupedItems)
|
||||
{
|
||||
items.Add(new GroupingsPageHeaderListItem(itemGroup.Name, itemGroup.ItemCount));
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
GroupedItems.ReplaceRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
// HACK: we need this on iOS, so that it doesn't crash when adding coming from an empty list
|
||||
var first = true;
|
||||
var items = new List<IGroupingsPageListItem>();
|
||||
foreach (var itemGroup in groupedItems)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
items.Add(new GroupingsPageHeaderListItem(itemGroup.Name, itemGroup.ItemCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
first = false;
|
||||
}
|
||||
items.AddRange(itemGroup);
|
||||
}
|
||||
|
||||
if (groupedItems.Any())
|
||||
{
|
||||
GroupedItems.ReplaceRange(new List<IGroupingsPageListItem> { new GroupingsPageHeaderListItem(groupedItems[0].Name, groupedItems[0].ItemCount) });
|
||||
GroupedItems.AddRange(items);
|
||||
}
|
||||
else
|
||||
{
|
||||
GroupedItems.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public interface IGroupingsPageListItem
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Skrap rekening</value>
|
||||
</data>
|
||||
|
||||
@@ -276,16 +276,16 @@
|
||||
<value>Çıxış etmək istədiyinizə əminsiniz?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Hesabı sil</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
<value>Bu istifadəçini silmək istədiyinizə əminsiniz?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Hesab artıq əlavə edildi</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
<value>Buna indi keçmək istəyirsiniz?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Ana parol</value>
|
||||
@@ -2105,19 +2105,28 @@
|
||||
<value>Bir və ya daha çox təşkilat siyasəti, fərdi anbarınızı ixrac etməyinizin qarşısını alır.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Hesab əlavə et</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
<value>Kilidi açıldı</value>
|
||||
</data>
|
||||
<data name="AccountLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
<value>Kilidli</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Çıxış edildi</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
<value>Növbəti mövcud hesaba keçildi</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Hesab kilidlidir</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Hesabdan uğurla çıxış edildi</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Hesab uğurla silindi</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Hesabı sil</value>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Превключено към следващата налична регистрация</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Регистрацията е заключена</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Отписването от регистрацията беше успешно</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Регистрацията беше премахната успешно</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Изтриване на регистрацията</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Prebačeni ste na sljedeći dostupan račun </value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Račun zaključan </value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Uspješno odjavljeni sa računa </value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Račun je uspješno uklonjen</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Obriši račun</value>
|
||||
</data>
|
||||
|
||||
@@ -276,16 +276,16 @@
|
||||
<value>Segur que voleu tancar la sessió?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Suprimeix el compte</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
<value>Voleu suprimir el compte?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>El compte ja s'ha afegit</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
<value>T'agradaria canviar-lo ara?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Contrasenya mestra</value>
|
||||
@@ -2105,19 +2105,28 @@
|
||||
<value>Una o més polítiques d'organització us impedeixen exportar la vostra caixa forta.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Afig compte</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
<value>Desbloquejat</value>
|
||||
</data>
|
||||
<data name="AccountLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
<value>Bloquejat</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Sessió tancada</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
<value>S'ha canviat al següent compte disponible</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Compte bloquejat</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>El compte s'ha tancat correctament</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>El compte s'ha suprimit correctament</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Suprimeix el compte</value>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Přepnuto na další dostupný účet</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Odstranit účet</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Skiftede til næste tilgængelige konto</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Konto låst</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Konto logget ud</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Konto fjernet</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Slet konto</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Gehe in die iOS Einstellungen</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Drücke "Passwörter & Accounts"</value>
|
||||
<value>2. Tippe auf "Passwörter"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tippe auf "Automatisch ausfüllen"</value>
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Zum nächsten verfügbaren Konto gewechselt</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Konto gesperrt</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Konto erfolgreich abgemeldet</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Konto erfolgreich gelöscht</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Konto löschen</value>
|
||||
</data>
|
||||
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Μετάβαση στον επόμενο διαθέσιμο λογαριασμό</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Διαγραφή Λογαριασμού</value>
|
||||
</data>
|
||||
|
||||
@@ -2132,6 +2132,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Cambiado a la siguiente cuenta disponible</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Eliminar cuenta</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Vahetati järgmise saadaoleva konto peale</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Kasutajakonto on lukus</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Konto on edukalt välja logitud</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Konto on edukalt eemaldatud</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Kustuta konto</value>
|
||||
</data>
|
||||
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>به حساب بعدی موجود تغییر کرد</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>حساب قفل شده است</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>حساب کاربری با موفقیت خارج شد</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>حساب کاربری با موفقیت حذف شد</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>حذف حساب</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Siirry iOS:n "Asetukset" -sovellukseen</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Napauta "Salasanat ja tilit"</value>
|
||||
<value>2. Napauta "Salasanat"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Napauta "Täytä salasanat automaattisesti"</value>
|
||||
@@ -1538,7 +1538,7 @@
|
||||
<value>Oletus (järjestelmä)</value>
|
||||
</data>
|
||||
<data name="CopyNotes" xml:space="preserve">
|
||||
<value>Kopioi muistiinpanot</value>
|
||||
<value>Kopioi merkinnät</value>
|
||||
</data>
|
||||
<data name="Exit" xml:space="preserve">
|
||||
<value>Poistu</value>
|
||||
@@ -1569,7 +1569,7 @@
|
||||
<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" -näytöstä.</value>
|
||||
<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>
|
||||
</data>
|
||||
<data name="ThemeAppliedOnRestart" xml:space="preserve">
|
||||
<value>Teema vaihtuu kun sovellus käynnistetään uudelleen.</value>
|
||||
@@ -1931,7 +1931,7 @@
|
||||
<value>Salasana on poistettu.</value>
|
||||
</data>
|
||||
<data name="NotesInfo" xml:space="preserve">
|
||||
<value>Yksityiset muistiinpanot tästä Sendistä.</value>
|
||||
<value>Yksityisiä merkintöjä tästä Sendistä.</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">
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Vaihdettu seuraavaan käytettävissä olevaan tiliin</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Tili lukittu</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Tilin uloskirjaus onnistui</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Tilin poisto onnistui</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Poista tili</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -1165,7 +1165,7 @@
|
||||
<value>Le service de saisie automatique de Bitwarden utilise l'outil de saisie automatique d'Android pour aider à saisir les identifiants, les cartes de crédit et les informations d'identité dans d'autres applis sur votre appareil.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Utilisez le service d'accessibilité de Bitwarden pour la saisie automatique de vos identifiants.</value>
|
||||
<value>Utilisez le service de remplissage automatique de Bitwarden pour remplir les informations de connexion dans d'autres applications.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
|
||||
<value>Ouvrir les paramètres de remplissage automatique</value>
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Allez dans l'application "Réglages" d'iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Appuyez sur "Mots de passe et comptes"</value>
|
||||
<value>2. Appuyez sur "Mots de passes et comptes"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Appuyez sur "Préremplir mots de passe"</value>
|
||||
@@ -1935,7 +1935,7 @@
|
||||
<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>Désactiver ce Send pour que personne ne puisse y accéder.</value>
|
||||
<value>Désactiver cet envoi pour que personne ne puisse y accéder.</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">
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Passage au prochain compte disponible</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Compte verrouillé</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Compte déconnecté avec succès</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Compte supprimé avec succès</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Supprimer le compte</value>
|
||||
</data>
|
||||
|
||||
@@ -2126,6 +2126,15 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -1300,7 +1300,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2121,6 +2121,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Obriši račun</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Megtörtént az átkapcsolás a következő elérhető fiókra.</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>A fiók lezárásra került.</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>A fiókból kijelentkezés sikeres volt.</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>A fiók eltávolítása sikeres volt.</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Fiók törlése</value>
|
||||
</data>
|
||||
|
||||
@@ -276,13 +276,13 @@
|
||||
<value>Anda yakin ingin keluar?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Hapus Akun</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
<value>Apakah anda yakin ingin menghapus akun ini?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Akun telah ditambahkan</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
@@ -2105,22 +2105,31 @@
|
||||
<value>One or more organization policies prevents your from exporting your personal vault.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Tambahkan Akun</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
<value>Tidak terkunci</value>
|
||||
</data>
|
||||
<data name="AccountLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
<value>Terkunci</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Keluar</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Akun terkunci</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Berhasil keluar</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
<value>Hapus akun</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccountIsPermanent" xml:space="preserve">
|
||||
<value>Deleting your account is permanent</value>
|
||||
@@ -2129,13 +2138,13 @@
|
||||
<value>Your account and all associated data will be erased and unrecoverable. Are you sure you want to continue?</value>
|
||||
</data>
|
||||
<data name="DeletingYourAccount" xml:space="preserve">
|
||||
<value>Deleting your account</value>
|
||||
<value>Hapus akun anda</value>
|
||||
</data>
|
||||
<data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve">
|
||||
<value>Your account has been permanently deleted</value>
|
||||
<value>Akun Anda telah dihapus secara permanen.</value>
|
||||
</data>
|
||||
<data name="InvalidVerificationCode" xml:space="preserve">
|
||||
<value>Invalid Verification Code.</value>
|
||||
<value>Kode verifikasi tidak valid.</value>
|
||||
</data>
|
||||
<data name="RequestOTP" xml:space="preserve">
|
||||
<value>Request one-time password</value>
|
||||
@@ -2153,18 +2162,18 @@
|
||||
<value>Sending code</value>
|
||||
</data>
|
||||
<data name="Verifying" xml:space="preserve">
|
||||
<value>Verifying</value>
|
||||
<value>Memverifikasi...</value>
|
||||
</data>
|
||||
<data name="ResendCode" xml:space="preserve">
|
||||
<value>Resend Code</value>
|
||||
<value>Kirim ulang kode</value>
|
||||
</data>
|
||||
<data name="AVerificationCodeWasSentToYourEmail" xml:space="preserve">
|
||||
<value>A verification code was sent to your email</value>
|
||||
<value>Kode verifikasi telah dikirim ke email Anda.</value>
|
||||
</data>
|
||||
<data name="AnErrorOccurredWhileSendingAVerificationCodeToYourEmailPleaseTryAgain" xml:space="preserve">
|
||||
<value>An error occurred while sending a verification code to your email. Please try again</value>
|
||||
</data>
|
||||
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
|
||||
<value>Enter the verification code that was sent to your email</value>
|
||||
<value>Masukkan kode verifikasi yang dikirim ke email anda</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
<value>Inviaci un'email per ottenere aiuto o fare una segnalazione.</value>
|
||||
</data>
|
||||
<data name="EnterPIN" xml:space="preserve">
|
||||
<value>Inserisci il tuo PIN.</value>
|
||||
<value>Digita il tuo PIN.</value>
|
||||
</data>
|
||||
<data name="Favorites" xml:space="preserve">
|
||||
<value>Preferiti</value>
|
||||
@@ -247,7 +247,7 @@
|
||||
<comment>Description message for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
|
||||
<value>Connessione ad Internet richiesta</value>
|
||||
<value>Connessione a Internet richiesta</value>
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
@@ -378,7 +378,7 @@
|
||||
<value>Verifica impronta</value>
|
||||
</data>
|
||||
<data name="VerifyMasterPassword" xml:space="preserve">
|
||||
<value>Verifica Password Principale</value>
|
||||
<value>Verifica password principale</value>
|
||||
</data>
|
||||
<data name="VerifyPIN" xml:space="preserve">
|
||||
<value>Verifica PIN</value>
|
||||
@@ -393,7 +393,7 @@
|
||||
<value>Visita il nostro sito</value>
|
||||
</data>
|
||||
<data name="VisitOurWebsiteDescription" xml:space="preserve">
|
||||
<value>Visita il nostro sito per ottenere aiuto, notizie, mandarci una email e/o imparare di più su come usare Bitwarden.</value>
|
||||
<value>Visita il nostro sito per ottenere aiuto, notizie, mandarci un'email e/o imparare di più su come usare Bitwarden.</value>
|
||||
</data>
|
||||
<data name="Website" xml:space="preserve">
|
||||
<value>Sito web</value>
|
||||
@@ -430,7 +430,7 @@
|
||||
<value>Il modo più semplice per aggiungere nuovi login alla tua cassaforte è dall'estensione dell'applicazione Bitwarden. Scopri di più sull'utilizzo dell'estensione dell'applicazione Bitwarden navigando nella schermata "Impostazioni".</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionDescription" xml:space="preserve">
|
||||
<value>Usa Bitwarden su Safari e altre app per auto-completare i tuoi login.</value>
|
||||
<value>Usa Bitwarden su Safari e altre applicazioni per auto-completare i tuoi login.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillService" xml:space="preserve">
|
||||
<value>Servizio auto-completamento di Bitwarden</value>
|
||||
@@ -448,7 +448,7 @@
|
||||
<value>Cambia password principale</value>
|
||||
</data>
|
||||
<data name="ChangePasswordConfirmation" xml:space="preserve">
|
||||
<value>Puoi cambiare la tua password principale solo sulla cassaforte online di bitwarden.com. Vuoi visitare ora il sito?</value>
|
||||
<value>Puoi cambiare la tua password principale solo sulla cassaforte in linea di bitwarden.com. Vuoi visitare ora il sito?</value>
|
||||
</data>
|
||||
<data name="Close" xml:space="preserve">
|
||||
<value>Chiudi</value>
|
||||
@@ -467,7 +467,7 @@
|
||||
<value>Modifica elemento</value>
|
||||
</data>
|
||||
<data name="EnableAutomaticSyncing" xml:space="preserve">
|
||||
<value>Abilita la sincronizzazione automatica</value>
|
||||
<value>Abilita sincronizzazione automatica</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>Inserisci l'indirizzo email del tuo account per ricevere il suggerimento della password principale.</value>
|
||||
@@ -479,7 +479,7 @@
|
||||
<value>Quasi fatto!</value>
|
||||
</data>
|
||||
<data name="ExtensionEnable" xml:space="preserve">
|
||||
<value>Abilita l'Estensione App</value>
|
||||
<value>Abilita l'estensione dell'applicazione</value>
|
||||
</data>
|
||||
<data name="ExtensionInSafari" xml:space="preserve">
|
||||
<value>Su Safari, trova Bitwarden utilizzando l'icona di condivisione (suggerimento: scorri a destra sulla riga inferiore del menu).</value>
|
||||
@@ -489,7 +489,7 @@
|
||||
<value>Ottieni accesso immediato alle tue password!</value>
|
||||
</data>
|
||||
<data name="ExtensionReady" xml:space="preserve">
|
||||
<value>Sei pronto a fare il login!</value>
|
||||
<value>Sei pronto ad accedere!</value>
|
||||
</data>
|
||||
<data name="ExtensionSetup" xml:space="preserve">
|
||||
<value>I tuoi login sono ora facilmente accessibili da Safari, Chrome e altre applicazioni supportate.</value>
|
||||
@@ -510,10 +510,10 @@
|
||||
<value>Impronta</value>
|
||||
</data>
|
||||
<data name="GeneratePassword" xml:space="preserve">
|
||||
<value>Genera Password</value>
|
||||
<value>Genera password</value>
|
||||
</data>
|
||||
<data name="GetPasswordHint" xml:space="preserve">
|
||||
<value>Ottenere il suggerimento per la password principale</value>
|
||||
<value>Ottieni il suggerimento per la password principale</value>
|
||||
</data>
|
||||
<data name="ImportItems" xml:space="preserve">
|
||||
<value>Importa elementi</value>
|
||||
@@ -555,7 +555,7 @@
|
||||
<value>Azione timeout cassaforte</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
|
||||
<value>La disconnessione rimuove tutti gli accessi alla tua cassaforte e richiede l'autenticazione online dopo il periodo di scadenza. Sei sicuro di voler utilizzare questa impostazione?</value>
|
||||
<value>La disconnessione rimuove tutti gli accessi alla tua cassaforte e richiede l'autenticazione in linea dopo il periodo di scadenza. Sei sicuro di voler utilizzare questa impostazione?</value>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>Connessione in corso...</value>
|
||||
@@ -574,10 +574,10 @@
|
||||
<value>La password principale è la password che utilizzi per accedere alla tua cassaforte. È molto importante che tu non la dimentichi. Non c'è modo di recuperare questa password nel caso che tu la dimenticassi.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHint" xml:space="preserve">
|
||||
<value>Indizio per la Password Principale (opzionale)</value>
|
||||
<value>Suggerimento per la password principale (facoltativo)</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHintDescription" xml:space="preserve">
|
||||
<value>Un indizio per la password principale può aiutarti a ricordarla nel caso te la dimenticassi.</value>
|
||||
<value>Un suggerimento per la password principale può aiutarti a ricordarla nel caso la dimenticassi.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
|
||||
<value>La password principale deve essere lunga almeno 8 caratteri.</value>
|
||||
@@ -594,7 +594,7 @@
|
||||
<value>Altre impostazioni</value>
|
||||
</data>
|
||||
<data name="MustLogInMainApp" xml:space="preserve">
|
||||
<value>È necessario accedere all'app di Bitwarden principale prima di poter utilizzare l'estensione.</value>
|
||||
<value>È necessario accedere all'applicazione principale di Bitwarden prima di poter utilizzare l'estensione.</value>
|
||||
</data>
|
||||
<data name="Never" xml:space="preserve">
|
||||
<value>Mai</value>
|
||||
@@ -619,7 +619,7 @@
|
||||
<comment>Confirmation, like "Ok, I understand it"</comment>
|
||||
</data>
|
||||
<data name="OptionDefaults" xml:space="preserve">
|
||||
<value>Le opzioni predefinite sono impostate dal generatore di password dell'app principale Bitwarden.</value>
|
||||
<value>Le opzioni predefinite sono impostate dal generatore di password dell'applicazione principale Bitwarden.</value>
|
||||
</data>
|
||||
<data name="Options" xml:space="preserve">
|
||||
<value>Opzioni</value>
|
||||
@@ -631,7 +631,7 @@
|
||||
<value>Password generata.</value>
|
||||
</data>
|
||||
<data name="PasswordGenerator" xml:space="preserve">
|
||||
<value>Generatore di Password</value>
|
||||
<value>Generatore di password</value>
|
||||
</data>
|
||||
<data name="PasswordHint" xml:space="preserve">
|
||||
<value>Suggerimento password</value>
|
||||
@@ -656,7 +656,7 @@
|
||||
<value>Rigenera password</value>
|
||||
</data>
|
||||
<data name="RetypeMasterPassword" xml:space="preserve">
|
||||
<value>Ri-digita la tua password principale</value>
|
||||
<value>Ri-digita la password principale</value>
|
||||
</data>
|
||||
<data name="SearchVault" xml:space="preserve">
|
||||
<value>Cerca nella cassaforte</value>
|
||||
@@ -671,7 +671,7 @@
|
||||
<value>Imposta PIN</value>
|
||||
</data>
|
||||
<data name="SetPINDirection" xml:space="preserve">
|
||||
<value>Immetti un codice PIN a 4 cifre per sbloccare l'applicazione.</value>
|
||||
<value>Digita un codice PIN a 4 cifre per sbloccare l'applicazione.</value>
|
||||
</data>
|
||||
<data name="ItemInformation" xml:space="preserve">
|
||||
<value>Informazioni elemento</value>
|
||||
@@ -704,7 +704,7 @@
|
||||
<value>Verifica in due passaggi</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>L'autenticazione in due passaggi rende il tuo account più sicuro, richiedendo di verificare l'accesso con un altro dispositivo come una chiave di sicurezza, app di autenticazione, SMS, telefonata o email. Può essere abilitata su bitwarden.com. Vuoi visitare il sito ora?</value>
|
||||
<value>L'autenticazione in due passaggi rende il tuo account più sicuro, richiedendo di verificare l'accesso con un altro dispositivo come una chiave di sicurezza, applicazione di autenticazione, SMS, telefonata o email. Può essere abilitata su bitwarden.com. Vuoi visitare il sito ora?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Sblocca con {0}</value>
|
||||
@@ -759,7 +759,7 @@
|
||||
<value>Apri impostazioni di accessibilità</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceStep1" xml:space="preserve">
|
||||
<value>1. Nella schermata impostazioni di accessibilità di Android, tocca "Bitwarden".</value>
|
||||
<value>1. Nella schermata impostazioni di accessibilità di Android, tocca "Bitwarden" nella gestione dei servizi.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceStep2" xml:space="preserve">
|
||||
<value>2. Attiva l'interruttore e premi OK per accettare.</value>
|
||||
@@ -1597,7 +1597,7 @@
|
||||
<value>Verifica biometrica</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Dati biometrici</value>
|
||||
<value>dati biometrici</value>
|
||||
</data>
|
||||
<data name="UseBiometricsToUnlock" xml:space="preserve">
|
||||
<value>Sblocca con dati biometrici</value>
|
||||
@@ -1665,7 +1665,7 @@
|
||||
<comment>Clone an entity (verb).</comment>
|
||||
</data>
|
||||
<data name="PasswordGeneratorPolicyInEffect" xml:space="preserve">
|
||||
<value>Una o più policy dell'organizzazione controllano le impostazioni del tuo generatore</value>
|
||||
<value>Una o più politiche dell'organizzazione stanno influenzando le impostazioni del tuo generatore</value>
|
||||
</data>
|
||||
<data name="Open" xml:space="preserve">
|
||||
<value>Apri</value>
|
||||
@@ -1926,7 +1926,7 @@
|
||||
<value>Sei sicuro di voler rimuovere la password?</value>
|
||||
</data>
|
||||
<data name="RemovingSendPassword" xml:space="preserve">
|
||||
<value>Rimuovo la password</value>
|
||||
<value>Rimozione password</value>
|
||||
</data>
|
||||
<data name="SendPasswordRemoved" xml:space="preserve">
|
||||
<value>La password è stata rimossa.</value>
|
||||
@@ -2052,10 +2052,10 @@
|
||||
<value>Aggiorna password principale</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>La tua password principale è stata recentemente modificata da un amministratore nella tua organizzazione. Per accedere alla cassaforte, devi aggiornarla ora. Procedendo sarai disconnesso dalla sessione attuale, richiedendo di effettuare nuovamente l'accesso. Le sessioni attive su altri dispositivi possono continuare a rimanere attive per un massimo di un'ora.</value>
|
||||
<value>La tua password principale è stata recentemente modificata da un amministratore nella tua organizzazione. Per accedere alla cassaforte, aggiorna ora la password principale. Procedendo sarai disconnesso dalla sessione attuale e ti sarà richiesto di effettuare nuovamente l'accesso. Le sessioni attive su altri dispositivi potrebbero continuare a rimanere attive per un massimo di un'ora.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Aggiornamento password in corso</value>
|
||||
<value>Aggiornamento password</value>
|
||||
</data>
|
||||
<data name="UpdatePasswordError" xml:space="preserve">
|
||||
<value>Attualmente non è possibile aggiornare la password</value>
|
||||
@@ -2094,7 +2094,7 @@
|
||||
<value>Assicurati che il browser predefinito supporti WebAuthn e riprova.</value>
|
||||
</data>
|
||||
<data name="ResetPasswordAutoEnrollInviteWarning" xml:space="preserve">
|
||||
<value>Questa organizzazione ha una policy aziendale che ti iscriverà automaticamente al ripristino della password. Ciò permetterà agli amministratori dell'organizzazione di cambiare la tua password principale.</value>
|
||||
<value>Questa organizzazione ha una politica aziendale che ti iscriverà automaticamente al ripristino della password. Ciò permetterà agli amministratori dell'organizzazione di cambiare la tua password principale.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Le policy dell'organizzazione controllano il timeout della tua cassaforte. Il tempo massimo consentito è di $HOURS$ ore e $MINUTES$ minuti</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Passato all'account successivo disponibile</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account bloccato</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account disconnesso correttamente</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account rimosso correttamente</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Elimina account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>次の利用可能なアカウントに切り替えました</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>アカウントをロックしました</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>ログアウトしました</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>アカウントを削除しました</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>アカウントの削除</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>사용 가능한 다음 계정으로 전환함</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>계정 삭제</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Pārslēdzās uz nākamo pieejamo kontu</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Konts ir slēgts</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Izrakstīšanās no konta bija veiksmīga</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Konts tika veiksmīgi noņemts</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Dzēst kontu</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -276,13 +276,13 @@
|
||||
<value>Er du sikker på at du vil logge av?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Fjern konto</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
<value>Er du sikker på at du vil fjerne denne kontoen?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Kontoen er allerede lagt til</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
@@ -549,13 +549,13 @@
|
||||
<value>Umiddelbart</value>
|
||||
</data>
|
||||
<data name="VaultTimeout" xml:space="preserve">
|
||||
<value>Tidsavbrudd i hvelvet</value>
|
||||
<value>Tidsavbrudd for hvelvet</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutAction" xml:space="preserve">
|
||||
<value>Handling ved pause i hvelvet</value>
|
||||
<value>Hendelse ved tidsavbrudd for hvelvet</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
|
||||
<value>Hvis du logger ut, fjerner du all tilgang til hvelvet ditt og krever online godkjenning etter tidsavbrudd. Er du sikker på at du vil bruke denne innstillingen?</value>
|
||||
<value>Dersom du logger ut vil all tilgang til hvelvet fjernes og du må autentisere online etter tidsavbruddet. Er du sikker på at du vil bruke denne innstillingen?</value>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>Logger på...</value>
|
||||
@@ -750,7 +750,7 @@
|
||||
<comment>This is used for the autofill service. ex. "There are no items in your vault for twitter.com".</comment>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOverlay" xml:space="preserve">
|
||||
<value>Når du velger et inntastingsfelt og ser Bitwardens tjeneste for automatiske utfylling, kan du trykke på den for å starte den automatisk utfyllingen.</value>
|
||||
<value>Når du velger et inntastingsfelt og ser Bitwardens autofylltjeneste, kan du trykke på den for å starte autofylltjenesten.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceNotificationContent" xml:space="preserve">
|
||||
<value>Trykk på denne beskjeden for å auto-utfylle en gjenstand fra ditt hvelv.</value>
|
||||
@@ -774,7 +774,7 @@
|
||||
<value>Status</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceAlert2" xml:space="preserve">
|
||||
<value>Den enkleste måten å legge til nye innlogginger i hvelvet ditt, er fra Bitwarden sin auto-utfyllingstjeneste. Lær mer om å bruke Bitwarden sin auto-utfyllingstjeneste ved å navigere til "Innstillinger".</value>
|
||||
<value>Den enkleste måten å legge til nye innlogginger i hvelvet ditt, er fra Bitwarden sin autofylltjeneste. Lær mer om å bruke Bitwarden sin autofylltjeneste ved å navigere til "Innstillinger".</value>
|
||||
</data>
|
||||
<data name="Autofill" xml:space="preserve">
|
||||
<value>Auto-utfylling</value>
|
||||
@@ -1156,16 +1156,16 @@
|
||||
<value>Det er ingen gjenstander i denne mappen.</value>
|
||||
</data>
|
||||
<data name="NoItemsTrash" xml:space="preserve">
|
||||
<value>Det er ingen objekter i papirkurven.</value>
|
||||
<value>Det er ingen elementer i papirkurven.</value>
|
||||
</data>
|
||||
<data name="AutofillAccessibilityService" xml:space="preserve">
|
||||
<value>Auto-utfyllingstilgjengelighetstjeneste</value>
|
||||
</data>
|
||||
<data name="AutofillServiceDescription" xml:space="preserve">
|
||||
<value>Bitwarden sin auto-utfyllingstjeneste bruker Android Autofill Framework for å bidra til å fylle inn innlogginger, bankkort og identifikasjonsinfo inn i andre apper på din enhet.</value>
|
||||
<value>Bitwarden sin autofylltjeneste bruker Android Autofill Framework for å bidra til å fylle inn innlogginger, bankkort og identifikasjonsinfo inn i andre apper på din enhet.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Bruk Bitwarden sin auto-utfyllingstjeneste for å fylle ut innlogginger, bankkort og identifikasjonsinfo i andre apper.</value>
|
||||
<value>Bruk Bitwarden sin autofylltjeneste for å fylle ut innlogginger, bankkort og identifikasjonsinfo i andre apper.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
|
||||
<value>Åpne auto-utfyllingsinnstillingene</value>
|
||||
@@ -1199,7 +1199,7 @@
|
||||
<value>Skjult</value>
|
||||
</data>
|
||||
<data name="FieldTypeLinked" xml:space="preserve">
|
||||
<value>Tilknyttet</value>
|
||||
<value>Linket</value>
|
||||
</data>
|
||||
<data name="FieldTypeText" xml:space="preserve">
|
||||
<value>Tekst</value>
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Gå til iOS-appen «Innstillinger»</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Trykk på «Passord og kontoer»</value>
|
||||
<value>2. Trykk på "Passord og kontoer"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Trykk «Autoutfyll passord»</value>
|
||||
@@ -1329,10 +1329,10 @@
|
||||
<value>Innlogginger</value>
|
||||
</data>
|
||||
<data name="SecureNotes" xml:space="preserve">
|
||||
<value>Sikre notiser</value>
|
||||
<value>Sikre notater</value>
|
||||
</data>
|
||||
<data name="AllItems" xml:space="preserve">
|
||||
<value>Alle gjenstander</value>
|
||||
<value>Alle elementer</value>
|
||||
</data>
|
||||
<data name="URIs" xml:space="preserve">
|
||||
<value>URI-er</value>
|
||||
@@ -1343,13 +1343,13 @@
|
||||
<comment>A loading message when doing an exposed password check.</comment>
|
||||
</data>
|
||||
<data name="CheckPassword" xml:space="preserve">
|
||||
<value>Sjekk om passordet har blitt utsatt.</value>
|
||||
<value>Sjekk om passordet har blitt lekket.</value>
|
||||
</data>
|
||||
<data name="PasswordExposed" xml:space="preserve">
|
||||
<value>Dette passordet har blitt utsatt {0} gang(er) i et databrudd. Du burde endre det.</value>
|
||||
<value>Dette passordet har blitt eksponert {0} gang(er) i et datalekkasjer. Du bør endre det.</value>
|
||||
</data>
|
||||
<data name="PasswordSafe" xml:space="preserve">
|
||||
<value>Dette passordet ble ikke funnet i noen kjente databrudd. Det burde være trygt å bruke.</value>
|
||||
<value>Dette passordet ble ikke funnet i noen kjente datalekkasjer. Det bør være trygt å bruke.</value>
|
||||
</data>
|
||||
<data name="IdentityName" xml:space="preserve">
|
||||
<value>Identitetsnavn</value>
|
||||
@@ -1364,10 +1364,10 @@
|
||||
<value>Typer</value>
|
||||
</data>
|
||||
<data name="NoPasswordsToList" xml:space="preserve">
|
||||
<value>Det er ingen passord å liste opp.</value>
|
||||
<value>Det er ingen passord å vise</value>
|
||||
</data>
|
||||
<data name="NoItemsToList" xml:space="preserve">
|
||||
<value>Det er ingen gjenstander å liste opp.</value>
|
||||
<value>Det er ingen elementer å vise.</value>
|
||||
</data>
|
||||
<data name="SearchCollection" xml:space="preserve">
|
||||
<value>Søk i samling</value>
|
||||
@@ -1388,13 +1388,13 @@
|
||||
<value>Flytt opp</value>
|
||||
</data>
|
||||
<data name="Miscellaneous" xml:space="preserve">
|
||||
<value>Annet</value>
|
||||
<value>Diverse</value>
|
||||
</data>
|
||||
<data name="Ownership" xml:space="preserve">
|
||||
<value>Eierskap</value>
|
||||
</data>
|
||||
<data name="WhoOwnsThisItem" xml:space="preserve">
|
||||
<value>Hvem eier dette objektet?</value>
|
||||
<value>Hvem eier dette elementet?</value>
|
||||
</data>
|
||||
<data name="NoCollectionsToList" xml:space="preserve">
|
||||
<value>Det er ingen samlinger å liste opp.</value>
|
||||
@@ -1404,7 +1404,7 @@
|
||||
<comment>ex: Item moved to Organization.</comment>
|
||||
</data>
|
||||
<data name="ItemShared" xml:space="preserve">
|
||||
<value>Gjenstanden har blitt delt.</value>
|
||||
<value>Elementet har blitt delt.</value>
|
||||
</data>
|
||||
<data name="SelectOneCollection" xml:space="preserve">
|
||||
<value>Du må velge minst én samling.</value>
|
||||
@@ -1413,13 +1413,13 @@
|
||||
<value>Del</value>
|
||||
</data>
|
||||
<data name="ShareItem" xml:space="preserve">
|
||||
<value>Del objekt</value>
|
||||
<value>Del element</value>
|
||||
</data>
|
||||
<data name="MoveToOrganization" xml:space="preserve">
|
||||
<value>Flytt til organisasjon</value>
|
||||
</data>
|
||||
<data name="NoOrgsToList" xml:space="preserve">
|
||||
<value>Det er ingen organisasjoner å liste opp.</value>
|
||||
<value>Det er ingen organisasjoner å vise.</value>
|
||||
</data>
|
||||
<data name="MoveToOrgDesc" xml:space="preserve">
|
||||
<value>Velg en organisasjon som du ønsker å flytte denne gjenstanden til. Flytting til en organisasjon overfører eierskap til den aktuelle organisasjonen. Du vil ikke lenger være den direkte eieren av denne varen når den er flyttet.</value>
|
||||
@@ -1431,7 +1431,7 @@
|
||||
<value>Passfrase</value>
|
||||
</data>
|
||||
<data name="WordSeparator" xml:space="preserve">
|
||||
<value>Ordadskiller</value>
|
||||
<value>Orddeler</value>
|
||||
</data>
|
||||
<data name="Clear" xml:space="preserve">
|
||||
<value>Tøm</value>
|
||||
@@ -1442,7 +1442,7 @@
|
||||
<comment>Short for "Password Generator"</comment>
|
||||
</data>
|
||||
<data name="NoFoldersToList" xml:space="preserve">
|
||||
<value>Det er ingen mapper å liste opp.</value>
|
||||
<value>Det er ingen mapper å vise</value>
|
||||
</data>
|
||||
<data name="FingerprintPhrase" xml:space="preserve">
|
||||
<value>Fingeravtrykksfrase</value>
|
||||
@@ -1474,10 +1474,10 @@
|
||||
<value>30 minutter</value>
|
||||
</data>
|
||||
<data name="SetPINDescription" xml:space="preserve">
|
||||
<value>Angi PIN-koden din for å låse opp Bitwarden. PIN-innstillingene tilbakestilles hvis du logger deg helt ut av programmet.</value>
|
||||
<value>Angi PIN-koden for å låse opp Bitwarden. PIN-innstillingene dine blir tilbakestilt hvis du noen gang logger deg ut av applikasjonen.</value>
|
||||
</data>
|
||||
<data name="LoggedInAsOn" xml:space="preserve">
|
||||
<value>Logget på som {0} gjennom {1}.</value>
|
||||
<value>Logget på som {0} på {1}.</value>
|
||||
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="VaultLockedMasterPassword" xml:space="preserve">
|
||||
@@ -1494,7 +1494,7 @@
|
||||
<comment>A dark color</comment>
|
||||
</data>
|
||||
<data name="Light" xml:space="preserve">
|
||||
<value>Lyst</value>
|
||||
<value>Lys</value>
|
||||
<comment>A light color</comment>
|
||||
</data>
|
||||
<data name="FiveMinutes" xml:space="preserve">
|
||||
@@ -1517,7 +1517,7 @@
|
||||
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
|
||||
</data>
|
||||
<data name="ClearClipboardDescription" xml:space="preserve">
|
||||
<value>Slett automatisk kopierte verdier fra utklippstavlen.</value>
|
||||
<value>Slett kopierte verdier fra utklippstavlen automatisk.</value>
|
||||
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
|
||||
</data>
|
||||
<data name="DefaultUriMatchDetection" xml:space="preserve">
|
||||
@@ -1544,10 +1544,10 @@
|
||||
<value>Avslutt</value>
|
||||
</data>
|
||||
<data name="ExitConfirmation" xml:space="preserve">
|
||||
<value>Er du sikker på at du vil lukke Bitwarden?</value>
|
||||
<value>Er du sikker på at du vil avslutte Bitwarden?</value>
|
||||
</data>
|
||||
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
|
||||
<value>You you want to require unlocking with your master password when the application is restarted?</value>
|
||||
<value>Ønsker du å låse opp ved å bruke hovedpassordet når applikasjonen startes på nytt?</value>
|
||||
</data>
|
||||
<data name="Black" xml:space="preserve">
|
||||
<value>Svart</value>
|
||||
@@ -1557,13 +1557,13 @@
|
||||
<value>Svartelistede URI-er</value>
|
||||
</data>
|
||||
<data name="BlacklistedUrisDescription" xml:space="preserve">
|
||||
<value>URIs that are blacklisted will not offer auto-fill. The list of apps should be comma separated. Ex: "https://twitter.com, androidapp://com.twitter.android".</value>
|
||||
<value>URI-er som er svartelistet vil ikke bli fylt ut automatisk. Listen over apper bør kommasepareres. F.eks.: "https://twitter.com, androidapp://com.twitter.android".</value>
|
||||
</data>
|
||||
<data name="DisableSavePrompt" xml:space="preserve">
|
||||
<value>Skru av lagreforespørsel</value>
|
||||
<value>Deaktiver lagreforespørsel</value>
|
||||
</data>
|
||||
<data name="DisableSavePromptDescription" xml:space="preserve">
|
||||
<value>"Lagreforespørselen" spør deg automatisk om du vil lagre nye objekter i hvelvet ditt når du skriver dem inn for første gang.</value>
|
||||
<value>"Lagreforespørselen" spør deg automatisk om du vil lagre nye elementer i hvelvet ditt når du skriver dem inn for første gang.</value>
|
||||
</data>
|
||||
<data name="OnRestart" xml:space="preserve">
|
||||
<value>Ved omstart av appen</value>
|
||||
@@ -1579,7 +1579,7 @@
|
||||
<comment>ex. Uppercase the first character of a word.</comment>
|
||||
</data>
|
||||
<data name="IncludeNumber" xml:space="preserve">
|
||||
<value>Inkluder nummer</value>
|
||||
<value>Inkluder siffer</value>
|
||||
</data>
|
||||
<data name="Download" xml:space="preserve">
|
||||
<value>Last ned</value>
|
||||
@@ -1588,13 +1588,13 @@
|
||||
<value>Delt</value>
|
||||
</data>
|
||||
<data name="ToggleVisibility" xml:space="preserve">
|
||||
<value>Toggle Visiblity</value>
|
||||
<value>Filsynlighet av/på</value>
|
||||
</data>
|
||||
<data name="LoginExpired" xml:space="preserve">
|
||||
<value>Innloggingsøkten din har utløpt.</value>
|
||||
<value>Økten din har utløpt.</value>
|
||||
</data>
|
||||
<data name="BiometricsDirection" xml:space="preserve">
|
||||
<value>Bruk biometri for å bekrefte.</value>
|
||||
<value>Biometrisk verifisering</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Biometri</value>
|
||||
@@ -1627,7 +1627,7 @@
|
||||
<value>Filformat</value>
|
||||
</data>
|
||||
<data name="ExportVaultMasterPasswordDescription" xml:space="preserve">
|
||||
<value>Skriv inn ditt superpassordet for å eksportere dine hvelvdataer.</value>
|
||||
<value>Skriv inn hovedpassordet for å eksportere hvelvdataene.</value>
|
||||
</data>
|
||||
<data name="SendVerificationCodeToEmail" xml:space="preserve">
|
||||
<value>Send en verifiseringskode til e-posten din</value>
|
||||
@@ -1639,13 +1639,13 @@
|
||||
<value>Bekreft din identitet for å fortsette.</value>
|
||||
</data>
|
||||
<data name="ExportVaultWarning" xml:space="preserve">
|
||||
<value>Denne eksporten inneholder hvelvdataene dine i et ukryptert format. Du skal ikke lagre eller sende den eksporterte filen over usikre kanaler (for eksempel e-post). Slett den umiddelbart etter at du er ferdig med å bruke den.</value>
|
||||
<value>Denne eksporten inneholder hvelvdataene dine i et ukryptert format. Du bør ikke lagre eller sende den eksporterte filen over usikre kanaler (for eksempel e-post). Slett den umiddelbart etter at du er ferdig med å bruke den.</value>
|
||||
</data>
|
||||
<data name="EncExportKeyWarning" xml:space="preserve">
|
||||
<value>Denne eksporten krypterer dataene dine ved hjelp av kontoen din sin krypteringsnøkkel. Hvis du noen gang endrer krypteringsnøkkelen til kontoen din, bør du eksportere dataene igjen, ettersom du da ikke vil kunne dekryptere denne eksportfilen.</value>
|
||||
</data>
|
||||
<data name="EncExportAccountWarning" xml:space="preserve">
|
||||
<value>Kontokrypteringsnøkler er unike for hver Bitwarden sin brukerkonto, og du kan ikke importere en kryptert eksport til en annen konto.</value>
|
||||
<value>Kontokrypteringsnøkler er unike for hver Bitwarden sin brukerkonto, så du kan ikke importere en kryptert eksport til en annen konto.</value>
|
||||
</data>
|
||||
<data name="ExportVaultConfirmationTitle" xml:space="preserve">
|
||||
<value>Bekreft eksport av hvelvet</value>
|
||||
@@ -1688,7 +1688,7 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemSoftDeleted" xml:space="preserve">
|
||||
<value>Varen ble sendt til papirkurven.</value>
|
||||
<value>Elementet ble sendt til papirkurven.</value>
|
||||
<comment>Confirmation message after successfully soft-deleting a login</comment>
|
||||
</data>
|
||||
<data name="Restore" xml:space="preserve">
|
||||
@@ -1700,7 +1700,7 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="ItemRestored" xml:space="preserve">
|
||||
<value>Varen har blitt gjenopprettet.</value>
|
||||
<value>Elementet har blitt gjenopprettet.</value>
|
||||
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
|
||||
</data>
|
||||
<data name="Trash" xml:space="preserve">
|
||||
@@ -1716,7 +1716,7 @@
|
||||
<comment>Confirmation alert message when permanently deleteing a cipher.</comment>
|
||||
</data>
|
||||
<data name="DoYouReallyWantToRestoreCipher" xml:space="preserve">
|
||||
<value>Vil du virkelig gjenopprette denne gjenstanden?</value>
|
||||
<value>Vil du virkelig gjenopprette dette elementet?</value>
|
||||
<comment>Confirmation alert message when restoring a soft-deleted cipher.</comment>
|
||||
</data>
|
||||
<data name="DoYouReallyWantToSoftDeleteCipher" xml:space="preserve">
|
||||
@@ -1751,7 +1751,7 @@
|
||||
<value>Angi hovedpassord</value>
|
||||
</data>
|
||||
<data name="SetMasterPasswordSummary" xml:space="preserve">
|
||||
<value>For å fullføre innloggingen med SSO, angi et superpassord for å få tilgang til og beskytte hvelvet ditt.</value>
|
||||
<value>For å fullføre innloggingen med SSO, angi et hovedpassord for å få tilgang til og beskytte hvelvet ditt.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
|
||||
<value>En eller flere av organisasjonens vilkår krever hovedpassordet ditt for å oppfylle følgende krav:</value>
|
||||
@@ -1763,13 +1763,13 @@
|
||||
<value>Minste lengde på {0}</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectUppercase" xml:space="preserve">
|
||||
<value>Inneholder ett eller flere store tegn</value>
|
||||
<value>Inneholder én eller flere store bokstaver</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectLowercase" xml:space="preserve">
|
||||
<value>Inneholder ett eller flere små tegn</value>
|
||||
<value>Inneholder én eller flere små bokstaver</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectNumbers" xml:space="preserve">
|
||||
<value>Inneholde ett eller flere tall</value>
|
||||
<value>Inneholde ett eller flere siffer</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectSpecial" xml:space="preserve">
|
||||
<value>Inneholder ett eller flere av de følgende spesialtegn: {0}</value>
|
||||
@@ -1778,7 +1778,7 @@
|
||||
<value>Ugyldig passord</value>
|
||||
</data>
|
||||
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
|
||||
<value>Passordet oppfyller ikke organisasjonens krav. Kontroller policyinformasjonen og prøv på nytt.</value>
|
||||
<value>Passordet oppfyller ikke organisasjonens krav. Kontroller organisasjonens vilkår og prøv på nytt.</value>
|
||||
</data>
|
||||
<data name="Loading" xml:space="preserve">
|
||||
<value>Laster</value>
|
||||
@@ -1788,13 +1788,13 @@
|
||||
</value>
|
||||
</data>
|
||||
<data name="AcceptPoliciesError" xml:space="preserve">
|
||||
<value>Bruksvilkårene og personvernerklæring er ikke godkjent.</value>
|
||||
<value>Vilkårene for bruk og personvernerklæring er ikke akseptert.</value>
|
||||
</data>
|
||||
<data name="TermsOfService" xml:space="preserve">
|
||||
<value>Vilkår for bruk</value>
|
||||
</data>
|
||||
<data name="PrivacyPolicy" xml:space="preserve">
|
||||
<value>Retningslinjer for personvern</value>
|
||||
<value>Personvernsretningslinjer</value>
|
||||
</data>
|
||||
<data name="AccessibilityDrawOverPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden trenger oppmerksomhet – Aktiver "Draw-Over" i "Auto-utfyllingstjenester" fra Bitwarden-innstillinger</value>
|
||||
@@ -1836,10 +1836,10 @@
|
||||
<value>Hvis aktivert, vil tilgjengelighet vise en popup for å forsterke Autofill Service for eldre apper som ikke støtter Android Autofill Framework.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
|
||||
<value>På grunn av bedrifsretningslinjer er du begrenset fra å lagre objekter til ditt personlige hvelv. Endre alternativ for eierskap til en organisasjon og velg blant tilgjengelige samlinger.</value>
|
||||
<value>På grunn av virksomhetsvilkår er du begrenset fra å lagre objekter til ditt personlige hvelv. Endre alternativ for eierskap til en organisasjon og velg blant tilgjengelige samlinger.</value>
|
||||
</data>
|
||||
<data name="PersonalOwnershipPolicyInEffect" xml:space="preserve">
|
||||
<value>En bedriftsretningslinje påvirker dine eierskapsinnstillinger.</value>
|
||||
<value>Organisasjonsvilkår påvirker dine eierskapsinnstillinger.</value>
|
||||
</data>
|
||||
<data name="Send" xml:space="preserve">
|
||||
<value>Send</value>
|
||||
@@ -1877,10 +1877,10 @@
|
||||
<value>Dato for sletting</value>
|
||||
</data>
|
||||
<data name="DeletionTime" xml:space="preserve">
|
||||
<value>Sletting tid</value>
|
||||
<value>Slettetidspunkt</value>
|
||||
</data>
|
||||
<data name="DeletionDateInfo" xml:space="preserve">
|
||||
<value>Send-en vil bli slettet permanent på den angitte dato og klokkeslett.</value>
|
||||
<value>Send-en vil bli permanent slettet på angitte dato og klokkeslett.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="PendingDelete" xml:space="preserve">
|
||||
@@ -1900,7 +1900,7 @@
|
||||
<value>Utløpt</value>
|
||||
</data>
|
||||
<data name="MaximumAccessCount" xml:space="preserve">
|
||||
<value>Maksimal antall tilganger</value>
|
||||
<value>Maksimalt antall tilganger</value>
|
||||
</data>
|
||||
<data name="MaximumAccessCountInfo" xml:space="preserve">
|
||||
<value>Hvis satt, vil brukere ikke lenger ha tilgang til dette send når maksimal antall tilgang er nådd.</value>
|
||||
@@ -1910,13 +1910,13 @@
|
||||
<value>Maksimalt antall tilganger nådd</value>
|
||||
</data>
|
||||
<data name="CurrentAccessCount" xml:space="preserve">
|
||||
<value>Antall nåværende tilgang</value>
|
||||
<value>Antall nåværende tilganger</value>
|
||||
</data>
|
||||
<data name="NewPassword" xml:space="preserve">
|
||||
<value>Nytt passord</value>
|
||||
</data>
|
||||
<data name="PasswordInfo" xml:space="preserve">
|
||||
<value>Eventuelt krever et passord for brukere å få tilgang til denne Send.</value>
|
||||
<value>Valgfritt passordkrav å få tilgang til denne 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">
|
||||
@@ -1940,18 +1940,18 @@
|
||||
<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">
|
||||
<value>Det er ingen sendinger på kontoen din.</value>
|
||||
<value>Det er ingen Send-er i kontoen din.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AddASend" xml:space="preserve">
|
||||
<value>Legg til en sendt</value>
|
||||
<value>Legg til en 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="CopyLink" xml:space="preserve">
|
||||
<value>Kopier lenke</value>
|
||||
</data>
|
||||
<data name="ShareLink" xml:space="preserve">
|
||||
<value>Del link</value>
|
||||
<value>Del lenke</value>
|
||||
</data>
|
||||
<data name="SendLink" xml:space="preserve">
|
||||
<value>Send lenke</value>
|
||||
@@ -2008,7 +2008,7 @@
|
||||
<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>På grunn av en virksomhetsregel kan du kun slette en eksisterende Send.</value>
|
||||
<value>På grunn av virksomhetsvilkår kan du kun slette en eksisterende 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="AboutSend" xml:space="preserve">
|
||||
@@ -2019,11 +2019,11 @@
|
||||
<value>Skjul min e-postadresse fra mottakere.</value>
|
||||
</data>
|
||||
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||
<value>En eller flere av organisasjons retningslinjer påvirker generatorinnstillingene dine.</value>
|
||||
<value>En eller flere av organisasjons vilkår påvirker generatorinnstillingene dine.</value>
|
||||
<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>Gratis kontoer kan bare dele tekst. Et premiummedlemskap kreves for å bruke filer med Send.</value>
|
||||
<value>Gratiskontoer kan kun dele tekst. Et premiummedlemskap kreves for å bruke filer med 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">
|
||||
@@ -2034,13 +2034,13 @@
|
||||
<value>Forespørsel om hovedpassord på nytt</value>
|
||||
</data>
|
||||
<data name="PasswordConfirmation" xml:space="preserve">
|
||||
<value>Superpassord bekreftelse</value>
|
||||
<value>Hovedpassord bekreftelse</value>
|
||||
</data>
|
||||
<data name="PasswordConfirmationDesc" xml:space="preserve">
|
||||
<value>Denne handlingen er beskyttet, for å fortsette å skrive inn superpassordet på nytt for å verifisere din identitet.</value>
|
||||
<value>Denne handlingen er beskyttet, for å fortsette å skrive inn hovedpassordet på nytt for å verifisere din identitet.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Bekreftelsekode kreves</value>
|
||||
<value>Captcha kreves</value>
|
||||
</data>
|
||||
<data name="CaptchaFailed" xml:space="preserve">
|
||||
<value>Captcha feilet. Prøv på nytt.</value>
|
||||
@@ -2094,31 +2094,40 @@
|
||||
<value>Sørg for at standardnettleseren din støtter WebAuthn og prøv igjen.</value>
|
||||
</data>
|
||||
<data name="ResetPasswordAutoEnrollInviteWarning" xml:space="preserve">
|
||||
<value>Denne organisasjonen har en bedriftsoppsettsregel som automatisk innrullerer deg i tilbakestilling av passord. Registrering vil tillate organisasjonsadministratorer å endre hovedpassordet ditt.</value>
|
||||
<value>Denne organisasjonen har en virksomhetsvilkår som automatisk innrullerer deg i tilbakestilling av passord. Registrering vil tillate organisasjonsadministratorer å endre hovedpassordet ditt.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Din organisasjons retningslinjer påvirker tidsavbruddet for hvelvet. Maksimalt tillatt tidsavbrudd for hvelv er {0} time(r) og {1} minutt(er)</value>
|
||||
<value>Din organisasjons vikår påvirker tidsavbruddet for hvelvet. Maksimalt tillatt tidsavbrudd for hvelv er {0} time(r) og {1} minutt(er)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Tidsavbruddet ditt for hvelvet overstiger begrensningene som er satt av organisasjonen din.</value>
|
||||
</data>
|
||||
<data name="DisablePersonalVaultExportPolicyInEffect">
|
||||
<value>En eller flere organisasjonsoppsettsregler hindrer deg i å eksportere ditt personlige hvelv.</value>
|
||||
<value>En eller flere organisasjonvilkår hindrer deg i å eksportere ditt personlige hvelv.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Legg til konto</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
<value>Ulåst</value>
|
||||
</data>
|
||||
<data name="AccountLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
<value>Låst</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Logget av</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
<value>Byttet til neste tilgjengelige konto</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Konto låst</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Kontoen er logget av</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Kontoen er fjernet</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Slett konto</value>
|
||||
@@ -2163,9 +2172,9 @@
|
||||
<value>En verifiseringskode er sendt til din e-post</value>
|
||||
</data>
|
||||
<data name="AnErrorOccurredWhileSendingAVerificationCodeToYourEmailPleaseTryAgain" xml:space="preserve">
|
||||
<value>En feil oppstod ved sending av en verifiseringskode til e-posten. Vennligst prøv igjen</value>
|
||||
<value>En feil oppstod ved sending av verifiseringskode til e-posten. Vennligst prøv igjen</value>
|
||||
</data>
|
||||
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
|
||||
<value>Skriv inn bekreftelseskoden som ble sendt til din e-post</value>
|
||||
<value>Skriv inn verifiseringskoden som ble sendt til din e-post</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account geblokkeerd</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account succesvol uitgelogd</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account succesvol verwijderd</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Account verwijderen</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Przełączono na następne dostępne konto</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Konto zostało zablokowane</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Wylogowano z konta</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Konto zostało usunięte</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Usuń konto</value>
|
||||
</data>
|
||||
|
||||
@@ -1162,7 +1162,7 @@
|
||||
<value>Serviço de Acessibilidade de Autopreenchimento</value>
|
||||
</data>
|
||||
<data name="AutofillServiceDescription" xml:space="preserve">
|
||||
<value>O serviço de autopreenchimento do Bitwarden utiliza a Estrutura de Autopreenchimento do Android para ajudar no preenchimento de credenciais, cartões de crédito, e informação de identidade em outros aplicativos do seu dispositivo.</value>
|
||||
<value>O serviço de autopreenchimento do Bitwarden usa a Estrutura de Preenchimento Automático do Android para auxiliar no preenchimento de credenciais em outros aplicativos no seu dispositivo.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Use o serviço de acessibilidade do bitwarden para preencher automaticamente suas credenciais.</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Alterada para a próxima conta disponível</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Conta Bloqueada</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Conta desconectada com sucesso</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Conta removida com sucesso</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Excluir Conta</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Accesați Setările iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Selectați "Parole și Conturi"</value>
|
||||
<value>2. Selectați „Parole”</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Selectați "Auto-completare parole"</value>
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Comutat la următorul cont disponibil</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Cont blocat</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Contul s-a deconectat cu succes</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Cont eliminat cu succes</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Ștergere cont</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Перейдите в 'Настройки' iOS</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Нажмите 'Пароли и учетные записи'</value>
|
||||
<value>2. Нажмите на пункт "Пароли и учетные записи"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Нажмите 'Автозаполнение паролей'</value>
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Переключено на следующую доступную учетную запись</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Учетная запись заблокирована</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Вы успешно вышли из учетной записи</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Учетная запись успешно удалена</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Удалить аккаунт</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -1428,7 +1428,7 @@
|
||||
<value>Počet slov</value>
|
||||
</data>
|
||||
<data name="Passphrase" xml:space="preserve">
|
||||
<value>Heslo</value>
|
||||
<value>Prístupová fráza</value>
|
||||
</data>
|
||||
<data name="WordSeparator" xml:space="preserve">
|
||||
<value>Oddeľovač slov</value>
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Prepnuté na ďalší dostupný účet</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Zamknutý účet</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Účet bol úspešne odhlásený</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Účet bol úspešne odstránený</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Odstrániť účet</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Pojdite v nastavitve iOS aplikacije</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Izbriši račun</value>
|
||||
</data>
|
||||
|
||||
@@ -2121,6 +2121,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Пребацили сте се на следећи доступни налог</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Налог закључан</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Успешно одјављивање</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Налог je успешно уклоњен</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Избриши Налог</value>
|
||||
</data>
|
||||
|
||||
@@ -1162,10 +1162,10 @@
|
||||
<value>Tillgänglighetstjänst för automatisk ifyllnad</value>
|
||||
</data>
|
||||
<data name="AutofillServiceDescription" xml:space="preserve">
|
||||
<value>Bitwardens tillgänglighetstjänst för automatisk ifyllnad använder Android Autofill Framework för att assistera med att fylla i inloggningar, kreditkort och identitetsinformation inuti andra appar på din enhet.</value>
|
||||
<value>The Bitwarden auto-fill service uses the Android Autofill Framework to assist in filling login information into other apps on your device.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Använd Bitwardens tillgänglighetstjänst för att automatiskt fylla i inloggningar, kreditkort och identitetsinformation inuti andra appar.</value>
|
||||
<value>Use the Bitwarden auto-fill service to fill login information into other apps.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
|
||||
<value>Öppna inställningar för automatisk ifyllnad</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Radera konto</value>
|
||||
</data>
|
||||
|
||||
@@ -1300,7 +1300,7 @@
|
||||
<value>௧. iOS "அமைவுகள்" செயலிக்குச் செல்</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. "கடவுச்சொற்கள் & கணக்குகள்"ஐத் தட்டு</value>
|
||||
<value>2. "கடவுச்சொற்கள்"ஐத் தட்டு</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. "கடவுச்சொற்கள் தன்னிரப்பல்"ஐத் தட்டு</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>அடுத்து கிடைத்த கணக்கிற்கு நிலைமாறியது</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>கணக்கை அழி</value>
|
||||
</data>
|
||||
|
||||
@@ -1299,7 +1299,7 @@
|
||||
<value>1. Go to the iOS "Settings" app</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn2" xml:space="preserve">
|
||||
<value>2. Tap "Passwords & Accounts"</value>
|
||||
<value>2. Tap "Passwords"</value>
|
||||
</data>
|
||||
<data name="AutofillTurnOn3" xml:space="preserve">
|
||||
<value>3. Tap "AutoFill Passwords"</value>
|
||||
@@ -2120,6 +2120,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Bir sonraki hesaba geçildi</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Hesap kilitlendi</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Başarıyla çıkış yapıldı</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Hesap başarıyla kaldırıldı</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Hesabı sil</value>
|
||||
</data>
|
||||
|
||||
@@ -276,16 +276,16 @@
|
||||
<value>Ви дійсно хочете вийти?</value>
|
||||
</data>
|
||||
<data name="RemoveAccount" xml:space="preserve">
|
||||
<value>Remove Account</value>
|
||||
<value>Вилучити обліковий запис</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to remove this account?</value>
|
||||
<value>Ви дійсно хочете вилучити цей обліковий запис?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Account Already Added</value>
|
||||
<value>Обліковий запис вже додано</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
<value>Бажаєте перемкнутися на нього зараз?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Головний пароль</value>
|
||||
@@ -1162,10 +1162,10 @@
|
||||
<value>Служба спеціальних можливостей автозаповнення</value>
|
||||
</data>
|
||||
<data name="AutofillServiceDescription" xml:space="preserve">
|
||||
<value>Служба автозаповнення Bitwarden використовує Android Autofill Framework для заповнення паролів, кредитних карток та особистої інформації в інших програмах на вашому пристрої.</value>
|
||||
<value>Служба автозаповнення Bitwarden використовує Android Autofill Framework для введення облікових даних в інших програмах на вашому пристрої.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
|
||||
<value>Використовуйте службу автозаповнення Bitwarden, щоб автоматично вводити паролі, кредитні картки та особисту інформацію в інших програмах.</value>
|
||||
<value>Використовуйте службу автозаповнення Bitwarden, щоб автоматично вводити облікові дані в інших програмах.</value>
|
||||
</data>
|
||||
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
|
||||
<value>Відкрити налаштування автозаповнення</value>
|
||||
@@ -1935,7 +1935,7 @@
|
||||
<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>Деактивувати це відправлення для скасування доступу до нього.</value>
|
||||
<value>Деактивувати це відправлення для скасування доступу до нього</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">
|
||||
@@ -2003,7 +2003,7 @@
|
||||
<value>Спеціальний</value>
|
||||
</data>
|
||||
<data name="ShareOnSave" xml:space="preserve">
|
||||
<value>Поділитися цим відправленням після збереження.</value>
|
||||
<value>Поділитися цим відправленням після збереження</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">
|
||||
@@ -2015,7 +2015,7 @@
|
||||
<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>Приховувати мою адресу електронної пошти від отримувачів.</value>
|
||||
<value>Приховувати мою адресу електронної пошти від отримувачів</value>
|
||||
</data>
|
||||
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||
<value>На параметри відправлень впливають одна чи декілька політик організації.</value>
|
||||
@@ -2105,19 +2105,28 @@
|
||||
<value>Одна чи декілька організаційних політик не дозволяють вам експортувати особисте сховище.</value>
|
||||
</data>
|
||||
<data name="AddAccount" xml:space="preserve">
|
||||
<value>Add Account</value>
|
||||
<value>Додати обліковий запис</value>
|
||||
</data>
|
||||
<data name="AccountUnlocked" xml:space="preserve">
|
||||
<value>Unlocked</value>
|
||||
<value>Розблоковано</value>
|
||||
</data>
|
||||
<data name="AccountLocked" xml:space="preserve">
|
||||
<value>Locked</value>
|
||||
<value>Заблоковано</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOut" xml:space="preserve">
|
||||
<value>Logged Out</value>
|
||||
<value>Ви вийшли з системи</value>
|
||||
</data>
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
<value>Ви перемкнулися на інший доступний обліковий запис</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Обліковий запис заблоковано</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Ви успішно вийшли з облікового запису</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Обліковий запис успішно вилучено</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Видалити обліковий запис</value>
|
||||
|
||||
@@ -2119,6 +2119,15 @@
|
||||
<data name="AccountSwitchedAutomatically" xml:space="preserve">
|
||||
<value>Switched to next available account</value>
|
||||
</data>
|
||||
<data name="AccountLockedSuccessfully" xml:space="preserve">
|
||||
<value>Account Locked</value>
|
||||
</data>
|
||||
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
|
||||
<value>Account logged out successfully</value>
|
||||
</data>
|
||||
<data name="AccountRemovedSuccessfully" xml:space="preserve">
|
||||
<value>Account removed successfully</value>
|
||||
</data>
|
||||
<data name="DeleteAccount" xml:space="preserve">
|
||||
<value>Delete Account</value>
|
||||
</data>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,8 @@ namespace Bit.App.Services
|
||||
Constants.iOSAutoFillBiometricIntegrityKey,
|
||||
Constants.iOSExtensionClearCiphersCacheKey,
|
||||
Constants.iOSExtensionBiometricIntegrityKey,
|
||||
Constants.iOSShareExtensionClearCiphersCacheKey,
|
||||
Constants.iOSShareExtensionBiometricIntegrityKey,
|
||||
Constants.RememberedEmailKey,
|
||||
Constants.RememberedOrgIdentifierKey,
|
||||
};
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<Setter Property="TextColor"
|
||||
Value="{DynamicResource ButtonTextColor}" />
|
||||
<Setter Property="FontSize"
|
||||
Value="18" />
|
||||
Value="Medium" />
|
||||
<Setter Property="CornerRadius"
|
||||
Value="5" />
|
||||
<Setter Property="Margin"
|
||||
@@ -126,7 +126,7 @@
|
||||
<Setter Property="TextColor"
|
||||
Value="{DynamicResource ButtonPrimaryTextColor}" />
|
||||
<Setter Property="FontSize"
|
||||
Value="18" />
|
||||
Value="Medium" />
|
||||
<Setter Property="FontAttributes"
|
||||
Value="Bold" />
|
||||
<Setter Property="CornerRadius"
|
||||
@@ -298,6 +298,18 @@
|
||||
<Setter Property="FontSize"
|
||||
Value="25" />
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
Class="accountlist-title-platform"
|
||||
ApplyToDerivedTypes="True">
|
||||
<Setter Property="FontSize"
|
||||
Value="Body" />
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
Class="accountlist-sub-platform"
|
||||
ApplyToDerivedTypes="True">
|
||||
<Setter Property="FontSize"
|
||||
Value="Caption" />
|
||||
</Style>
|
||||
|
||||
<!-- Box -->
|
||||
|
||||
|
||||
@@ -221,6 +221,14 @@
|
||||
<Setter Property="TextColor"
|
||||
Value="{DynamicResource MutedColor}" />
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
Class="accountlist-title">
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
Class="accountlist-sub">
|
||||
<Setter Property="TextColor"
|
||||
Value="{DynamicResource MutedColor}" />
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
ApplyToDerivedTypes="True"
|
||||
Class="list-title-icon">
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<Setter Property="TextColor"
|
||||
Value="{DynamicResource ButtonTextColor}" />
|
||||
<Setter Property="FontSize"
|
||||
Value="18" />
|
||||
Value="Medium" />
|
||||
<Setter Property="Margin"
|
||||
Value="0, 5, 0, 0" />
|
||||
<Setter Property="VisualStateManager.VisualStateGroups">
|
||||
@@ -143,7 +143,7 @@
|
||||
<Setter Property="TextColor"
|
||||
Value="{DynamicResource ButtonPrimaryTextColor}" />
|
||||
<Setter Property="FontSize"
|
||||
Value="18" />
|
||||
Value="Medium" />
|
||||
<Setter Property="FontAttributes"
|
||||
Value="Bold" />
|
||||
<Setter Property="Margin"
|
||||
@@ -320,6 +320,16 @@
|
||||
<Setter Property="FontSize"
|
||||
Value="25" />
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
Class="accountlist-title-platform"
|
||||
ApplyToDerivedTypes="True">
|
||||
</Style>
|
||||
<Style TargetType="Label"
|
||||
Class="accountlist-sub-platform"
|
||||
ApplyToDerivedTypes="True">
|
||||
<Setter Property="FontSize"
|
||||
Value="Small" />
|
||||
</Style>
|
||||
|
||||
<!-- Box -->
|
||||
|
||||
|
||||
@@ -502,41 +502,25 @@ namespace Bit.App.Utilities
|
||||
|
||||
public static async Task LogOutAsync(string userId, bool userInitiated = false)
|
||||
{
|
||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
||||
var cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
|
||||
var folderService = ServiceContainer.Resolve<IFolderService>("folderService");
|
||||
var collectionService = ServiceContainer.Resolve<ICollectionService>("collectionService");
|
||||
var passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>(
|
||||
"passwordGenerationService");
|
||||
var vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
var stateService = ServiceContainer.Resolve<IStateService>("stateService");
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
var vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
|
||||
|
||||
var isActiveAccount = await stateService.IsActiveAccountAsync(userId);
|
||||
|
||||
var isAccountRemoval = await vaultTimeoutService.IsLoggedOutByTimeoutAsync(userId) ||
|
||||
await vaultTimeoutService.ShouldLogOutByTimeoutAsync(userId);
|
||||
|
||||
if (userId == null)
|
||||
{
|
||||
userId = await stateService.GetActiveUserIdAsync();
|
||||
}
|
||||
|
||||
await Task.WhenAll(
|
||||
cipherService.ClearAsync(userId),
|
||||
folderService.ClearAsync(userId),
|
||||
collectionService.ClearAsync(userId),
|
||||
passwordGenerationService.ClearAsync(userId),
|
||||
deviceActionService.ClearCacheAsync(),
|
||||
tokenService.ClearTokenAsync(userId),
|
||||
cryptoService.ClearKeysAsync(userId),
|
||||
settingsService.ClearAsync(userId),
|
||||
vaultTimeoutService.ClearAsync(userId),
|
||||
policyService.ClearAsync(userId),
|
||||
stateService.LogoutAccountAsync(userId, userInitiated));
|
||||
await stateService.LogoutAccountAsync(userId, userInitiated);
|
||||
|
||||
searchService.ClearIndex();
|
||||
if (isActiveAccount)
|
||||
{
|
||||
await ClearServiceCacheAsync();
|
||||
}
|
||||
|
||||
if (!userInitiated)
|
||||
{
|
||||
@@ -558,8 +542,7 @@ namespace Bit.App.Utilities
|
||||
if (!isActiveAccount)
|
||||
{
|
||||
var platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
if (await vaultTimeoutService.IsLoggedOutByTimeoutAsync(userId) ||
|
||||
await vaultTimeoutService.ShouldLogOutByTimeoutAsync())
|
||||
if (isAccountRemoval)
|
||||
{
|
||||
platformUtilsService.ShowToast("info", null, AppResources.AccountRemovedSuccessfully);
|
||||
return;
|
||||
@@ -571,6 +554,14 @@ namespace Bit.App.Utilities
|
||||
public static async Task OnAccountSwitchAsync()
|
||||
{
|
||||
var environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
await environmentService.SetUrlsFromStorageAsync();
|
||||
await ClearServiceCacheAsync();
|
||||
var deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
|
||||
await deviceActionService.OnAccountSwitchCompleteAsync();
|
||||
}
|
||||
|
||||
public static async Task ClearServiceCacheAsync()
|
||||
{
|
||||
var tokenService = ServiceContainer.Resolve<ITokenService>("tokenService");
|
||||
var cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
|
||||
var settingsService = ServiceContainer.Resolve<ISettingsService>("settingsService");
|
||||
@@ -584,8 +575,6 @@ namespace Bit.App.Utilities
|
||||
var policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
|
||||
var searchService = ServiceContainer.Resolve<ISearchService>("searchService");
|
||||
|
||||
await environmentService.SetUrlsFromStorageAsync();
|
||||
|
||||
await Task.WhenAll(
|
||||
cipherService.ClearCacheAsync(),
|
||||
deviceActionService.ClearCacheAsync());
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace Bit.Core.Abstractions
|
||||
Task SetAutofillTileAddedAsync(bool? value);
|
||||
Task<string> GetEmailAsync(string userId = null);
|
||||
Task<string> GetNameAsync(string userId = null);
|
||||
Task SetNameAsync(string value, string userId = null);
|
||||
Task<string> GetOrgIdentifierAsync(string userId = null);
|
||||
Task<long?> GetLastActiveTimeAsync(string userId = null);
|
||||
Task SetLastActiveTimeAsync(long? value, string userId = null);
|
||||
@@ -62,8 +63,8 @@ namespace Bit.Core.Abstractions
|
||||
Task SetVaultTimeoutAsync(int? value, string userId = null);
|
||||
Task<VaultTimeoutAction?> GetVaultTimeoutActionAsync(string userId = null);
|
||||
Task SetVaultTimeoutActionAsync(VaultTimeoutAction? value, string userId = null);
|
||||
Task<DateTime?> GetLastFileCacheClearAsync(string userId = null);
|
||||
Task SetLastFileCacheClearAsync(DateTime? value, string userId = null);
|
||||
Task<DateTime?> GetLastFileCacheClearAsync();
|
||||
Task SetLastFileCacheClearAsync(DateTime? value);
|
||||
Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null);
|
||||
Task SetPreviousPageInfoAsync(PreviousPageInfo value, string userId = null);
|
||||
Task<int> GetInvalidUnlockAttemptsAsync(string userId = null);
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
public static string iOSAutoFillBiometricIntegrityKey = "iOSAutoFillBiometricIntegrityState";
|
||||
public static string iOSExtensionClearCiphersCacheKey = "iOSExtensionClearCiphersCache";
|
||||
public static string iOSExtensionBiometricIntegrityKey = "iOSExtensionBiometricIntegrityState";
|
||||
public static string iOSShareExtensionClearCiphersCacheKey = "iOSShareExtensionClearCiphersCache";
|
||||
public static string iOSShareExtensionBiometricIntegrityKey = "iOSShareExtensionBiometricIntegrityState";
|
||||
public static string EventCollectionKey = "eventCollection";
|
||||
public static string RememberedEmailKey = "rememberedEmail";
|
||||
public static string RememberedOrgIdentifierKey = "rememberedOrgIdentifier";
|
||||
@@ -39,7 +41,8 @@
|
||||
{
|
||||
ClearCiphersCacheKey,
|
||||
iOSAutoFillClearCiphersCacheKey,
|
||||
iOSExtensionClearCiphersCacheKey
|
||||
iOSExtensionClearCiphersCacheKey,
|
||||
iOSShareExtensionClearCiphersCacheKey
|
||||
};
|
||||
|
||||
public static string CiphersKey(string userId) => $"ciphers_{userId}";
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@@ -354,7 +352,6 @@ namespace Bit.Core.Services
|
||||
private async Task<T> GetValueAsync<T>(Storage storage, string key)
|
||||
{
|
||||
var value = await GetStorageService(storage).GetAsync<T>(key);
|
||||
Log("GET", storage, key, JsonConvert.SerializeObject(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -365,13 +362,11 @@ namespace Bit.Core.Services
|
||||
await RemoveValueAsync(storage, key);
|
||||
return;
|
||||
}
|
||||
Log("SET", storage, key, JsonConvert.SerializeObject(value));
|
||||
await GetStorageService(storage).SaveAsync(key, value);
|
||||
}
|
||||
|
||||
private async Task RemoveValueAsync(Storage storage, string key)
|
||||
{
|
||||
Log("REMOVE", storage, key, null);
|
||||
await GetStorageService(storage).RemoveAsync(key);
|
||||
}
|
||||
|
||||
@@ -387,29 +382,5 @@ namespace Bit.Core.Services
|
||||
return _liteDbStorageService;
|
||||
}
|
||||
}
|
||||
|
||||
private void Log(string tag, Storage storage, string key, string value)
|
||||
{
|
||||
// TODO Remove this once all bugs are squished
|
||||
string text;
|
||||
switch (storage)
|
||||
{
|
||||
case Storage.Secure:
|
||||
text = "SECURE / ";
|
||||
break;
|
||||
case Storage.Prefs:
|
||||
text = "PREFS / ";
|
||||
break;
|
||||
default:
|
||||
text = "LITEDB / ";
|
||||
break;
|
||||
}
|
||||
text += "Key: " + key + " / ";
|
||||
if (value != null)
|
||||
{
|
||||
text += "Value: " + value;
|
||||
}
|
||||
Debug.WriteLine(text, ">>> " + tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using Bit.Core.Abstractions;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Enums;
|
||||
@@ -9,7 +8,6 @@ using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@@ -48,7 +46,6 @@ namespace Bit.Core.Services
|
||||
{
|
||||
return true;
|
||||
}
|
||||
await CheckStateAsync();
|
||||
return userId == await GetActiveUserIdAsync();
|
||||
}
|
||||
|
||||
@@ -160,8 +157,9 @@ namespace Bit.Core.Services
|
||||
await CheckStateAsync();
|
||||
await RemoveAccountAsync(userId, userInitiated);
|
||||
|
||||
// If user initiated logout (not vault timeout) find the next user to make active, if any
|
||||
if (userInitiated && _state?.Accounts != null)
|
||||
// If user initiated logout (not vault timeout) and ActiveUserId is null after account removal, find the
|
||||
// next user to make active, if any
|
||||
if (userInitiated && _state?.ActiveUserId == null && _state?.Accounts != null)
|
||||
{
|
||||
foreach (var account in _state.Accounts)
|
||||
{
|
||||
@@ -470,6 +468,15 @@ namespace Bit.Core.Services
|
||||
))?.Profile?.Name;
|
||||
}
|
||||
|
||||
public async Task SetNameAsync(string value, string userId = null)
|
||||
{
|
||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
||||
await GetDefaultStorageOptionsAsync());
|
||||
var account = await GetAccountAsync(reconciledOptions);
|
||||
account.Profile.Name = value;
|
||||
await SaveAccountAsync(account, reconciledOptions);
|
||||
}
|
||||
|
||||
public async Task<string> GetOrgIdentifierAsync(string userId = null)
|
||||
{
|
||||
return (await GetAccountAsync(
|
||||
@@ -525,20 +532,18 @@ namespace Bit.Core.Services
|
||||
await SaveAccountAsync(account, reconciledOptions);
|
||||
}
|
||||
|
||||
public async Task<DateTime?> GetLastFileCacheClearAsync(string userId = null)
|
||||
public async Task<DateTime?> GetLastFileCacheClearAsync()
|
||||
{
|
||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
||||
await GetDefaultStorageOptionsAsync());
|
||||
var options = await GetDefaultStorageOptionsAsync();
|
||||
var key = Constants.LastFileCacheClearKey;
|
||||
return await GetValueAsync<DateTime?>(key, reconciledOptions);
|
||||
return await GetValueAsync<DateTime?>(key, options);
|
||||
}
|
||||
|
||||
public async Task SetLastFileCacheClearAsync(DateTime? value, string userId = null)
|
||||
public async Task SetLastFileCacheClearAsync(DateTime? value)
|
||||
{
|
||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
||||
await GetDefaultStorageOptionsAsync());
|
||||
var options = await GetDefaultStorageOptionsAsync();
|
||||
var key = Constants.LastFileCacheClearKey;
|
||||
await SetValueAsync(key, value, reconciledOptions);
|
||||
await SetValueAsync(key, value, options);
|
||||
}
|
||||
|
||||
public async Task<PreviousPageInfo> GetPreviousPageInfoAsync(string userId = null)
|
||||
@@ -1176,25 +1181,26 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task<T> GetValueAsync<T>(string key, StorageOptions options)
|
||||
{
|
||||
var value = await GetStorageService(options).GetAsync<T>(key);
|
||||
Log("GET", options, key, JsonConvert.SerializeObject(value));
|
||||
return value;
|
||||
return await GetStorageService(options).GetAsync<T>(key);
|
||||
}
|
||||
|
||||
private async Task SetValueAsync<T>(string key, T value, StorageOptions options)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
Log("REMOVE", options, key, null);
|
||||
await GetStorageService(options).RemoveAsync(key);
|
||||
return;
|
||||
}
|
||||
Log("SET", options, key, JsonConvert.SerializeObject(value));
|
||||
await GetStorageService(options).SaveAsync(key, value);
|
||||
}
|
||||
|
||||
private async Task SetValueGloballyAsync<T>(Func<string, string> keyPrefix, T value, StorageOptions options)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
// don't remove values globally
|
||||
return;
|
||||
}
|
||||
await CheckStateAsync();
|
||||
if (_state?.Accounts == null)
|
||||
{
|
||||
@@ -1237,14 +1243,11 @@ namespace Bit.Core.Services
|
||||
}
|
||||
|
||||
// Storage
|
||||
_state = await GetStateFromStorageAsync();
|
||||
if (_state?.Accounts?.ContainsKey(options.UserId) ?? false)
|
||||
var state = await GetStateFromStorageAsync();
|
||||
if (state?.Accounts?.ContainsKey(options.UserId) ?? false)
|
||||
{
|
||||
if (_state.Accounts[options.UserId].VolatileData == null)
|
||||
{
|
||||
_state.Accounts[options.UserId].VolatileData = new Account.AccountVolatileData();
|
||||
}
|
||||
return _state.Accounts[options.UserId];
|
||||
state.Accounts[options.UserId].VolatileData = new Account.AccountVolatileData();
|
||||
return state.Accounts[options.UserId];
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -1312,8 +1315,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
_state.Accounts[userId].Tokens.AccessToken = null;
|
||||
_state.Accounts[userId].Tokens.RefreshToken = null;
|
||||
_state.Accounts[userId].VolatileData.Key = null;
|
||||
_state.Accounts[userId].VolatileData.BiometricLocked = null;
|
||||
_state.Accounts[userId].VolatileData = null;
|
||||
}
|
||||
}
|
||||
if (userInitiated && _state?.ActiveUserId == userId)
|
||||
@@ -1357,7 +1359,6 @@ namespace Bit.Core.Services
|
||||
await SetOrgKeysEncryptedAsync(null, userId);
|
||||
await SetPrivateKeyEncryptedAsync(null, userId);
|
||||
await SetLastActiveTimeAsync(null, userId);
|
||||
await SetLastFileCacheClearAsync(null, userId);
|
||||
await SetPreviousPageInfoAsync(null, userId);
|
||||
await SetInvalidUnlockAttemptsAsync(null, userId);
|
||||
await SetLocalDataAsync(null, userId);
|
||||
@@ -1505,19 +1506,12 @@ namespace Bit.Core.Services
|
||||
|
||||
private async Task<State> GetStateFromStorageAsync()
|
||||
{
|
||||
var state = await _storageService.GetAsync<State>(Constants.StateKey);
|
||||
// TODO Remove logging once all bugs are squished
|
||||
Debug.WriteLine(JsonConvert.SerializeObject(state, Formatting.Indented),
|
||||
">>> GetStateFromStorageAsync()");
|
||||
return state;
|
||||
return await _storageService.GetAsync<State>(Constants.StateKey);
|
||||
}
|
||||
|
||||
private async Task SaveStateToStorageAsync(State state)
|
||||
{
|
||||
await _storageService.SaveAsync(Constants.StateKey, state);
|
||||
// TODO Remove logging once all bugs are squished
|
||||
Debug.WriteLine(JsonConvert.SerializeObject(state, Formatting.Indented),
|
||||
">>> SaveStateToStorageAsync()");
|
||||
}
|
||||
|
||||
private async Task CheckStateAsync()
|
||||
@@ -1560,17 +1554,5 @@ namespace Bit.Core.Services
|
||||
}
|
||||
throw new Exception("User does not exist in account list");
|
||||
}
|
||||
|
||||
private void Log(string tag, StorageOptions options, string key, string value)
|
||||
{
|
||||
// TODO Remove this once all bugs are squished
|
||||
var text = options?.UseSecureStorage ?? false ? "SECURE / " : "";
|
||||
text += "Key: " + key + " / ";
|
||||
if (value != null)
|
||||
{
|
||||
text += "Value: " + value;
|
||||
}
|
||||
Debug.WriteLine(text, ">>> " + tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,6 +327,7 @@ namespace Bit.Core.Services
|
||||
var organizations = response.Organizations.ToDictionary(o => o.Id, o => new OrganizationData(o));
|
||||
await _organizationService.ReplaceAsync(organizations);
|
||||
await _stateService.SetEmailVerifiedAsync(response.EmailVerified);
|
||||
await _stateService.SetNameAsync(response.Name);
|
||||
await _keyConnectorService.SetUsesKeyConnector(response.UsesKeyConnector);
|
||||
}
|
||||
|
||||
|
||||
@@ -208,6 +208,10 @@ namespace Bit.Core.Services
|
||||
if (_accessTokenForDecoding == null)
|
||||
{
|
||||
await GetTokenAsync();
|
||||
if (_accessTokenForDecoding == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var decoded = DecodeToken();
|
||||
if (decoded?["amr"] == null)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user