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

Compare commits

..

1 Commits

Author SHA1 Message Date
Rico Acosta
8a1bc79eba Update config.yml
CS wants to bring more attention to the autofill report, requests changing to UPPCASE
2023-01-24 15:57:46 -06:00
258 changed files with 3981 additions and 17492 deletions

View File

@@ -1,6 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: Report mobile autofill failure
- name: Report mobile AUTOFILL failure
url: https://docs.google.com/forms/d/e/1FAIpQLScMopHyN7KGJs8hW562VTzbIGL4KcFnx0wJcsW0GYE1BnPiGA/viewform
about: We are aware of some situations where the Bitwarden mobile app will not autofill information correctly. This is something the Bitwarden team is actively working on but need your help as a community and active Bitwarden users!
- name: Feature Requests

View File

@@ -7,13 +7,13 @@
<key>provisioningProfiles</key>
<dict>
<key>com.8bit.bitwarden</key>
<string>Dist: Bitwarden</string>
<string>Dist: Bitwarden 2021</string>
<key>com.8bit.bitwarden.autofill</key>
<string>Dist: Autofill</string>
<string>Dist: Autofill 2021</string>
<key>com.8bit.bitwarden.find-login-action-extension</key>
<string>Dist: Extension</string>
<string>Dist: Extension 2021</string>
<key>com.8bit.bitwarden.share-extension</key>
<string>Dist: Share Extension</string>
<string>Dist: Share Extension 2021</string>
<key>com.8bit.bitwarden.watchkitapp</key>
<string>Dist: Bitwarden Watch App</string>
<key>com.8bit.bitwarden.watchkitapp.watchkitextension</key>

Binary file not shown.

Binary file not shown.

View File

@@ -37,8 +37,6 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
with:
submodules: 'true'
- name: Check if special branches exist
id: branch-check
@@ -74,9 +72,6 @@ jobs:
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
- name: Setup Windows builder
run: choco install checksum --no-progress
- name: Work Around for broken Windows 2022 Runner Image
run: |
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
@@ -153,7 +148,7 @@ jobs:
shell: pwsh
- name: Run Core tests
run: dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx"
run: dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx" || true
shell: pwsh
- name: Report test results
@@ -254,34 +249,6 @@ jobs:
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
if-no-files-found: error
- name: Create checksum for Prod .apk artifact
if: ${{ matrix.variant == 'prod' }}
run: |
checksum -f="./com.x8bit.bitwarden.apk" `
-t sha256 | Out-File -Encoding ASCII ./bw-android-apk-sha256.txt
- name: Create checksum for Other .apk artifact
if: ${{ matrix.variant != 'prod' }}
run: |
checksum -f="./com.x8bit.bitwarden.${{ matrix.variant }}.apk" `
-t sha256 | Out-File -Encoding ASCII ./bw-android-${{ matrix.variant }}-apk-sha256.txt
- name: Upload .apk sha file for prod
if: ${{ matrix.variant == 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: bw-android-apk-sha256.txt
path: ./bw-android-apk-sha256.txt
if-no-files-found: error
- name: Upload .apk sha file for other
if: ${{ matrix.variant != 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: bw-android-${{ matrix.variant }}-apk-sha256.txt
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt
if-no-files-found: error
- name: Deploy to Play Store
if: ${{ matrix.variant == 'prod' && (( github.ref == 'refs/heads/master'
&& needs.setup.outputs.rc_branch_exists == 0
@@ -310,9 +277,6 @@ jobs:
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
- name: Setup Windows builder
run: choco install checksum --no-progress
- name: Work Around for broken Windows 2022 Runner Image
run: |
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
@@ -483,18 +447,6 @@ jobs:
path: ./com.x8bit.bitwarden-fdroid.apk
if-no-files-found: error
- name: Create checksum for F-Droid artifact
run: |
checksum -f="./com.x8bit.bitwarden-fdroid.apk" `
-t sha256 | Out-File -Encoding ASCII ./bw-fdroid-apk-sha256.txt
- name: Upload F-Droid sha file
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
with:
name: bw-fdroid-apk-sha256.txt
path: ./bw-fdroid-apk-sha256.txt
if-no-files-found: error
ios:
name: Apple iOS
@@ -516,8 +468,6 @@ jobs:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
with:
submodules: 'true'
- name: Login to Azure - Prod Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf

View File

@@ -64,7 +64,7 @@ jobs:
environment: 'production'
description: 'Deployment ${{ steps.version.outputs.version }} from branch ${{ steps.branch.outputs.branch-name }}'
task: release
- name: Download all artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
@@ -92,9 +92,7 @@ jobs:
artifacts: "./com.x8bit.bitwarden.aab/com.x8bit.bitwarden.aab,
./com.x8bit.bitwarden.apk/com.x8bit.bitwarden.apk,
./com.x8bit.bitwarden-fdroid.apk/com.x8bit.bitwarden-fdroid.apk,
./Bitwarden iOS.zip,
./bw-android-apk-sha256.txt/bw-android-apk-sha256.txt,
./bw-fdroid-apk-sha256.txt/bw-fdroid-apk-sha256.txt"
./Bitwarden iOS.zip"
commit: ${{ github.sha }}
tag: v${{ steps.version.outputs.version }}
name: Version ${{ steps.version.outputs.version }}

View File

@@ -32,14 +32,32 @@ jobs:
echo "new-version=$NEW_VER" >> $GITHUB_OUTPUT
trigger_version_bump:
name: "Version bump"
name: "Trigger version bump workflow"
runs-on: ubuntu-22.04
needs:
- setup
steps:
- name: Bump version to ${{ needs.setup.outputs.version_number }}
uses: ./.github/workflows/version-bump.yml
secrets:
AZURE_PROD_KV_CREDENTIALS: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Login to Azure
uses: Azure/login@ec3c14589bd3e9312b3cc8c41e6860e258df9010
with:
version_number: ${{ needs.setup.outputs.version_number }}
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
with:
keyvault: "bitwarden-prod-kv"
secrets: "github-pat-bitwarden-devops-bot-repo-scope"
- name: Call GitHub API to trigger workflow bump
env:
TOKEN: ${{ steps.retrieve-secrets.outputs.github-pat-bitwarden-devops-bot-repo-scope }}
VERSION: ${{ needs.setup.outputs.version_number}}
run: |
JSON_STRING=$(printf '{"ref":"master", "inputs": { "version_number":"%s"}}' "$VERSION")
curl \
-X POST \
-i -u bitwarden-devops-bot:$TOKEN \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/bitwarden/mobile/actions/workflows/version-bump.yml/dispatches \
-d $JSON_STRING

View File

@@ -7,13 +7,6 @@ on:
version_number:
description: "New Version"
required: true
workflow_call:
inputs:
version_number:
required: true
secrets:
AZURE_PROD_KV_CREDENTIALS:
required: true
jobs:
bump_version:

1
.gitignore vendored
View File

@@ -30,7 +30,6 @@ Components/
[Rr]eleases/
x64/
x86/
!src/lib/x86/
build/
bld/
[Bb]in/

3
.gitmodules vendored
View File

@@ -1,3 +0,0 @@
[submodule "lib/MessagePack"]
path = lib/MessagePack
url = https://github.com/bitwarden/MessagePack.git

View File

@@ -23,3 +23,15 @@ Interested in contributing in a big way? Consider joining our team! We're hiring
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [Contributing Guidelines](https://contributing.bitwarden.com/contributing/). Check out the [Contributing Documentation](https://contributing.bitwarden.com/) for how to get started with your first contribution.
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
### Dotnet-format
We recently migrated to using dotnet-format as code formatter. All previous branches will need to updated to avoid large merge conflicts using the following steps:
1. Check out your local Branch
2. Run `git merge e0efcfbe45b2a27c73e9593bfd7a71fad2aa7a35`
3. Resolve any merge conflicts, commit.
4. Run `dotnet tool run dotnet-format`
5. Commit
6. Run `git merge -Xours 04539af2a66668b6e85476d5cf318c9150ec4357`
7. Push

View File

@@ -1,11 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_41_29)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.214 34C70.7096 34 71.1457 34.1883 71.5124 34.555C71.8791 34.9217 72.0674 35.3479 72.0971 35.8534V50.4336H71.0669V51.9453H72.0971V58.0938C72.0971 59.749 71.7701 61.3942 71.1258 63.0295C70.4816 64.6549 69.6788 66.1019 68.7274 67.3706C67.766 68.6293 66.6262 69.8582 65.308 71.0575C63.98 72.2567 62.7609 73.2478 61.6409 74.0407C60.521 74.8237 59.3515 75.5769 58.1324 76.2806C56.9134 76.9843 56.0511 77.4699 55.5357 77.7177C55.0303 77.9655 54.614 78.1538 54.3068 78.2926C54.0788 78.4115 53.8211 78.471 53.5535 78.471C53.2859 78.471 53.0282 78.4115 52.8003 78.2926C52.5297 78.1791 52.1822 78.0118 51.7511 77.8042C51.6927 77.7761 51.6328 77.7473 51.5713 77.7177C51.0559 77.46 50.1937 76.9843 48.9746 76.2806C47.7555 75.5769 46.586 74.8336 45.4661 74.0407C44.3461 73.2478 43.1172 72.2567 41.799 71.0575C40.4709 69.8682 39.3311 68.6392 38.3797 67.3706C37.4183 66.1119 36.6155 64.6648 35.9713 63.0295C35.3271 61.4041 35 59.749 35 58.0938V35.8534C35 35.3479 35.1883 34.9217 35.555 34.555C35.9217 34.1883 36.3479 34 36.8534 34H70.214ZM67.211 57.5H70.1118V59H67.177C66.4282 66.7468 53.5337 73.2875 53.5337 73.2875V38.7573H67.211V50.4336H70.1118V51.9219H67.211V53.8027H69.895V55.291H67.211V57.5Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58 46C56.3431 46 55 47.3431 55 49V60C55 61.6569 56.3431 63 58 63H107C108.657 63 110 61.6569 110 60V49C110 47.3431 108.657 46 107 46H58ZM59.7817 50.4336H57.1157V59H60.3208C60.9692 59 61.5278 58.9023 61.9966 58.707C62.4692 58.5078 62.8325 58.2227 63.0864 57.8516C63.3403 57.4805 63.4673 57.0352 63.4673 56.5156C63.4673 56.0664 63.397 55.707 63.2563 55.4375C63.1196 55.1641 62.936 54.957 62.7056 54.8164C62.4751 54.6719 62.2173 54.5703 61.9321 54.5117V54.4531C62.2134 54.4023 62.4517 54.293 62.647 54.125C62.8423 53.957 62.9907 53.7422 63.0923 53.4805C63.1978 53.2188 63.2505 52.9258 63.2505 52.6016C63.2505 51.7969 62.9575 51.2344 62.3716 50.9141C61.7856 50.5938 60.9224 50.4336 59.7817 50.4336ZM59.9868 53.8262H58.9321V51.9219H59.8872C60.4067 51.9219 60.7856 51.9941 61.0239 52.1387C61.2661 52.2793 61.3872 52.5137 61.3872 52.8418C61.3872 53.166 61.2856 53.4121 61.0825 53.5801C60.8794 53.7441 60.5142 53.8262 59.9868 53.8262ZM58.9321 57.5V55.2676H60.0571C60.4438 55.2676 60.7466 55.3125 60.9653 55.4023C61.188 55.4922 61.3462 55.6172 61.4399 55.7773C61.5337 55.9375 61.5806 56.123 61.5806 56.334C61.5806 56.6895 61.4731 56.9727 61.2583 57.1836C61.0435 57.3945 60.6626 57.5 60.1157 57.5H58.9321ZM65.1782 59H70.1118V57.5H66.9946V55.291H69.895V53.8027H66.9946V51.9219H70.1118V50.4336H65.1782V59ZM73.3931 59H75.2095V51.9453H77.5356V50.4336H71.0669V51.9453H73.3931V59ZM83.4771 56.9609L84.0981 59H86.0552L83.02 50.3984H80.7993L77.7759 59H79.7329L80.354 56.9609H83.4771ZM82.4224 53.4453L83.0435 55.4375H80.811L81.4263 53.4453C81.4536 53.3555 81.4985 53.2051 81.561 52.9941C81.6235 52.7832 81.688 52.5605 81.7544 52.3262C81.8247 52.0879 81.8794 51.8887 81.9185 51.7285C81.9575 51.8887 82.0083 52.0781 82.0708 52.2969C82.1372 52.5117 82.2017 52.7246 82.2642 52.9355C82.3306 53.1426 82.3833 53.3125 82.4224 53.4453Z" fill="#6795E8"/>
</g>
<defs>
<clipPath id="clip0_41_29">
<rect width="108" height="108" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,17 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_36_10)">
<path d="M71.5717 34.6343L113 76.0625L89.709 119.077L40.6492 70.0168L53.5336 77.4501L70.8779 60.1057L71.5717 34.6343Z" fill="url(#paint0_linear_36_10)"/>
<path d="M71.5124 34.555C71.1457 34.1883 70.7096 34 70.214 34H36.8534C36.3479 34 35.9217 34.1883 35.555 34.555C35.1883 34.9217 35 35.3479 35 35.8534V58.0938C35 59.749 35.3271 61.4041 35.9713 63.0295C36.6155 64.6648 37.4183 66.1119 38.3797 67.3706C39.3311 68.6392 40.4709 69.8682 41.799 71.0575C43.1172 72.2567 44.3461 73.2478 45.4661 74.0407C46.586 74.8336 47.7555 75.5769 48.9746 76.2806C50.1937 76.9843 51.0559 77.46 51.5713 77.7177C52.0867 77.9655 52.493 78.1637 52.8003 78.2926C53.0282 78.4115 53.2859 78.471 53.5535 78.471C53.8211 78.471 54.0788 78.4115 54.3068 78.2926C54.614 78.1538 55.0303 77.9655 55.5357 77.7177C56.0511 77.4699 56.9134 76.9843 58.1324 76.2806C59.3515 75.5769 60.521 74.8237 61.6409 74.0407C62.7609 73.2478 63.98 72.2567 65.308 71.0575C66.6262 69.8582 67.766 68.6293 68.7274 67.3706C69.6788 66.1019 70.4816 64.6549 71.1258 63.0295C71.7701 61.3942 72.0971 59.749 72.0971 58.0938V35.8534C72.0674 35.3479 71.8791 34.9217 71.5124 34.555ZM67.211 58.3019C67.211 66.3497 53.5337 73.2875 53.5337 73.2875V38.7573H67.211C67.211 38.7573 67.211 50.2542 67.211 58.3019Z" fill="white"/>
<path d="M55 49C55 47.3431 56.3431 46 58 46H107C108.657 46 110 47.3431 110 49V60C110 61.6569 108.657 63 107 63H58C56.3431 63 55 61.6569 55 60V49Z" fill="#6795E8"/>
<path d="M57.116 50.4336H59.782C60.9226 50.4336 61.7859 50.5938 62.3718 50.9141C62.9578 51.2344 63.2507 51.7969 63.2507 52.6016C63.2507 52.9258 63.198 53.2188 63.0925 53.4805C62.991 53.7422 62.8425 53.957 62.6472 54.125C62.4519 54.293 62.2136 54.4023 61.9324 54.4531V54.5117C62.2175 54.5703 62.4753 54.6719 62.7058 54.8164C62.9363 54.957 63.1199 55.1641 63.2566 55.4375C63.3972 55.707 63.4675 56.0664 63.4675 56.5156C63.4675 57.0352 63.3406 57.4805 63.0867 57.8516C62.8328 58.2227 62.4695 58.5078 61.9968 58.707C61.5281 58.9023 60.9695 59 60.321 59H57.116V50.4336ZM58.9324 53.8262H59.9871C60.5144 53.8262 60.8796 53.7441 61.0828 53.5801C61.2859 53.4121 61.3875 53.166 61.3875 52.8418C61.3875 52.5137 61.2664 52.2793 61.0242 52.1387C60.7859 51.9941 60.407 51.9219 59.8875 51.9219H58.9324V53.8262ZM58.9324 55.2676V57.5H60.116C60.6628 57.5 61.0437 57.3945 61.2585 57.1836C61.4734 56.9727 61.5808 56.6895 61.5808 56.334C61.5808 56.123 61.5339 55.9375 61.4402 55.7773C61.3464 55.6172 61.1882 55.4922 60.9656 55.4023C60.7468 55.3125 60.4441 55.2676 60.0574 55.2676H58.9324ZM70.1121 59H65.1785V50.4336H70.1121V51.9219H66.9949V53.8027H69.8953V55.291H66.9949V57.5H70.1121V59ZM75.2097 59H73.3933V51.9453H71.0671V50.4336H77.5359V51.9453H75.2097V59ZM84.0984 59L83.4773 56.9609H80.3542L79.7332 59H77.7761L80.7996 50.3984H83.0203L86.0554 59H84.0984ZM83.0437 55.4375L82.4226 53.4453C82.3835 53.3125 82.3308 53.1426 82.2644 52.9355C82.2019 52.7246 82.1375 52.5117 82.071 52.2969C82.0085 52.0781 81.9578 51.8887 81.9187 51.7285C81.8796 51.8887 81.825 52.0879 81.7546 52.3262C81.6882 52.5605 81.6238 52.7832 81.5613 52.9941C81.4988 53.2051 81.4539 53.3555 81.4265 53.4453L80.8113 55.4375H83.0437Z" fill="#212529"/>
</g>
<defs>
<linearGradient id="paint0_linear_36_10" x1="37.8512" y1="38.8122" x2="89.011" y2="89.972" gradientUnits="userSpaceOnUse">
<stop stop-opacity="0.247059"/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_36_10">
<rect width="108" height="108" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,11 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_41_21)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.214 34C70.7096 34 71.1457 34.1883 71.5124 34.555C71.8791 34.9217 72.0674 35.3479 72.0971 35.8534V50.4336H71.647L72.0971 51.7604V58.0938C72.0971 59.749 71.7701 61.3942 71.1258 63.0295C70.4816 64.6549 69.6788 66.1019 68.7274 67.3706C67.766 68.6293 66.6262 69.8582 65.308 71.0575C63.98 72.2567 62.7609 73.2478 61.6409 74.0407C60.521 74.8237 59.3515 75.5769 58.1324 76.2806C56.9134 76.9843 56.0511 77.4699 55.5357 77.7177C55.0303 77.9655 54.614 78.1538 54.3068 78.2926C54.0788 78.4115 53.8211 78.471 53.5535 78.471C53.2859 78.471 53.0282 78.4115 52.8003 78.2926C52.5297 78.1791 52.1822 78.0118 51.7511 77.8042C51.6927 77.7761 51.6328 77.7473 51.5713 77.7177C51.0559 77.46 50.1937 76.9843 48.9746 76.2806C47.7555 75.5769 46.586 74.8336 45.4661 74.0407C44.3461 73.2478 43.1172 72.2567 41.799 71.0575C40.4709 69.8682 39.3311 68.6392 38.3797 67.3706C37.4183 66.1119 36.6155 64.6648 35.9713 63.0295C35.3271 61.4041 35 59.749 35 58.0938V35.8534C35 35.3479 35.1883 34.9217 35.555 34.555C35.9217 34.1883 36.3479 34 36.8534 34H70.214ZM67.177 59C66.4282 66.7468 53.5337 73.2875 53.5337 73.2875V38.7573H67.211V50.4336H70.9321V51.9219H67.8149V53.8027H70.7153V55.291H67.8149V57.5H70.9321V59H67.177Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58 46C56.3431 46 55 47.3431 55 49V60C55 61.6569 56.3431 63 58 63H107C108.657 63 110 61.6569 110 60V49C110 47.3431 108.657 46 107 46H58ZM63.6665 57.0547C64.0376 56.4062 64.2231 55.5996 64.2231 54.6348C64.2231 53.7168 64.0415 52.9473 63.6782 52.3262C63.3149 51.7012 62.8032 51.2305 62.1431 50.9141C61.4829 50.5938 60.7036 50.4336 59.8052 50.4336H57.1157V59H59.5415C60.5259 59 61.3677 58.8379 62.0669 58.5137C62.7661 58.1855 63.2993 57.6992 63.6665 57.0547ZM62.0552 53.123C62.2427 53.5293 62.3364 54.0488 62.3364 54.6816C62.3364 55.6152 62.1196 56.3184 61.686 56.791C61.2563 57.2637 60.5981 57.5 59.7114 57.5H58.9321V51.9219H59.8989C60.4302 51.9219 60.8755 52.0195 61.2349 52.2148C61.5981 52.4102 61.8716 52.7129 62.0552 53.123ZM65.9985 59H70.9321V57.5H67.8149V55.291H70.7153V53.8027H67.8149V51.9219H70.9321V50.4336H65.9985V59ZM76.5337 59L79.4458 50.4336H77.6118L75.9888 55.5312C75.9614 55.6211 75.9165 55.7852 75.854 56.0234C75.7954 56.2578 75.7349 56.5059 75.6724 56.7676C75.6138 57.0293 75.5728 57.2461 75.5493 57.418C75.5259 57.2461 75.481 57.0293 75.4146 56.7676C75.3521 56.502 75.2896 56.252 75.2271 56.0176C75.1646 55.7793 75.1196 55.6172 75.0923 55.5312L73.481 50.4336H71.647L74.5532 59H76.5337Z" fill="#2DA49D"/>
</g>
<defs>
<clipPath id="clip0_41_21">
<rect width="108" height="108" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,17 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_36_2)">
<path d="M71.5717 34.6343L113 76.0625L89.709 119.077L40.6492 70.0168L53.5336 77.4501L70.8779 60.1057L71.5717 34.6343Z" fill="url(#paint0_linear_36_2)"/>
<path d="M71.5124 34.555C71.1457 34.1883 70.7096 34 70.214 34H36.8534C36.3479 34 35.9217 34.1883 35.555 34.555C35.1883 34.9217 35 35.3479 35 35.8534V58.0938C35 59.749 35.3271 61.4041 35.9713 63.0295C36.6155 64.6648 37.4183 66.1119 38.3797 67.3706C39.3311 68.6392 40.4709 69.8682 41.799 71.0575C43.1172 72.2567 44.3461 73.2478 45.4661 74.0407C46.586 74.8336 47.7555 75.5769 48.9746 76.2806C50.1937 76.9843 51.0559 77.46 51.5713 77.7177C52.0867 77.9655 52.493 78.1637 52.8003 78.2926C53.0282 78.4115 53.2859 78.471 53.5535 78.471C53.8211 78.471 54.0788 78.4115 54.3068 78.2926C54.614 78.1538 55.0303 77.9655 55.5357 77.7177C56.0511 77.4699 56.9134 76.9843 58.1324 76.2806C59.3515 75.5769 60.521 74.8237 61.6409 74.0407C62.7609 73.2478 63.98 72.2567 65.308 71.0575C66.6262 69.8582 67.766 68.6293 68.7274 67.3706C69.6788 66.1019 70.4816 64.6549 71.1258 63.0295C71.7701 61.3942 72.0971 59.749 72.0971 58.0938V35.8534C72.0674 35.3479 71.8791 34.9217 71.5124 34.555ZM67.211 58.3019C67.211 66.3497 53.5337 73.2875 53.5337 73.2875V38.7573H67.211C67.211 38.7573 67.211 50.2542 67.211 58.3019Z" fill="white"/>
<path d="M55 49C55 47.3431 56.3431 46 58 46H107C108.657 46 110 47.3431 110 49V60C110 61.6569 108.657 63 107 63H58C56.3431 63 55 61.6569 55 60V49Z" fill="#2DA49D"/>
<path d="M64.2234 54.6348C64.2234 55.5996 64.0378 56.4062 63.6667 57.0547C63.2996 57.6992 62.7664 58.1855 62.0671 58.5137C61.3679 58.8379 60.5261 59 59.5417 59H57.116V50.4336H59.8054C60.7039 50.4336 61.4832 50.5938 62.1433 50.9141C62.8035 51.2305 63.3152 51.7012 63.6785 52.3262C64.0417 52.9473 64.2234 53.7168 64.2234 54.6348ZM62.3367 54.6816C62.3367 54.0488 62.2429 53.5293 62.0554 53.123C61.8718 52.7129 61.5984 52.4102 61.2351 52.2148C60.8757 52.0195 60.4304 51.9219 59.8992 51.9219H58.9324V57.5H59.7117C60.5984 57.5 61.2566 57.2637 61.6863 56.791C62.1199 56.3184 62.3367 55.6152 62.3367 54.6816ZM70.9324 59H65.9988V50.4336H70.9324V51.9219H67.8152V53.8027H70.7156V55.291H67.8152V57.5H70.9324V59ZM79.446 50.4336L76.5339 59H74.5535L71.6472 50.4336H73.4812L75.0925 55.5312C75.1199 55.6172 75.1648 55.7793 75.2273 56.0176C75.2898 56.252 75.3523 56.502 75.4148 56.7676C75.4812 57.0293 75.5261 57.2461 75.5496 57.418C75.573 57.2461 75.614 57.0293 75.6726 56.7676C75.7351 56.5059 75.7957 56.2578 75.8542 56.0234C75.9167 55.7852 75.9617 55.6211 75.989 55.5312L77.6121 50.4336H79.446Z" fill="#212529"/>
</g>
<defs>
<linearGradient id="paint0_linear_36_2" x1="37.8512" y1="38.8122" x2="89.011" y2="89.972" gradientUnits="userSpaceOnUse">
<stop stop-opacity="0.247059"/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_36_2">
<rect width="108" height="108" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -1,11 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_41_13)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.214 34C70.7096 34 71.1457 34.1883 71.5124 34.555C71.8791 34.9217 72.0674 35.3479 72.0971 35.8534V52.9823L70.8325 49.3984H68.6118L67.211 53.3838V38.7573H53.5337V73.2875C53.5337 73.2875 67.211 66.3497 67.211 58.3019V58H67.5454L68.1665 55.9609H71.2896L71.9106 58H72.0971V58.0938C72.0971 59.749 71.7701 61.3942 71.1258 63.0295C70.4816 64.6549 69.6788 66.1019 68.7274 67.3706C67.766 68.6293 66.6262 69.8582 65.308 71.0575C63.98 72.2567 62.7609 73.2478 61.6409 74.0407C60.521 74.8237 59.3515 75.5769 58.1324 76.2806C56.9134 76.9843 56.0511 77.4699 55.5357 77.7177C55.0303 77.9655 54.614 78.1538 54.3068 78.2926C54.0788 78.4115 53.8211 78.471 53.5535 78.471C53.2859 78.471 53.0282 78.4115 52.8003 78.2926C52.5297 78.1791 52.1822 78.0118 51.7511 77.8042C51.6927 77.7761 51.6328 77.7473 51.5713 77.7177C51.0559 77.46 50.1937 76.9843 48.9746 76.2806C47.7555 75.5769 46.586 74.8336 45.4661 74.0407C44.3461 73.2478 43.1172 72.2567 41.799 71.0575C40.4709 69.8682 39.3311 68.6392 38.3797 67.3706C37.4183 66.1119 36.6155 64.6648 35.9713 63.0295C35.3271 61.4041 35 59.749 35 58.0938V35.8534C35 35.3479 35.1883 34.9217 35.555 34.555C35.9217 34.1883 36.3479 34 36.8534 34H70.214ZM70.2349 52.4453L70.856 54.4375H68.6235L69.2388 52.4453C69.2661 52.3555 69.311 52.2051 69.3735 51.9941C69.436 51.7832 69.5005 51.5605 69.5669 51.3262C69.6372 51.0879 69.6919 50.8887 69.731 50.7285C69.77 50.8887 69.8208 51.0781 69.8833 51.2969C69.9497 51.5117 70.0142 51.7246 70.0767 51.9355C70.1431 52.1426 70.1958 52.3125 70.2349 52.4453Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M58 46C56.3431 46 55 47.3431 55 49V60C55 61.6569 56.3431 63 58 63H107C108.657 63 110 61.6569 110 60V49C110 47.3431 108.657 46 107 46H58ZM64.6626 55.457C64.8149 54.9258 64.8911 54.3418 64.8911 53.7051C64.8911 52.8145 64.7446 52.0391 64.4517 51.3789C64.1626 50.7188 63.7173 50.207 63.1157 49.8438C62.5181 49.4805 61.7544 49.2988 60.8247 49.2988C59.8911 49.2988 59.1216 49.4805 58.5161 49.8438C57.9106 50.207 57.4614 50.7188 57.1685 51.3789C56.8794 52.0352 56.7349 52.8066 56.7349 53.6934C56.7349 54.3574 56.8169 54.9609 56.981 55.5039C57.145 56.0469 57.3931 56.5137 57.7251 56.9043C58.061 57.2949 58.4849 57.5957 58.9966 57.8066C59.5083 58.0137 60.1138 58.1172 60.813 58.1172H60.8774H60.9478L62.5181 60.0391H64.8442L62.7817 57.7363C63.2622 57.5176 63.6587 57.2148 63.9712 56.8281C64.2837 56.4414 64.5142 55.9844 64.6626 55.457ZM58.8618 55.252C58.7134 54.8184 58.6392 54.3027 58.6392 53.7051C58.6392 53.1035 58.7134 52.5879 58.8618 52.1582C59.0142 51.7246 59.2505 51.3926 59.5708 51.1621C59.895 50.9277 60.313 50.8105 60.8247 50.8105C61.5942 50.8105 62.147 51.0684 62.4829 51.584C62.8188 52.0996 62.9868 52.8066 62.9868 53.7051C62.9868 54.3027 62.9126 54.8184 62.7642 55.252C62.6196 55.6816 62.3872 56.0137 62.0669 56.248C61.7466 56.4785 61.3286 56.5938 60.813 56.5938C60.3052 56.5938 59.8911 56.4785 59.5708 56.248C59.2505 56.0137 59.0142 55.6816 58.8618 55.252ZM71.2896 55.9609L71.9106 58H73.8677L70.8325 49.3984H68.6118L65.5884 58H67.5454L68.1665 55.9609H71.2896ZM70.2349 52.4453L70.856 54.4375H68.6235L69.2388 52.4453C69.2661 52.3555 69.311 52.2051 69.3735 51.9941C69.436 51.7832 69.5005 51.5605 69.5669 51.3262C69.6372 51.0879 69.6919 50.8887 69.731 50.7285C69.77 50.8887 69.8208 51.0781 69.8833 51.2969C69.9497 51.5117 70.0142 51.7246 70.0767 51.9355C70.1431 52.1426 70.1958 52.3125 70.2349 52.4453Z" fill="#C32998"/>
</g>
<defs>
<clipPath id="clip0_41_13">
<rect width="108" height="108" rx="34" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -1,17 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_34_2)">
<path d="M71.5717 34.6343L113 76.0625L89.709 119.077L40.6492 70.0168L53.5336 77.4501L70.8779 60.1057L71.5717 34.6343Z" fill="url(#paint0_linear_34_2)"/>
<path d="M71.5124 34.555C71.1457 34.1883 70.7096 34 70.214 34H36.8534C36.3479 34 35.9217 34.1883 35.555 34.555C35.1883 34.9217 35 35.3479 35 35.8534V58.0938C35 59.749 35.3271 61.4041 35.9713 63.0295C36.6155 64.6648 37.4183 66.1119 38.3797 67.3706C39.3311 68.6392 40.4709 69.8682 41.799 71.0575C43.1172 72.2567 44.3461 73.2478 45.4661 74.0407C46.586 74.8336 47.7555 75.5769 48.9746 76.2806C50.1937 76.9843 51.0559 77.46 51.5713 77.7177C52.0867 77.9655 52.493 78.1637 52.8003 78.2926C53.0282 78.4115 53.2859 78.471 53.5535 78.471C53.8211 78.471 54.0788 78.4115 54.3068 78.2926C54.614 78.1538 55.0303 77.9655 55.5357 77.7177C56.0511 77.4699 56.9134 76.9843 58.1324 76.2806C59.3515 75.5769 60.521 74.8237 61.6409 74.0407C62.7609 73.2478 63.98 72.2567 65.308 71.0575C66.6262 69.8582 67.766 68.6293 68.7274 67.3706C69.6788 66.1019 70.4816 64.6549 71.1258 63.0295C71.7701 61.3942 72.0971 59.749 72.0971 58.0938V35.8534C72.0674 35.3479 71.8791 34.9217 71.5124 34.555ZM67.211 58.3019C67.211 66.3497 53.5337 73.2875 53.5337 73.2875V38.7573H67.211C67.211 38.7573 67.211 50.2542 67.211 58.3019Z" fill="white"/>
<path d="M55 49C55 47.3431 56.3431 46 58 46H107C108.657 46 110 47.3431 110 49V60C110 61.6569 108.657 63 107 63H58C56.3431 63 55 61.6569 55 60V49Z" fill="#C32998"/>
<path d="M64.8914 53.7051C64.8914 54.3418 64.8152 54.9258 64.6628 55.457C64.5144 55.9844 64.2839 56.4414 63.9714 56.8281C63.6589 57.2148 63.2625 57.5176 62.782 57.7363L64.8445 60.0391H62.5183L60.948 58.1172C60.9207 58.1172 60.8972 58.1172 60.8777 58.1172C60.8582 58.1172 60.8367 58.1172 60.8132 58.1172C60.114 58.1172 59.5085 58.0137 58.9968 57.8066C58.4851 57.5957 58.0613 57.2949 57.7253 56.9043C57.3933 56.5137 57.1453 56.0469 56.9812 55.5039C56.8171 54.9609 56.7351 54.3574 56.7351 53.6934C56.7351 52.8066 56.8796 52.0352 57.1687 51.3789C57.4617 50.7188 57.9109 50.207 58.5164 49.8438C59.1218 49.4805 59.8914 49.2988 60.825 49.2988C61.7546 49.2988 62.5183 49.4805 63.116 49.8438C63.7175 50.207 64.1628 50.7188 64.4519 51.3789C64.7449 52.0391 64.8914 52.8145 64.8914 53.7051ZM58.6394 53.7051C58.6394 54.3027 58.7136 54.8184 58.8621 55.252C59.0144 55.6816 59.2507 56.0137 59.571 56.248C59.8914 56.4785 60.3054 56.5938 60.8132 56.5938C61.3289 56.5938 61.7468 56.4785 62.0671 56.248C62.3875 56.0137 62.6199 55.6816 62.7644 55.252C62.9128 54.8184 62.9871 54.3027 62.9871 53.7051C62.9871 52.8066 62.8191 52.0996 62.4832 51.584C62.1472 51.0684 61.5945 50.8105 60.825 50.8105C60.3132 50.8105 59.8953 50.9277 59.571 51.1621C59.2507 51.3926 59.0144 51.7246 58.8621 52.1582C58.7136 52.5879 58.6394 53.1035 58.6394 53.7051ZM71.9109 58L71.2898 55.9609H68.1667L67.5457 58H65.5886L68.6121 49.3984H70.8328L73.8679 58H71.9109ZM70.8562 54.4375L70.2351 52.4453C70.196 52.3125 70.1433 52.1426 70.0769 51.9355C70.0144 51.7246 69.95 51.5117 69.8835 51.2969C69.821 51.0781 69.7703 50.8887 69.7312 50.7285C69.6921 50.8887 69.6375 51.0879 69.5671 51.3262C69.5007 51.5605 69.4363 51.7832 69.3738 51.9941C69.3113 52.2051 69.2664 52.3555 69.239 52.4453L68.6238 54.4375H70.8562Z" fill="white"/>
</g>
<defs>
<linearGradient id="paint0_linear_34_2" x1="37.8512" y1="38.8122" x2="89.011" y2="89.972" gradientUnits="userSpaceOnUse">
<stop stop-opacity="0.247059"/>
<stop offset="1" stop-opacity="0"/>
</linearGradient>
<clipPath id="clip0_34_2">
<rect width="108" height="108" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,136 +0,0 @@
#! /bin/sh
function print_example() {
echo "Example"
echo " icons ios ~/AppIcon.pdf ~/Icons/"
}
function print_usage() {
echo "Usage"
echo " icons <ios|watch|complication|macos> in-file.pdf (out-dir)"
}
function command_exists() {
if type "$1" >/dev/null 2>&1; then
return 1
else
return 0
fi
}
if command_exists "sips" == 0 ; then
echo "sips tool not found"
exit 1
fi
if [ "$1" = "--help" ] || [ "$1" = "-h" ] ; then
print_usage
exit 0
fi
PLATFORM="$1"
FILE="$2"
if [ -z "$PLATFORM" ] || [ -z "$FILE" ] ; then
echo "Error: missing arguments"
echo ""
print_usage
echo ""
print_example
exit 1
fi
DIR="$3"
if [ -z "$DIR" ] ; then
DIR=$(dirname $FILE)
fi
# Create directory if needed
mkdir -p "$DIR"
if [[ "$PLATFORM" == *"ios"* ]] ; then # iOS
sips -s format png -Z '180' "${FILE}" --out "${DIR}"/Icon-180.png
sips -s format png -Z '29' "${FILE}" --out "${DIR}"/Icon-29.png
sips -s format png -Z '58' "${FILE}" --out "${DIR}"/Icon-58.png
sips -s format png -Z '120' "${FILE}" --out "${DIR}"/Icon-120.png
sips -s format png -Z '87' "${FILE}" --out "${DIR}"/Icon-87.png
sips -s format png -Z '40' "${FILE}" --out "${DIR}"/Icon-40.png
sips -s format png -Z '80' "${FILE}" --out "${DIR}"/Icon-80.png
sips -s format png -Z '76' "${FILE}" --out "${DIR}"/Icon-76.png
sips -s format png -Z '152' "${FILE}" --out "${DIR}"/Icon-152.png
sips -s format png -Z '167' "${FILE}" --out "${DIR}"/Icon-167.png
sips -s format png -Z '60' "${FILE}" --out "${DIR}"/Icon-60.png
sips -s format png -Z '20' "${FILE}" --out "${DIR}"/Icon-20.png
sips -s format png -Z '1024' "${FILE}" --out "${DIR}"/Icon-1024.png
# https://developer.apple.com/library/archive/documentation/Xcode/Reference/xcode_ref-Asset_Catalog_Format/AppIconType.html
contents_json='{"images":[{"size":"20x20","idiom":"iphone","filename":"iPhoneNotification@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"iPhoneNotification@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"iPhoneSettings@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"iPhoneSettings@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"iPhoneSpotlight@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"iPhoneSpotlight@3x.png","scale":"3x"},{"size":"60x60","idiom":"iphone","filename":"iPhone@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"iPhone@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"iPadNotification.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"iPadNotification@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"iPadSettings.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"iPadSettings@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"iPadSpotlight.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"iPadSpotlight@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"iPad.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"iPad@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"iPadPro@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"AppStoreMarketing.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}'
echo $contents_json > "${DIR}"/Contents.json
fi
if [[ "$PLATFORM" == *"watch"* ]] ; then # Apple Watch
sips -s format png -Z '48' "${FILE}" --out "${DIR}"/Watch38mmNotificationCenter.png
sips -s format png -Z '55' "${FILE}" --out "${DIR}"/Watch42mmNotificationCenter.png
sips -s format png -Z '66' "${FILE}" --out "${DIR}"/Watch66NotificationCenter.png
sips -s format png -Z '58' "${FILE}" --out "${DIR}"/WatchCompanionSettings@2x.png
sips -s format png -Z '87' "${FILE}" --out "${DIR}"/WatchCompanionSettings@3x.png
sips -s format png -Z '80' "${FILE}" --out "${DIR}"/Watch38MM42MMHomeScreen.png
sips -s format png -Z '88' "${FILE}" --out "${DIR}"/Watch40MMHomeScreen.png
sips -s format png -Z '92' "${FILE}" --out "${DIR}"/Watch41MMHomeScreen.png
sips -s format png -Z '100' "${FILE}" --out "${DIR}"/Watch44MMHomeScreen.png
sips -s format png -Z '102' "${FILE}" --out "${DIR}"/Watch45MMHomeScreen.png
sips -s format png -Z '108' "${FILE}" --out "${DIR}"/Watch49MMHomeScreen.png
sips -s format png -Z '172' "${FILE}" --out "${DIR}"/Watch38MMShortLook.png
sips -s format png -Z '196' "${FILE}" --out "${DIR}"/Watch40MM42MMShortLook.png
sips -s format png -Z '216' "${FILE}" --out "${DIR}"/Watch44MMShortLook.png
sips -s format png -Z '234' "${FILE}" --out "${DIR}"/Watch234ShortLook.png
sips -s format png -Z '258' "${FILE}" --out "${DIR}"/Watch258ShortLook.png
sips -s format png -Z '1024' "${FILE}" --out "${DIR}"/WatchAppStore.png
# https://developer.apple.com/library/archive/documentation/Xcode/Reference/xcode_ref-Asset_Catalog_Format/AppIconType.html
contents_json='{"images":[{"size":"24x24","idiom":"watch","scale":"2x","filename":"Watch38mmNotificationCenter.png","role":"notificationCenter","subtype":"38mm"},{"size":"27.5x27.5","idiom":"watch","scale":"2x","filename":"Watch42mmNotificationCenter.png","role":"notificationCenter","subtype":"42mm"},{"size":"29x29","idiom":"watch","filename":"WatchCompanionSettings@2x.png","role":"companionSettings","scale":"2x"},{"size":"29x29","idiom":"watch","filename":"WatchCompanionSettings@3x.png","role":"companionSettings","scale":"3x"},{"size":"40x40","idiom":"watch","filename":"Watch38MM42MMHomeScreen.png","scale":"2x","role":"appLauncher","subtype":"38mm"},{"size":"44x44","idiom":"watch","scale":"2x","filename":"Watch40MMHomeScreen.png","role":"appLauncher","subtype":"40mm"},{"size":"50x50","idiom":"watch","scale":"2x","filename":"Watch44MMHomeScreen.png","role":"appLauncher","subtype":"44mm"},{"size":"86x86","idiom":"watch","scale":"2x","filename":"Watch38MMShortLook.png","role":"quickLook","subtype":"38mm"},{"size":"98x98","idiom":"watch","scale":"2x","filename":"Watch40MM42MMShortLook.png","role":"quickLook","subtype":"42mm"},{"size":"108x108","idiom":"watch","scale":"2x","filename":"Watch44MMShortLook.png","role":"quickLook","subtype":"44mm"},{"idiom":"watch-marketing","filename":"WatchAppStore.png","size":"1024x1024","scale":"1x"}],"info":{"version":1,"author":"xcode"}}'
echo $contents_json > "${DIR}"/Contents.json
fi
if [[ "$PLATFORM" == *"complication"* ]] ; then # Apple Watch
sips -s format png -Z '32' "${FILE}" --out "${DIR}"/Circular38mm2x.png
sips -s format png -Z '36' "${FILE}" --out "${DIR}"/Circular40mm2x.png
sips -s format png -Z '36' "${FILE}" --out "${DIR}"/Circular42mm2x.png
sips -s format png -Z '40' "${FILE}" --out "${DIR}"/Circular44mm2x.png
sips -s format png -Z '182' "${FILE}" --out "${DIR}"/ExtraLarge38mm2x.png
sips -s format png -Z '203' "${FILE}" --out "${DIR}"/ExtraLarge40mm2x.png
sips -s format png -Z '203' "${FILE}" --out "${DIR}"/ExtraLarge42mm2x.png
sips -s format png -Z '224' "${FILE}" --out "${DIR}"/ExtraLarge44mm2x.png
sips -s format png -Z '84' "${FILE}" --out "${DIR}"/GraphicBezel40mm2x.png
sips -s format png -Z '84' "${FILE}" --out "${DIR}"/GraphicBezel42mm2x.png
sips -s format png -Z '94' "${FILE}" --out "${DIR}"/GraphicBezel44mm2x.png
sips -s format png -Z '84' "${FILE}" --out "${DIR}"/GraphicCircular40mm2x.png
sips -s format png -Z '84' "${FILE}" --out "${DIR}"/GraphicCircular42mm2x.png
sips -s format png -Z '94' "${FILE}" --out "${DIR}"/GraphicCircular44mm2x.png
sips -s format png -Z '40' "${FILE}" --out "${DIR}"/GraphicCorner40mm2x.png
sips -s format png -Z '40' "${FILE}" --out "${DIR}"/GraphicCorner42mm2x.png
sips -s format png -Z '44' "${FILE}" --out "${DIR}"/GraphicCorner44mm2x.png
sips -s format png -Z '52' "${FILE}" --out "${DIR}"/GraphicModular38mm2x.png
sips -s format png -Z '58' "${FILE}" --out "${DIR}"/GraphicModular40mm2x.png
sips -s format png -Z '58' "${FILE}" --out "${DIR}"/GraphicModular42mm2x.png
sips -s format png -Z '64' "${FILE}" --out "${DIR}"/GraphicModular44mm2x.png
sips -s format png -Z '40' "${FILE}" --out "${DIR}"/GraphicUtilitarian38mm2x.png
sips -s format png -Z '44' "${FILE}" --out "${DIR}"/GraphicUtilitarian40mm2x.png
sips -s format png -Z '44' "${FILE}" --out "${DIR}"/GraphicUtilitarian42mm2x.png
sips -s format png -Z '50' "${FILE}" --out "${DIR}"/GraphicUtilitarian44mm2x.png
sips -s format png -Z '206' "${FILE}" --out "${DIR}"/GraphicExtraLarge38mm2x.png
sips -s format png -Z '264' "${FILE}" --out "${DIR}"/GraphicExtraLarge44mm2x.png
echo "NOTE: Graphic Extra Large is not generated since that is not rectangular"
fi
if [[ "$PLATFORM" == *"macos"* ]] ; then # macOS
sips -s format png -Z '1024' "${FILE}" --out "${DIR}"/icon_512x512@2x.png
sips -s format png -Z '512' "${FILE}" --out "${DIR}"/icon_512x512.png
sips -s format png -Z '512' "${FILE}" --out "${DIR}"/icon_256x256@2x.png
sips -s format png -Z '256' "${FILE}" --out "${DIR}"/icon_256x256.png
sips -s format png -Z '256' "${FILE}" --out "${DIR}"/icon_128x128@2x.png
sips -s format png -Z '128' "${FILE}" --out "${DIR}"/icon_128x128.png
sips -s format png -Z '64' "${FILE}" --out "${DIR}"/icon_32x32@2x.png
sips -s format png -Z '32' "${FILE}" --out "${DIR}"/icon_32x32.png
sips -s format png -Z '32' "${FILE}" --out "${DIR}"/icon_16x16@2x.png
sips -s format png -Z '16' "${FILE}" --out "${DIR}"/icon_16x16.png
fi

View File

@@ -4,7 +4,6 @@
#addin nuget:?package=Cake.Incubator&version=7.0.0
#tool dotnet:?package=GitVersion.Tool&version=5.10.3
using Path = System.IO.Path;
using System.Text.RegularExpressions;
var debugScript = Argument<bool>("debugScript", false);
var target = Argument("target", "Default");
@@ -36,7 +35,6 @@ VariantConfig GetVariant() => variant.ToLower() switch{
GitVersion _gitVersion; //will be set by GetGitInfo task
var _slnPath = Path.Combine(""); //base path used to access files. If build.cake file is moved, just update this
string _androidPackageName = string.Empty; //will be set by UpdateAndroidManifest task
string _iOSVersionName = string.Empty; //will be set by UpdateiOSPlist task
string CreateFeatureBranch(string prevVersionName, GitVersion git) => $"{prevVersionName}-{git.BranchName.Replace("/","-")}";
string GetVersionName(string prevVersionName, VariantConfig buildVariant, GitVersion git) => buildVariant is Prod? prevVersionName : CreateFeatureBranch(prevVersionName, git);
int CreateBuildNumber(int previousNumber) => ++previousNumber;
@@ -165,8 +163,7 @@ enum iOSProjectType
MainApp,
Autofill,
Extension,
ShareExtension,
WatchApp
ShareExtension
}
string GetiOSBundleId(VariantConfig buildVariant, iOSProjectType projectType) => projectType switch
@@ -174,7 +171,6 @@ string GetiOSBundleId(VariantConfig buildVariant, iOSProjectType projectType) =>
iOSProjectType.Autofill => $"{buildVariant.iOSBundleId}.autofill",
iOSProjectType.Extension => $"{buildVariant.iOSBundleId}.find-login-action-extension",
iOSProjectType.ShareExtension => $"{buildVariant.iOSBundleId}.share-extension",
iOSProjectType.WatchApp => $"{buildVariant.iOSBundleId}.watchkitapp",
_ => buildVariant.iOSBundleId
};
@@ -209,7 +205,6 @@ private void UpdateiOSInfoPlist(string plistPath, VariantConfig buildVariant, Gi
if(projectType == iOSProjectType.MainApp)
{
_iOSVersionName = newVersionName;
plist["CFBundleURLTypes"][0]["CFBundleURLName"] = $"{buildVariant.iOSBundleId}.url";
}
@@ -245,79 +240,10 @@ private void UpdateiOSEntitlementsPlist(string entitlementsPath, VariantConfig b
Information($"{entitlementsPath} updated with success!");
}
private void UpdateWatchKitAppInfoPlist(string plistPath, VariantConfig buildVariant)
{
var plistFile = File(plistPath);
dynamic plist = DeserializePlist(plistFile);
var prevBundleId = plist["NSExtension"]["NSExtensionAttributes"]["WKAppBundleIdentifier"];
var newBundleId = GetiOSBundleId(buildVariant, iOSProjectType.WatchApp);
plist["NSExtension"]["NSExtensionAttributes"]["WKAppBundleIdentifier"] = newBundleId;
SerializePlist(plistFile, plist);
Information($"Changed Bundle Identifier from {prevBundleId} to {newBundleId}");
Information($"{plistPath} updated with success!");
}
private void UpdateWatchPbxproj(string pbxprojPath, string newVersion)
{
var fileText = FileReadText(pbxprojPath);
if (string.IsNullOrEmpty(fileText))
{
throw new Exception($"Couldn't find {pbxprojPath}");
}
const string pattern = @"MARKETING_VERSION = [^;]*;";
fileText = Regex.Replace(fileText, pattern, $"MARKETING_VERSION = {newVersion};");
FileWriteText(pbxprojPath, fileText);
Information($"{pbxprojPath} modified successfully.");
}
/// <summary>
/// Updates the target icons on the given appiconset target
/// taking as source the icon in appIcons/iOS folder for the giving variant
/// </summary>
/// <param name="target">It can be <ios|watch|complication|macos></param>
/// <param name="appiconsetTarget">Folder to copy the generated icons to</param>
private void UpdateAppleIcons(string target, string appiconsetTarget)
{
Information($"Updating {target} App Icons");
var iconsTempDirPath = Path.Combine(_slnPath, "appIcons", "temp");
CreateDirectory(iconsTempDirPath);
var arguments = new ProcessArgumentBuilder();
arguments.Append(target);
arguments.Append(Path.Combine(_slnPath, "appIcons", "iOS", $"{variant}.png"));
arguments.Append(iconsTempDirPath);
using(var process = StartAndReturnProcess(Path.Combine(_slnPath, "appIcons", "icongen.sh"),
new ProcessSettings { Arguments = arguments }))
{
process.WaitForExit();
Information("Exit code: {0}", process.GetExitCode());
}
var generatedIconsPath = Path.Combine(iconsTempDirPath, "*.png");
CopyFiles(generatedIconsPath, appiconsetTarget);
DeleteDirectory(iconsTempDirPath, new DeleteDirectorySettings {
Recursive = true,
Force = true
});
Information($"{target} App Icons have been updated");
}
Task("UpdateiOSIcons")
Task("UpdateiOSIcon")
.Does(()=>{
UpdateAppleIcons("ios", Path.Combine(_slnPath, "src", "iOS", "Resources", "Assets.xcassets", "AppIcons.appiconset"));
UpdateAppleIcons("watch", Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden WatchKit App", "Assets.xcassets", "AppIcon.appiconset"));
// TODO: Update complication icons when they start working
//TODO we'll implement variant icons later
Information($"Updating IOS App Icon");
});
Task("UpdateiOSPlist")
@@ -370,10 +296,8 @@ Task("UpdateiOSCodeFiles")
var fileList = new string[] {
Path.Combine(_slnPath, "src", "iOS.Core", "Utilities", "iOSCoreHelpers.cs"),
Path.Combine(_slnPath, "src", "iOS.Core", "Constants.cs"),
Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden.xcodeproj", "project.pbxproj"),
Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden WatchKit Extension", "Helpers", "KeychainHelper.swift"),
Path.Combine(".github", "resources", "export-options-ad-hoc.plist"),
Path.Combine(".github", "resources", "export-options-app-store.plist")
Path.Combine(".github", "resources", "export-options-app-store.plist"),
};
foreach(string path in fileList)
@@ -381,22 +305,6 @@ Task("UpdateiOSCodeFiles")
ReplaceInFile(path, "com.8bit.bitwarden", buildVariant.iOSBundleId);
}
});
Task("UpdateWatchProject")
.IsDependentOn("UpdateiOSPlist")
.WithCriteria(() => !string.IsNullOrEmpty(_iOSVersionName))
.Does(()=> {
var watchProjectPath = Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden.xcodeproj", "project.pbxproj");
UpdateWatchPbxproj(watchProjectPath, _iOSVersionName);
});
Task("UpdateWatchKitAppInfoPlist")
.Does(()=> {
var buildVariant = GetVariant();
var infoPath = Path.Combine(_slnPath, "src", "watchOS", "bitwarden", "bitwarden WatchKit Extension", "Info.plist");
UpdateWatchKitAppInfoPlist(infoPath, buildVariant);
});
#endregion iOS
#region Main Tasks
@@ -410,14 +318,12 @@ Task("Android")
});
Task("iOS")
.IsDependentOn("UpdateiOSIcons")
//.IsDependentOn("UpdateiOSIcon")
.IsDependentOn("UpdateiOSPlist")
.IsDependentOn("UpdateiOSAutofillPlist")
.IsDependentOn("UpdateiOSExtensionPlist")
.IsDependentOn("UpdateiOSShareExtensionPlist")
.IsDependentOn("UpdateiOSCodeFiles")
.IsDependentOn("UpdateWatchProject")
.IsDependentOn("UpdateWatchKitAppInfoPlist")
.Does(()=>
{
Information("iOS app updated");

Submodule lib/MessagePack deleted from 1ecb15e311

Binary file not shown.

Binary file not shown.

View File

@@ -169,10 +169,6 @@
<GoogleServicesJson Include="google-services.json" />
<GoogleServicesJson Include="google-services.json.enc" />
<None Include="fdroid-keystore.jks.enc" />
<AndroidNativeLibrary Include="lib\arm64-v8a\libargon2.so" />
<AndroidNativeLibrary Include="lib\armeabi-v7a\libargon2.so" />
<AndroidNativeLibrary Include="lib\x86\libargon2.so" />
<AndroidNativeLibrary Include="lib\x86_64\libargon2.so" />
<None Include="Properties\AndroidManifest.xml" />
<None Include="upload-keystore.jks.enc" />
</ItemGroup>

View File

@@ -12,7 +12,6 @@ namespace Bit.Droid.Autofill
private List<Field> _passwordFields = null;
private List<Field> _usernameFields = null;
private HashSet<string> _ignoreSearchTerms = new HashSet<string> { "search", "find", "recipient", "edit" };
private HashSet<string> _usernameTerms = new HashSet<string> { "email", "phone", "username"};
private HashSet<string> _passwordTerms = new HashSet<string> { "password", "pswd" };
public List<AutofillId> AutofillIds { get; private set; } = new List<AutofillId>();
@@ -99,11 +98,6 @@ namespace Bit.Droid.Autofill
_usernameFields.Add(usernameField);
}
}
if (!_usernameFields.Any())
{
_usernameFields = Fields.Where(f => FieldIsUsername(f)).ToList();
}
}
return _usernameFields;
}
@@ -327,23 +321,13 @@ namespace Bit.Droid.Autofill
}
return inputTypePassword && !ValueContainsAnyTerms(f.IdEntry, _ignoreSearchTerms) &&
!ValueContainsAnyTerms(f.Hint, _ignoreSearchTerms) && !FieldIsUsername(f);
!ValueContainsAnyTerms(f.Hint, _ignoreSearchTerms);
}
private bool FieldHasPasswordTerms(Field f)
{
return ValueContainsAnyTerms(f.IdEntry, _passwordTerms) || ValueContainsAnyTerms(f.Hint, _passwordTerms);
}
private bool FieldIsUsername(Field f)
{
return f.InputType.HasFlag(InputTypes.TextVariationWebEmailAddress) || FieldHasUsernameTerms(f);
}
private bool FieldHasUsernameTerms(Field f)
{
return ValueContainsAnyTerms(f.IdEntry, _usernameTerms) || ValueContainsAnyTerms(f.Hint, _usernameTerms);
}
private bool ValueContainsAnyTerms(string value, HashSet<string> terms)
{
@@ -355,4 +339,4 @@ namespace Bit.Droid.Autofill
return terms.Any(t => lowerValue.Contains(t));
}
}
}
}

View File

@@ -170,7 +170,7 @@ namespace Bit.Droid
{
if (intent?.GetStringExtra("uri") is string uri)
{
_messagingService.Send(App.App.POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE);
_messagingService.Send("popAllAndGoToAutofillCiphers");
if (_appOptions != null)
{
_appOptions.Uri = uri;
@@ -178,7 +178,7 @@ namespace Bit.Droid
}
else if (intent.GetBooleanExtra("generatorTile", false))
{
_messagingService.Send(App.App.POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE);
_messagingService.Send("popAllAndGoToTabGenerator");
if (_appOptions != null)
{
_appOptions.GeneratorTile = true;
@@ -186,7 +186,7 @@ namespace Bit.Droid
}
else if (intent.GetBooleanExtra("myVaultTile", false))
{
_messagingService.Send(App.App.POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE);
_messagingService.Send("popAllAndGoToTabMyVault");
if (_appOptions != null)
{
_appOptions.MyVaultTile = true;
@@ -198,7 +198,7 @@ namespace Bit.Droid
{
_appOptions.CreateSend = GetCreateSendRequest(intent);
}
_messagingService.Send(App.App.POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE);
_messagingService.Send("popAllAndGoToTabSend");
}
else
{

View File

@@ -81,8 +81,7 @@ namespace Bit.Droid
ServiceContainer.Resolve<IAuthService>("authService"),
ServiceContainer.Resolve<ILogger>("logger"),
ServiceContainer.Resolve<IMessagingService>("messagingService"),
ServiceContainer.Resolve<IWatchDeviceService>(),
ServiceContainer.Resolve<IConditionedAwaiterManager>());
ServiceContainer.Resolve<IWatchDeviceService>());
ServiceContainer.Register<IAccountsManager>("accountsManager", accountsManager);
}
#if !FDROID
@@ -144,8 +143,7 @@ namespace Bit.Droid
var secureStorageService = new SecureStorageService();
var cryptoPrimitiveService = new CryptoPrimitiveService();
var mobileStorageService = new MobileStorageService(preferencesStorage, liteDbStorage);
var storageMediatorService = new StorageMediatorService(mobileStorageService, secureStorageService, preferencesStorage);
var stateService = new StateService(mobileStorageService, secureStorageService, storageMediatorService, messagingService);
var stateService = new StateService(mobileStorageService, secureStorageService, messagingService);
var stateMigrationService =
new StateMigrationService(liteDbStorage, preferencesStorage, secureStorageService);
var clipboardService = new ClipboardService(stateService);
@@ -160,7 +158,6 @@ namespace Bit.Droid
var cryptoService = new CryptoService(stateService, cryptoFunctionService);
var passwordRepromptService = new MobilePasswordRepromptService(platformUtilsService, cryptoService);
ServiceContainer.Register<ISynchronousStorageService>(preferencesStorage);
ServiceContainer.Register<IBroadcasterService>("broadcasterService", broadcasterService);
ServiceContainer.Register<IMessagingService>("messagingService", messagingService);
ServiceContainer.Register<ILocalizeService>("localizeService", localizeService);
@@ -168,7 +165,6 @@ namespace Bit.Droid
ServiceContainer.Register<ICryptoPrimitiveService>("cryptoPrimitiveService", cryptoPrimitiveService);
ServiceContainer.Register<IStorageService>("storageService", mobileStorageService);
ServiceContainer.Register<IStorageService>("secureStorageService", secureStorageService);
ServiceContainer.Register<IStorageMediatorService>(storageMediatorService);
ServiceContainer.Register<IStateService>("stateService", stateService);
ServiceContainer.Register<IStateMigrationService>("stateMigrationService", stateMigrationService);
ServiceContainer.Register<IClipboardService>("clipboardService", clipboardService);
@@ -201,9 +197,7 @@ namespace Bit.Droid
private void Bootstrap()
{
var locale = ServiceContainer.Resolve<IStateService>().GetLocale();
(ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService)
.Init(locale != null ? new System.Globalization.CultureInfo(locale) : null);
(ServiceContainer.Resolve<II18nService>("i18nService") as MobileI18nService).Init();
ServiceContainer.Resolve<IAuthService>("authService").Init();
// Note: This is not awaited
var bootstrapTask = BootstrapAsync();

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.3.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="2023.1.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.NFC" />
@@ -45,11 +45,11 @@
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" />
<data android:scheme="http"/>
</intent>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
<data android:scheme="https"/>
</intent>
</queries>
</manifest>

View File

@@ -49,6 +49,12 @@ namespace Bit.Droid.Services
}
}
public bool IsCopyNotificationHandledByPlatform()
{
// Android 13+ provides built-in notification when text is copied to the clipboard
return (int)Build.VERSION.SdkInt >= 33;
}
private void CopyToClipboard(string text, bool isSensitive = true)
{
var clipboardManager = Application.Context.GetSystemService(Context.ClipboardService) as ClipboardManager;

View File

@@ -5,8 +5,6 @@ using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using System;
using System.Runtime.InteropServices;
using Java.Lang;
namespace Bit.Droid.Services
{
@@ -35,19 +33,5 @@ namespace Bit.Droid.Services
generator.Init(password, salt, iterations);
return ((KeyParameter)generator.GenerateDerivedMacParameters(keySize)).GetKey();
}
public byte[] Argon2id(byte[] password, byte[] salt, int iterations, int memory, int parallelism)
{
JavaSystem.LoadLibrary("argon2");
int keySize = 32;
var key = new byte[keySize];
argon2id_hash_raw(iterations, memory, parallelism,
password, password.Length, salt, salt.Length, key, key.Length);
return key;
}
[DllImport("argon2", EntryPoint = "argon2id_hash_raw")]
private static extern int argon2id_hash_raw(int timeCost, int memoryCost, int parallelism,
byte[] pwd, int pwdlen, byte[] salt, int saltlen, byte[] hash, int hashlen);
}
}

View File

@@ -502,6 +502,11 @@ namespace Bit.Droid.Services
public async Task SetScreenCaptureAllowedAsync()
{
if (CoreHelpers.ForceScreenCaptureEnabled())
{
return;
}
var activity = CrossCurrentActivity.Current?.Activity;
if (await _stateService.GetScreenCaptureAllowedAsync())
{

View File

@@ -2,6 +2,7 @@
using System.Threading.Tasks;
using Bit.App.Services;
using Bit.Core.Abstractions;
using Bit.Core.Models;
namespace Bit.Droid.Services
{
@@ -21,7 +22,7 @@ namespace Bit.Droid.Services
protected override bool CanSendData => false;
protected override Task SendDataToWatchAsync(byte[] rawData) => throw new NotImplementedException();
protected override Task SendDataToWatchAsync(WatchDTO watchDto) => throw new NotImplementedException();
protected override void ConnectToWatch() => throw new NotImplementedException();
}

Binary file not shown.

Binary file not shown.

View File

@@ -8,7 +8,6 @@ namespace Bit.App.Abstractions
{
void Init(Func<AppOptions> getOptionsFunc, IAccountsManagerHost accountsManagerHost);
Task NavigateOnAccountChangeAsync(bool? isAuthed = null);
Task StartDefaultNavigationFlowAsync(Action<AppOptions> appOptionsAction);
Task LogOutAsync(string userId, bool userInitiated, bool expired);
Task PromptToSwitchToExistingAccountAsync(string userId);
}

View File

@@ -1,9 +0,0 @@
using System;
namespace Bit.App.Abstractions
{
public interface IDeepLinkContext
{
bool OnNewUri(Uri uri);
}
}

View File

@@ -21,7 +21,6 @@
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2515" />
<PackageReference Include="ZXing.Net.Mobile" Version="2.4.1" />
<PackageReference Include="ZXing.Net.Mobile.Forms" Version="2.4.1" />
<PackageReference Include="MessagePack" Version="2.4.59" />
</ItemGroup>
<ItemGroup>
@@ -437,8 +436,6 @@
<None Remove="Utilities\AccountManagement\" />
<None Remove="Controls\DateTime\" />
<None Remove="Controls\IconLabelButton\" />
<None Remove="MessagePack" />
<None Remove="MessagePack.MSBuild.Tasks" />
<None Remove="Controls\PasswordStrengthProgressBar\" />
</ItemGroup>
</Project>

View File

@@ -23,11 +23,6 @@ namespace Bit.App
{
public partial class App : Application, IAccountsManagerHost
{
public const string POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE = "popAllAndGoToTabGenerator";
public const string POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE = "popAllAndGoToTabMyVault";
public const string POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE = "popAllAndGoToTabSend";
public const string POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE = "popAllAndGoToAutofillCiphers";
private readonly IBroadcasterService _broadcasterService;
private readonly IMessagingService _messagingService;
private readonly IStateService _stateService;
@@ -108,18 +103,12 @@ namespace Bit.App
await Task.Delay(1000);
await _accountsManager.NavigateOnAccountChangeAsync();
}
else if (message.Command == POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE ||
message.Command == POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE ||
message.Command == POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE ||
message.Command == POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE ||
message.Command == DeepLinkContext.NEW_OTP_MESSAGE)
else if (message.Command == "popAllAndGoToTabGenerator" ||
message.Command == "popAllAndGoToTabMyVault" ||
message.Command == "popAllAndGoToTabSend" ||
message.Command == "popAllAndGoToAutofillCiphers")
{
if (message.Command == DeepLinkContext.NEW_OTP_MESSAGE)
{
Options.OtpData = new OtpData((string)message.Data);
}
await Device.InvokeOnMainThreadAsync(async () =>
Device.BeginInvokeOnMainThread(async () =>
{
if (Current.MainPage is TabsPage tabsPage)
{
@@ -127,29 +116,24 @@ namespace Bit.App
{
await tabsPage.Navigation.PopModalAsync(false);
}
if (message.Command == POP_ALL_AND_GO_TO_AUTOFILL_CIPHERS_MESSAGE)
if (message.Command == "popAllAndGoToAutofillCiphers")
{
Current.MainPage = new NavigationPage(new CipherSelectionPage(Options));
Current.MainPage = new NavigationPage(new AutofillCiphersPage(Options));
}
else if (message.Command == POP_ALL_AND_GO_TO_TAB_MYVAULT_MESSAGE)
else if (message.Command == "popAllAndGoToTabMyVault")
{
Options.MyVaultTile = false;
tabsPage.ResetToVaultPage();
}
else if (message.Command == POP_ALL_AND_GO_TO_TAB_GENERATOR_MESSAGE)
else if (message.Command == "popAllAndGoToTabGenerator")
{
Options.GeneratorTile = false;
tabsPage.ResetToGeneratorPage();
}
else if (message.Command == POP_ALL_AND_GO_TO_TAB_SEND_MESSAGE)
else if (message.Command == "popAllAndGoToTabSend")
{
tabsPage.ResetToSendPage();
}
else if (message.Command == DeepLinkContext.NEW_OTP_MESSAGE)
{
tabsPage.ResetToVaultPage();
await tabsPage.Navigation.PushModalAsync(new NavigationPage(new CipherSelectionPage(Options)));
}
}
});
}
@@ -217,7 +201,7 @@ namespace Bit.App
Id = loginRequestData.Id,
IpAddress = loginRequestData.RequestIpAddress,
Email = await _stateService.GetEmailAsync(),
FingerprintPhrase = loginRequestData.FingerprintPhrase,
FingerprintPhrase = loginRequestData.RequestFingerprint,
RequestDate = loginRequestData.CreationDate,
DeviceType = loginRequestData.RequestDeviceType,
Origin = loginRequestData.Origin
@@ -324,7 +308,6 @@ namespace Bit.App
private async Task SleptAsync()
{
await _vaultTimeoutService.CheckVaultTimeoutAsync();
await ClearSensitiveFieldsAsync();
_messagingService.Send("stopEventTimer");
}
@@ -332,7 +315,6 @@ namespace Bit.App
{
await _stateService.CheckExtensionActiveUserAndSwitchIfNeededAsync();
await _vaultTimeoutService.CheckVaultTimeoutAsync();
await ClearSensitiveFieldsAsync();
_messagingService.Send("startEventTimer");
await UpdateThemeAsync();
await ClearCacheIfNeededAsync();
@@ -353,14 +335,6 @@ namespace Bit.App
});
}
private async Task ClearSensitiveFieldsAsync()
{
await Device.InvokeOnMainThreadAsync(() =>
{
_messagingService.Send(Constants.ClearSensitiveFields);
});
}
private void SetCulture()
{
// Calendars are removed by linker. ref https://bugzilla.xamarin.com/show_bug.cgi?id=59077
@@ -485,7 +459,14 @@ namespace Bit.App
switch (navTarget)
{
case NavigationTarget.HomeLogin:
Current.MainPage = new NavigationPage(new HomePage(Options));
if (navParams is HomeNavigationParams homeParams)
{
Current.MainPage = new NavigationPage(new HomePage(Options, homeParams.ShouldCheckRememberEmail));
}
else
{
Current.MainPage = new NavigationPage(new HomePage(Options));
}
break;
case NavigationTarget.Login:
if (navParams is LoginNavigationParams loginParams)
@@ -510,8 +491,7 @@ namespace Bit.App
Current.MainPage = new NavigationPage(new CipherAddEditPage(appOptions: Options));
break;
case NavigationTarget.AutofillCiphers:
case NavigationTarget.OtpCipherSelection:
Current.MainPage = new NavigationPage(new CipherSelectionPage(Options));
Current.MainPage = new NavigationPage(new AutofillCiphersPage(Options));
break;
case NavigationTarget.SendAddEdit:
Current.MainPage = new NavigationPage(new SendAddEditPage(Options));

View File

@@ -1,5 +1,4 @@
using System;
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
@@ -19,7 +18,7 @@ namespace Bit.App.Controls
nameof(WebsiteIconsEnabled), typeof(bool?), typeof(CipherViewCell));
public static readonly BindableProperty ButtonCommandProperty = BindableProperty.Create(
nameof(ButtonCommand), typeof(ICommand), typeof(CipherViewCell));
nameof(ButtonCommand), typeof(Command<CipherView>), typeof(CipherViewCell));
public CipherViewCell()
{
@@ -43,9 +42,9 @@ namespace Bit.App.Controls
set => SetValue(CipherProperty, value);
}
public ICommand ButtonCommand
public Command<CipherView> ButtonCommand
{
get => GetValue(ButtonCommandProperty) as ICommand;
get => GetValue(ButtonCommandProperty) as Command<CipherView>;
set => SetValue(ButtonCommandProperty, value);
}

View File

@@ -1,6 +1,4 @@
using System.Linq;
using Xamarin.CommunityToolkit.Converters;
using Xamarin.Forms;
using Xamarin.Forms;
namespace Bit.App.Controls
{
@@ -8,13 +6,4 @@ namespace Bit.App.Controls
{
public string ExtraDataForLogging { get; set; }
}
public class SelectionChangedEventArgsConverter : BaseNullableConverterOneWay<SelectionChangedEventArgs, object>
{
public override object? ConvertFrom(SelectionChangedEventArgs? value)
{
return value?.CurrentSelection.FirstOrDefault();
}
}
}

View File

@@ -69,7 +69,6 @@ namespace Bit.App.Controls
{
InitializeComponent();
SetBinding(PasswordStrengthProgressBar.PasswordStrengthLevelProperty, new Binding() { Path = nameof(PasswordStrengthViewModel.PasswordStrengthLevel) });
UpdateColors();
}
private static void OnControlPropertyChanged(BindableObject bindable, object oldValue, object newValue)

View File

@@ -1,6 +1,5 @@
using System;
using Bit.Core.Enums;
using Bit.Core.Utilities;
namespace Bit.App.Models
{
@@ -24,7 +23,6 @@ namespace Bit.App.Models
public Tuple<SendType, string, byte[], string> CreateSend { get; set; }
public bool CopyInsteadOfShareAfterSaving { get; set; }
public bool HideAccountSwitcher { get; set; }
public OtpData? OtpData { get; set; }
public void SetAllFrom(AppOptions o)
{
@@ -50,7 +48,6 @@ namespace Bit.App.Models
CreateSend = o.CreateSend;
CopyInsteadOfShareAfterSaving = o.CopyInsteadOfShareAfterSaving;
HideAccountSwitcher = o.HideAccountSwitcher;
OtpData = o.OtpData;
}
}
}

View File

@@ -162,7 +162,7 @@ namespace Bit.App.Pages
{
if (MasterPassword.Length < Constants.MasterPasswordMinimumChars)
{
await _platformUtilsService.ShowDialogAsync(string.Format(AppResources.MasterPasswordLengthValMessageX, Constants.MasterPasswordMinimumChars),
await _platformUtilsService.ShowDialogAsync(AppResources.MasterPasswordLengthValMessage,
AppResources.MasterPasswordPolicyValidationTitle, AppResources.Ok);
return false;
}

View File

@@ -15,13 +15,14 @@ namespace Bit.App.Pages
private readonly AppOptions _appOptions;
private IBroadcasterService _broadcasterService;
public HomePage(AppOptions appOptions = null)
public HomePage(AppOptions appOptions = null, bool shouldCheckRememberEmail = true)
{
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as HomeViewModel;
_vm.Page = this;
_vm.ShouldCheckRememberEmail = shouldCheckRememberEmail;
_vm.ShowCancelButton = _appOptions?.IosExtension ?? false;
_vm.StartLoginAction = async () => await StartLoginAsync();
_vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
@@ -70,6 +71,8 @@ namespace Bit.App.Pages
});
}
});
_vm.CheckNavigateLoginStep();
}
protected override bool OnBackButtonPressed()

View File

@@ -73,6 +73,8 @@ namespace Bit.App.Pages
public bool CanContinue => !string.IsNullOrEmpty(Email);
public bool ShouldCheckRememberEmail { get; set; }
public FormattedString CreateAccountText
{
get
@@ -108,6 +110,15 @@ namespace Bit.App.Pages
RememberEmail = !string.IsNullOrEmpty(Email);
}
public void CheckNavigateLoginStep()
{
if (ShouldCheckRememberEmail && RememberEmail)
{
StartLoginAction();
}
ShouldCheckRememberEmail = false;
}
public async Task ContinueToLoginStepAsync()
{
try
@@ -125,16 +136,16 @@ namespace Bit.App.Pages
AppResources.Ok);
return;
}
await _stateService.SetRememberedEmailAsync(RememberEmail ? Email : null);
var userId = await _stateService.GetUserIdAsync(Email);
if (!string.IsNullOrWhiteSpace(userId) &&
(await _stateService.GetEnvironmentUrlsAsync(userId))?.Base == _environmentService.BaseUrl &&
await _stateService.IsAuthenticatedAsync(userId))
if (!string.IsNullOrWhiteSpace(userId))
{
await _accountManager.PromptToSwitchToExistingAccountAsync(userId);
return;
var userEnvUrls = await _stateService.GetEnvironmentUrlsAsync(userId);
if (userEnvUrls?.Base == _environmentService.BaseUrl)
{
await _accountManager.PromptToSwitchToExistingAccountAsync(userId);
return;
}
}
StartLoginAction();
}

View File

@@ -3,8 +3,6 @@ using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using Xamarin.Forms;
@@ -12,7 +10,6 @@ namespace Bit.App.Pages
{
public partial class LockPage : BaseContentPage
{
private readonly IBroadcasterService _broadcasterService;
private readonly AppOptions _appOptions;
private readonly bool _autoPromptBiometric;
private readonly LockPageViewModel _vm;
@@ -25,7 +22,6 @@ namespace Bit.App.Pages
_appOptions = appOptions;
_autoPromptBiometric = autoPromptBiometric;
InitializeComponent();
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
_vm = BindingContext as LockPageViewModel;
_vm.Page = this;
_vm.UnlockedAction = () => Device.BeginInvokeOnMainThread(async () => await UnlockedAsync());
@@ -68,13 +64,6 @@ namespace Bit.App.Pages
protected override async void OnAppearing()
{
base.OnAppearing();
_broadcasterService.Subscribe(nameof(LockPage), message =>
{
if (message.Command == Constants.ClearSensitiveFields)
{
Device.BeginInvokeOnMainThread(_vm.ResetPinPasswordFields);
}
});
if (_appeared)
{
return;
@@ -140,7 +129,6 @@ namespace Bit.App.Pages
base.OnDisappearing();
_accountAvatar?.OnDisappearing();
_broadcasterService.Unsubscribe(nameof(LockPage));
}
private void Unlock_Clicked(object sender, EventArgs e)

View File

@@ -9,7 +9,6 @@ using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Domain;
using Bit.Core.Models.Request;
using Bit.Core.Services;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.Helpers;
using Xamarin.Forms;
@@ -33,8 +32,6 @@ namespace Bit.App.Pages
private readonly WeakEventManager<int?> _secretEntryFocusWeakEventManager = new WeakEventManager<int?>();
private string _email;
private string _masterPassword;
private string _pin;
private bool _showPassword;
private bool _pinLock;
private bool _biometricLock;
@@ -73,18 +70,6 @@ namespace Bit.App.Pages
};
}
public string MasterPassword
{
get => _masterPassword;
set => SetProperty(ref _masterPassword, value);
}
public string Pin
{
get => _pin;
set => SetProperty(ref _pin, value);
}
public bool ShowPassword
{
get => _showPassword;
@@ -149,6 +134,8 @@ namespace Bit.App.Pages
public Command TogglePasswordCommand { get; }
public string ShowPasswordIcon => ShowPassword ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
public string MasterPassword { get; set; }
public string Pin { get; set; }
public Action UnlockedAction { get; set; }
public event Action<int?> FocusSecretEntry
{
@@ -241,7 +228,8 @@ namespace Bit.App.Pages
}
ShowPassword = false;
var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile));
var kdf = await _stateService.GetKdfTypeAsync();
var kdfIterations = await _stateService.GetKdfIterationsAsync();
if (PinLock)
{
@@ -251,7 +239,7 @@ namespace Bit.App.Pages
if (_isPinProtected)
{
var key = await _cryptoService.MakeKeyFromPinAsync(Pin, _email,
kdfConfig,
kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000),
await _stateService.GetPinProtectedKeyAsync());
var encKey = await _cryptoService.GetEncKeyAsync(key);
var protectedPin = await _stateService.GetProtectedPinAsync();
@@ -266,7 +254,8 @@ namespace Bit.App.Pages
}
else
{
var key = await _cryptoService.MakeKeyFromPinAsync(Pin, _email, kdfConfig);
var key = await _cryptoService.MakeKeyFromPinAsync(Pin, _email,
kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000));
failed = false;
Pin = string.Empty;
await AppHelpers.ResetInvalidUnlockAttemptsAsync();
@@ -291,7 +280,7 @@ namespace Bit.App.Pages
}
else
{
var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdfConfig);
var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdf, kdfIterations);
var storedKeyHash = await _cryptoService.GetKeyHashAsync();
var passwordValid = false;
@@ -325,7 +314,8 @@ namespace Bit.App.Pages
var protectedPin = await _stateService.GetProtectedPinAsync();
var encKey = await _cryptoService.GetEncKeyAsync(key);
var decPin = await _cryptoService.DecryptToUtf8Async(new EncString(protectedPin), encKey);
var pinKey = await _cryptoService.MakePinKeyAysnc(decPin, _email, kdfConfig);
var pinKey = await _cryptoService.MakePinKeyAysnc(decPin, _email,
kdf.GetValueOrDefault(KdfType.PBKDF2_SHA256), kdfIterations.GetValueOrDefault(5000));
await _stateService.SetPinProtectedKeyAsync(await _cryptoService.EncryptAsync(key.Key, pinKey));
}
MasterPassword = string.Empty;
@@ -362,20 +352,6 @@ namespace Bit.App.Pages
}
}
public void ResetPinPasswordFields()
{
try
{
MasterPassword = string.Empty;
Pin = string.Empty;
ShowPassword = false;
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}
public void TogglePassword()
{
ShowPassword = !ShowPassword;

View File

@@ -2,7 +2,6 @@
using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities;
@@ -13,7 +12,6 @@ namespace Bit.App.Pages
{
public partial class LoginPage : BaseContentPage
{
private readonly IBroadcasterService _broadcasterService;
private readonly LoginPageViewModel _vm;
private readonly AppOptions _appOptions;
@@ -25,7 +23,6 @@ namespace Bit.App.Pages
{
_appOptions = appOptions;
InitializeComponent();
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>();
_vm = BindingContext as LoginPageViewModel;
_vm.Page = this;
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
@@ -73,13 +70,6 @@ namespace Bit.App.Pages
protected override async void OnAppearing()
{
base.OnAppearing();
_broadcasterService.Subscribe(nameof(LoginPage), message =>
{
if (message.Command == Constants.ClearSensitiveFields)
{
Device.BeginInvokeOnMainThread(_vm.ResetPasswordField);
}
});
_mainContent.Content = _mainLayout;
_accountAvatar?.OnAppearing();
@@ -114,7 +104,6 @@ namespace Bit.App.Pages
base.OnDisappearing();
_accountAvatar?.OnDisappearing();
_broadcasterService.Unsubscribe(nameof(LoginPage));
}
private async void LogIn_Clicked(object sender, EventArgs e)

View File

@@ -40,7 +40,6 @@ namespace Bit.App.Pages
private string _masterPassword;
private bool _isEmailEnabled;
private bool _isKnownDevice;
private bool _isExecutingLogin;
public LoginPageViewModel()
{
@@ -144,27 +143,20 @@ namespace Bit.App.Pages
try
{
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
await _stateService.SetPreLoginEmailAsync(Email);
await AccountSwitchingOverlayViewModel.RefreshAccountViewsAsync();
if (string.IsNullOrWhiteSpace(Email))
{
Email = await _stateService.GetRememberedEmailAsync();
}
var deviceIdentifier = await _appIdService.GetAppIdAsync();
IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier);
CanRemoveAccount = await _stateService.GetActiveUserEmailAsync() != Email;
IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, await _appIdService.GetAppIdAsync());
}
catch (ApiException apiEx) when (apiEx.Error.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
_logger.Exception(apiEx);
await _deviceActionService.HideLoadingAsync();
}
catch (Exception ex)
{
HandleException(ex);
}
finally
{
await _deviceActionService.HideLoadingAsync();
}
}
public async Task LogInAsync(bool showLoading = true, bool checkForExistingAccount = false)
@@ -199,7 +191,6 @@ namespace Bit.App.Pages
ShowPassword = false;
try
{
_isExecutingLogin = true;
if (checkForExistingAccount)
{
var userId = await _stateService.GetUserIdAsync(Email);
@@ -261,26 +252,6 @@ namespace Bit.App.Pages
AppResources.AnErrorHasOccurred, AppResources.Ok);
}
}
finally
{
_isExecutingLogin = false;
}
}
public void ResetPasswordField()
{
try
{
if (!_isExecutingLogin)
{
MasterPassword = string.Empty;
ShowPassword = false;
}
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}
private async Task MoreAsync()

View File

@@ -171,7 +171,7 @@ namespace Bit.App.Pages
var response = await _authService.PasswordlessCreateLoginRequestAsync(_email);
if (response != null)
{
FingerprintPhrase = response.FingerprintPhrase;
FingerprintPhrase = response.RequestFingerprint;
_requestId = response.Id;
_requestAccessCode = response.RequestAccessCode;
_requestKeyPair = response.RequestKeyPair;

View File

@@ -118,7 +118,7 @@ namespace Bit.App.Pages
}
var loginRequestData = await _authService.GetPasswordlessLoginRequestByIdAsync(LoginRequest.Id);
if (loginRequestData.IsAnswered)
if (loginRequestData.RequestApproved.HasValue && loginRequestData.ResponseDate.HasValue)
{
await _platformUtilsService.ShowDialogAsync(AppResources.ThisRequestIsNoLongerValid);
await Page.Navigation.PopModalAsync();

View File

@@ -1,5 +1,4 @@
using System;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions;
@@ -28,7 +27,6 @@ namespace Bit.App.Pages
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IStateService _stateService;
private readonly ILogger _logger;
private readonly IOrganizationService _organizationService;
private string _orgIdentifier;
@@ -44,7 +42,6 @@ namespace Bit.App.Pages
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_logger = ServiceContainer.Resolve<ILogger>("logger");
_organizationService = ServiceContainer.Resolve<IOrganizationService>();
PageTitle = AppResources.Bitwarden;
@@ -66,25 +63,9 @@ namespace Bit.App.Pages
public async Task InitAsync()
{
try
if (string.IsNullOrWhiteSpace(OrgIdentifier))
{
if (await TryClaimedDomainLogin())
{
return;
}
if (string.IsNullOrWhiteSpace(OrgIdentifier))
{
OrgIdentifier = await _stateService.GetRememberedOrgIdentifierAsync();
}
}
catch (Exception ex)
{
_logger.Exception(ex);
}
finally
{
await _deviceActionService.HideLoadingAsync();
OrgIdentifier = await _stateService.GetRememberedOrgIdentifierAsync();
}
}
@@ -226,37 +207,5 @@ namespace Bit.App.Pages
AppResources.AnErrorHasOccurred);
}
}
private async Task<bool> TryClaimedDomainLogin()
{
try
{
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
var userEmail = await _stateService.GetPreLoginEmailAsync();
var claimedDomainOrgDetails = await _organizationService.GetClaimedOrganizationDomainAsync(userEmail);
await _deviceActionService.HideLoadingAsync();
if (claimedDomainOrgDetails == null || !claimedDomainOrgDetails.SsoAvailable)
{
return false;
}
if (string.IsNullOrEmpty(claimedDomainOrgDetails.OrganizationIdentifier))
{
await _platformUtilsService.ShowDialogAsync(AppResources.OrganizationSsoIdentifierRequired, AppResources.AnErrorHasOccurred);
return false;
}
OrgIdentifier = claimedDomainOrgDetails.OrganizationIdentifier;
await LogInAsync();
return true;
}
catch (Exception ex)
{
HandleException(ex);
}
return false;
}
}
}

View File

@@ -48,7 +48,6 @@ namespace Bit.App.Pages
SubmitCommand = new Command(async () => await SubmitAsync());
ShowTerms = !_platformUtilsService.IsSelfHost();
PasswordStrengthViewModel = new PasswordStrengthViewModel(this);
CheckExposedMasterPassword = true;
}
public ICommand PoliciesClickCommand => new Command<string>((url) =>
@@ -148,7 +147,7 @@ namespace Bit.App.Pages
}
if (MasterPassword.Length < Constants.MasterPasswordMinimumChars)
{
await _platformUtilsService.ShowDialogAsync(string.Format(AppResources.MasterPasswordLengthValMessageX, Constants.MasterPasswordMinimumChars),
await _platformUtilsService.ShowDialogAsync(AppResources.MasterPasswordLengthValMessage,
AppResources.AnErrorHasOccurred, AppResources.Ok);
return;
}
@@ -176,8 +175,8 @@ namespace Bit.App.Pages
Name = string.IsNullOrWhiteSpace(Name) ? null : Name;
Email = Email.Trim().ToLower();
var kdfConfig = new KdfConfig(KdfType.PBKDF2_SHA256, Constants.Pbkdf2Iterations, null, null);
var key = await _cryptoService.MakeKeyAsync(MasterPassword, Email, kdfConfig);
var kdf = KdfType.PBKDF2_SHA256;
var key = await _cryptoService.MakeKeyAsync(MasterPassword, Email, kdf, Constants.KdfIterations);
var encKey = await _cryptoService.MakeEncKeyAsync(key);
var hashedPassword = await _cryptoService.HashPasswordAsync(MasterPassword, key);
var keys = await _cryptoService.MakeKeyPairAsync(encKey.Item1);
@@ -188,10 +187,8 @@ namespace Bit.App.Pages
MasterPasswordHash = hashedPassword,
MasterPasswordHint = Hint,
Key = encKey.Item2.EncryptedString,
Kdf = kdfConfig.Type,
KdfIterations = kdfConfig.Iterations,
KdfMemory = kdfConfig.Memory,
KdfParallelism = kdfConfig.Parallelism,
Kdf = kdf,
KdfIterations = Constants.KdfIterations,
Keys = new KeysRequest
{
PublicKey = keys.Item1,

View File

@@ -152,7 +152,7 @@ namespace Bit.App.Pages
if (MasterPassword.Length < Constants.MasterPasswordMinimumChars)
{
await Page.DisplayAlert(AppResources.MasterPasswordPolicyValidationTitle,
string.Format(AppResources.MasterPasswordLengthValMessageX, Constants.MasterPasswordMinimumChars), AppResources.Ok);
AppResources.MasterPasswordLengthValMessage, AppResources.Ok);
return;
}
}
@@ -163,9 +163,9 @@ namespace Bit.App.Pages
return;
}
var kdfConfig = new KdfConfig(KdfType.PBKDF2_SHA256, Constants.Pbkdf2Iterations, null, null);
var kdf = KdfType.PBKDF2_SHA256;
var email = await _stateService.GetEmailAsync();
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdfConfig);
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, Constants.KdfIterations);
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.ServerAuthorization);
var localMasterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.LocalAuthorization);
@@ -186,10 +186,8 @@ namespace Bit.App.Pages
MasterPasswordHash = masterPasswordHash,
Key = encKey.Item2.EncryptedString,
MasterPasswordHint = Hint,
Kdf = kdfConfig.Type.GetValueOrDefault(KdfType.PBKDF2_SHA256),
KdfIterations = kdfConfig.Iterations.GetValueOrDefault(Constants.Pbkdf2Iterations),
KdfMemory = kdfConfig.Memory,
KdfParallelism = kdfConfig.Parallelism,
Kdf = kdf,
KdfIterations = Constants.KdfIterations,
OrgIdentifier = OrgIdentifier,
Keys = new KeysRequest
{
@@ -203,7 +201,8 @@ namespace Bit.App.Pages
await _deviceActionService.ShowLoadingAsync(AppResources.CreatingAccount);
// Set Password and relevant information
await _apiService.SetPasswordAsync(request);
await _stateService.SetKdfConfigurationAsync(kdfConfig);
await _stateService.SetKdfTypeAsync(kdf);
await _stateService.SetKdfIterationsAsync(Constants.KdfIterations);
await _cryptoService.SetKeyAsync(key);
await _cryptoService.SetKeyHashAsync(localMasterPasswordHash);
await _cryptoService.SetEncKeyAsync(encKey.Item2.EncryptedString);

View File

@@ -43,11 +43,12 @@ namespace Bit.App.Pages
}
// Retrieve details for key generation
var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile));
var kdf = await _stateService.GetKdfTypeAsync();
var kdfIterations = await _stateService.GetKdfIterationsAsync();
var email = await _stateService.GetEmailAsync();
// Create new key and hash new password
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdfConfig);
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations);
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key);
// Create new encKey for the User

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
@@ -20,7 +20,6 @@
<ResourceDictionary>
<u:InverseBoolConverter x:Key="inverseBool" />
<u:LocalizableEnumConverter x:Key="localizableEnum" />
<u:IconGlyphConverter x:Key="iconGlyphConverter" />
<xct:EnumToBoolConverter x:Key="enumToBool"/>
<ToolbarItem Text="{u:I18n Cancel}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1"
x:Name="_closeItem" x:Key="closeItem" />
@@ -252,7 +251,7 @@
Grid.Row="1"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowAnonAddyApiAccessToken, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Text="{Binding ShowAnonAddyHiddenValueIcon}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
@@ -281,7 +280,7 @@
IsPassword="{Binding ShowFirefoxRelayApiAccessToken, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowFirefoxRelayApiAccessToken, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Text="{Binding ShowFirefoxRelayHiddenValueIcon}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
@@ -302,49 +301,7 @@
IsPassword="{Binding ShowSimpleLoginApiKey, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowSimpleLoginApiKey, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
<!--DUCKDUCKGO OPTIONS-->
<Grid StyleClass="box-row, box-row-input"
IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.DuckDuckGo}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Text="{u:I18n APIKeyRequiredParenthesis}"
StyleClass="box-label"/>
<Entry
x:Name="_duckDuckGoApiAccessTokenEntry"
Text="{Binding DuckDuckGoApiKey}"
StyleClass="box-value"
Grid.Row="1"
IsPassword="{Binding ShowDuckDuckGoApiKey, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowDuckDuckGoApiKey, Converter={StaticResource inverseBool, iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>
</Grid>
<!--FASTMAIL OPTIONS-->
<Grid StyleClass="box-row, box-row-input"
IsVisible="{Binding ForwardedEmailServiceSelected, Converter={StaticResource enumToBool}, ConverterParameter={x:Static enums:ForwardedEmailServiceType.Fastmail}}"
Grid.RowDefinitions="Auto,*"
Grid.ColumnDefinitions="*,Auto">
<Label
Text="{u:I18n APIKeyRequiredParenthesis}"
StyleClass="box-label"/>
<Entry
x:Name="_fastmailApiAccessTokenEntry"
Text="{Binding FastmailApiKey}"
StyleClass="box-value"
Grid.Row="1"
IsPassword="{Binding ShowFastmailApiKey, Converter={StaticResource inverseBool}}"/>
<controls:IconButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowFastmailApiKey, Converter={StaticResource iconGlyphConverter}, ConverterParameter={x:Static u:BooleanGlyphType.Eye}}"
Text="{Binding ShowSimpleLoginHiddenValueIcon}"
Command="{Binding ToggleForwardedEmailHiddenValueCommand}"
Grid.Row="1"
Grid.Column="1"/>

View File

@@ -52,8 +52,6 @@ namespace Bit.App.Pages
private bool _showFirefoxRelayApiAccessToken;
private bool _showAnonAddyApiAccessToken;
private bool _showSimpleLoginApiKey;
private bool _showDuckDuckGoApiKey;
private bool _showFastmailApiKey;
private bool _editMode;
public GeneratorPageViewModel()
@@ -81,8 +79,6 @@ namespace Bit.App.Pages
ForwardedEmailServiceTypeOptions = new List<ForwardedEmailServiceType> {
ForwardedEmailServiceType.AnonAddy,
ForwardedEmailServiceType.DuckDuckGo,
ForwardedEmailServiceType.Fastmail,
ForwardedEmailServiceType.FirefoxRelay,
ForwardedEmailServiceType.SimpleLogin
};
@@ -465,9 +461,15 @@ namespace Bit.App.Pages
{
return _showAnonAddyApiAccessToken;
}
set => SetProperty(ref _showAnonAddyApiAccessToken, value);
set => SetProperty(ref _showAnonAddyApiAccessToken, value,
additionalPropertyNames: new string[]
{
nameof(ShowAnonAddyHiddenValueIcon)
});
}
public string ShowAnonAddyHiddenValueIcon => _showAnonAddyApiAccessToken ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
public string AnonAddyDomainName
{
get => _usernameOptions.AnonAddyDomainName;
@@ -502,9 +504,15 @@ namespace Bit.App.Pages
{
return _showFirefoxRelayApiAccessToken;
}
set => SetProperty(ref _showFirefoxRelayApiAccessToken, value);
set => SetProperty(ref _showFirefoxRelayApiAccessToken, value,
additionalPropertyNames: new string[]
{
nameof(ShowFirefoxRelayHiddenValueIcon)
});
}
public string ShowFirefoxRelayHiddenValueIcon => _showFirefoxRelayApiAccessToken ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
public string SimpleLoginApiKey
{
get => _usernameOptions.SimpleLoginApiKey;
@@ -525,55 +533,14 @@ namespace Bit.App.Pages
{
return _showSimpleLoginApiKey;
}
set => SetProperty(ref _showSimpleLoginApiKey, value);
}
public string DuckDuckGoApiKey
{
get => _usernameOptions.DuckDuckGoApiKey;
set
{
if (_usernameOptions.DuckDuckGoApiKey != value)
set => SetProperty(ref _showSimpleLoginApiKey, value,
additionalPropertyNames: new string[]
{
_usernameOptions.DuckDuckGoApiKey = value;
TriggerPropertyChanged(nameof(DuckDuckGoApiKey));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
nameof(ShowSimpleLoginHiddenValueIcon)
});
}
public bool ShowDuckDuckGoApiKey
{
get
{
return _showDuckDuckGoApiKey;
}
set => SetProperty(ref _showDuckDuckGoApiKey, value);
}
public string FastmailApiKey
{
get => _usernameOptions.FastMailApiKey;
set
{
if (_usernameOptions.FastMailApiKey != value)
{
_usernameOptions.FastMailApiKey = value;
TriggerPropertyChanged(nameof(FastmailApiKey));
SaveUsernameOptionsAsync(false).FireAndForget();
}
}
}
public bool ShowFastmailApiKey
{
get
{
return _showFastmailApiKey;
}
set => SetProperty(ref _showFastmailApiKey, value);
}
public string ShowSimpleLoginHiddenValueIcon => _showSimpleLoginApiKey ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
public bool CapitalizeRandomWordUsername
{
@@ -811,8 +778,6 @@ namespace Bit.App.Pages
TriggerPropertyChanged(nameof(FirefoxRelayApiAccessToken));
TriggerPropertyChanged(nameof(AnonAddyDomainName));
TriggerPropertyChanged(nameof(AnonAddyApiAccessToken));
TriggerPropertyChanged(nameof(DuckDuckGoApiKey));
TriggerPropertyChanged(nameof(FastmailApiKey));
TriggerPropertyChanged(nameof(CatchAllEmailDomain));
TriggerPropertyChanged(nameof(ForwardedEmailServiceSelected));
TriggerPropertyChanged(nameof(UsernameTypeSelected));
@@ -884,12 +849,6 @@ namespace Bit.App.Pages
case ForwardedEmailServiceType.SimpleLogin:
ShowSimpleLoginApiKey = !ShowSimpleLoginApiKey;
break;
case ForwardedEmailServiceType.DuckDuckGo:
ShowDuckDuckGoApiKey = !ShowDuckDuckGoApiKey;
break;
case ForwardedEmailServiceType.Fastmail:
ShowFastmailApiKey = !ShowFastmailApiKey;
break;
}
}
}

View File

@@ -1,107 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="Bit.App.Pages.LoginPasswordlessRequestsListPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
x:DataType="pages:LoginPasswordlessRequestsListViewModel"
xmlns:models="clr-namespace:Bit.Core.Models.Response;assembly=BitwardenCore"
xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:u="clr-namespace:Bit.App.Utilities"
Title="{Binding PageTitle}">
<ContentPage.BindingContext>
<pages:LoginPasswordlessRequestsListViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
<ResourceDictionary>
<u:DateTimeConverter x:Key="dateTime" />
<xct:ItemSelectedEventArgsConverter x:Key="ItemSelectedEventArgsConverter" />
<controls:SelectionChangedEventArgsConverter x:Key="SelectionChangedEventArgsConverter" />
<DataTemplate
x:Key="loginRequestTemplate"
x:DataType="models:PasswordlessLoginResponse">
<Grid
Padding="10, 0"
RowSpacing="0"
RowDefinitions="*, Auto, *, 10"
ColumnDefinitions="*, *">
<Label
Text="{u:I18n FingerprintPhrase}"
FontSize="Small"
Padding="0, 10, 0 ,0"
FontAttributes="Bold"/>
<controls:MonoLabel
FormattedText="{Binding FingerprintPhrase}"
Grid.Row="1"
Grid.ColumnSpan="2"
FontSize="Small"
Padding="0, 5, 0, 10"
VerticalTextAlignment="Center"
TextColor="{DynamicResource FingerprintPhrase}"/>
<Label
Grid.Row="2"
HorizontalOptions="Start"
HorizontalTextAlignment="Start"
Text="{Binding RequestDeviceType}"
StyleClass="list-header-sub" />
<Label
Grid.Row="2"
Grid.Column="1"
HorizontalOptions="End"
HorizontalTextAlignment="End"
Text="{Binding CreationDate, Converter={StaticResource dateTime}}"
StyleClass="list-header-sub" />
<BoxView
StyleClass="list-section-separator-top, list-section-separator-top-platform"
VerticalOptions="End"
Grid.Row="3"
Grid.ColumnSpan="2"/>
</Grid>
</DataTemplate>
<StackLayout
x:Key="mainLayout"
x:Name="_mainLayout"
Padding="0, 10">
<RefreshView
IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}"
VerticalOptions="FillAndExpand"
BackgroundColor="{DynamicResource BackgroundColor}">
<controls:ExtendedCollectionView
ItemsSource="{Binding LoginRequests}"
ItemTemplate="{StaticResource loginRequestTemplate}"
SelectionMode="Single"
ExtraDataForLogging="Login requests page" >
<controls:ExtendedCollectionView.Behaviors>
<xct:EventToCommandBehavior
EventName="SelectionChanged"
Command="{Binding AnswerRequestCommand}"
EventArgsConverter="{StaticResource SelectionChangedEventArgsConverter}" />
</controls:ExtendedCollectionView.Behaviors>
</controls:ExtendedCollectionView>
</RefreshView>
<controls:IconLabelButton
VerticalOptions="End"
Margin="10,0"
Icon="{Binding Source={x:Static core:BitwardenIcons.Trash}}"
Label="{u:I18n DeclineAllRequests}"
ButtonCommand="{Binding DeclineAllRequestsCommand}"/>
</StackLayout>
</ResourceDictionary>
</ContentPage.Resources>
<ContentView
x:Name="_mainContent">
</ContentView>
</pages:BaseContentPage>

View File

@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Bit.Core.Abstractions;
using Bit.Core.Models.Response;
using Bit.Core.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public partial class LoginPasswordlessRequestsListPage : BaseContentPage
{
private LoginPasswordlessRequestsListViewModel _vm;
public LoginPasswordlessRequestsListPage()
{
InitializeComponent();
SetActivityIndicator(_mainContent);
_vm = BindingContext as LoginPasswordlessRequestsListViewModel;
_vm.Page = this;
}
protected override async void OnAppearing()
{
base.OnAppearing();
await LoadOnAppearedAsync(_mainLayout, false, _vm.RefreshAsync, _mainContent);
}
private async void Close_Clicked(object sender, System.EventArgs e)
{
if (DoOnce())
{
await Navigation.PopModalAsync();
}
}
}
}

View File

@@ -1,139 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Models.Response;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class LoginPasswordlessRequestsListViewModel : BaseViewModel
{
private readonly IAuthService _authService;
private readonly IStateService _stateService;
private readonly IDeviceActionService _deviceActionService;
private readonly IPlatformUtilsService _platformUtilsService;
private bool _isRefreshing;
public LoginPasswordlessRequestsListViewModel()
{
_authService = ServiceContainer.Resolve<IAuthService>();
_stateService = ServiceContainer.Resolve<IStateService>();
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
PageTitle = AppResources.PendingLogInRequests;
LoginRequests = new ObservableRangeCollection<PasswordlessLoginResponse>();
AnswerRequestCommand = new AsyncCommand<PasswordlessLoginResponse>(PasswordlessLoginAsync,
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
DeclineAllRequestsCommand = new AsyncCommand(DeclineAllRequestsAsync,
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
RefreshCommand = new Command(async () => await RefreshAsync());
}
public ICommand RefreshCommand { get; }
public AsyncCommand<PasswordlessLoginResponse> AnswerRequestCommand { get; }
public AsyncCommand DeclineAllRequestsCommand { get; }
public ObservableRangeCollection<PasswordlessLoginResponse> LoginRequests { get; }
public bool IsRefreshing
{
get => _isRefreshing;
set => SetProperty(ref _isRefreshing, value);
}
public async Task RefreshAsync()
{
try
{
IsRefreshing = true;
LoginRequests.ReplaceRange(await _authService.GetActivePasswordlessLoginRequestsAsync());
if (!LoginRequests.Any())
{
Page.Navigation.PopModalAsync().FireAndForget();
}
}
catch (Exception ex)
{
HandleException(ex);
}
finally
{
IsRefreshing = false;
}
}
private async Task PasswordlessLoginAsync(PasswordlessLoginResponse request)
{
if (request.IsExpired)
{
await _platformUtilsService.ShowDialogAsync(AppResources.LoginRequestHasAlreadyExpired);
await Page.Navigation.PopModalAsync();
return;
}
var loginRequestData = await _authService.GetPasswordlessLoginRequestByIdAsync(request.Id);
if (loginRequestData.IsAnswered)
{
await _platformUtilsService.ShowDialogAsync(AppResources.ThisRequestIsNoLongerValid);
return;
}
var page = new LoginPasswordlessPage(new LoginPasswordlessDetails()
{
PubKey = loginRequestData.PublicKey,
Id = loginRequestData.Id,
IpAddress = loginRequestData.RequestIpAddress,
Email = await _stateService.GetEmailAsync(),
FingerprintPhrase = loginRequestData.FingerprintPhrase,
RequestDate = loginRequestData.CreationDate,
DeviceType = loginRequestData.RequestDeviceType,
Origin = loginRequestData.Origin
});
await Device.InvokeOnMainThreadAsync(() => Application.Current.MainPage.Navigation.PushModalAsync(new NavigationPage(page)));
}
private async Task DeclineAllRequestsAsync()
{
try
{
if (!await _platformUtilsService.ShowDialogAsync(AppResources.AreYouSureYouWantToDeclineAllPendingLogInRequests, null, AppResources.Yes, AppResources.No))
{
return;
}
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
var taskList = new List<Task>();
foreach (var request in LoginRequests)
{
taskList.Add(_authService.PasswordlessLoginAsync(request.Id, request.PublicKey, false));
}
await Task.WhenAll(taskList);
await _deviceActionService.HideLoadingAsync();
await RefreshAsync();
_platformUtilsService.ShowToast("info", null, AppResources.RequestsDeclined);
}
catch (Exception ex)
{
HandleException(ex);
RefreshAsync().FireAndForget();
}
}
}
}

View File

@@ -80,22 +80,6 @@
Text="{u:I18n ClearClipboardDescription}"
StyleClass="box-footer-label" />
</StackLayout>
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row, box-row-input, box-row-input-options-platform">
<Label
Text="{u:I18n Language}"
StyleClass="box-label" />
<Picker
x:Name="_languagePicker"
ItemsSource="{Binding LocalesOptions, Mode=OneTime}"
SelectedItem="{Binding SelectedLocale}"
ItemDisplayBinding="{Binding Value}"
StyleClass="box-value" />
</StackLayout>
<Label
Text="{u:I18n LanguageChangeRequiresAppRestart}"
StyleClass="box-footer-label" />
</StackLayout>
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row, box-row-switch">
<Label

View File

@@ -34,7 +34,6 @@ namespace Bit.App.Pages
_autoDarkThemePicker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
_uriMatchPicker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
_clearClipboardPicker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
_languagePicker.On<iOS>().SetUpdateMode(UpdateMode.WhenFinished);
}
}

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.App.Utilities;
@@ -15,8 +14,7 @@ namespace Bit.App.Pages
{
private readonly IStateService _stateService;
private readonly IMessagingService _messagingService;
private readonly II18nService _i18nService;
private readonly IPlatformUtilsService _platformUtilsService;
private bool _autofillSavePrompt;
private string _autofillBlockedUris;
@@ -26,7 +24,6 @@ namespace Bit.App.Pages
private int _themeSelectedIndex;
private int _autoDarkThemeSelectedIndex;
private int _uriMatchSelectedIndex;
private KeyValuePair<string, string> _selectedLocale;
private bool _inited;
private bool _updatingAutofill;
private bool _showAndroidAutofillSettings;
@@ -35,8 +32,6 @@ namespace Bit.App.Pages
{
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_i18nService = ServiceContainer.Resolve<II18nService>();
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
PageTitle = AppResources.Options;
var iosIos = Device.RuntimePlatform == Device.iOS;
@@ -79,18 +74,12 @@ namespace Bit.App.Pages
new KeyValuePair<UriMatchType?, string>(UriMatchType.Exact, AppResources.Exact),
new KeyValuePair<UriMatchType?, string>(UriMatchType.Never, AppResources.Never),
};
LocalesOptions = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>(null, AppResources.DefaultSystem)
};
LocalesOptions.AddRange(_i18nService.LocaleNames.ToList());
}
public List<KeyValuePair<int?, string>> ClearClipboardOptions { get; set; }
public List<KeyValuePair<string, string>> ThemeOptions { get; set; }
public List<KeyValuePair<string, string>> AutoDarkThemeOptions { get; set; }
public List<KeyValuePair<UriMatchType?, string>> UriMatchOptions { get; set; }
public List<KeyValuePair<string, string>> LocalesOptions { get; }
public int ClearClipboardSelectedIndex
{
@@ -144,18 +133,6 @@ namespace Bit.App.Pages
}
}
public KeyValuePair<string, string> SelectedLocale
{
get => _selectedLocale;
set
{
if (SetProperty(ref _selectedLocale, value))
{
UpdateCurrentLocaleAsync().FireAndForget();
}
}
}
public bool Favicon
{
get => _favicon;
@@ -207,30 +184,19 @@ namespace Bit.App.Pages
public async Task InitAsync()
{
AutofillSavePrompt = !(await _stateService.GetAutofillDisableSavePromptAsync()).GetValueOrDefault();
var blockedUrisList = await _stateService.GetAutofillBlacklistedUrisAsync();
AutofillBlockedUris = blockedUrisList != null ? string.Join(", ", blockedUrisList) : null;
AutoTotpCopy = !(await _stateService.GetDisableAutoTotpCopyAsync() ?? false);
Favicon = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
var theme = await _stateService.GetThemeAsync();
ThemeSelectedIndex = ThemeOptions.FindIndex(k => k.Key == theme);
var autoDarkTheme = await _stateService.GetAutoDarkThemeAsync() ?? "dark";
AutoDarkThemeSelectedIndex = AutoDarkThemeOptions.FindIndex(k => k.Key == autoDarkTheme);
var defaultUriMatch = await _stateService.GetDefaultUriMatchAsync();
UriMatchSelectedIndex = defaultUriMatch == null ? 0 :
UriMatchOptions.FindIndex(k => (int?)k.Key == defaultUriMatch);
var clearClipboard = await _stateService.GetClearClipboardAsync();
ClearClipboardSelectedIndex = ClearClipboardOptions.FindIndex(k => k.Key == clearClipboard);
var appLocale = _stateService.GetLocale();
SelectedLocale = appLocale == null ? LocalesOptions.First() : LocalesOptions.FirstOrDefault(kv => kv.Key == appLocale);
_inited = true;
}
@@ -322,17 +288,5 @@ namespace Bit.App.Pages
catch { }
}
}
private async Task UpdateCurrentLocaleAsync()
{
if (!_inited)
{
return;
}
_stateService.SetLocale(SelectedLocale.Key);
await _platformUtilsService.ShowDialogAsync(string.Format(AppResources.LanguageChangeXDescription, SelectedLocale.Value), AppResources.Language, AppResources.Ok);
}
}
}

View File

@@ -9,7 +9,6 @@ using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models;
using Bit.Core.Models.Domain;
using Bit.Core.Models.Response;
using Bit.Core.Models.View;
using Bit.Core.Services;
using Bit.Core.Utilities;
@@ -36,7 +35,6 @@ namespace Bit.App.Pages
private readonly IClipboardService _clipboardService;
private readonly ILogger _loggerService;
private readonly IPushNotificationService _pushNotificationService;
private readonly IAuthService _authService;
private readonly IWatchDeviceService _watchDeviceService;
private const int CustomVaultTimeoutValue = -100;
@@ -51,6 +49,7 @@ namespace Bit.App.Pages
private bool _reportLoggingEnabled;
private bool _approvePasswordlessLoginRequests;
private bool _shouldConnectToWatch;
private List<KeyValuePair<string, int?>> _vaultTimeouts =
new List<KeyValuePair<string, int?>>
{
@@ -93,8 +92,8 @@ namespace Bit.App.Pages
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
_loggerService = ServiceContainer.Resolve<ILogger>("logger");
_pushNotificationService = ServiceContainer.Resolve<IPushNotificationService>();
_authService = ServiceContainer.Resolve<IAuthService>();
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
GroupedItems = new ObservableRangeCollection<ISettingsPageListItem>();
PageTitle = AppResources.Settings;
@@ -145,6 +144,7 @@ namespace Bit.App.Pages
!await _keyConnectorService.GetUsesKeyConnector();
_reportLoggingEnabled = await _loggerService.IsEnabled();
_approvePasswordlessLoginRequests = await _stateService.GetApprovePasswordlessLoginsAsync();
_shouldConnectToWatch = await _stateService.GetShouldConnectToWatchAsync();
BuildList();
@@ -422,9 +422,12 @@ namespace Bit.App.Pages
AppResources.Yes, AppResources.No);
}
var kdfConfig = await _stateService.GetActiveUserCustomDataAsync(a => new KdfConfig(a?.Profile));
var kdf = await _stateService.GetKdfTypeAsync();
var kdfIterations = await _stateService.GetKdfIterationsAsync();
var email = await _stateService.GetEmailAsync();
var pinKey = await _cryptoService.MakePinKeyAysnc(pin, email, kdfConfig);
var pinKey = await _cryptoService.MakePinKeyAysnc(pin, email,
kdf.GetValueOrDefault(Core.Enums.KdfType.PBKDF2_SHA256),
kdfIterations.GetValueOrDefault(5000));
var key = await _cryptoService.GetKeyAsync();
var pinProtectedKey = await _cryptoService.EncryptAsync(key.Key, pinKey);
@@ -563,14 +566,6 @@ namespace Bit.App.Pages
ExecuteAsync = () => TwoStepAsync()
}
};
if (_approvePasswordlessLoginRequests)
{
manageItems.Add(new SettingsPageListItem
{
Name = AppResources.PendingLogInRequests,
ExecuteAsync = () => PendingLoginRequestsAsync()
});
}
if (_supportsBiometric || _biometric)
{
var biometricName = AppResources.Biometrics;
@@ -762,25 +757,6 @@ namespace Bit.App.Pages
}
}
private async Task PendingLoginRequestsAsync()
{
try
{
var requests = await _authService.GetActivePasswordlessLoginRequestsAsync();
if (requests == null || !requests.Any())
{
_platformUtilsService.ShowToast("info", null, AppResources.NoPendingRequests);
return;
}
Page.Navigation.PushModalAsync(new NavigationPage(new LoginPasswordlessRequestsListPage())).FireAndForget();
}
catch (Exception ex)
{
HandleException(ex);
}
}
private bool IncludeLinksWithSubscriptionInfo()
{
if (Device.RuntimePlatform == Device.iOS)
@@ -806,6 +782,11 @@ namespace Bit.App.Pages
public async Task SetScreenCaptureAllowedAsync()
{
if (CoreHelpers.ForceScreenCaptureEnabled())
{
return;
}
try
{
if (!_screenCaptureAllowed

View File

@@ -1,26 +1,30 @@
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
x:Class="Bit.App.Pages.CipherSelectionPage"
x:Class="Bit.App.Pages.AutofillCiphersPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
xmlns:u="clr-namespace:Bit.App.Utilities"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:effects="clr-namespace:Bit.App.Effects;assembly=BitwardenApp"
x:DataType="pages:CipherSelectionPageViewModel"
x:DataType="pages:AutofillCiphersPageViewModel"
Title="{Binding PageTitle}"
x:Name="_page">
<ContentPage.BindingContext>
<pages:AutofillCiphersPageViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<controls:ExtendedToolbarItem
x:Name="_accountAvatar"
IconImageSource="{Binding AvatarImageSource}"
Command="{Binding Source={x:Reference _accountListOverlay}, Path=ToggleVisibililtyCommand}"
Order="Primary"
Priority="-2"
Priority="-1"
UseOriginalImage="True"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
<ToolbarItem IconImageSource="search.png" Clicked="Search_Clicked"
<ToolbarItem Icon="search.png" Clicked="Search_Clicked"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Search}" />
</ContentPage.ToolbarItems>
@@ -28,21 +32,6 @@
<ContentPage.Resources>
<ResourceDictionary>
<u:InverseBoolConverter x:Key="inverseBool" />
<controls:SelectionChangedEventArgsConverter x:Key="SelectionChangedEventArgsConverter" />
<ToolbarItem
x:Name="_closeItem"
x:Key="_closeItem"
Text="{u:I18n Close}"
Clicked="CloseItem_Clicked"
Order="Primary"
Priority="-1" />
<ToolbarItem x:Name="_addItem" x:Key="addItem"
IconImageSource="plus.png"
Command="{Binding AddCipherCommand}"
Order="Primary"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n AddItem}" />
<DataTemplate x:Key="cipherTemplate"
x:DataType="pages:GroupingsPageListItem">
@@ -81,44 +70,23 @@
Padding="20, 0"
Spacing="20"
IsVisible="{Binding ShowNoData}">
<Image
Source="empty_items_state" />
<Label
Text="{Binding NoDataText}"
HorizontalTextAlignment="Center"></Label>
<Button
Text="{u:I18n AddAnItem}"
Command="{Binding AddCipherCommand}" />
Clicked="AddButton_Clicked"></Button>
</StackLayout>
<Frame
IsVisible="{Binding ShowCallout}"
Padding="10"
Margin="20, 10"
HasShadow="False"
BackgroundColor="Transparent"
BorderColor="{DynamicResource PrimaryColor}">
<Label
Text="{u:I18n AddTheKeyToAnExistingOrNewItem}"
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Center" />
</Frame>
<controls:ExtendedCollectionView
IsVisible="{Binding ShowList}"
ItemsSource="{Binding GroupedItems}"
VerticalOptions="FillAndExpand"
ItemTemplate="{StaticResource listItemDataTemplateSelector}"
SelectionMode="Single"
SelectionChanged="RowSelected"
StyleClass="list, list-platform"
ExtraDataForLogging="Autofill Ciphers Page">
<controls:ExtendedCollectionView.Behaviors>
<xct:EventToCommandBehavior
EventName="SelectionChanged"
Command="{Binding SelectCipherCommand}"
EventArgsConverter="{StaticResource SelectionChangedEventArgsConverter}" />
</controls:ExtendedCollectionView.Behaviors>
</controls:ExtendedCollectionView>
ExtraDataForLogging="Autofill Ciphers Page" />
</StackLayout>
</ResourceDictionary>
</ContentPage.Resources>
@@ -136,10 +104,9 @@
<!-- Android FAB -->
<Button
x:Name="_fab"
ImageSource="plus.png"
Command="{Binding AddCipherCommand}"
Image="plus.png"
Clicked="AddButton_Clicked"
Style="{StaticResource btn-fab}"
IsVisible="{OnPlatform iOS=false, Android=true}"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="1, 1, AutoSize, AutoSize">
<Button.Effects>

View File

@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Controls;
using Bit.App.Models;
using Bit.App.Utilities;
using Bit.Core.Abstractions;
@@ -11,46 +12,27 @@ using Xamarin.Forms;
namespace Bit.App.Pages
{
public partial class CipherSelectionPage : BaseContentPage
public partial class AutofillCiphersPage : BaseContentPage
{
private readonly AppOptions _appOptions;
private readonly IBroadcasterService _broadcasterService;
private readonly ISyncService _syncService;
private readonly IVaultTimeoutService _vaultTimeoutService;
private readonly IAccountsManager _accountsManager;
private readonly CipherSelectionPageViewModel _vm;
private AutofillCiphersPageViewModel _vm;
public CipherSelectionPage(AppOptions appOptions)
public AutofillCiphersPage(AppOptions appOptions)
{
_appOptions = appOptions;
if (appOptions?.OtpData is null)
{
BindingContext = new AutofillCiphersPageViewModel();
}
else
{
BindingContext = new OTPCipherSelectionPageViewModel();
}
InitializeComponent();
if (Device.RuntimePlatform == Device.iOS)
{
ToolbarItems.Add(_closeItem);
ToolbarItems.Add(_addItem);
}
SetActivityIndicator(_mainContent);
_vm = BindingContext as CipherSelectionPageViewModel;
_vm = BindingContext as AutofillCiphersPageViewModel;
_vm.Page = this;
_vm.Init(appOptions);
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
_accountsManager = ServiceContainer.Resolve<IAccountsManager>();
}
protected async override void OnAppearing()
@@ -69,16 +51,10 @@ namespace Bit.App.Pages
return;
}
// TODO: There's currently an issue on iOS where the toolbar item is not getting updated
// as the others somehow. Removing this so at least we get the circle with ".." instead
// of a white circle
if (Device.RuntimePlatform != Device.iOS)
{
_accountAvatar?.OnAppearing();
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
}
_accountAvatar?.OnAppearing();
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
_broadcasterService.Subscribe(nameof(CipherSelectionPage), async (message) =>
_broadcasterService.Subscribe(nameof(AutofillCiphersPage), async (message) =>
{
try
{
@@ -140,44 +116,40 @@ namespace Bit.App.Pages
_accountAvatar?.OnDisappearing();
}
private void AddButton_Clicked(object sender, System.EventArgs e)
private async void RowSelected(object sender, SelectionChangedEventArgs e)
{
((ExtendedCollectionView)sender).SelectedItem = null;
if (!DoOnce())
{
return;
}
if (e.CurrentSelection?.FirstOrDefault() is GroupingsPageListItem item && item.Cipher != null)
{
await _vm.SelectCipherAsync(item.Cipher, item.FuzzyAutofill);
}
}
private async void AddButton_Clicked(object sender, System.EventArgs e)
{
if (!DoOnce())
{
return;
}
if (_vm is AutofillCiphersPageViewModel autofillVM)
{
AddFromAutofill(autofillVM).FireAndForget();
}
}
private async Task AddFromAutofill(AutofillCiphersPageViewModel autofillVM)
{
if (_appOptions.FillType.HasValue && _appOptions.FillType != CipherType.Login)
{
var pageForOther = new CipherAddEditPage(type: _appOptions.FillType, fromAutofill: true);
await Navigation.PushModalAsync(new NavigationPage(pageForOther));
return;
}
var pageForLogin = new CipherAddEditPage(null, CipherType.Login, uri: autofillVM.Uri, name: _vm.Name,
var pageForLogin = new CipherAddEditPage(null, CipherType.Login, uri: _vm.Uri, name: _vm.Name,
fromAutofill: true);
await Navigation.PushModalAsync(new NavigationPage(pageForLogin));
}
private void Search_Clicked(object sender, EventArgs e)
private void Search_Clicked(object sender, System.EventArgs e)
{
var page = new CiphersPage(null, appOptions: _appOptions);
Navigation.PushModalAsync(new NavigationPage(page)).FireAndForget();
}
void CloseItem_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_accountsManager.StartDefaultNavigationFlowAsync(op => op.OtpData = null).FireAndForget();
}
var page = new CiphersPage(null, autofillUrl: _vm.Uri);
Application.Current.MainPage = new NavigationPage(page);
}
}
}

View File

@@ -1,29 +1,91 @@
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.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class AutofillCiphersPageViewModel : CipherSelectionPageViewModel
public class AutofillCiphersPageViewModel : BaseViewModel
{
private CipherType? _fillType;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IDeviceActionService _deviceActionService;
private readonly IAutofillHandler _autofillHandler;
private readonly ICipherService _cipherService;
private readonly IStateService _stateService;
private readonly IPasswordRepromptService _passwordRepromptService;
private readonly IMessagingService _messagingService;
private readonly ILogger _logger;
private bool _showNoData;
private bool _showList;
private string _noDataText;
private bool _websiteIconsEnabled;
public AutofillCiphersPageViewModel()
{
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>("passwordRepromptService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_logger = ServiceContainer.Resolve<ILogger>("logger");
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
{
AllowAddAccountRow = false
};
}
public string Name { get; set; }
public string Uri { get; set; }
public Command CipherOptionsCommand { get; set; }
public bool LoadedOnce { get; set; }
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { get; set; }
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
public override void Init(AppOptions appOptions)
public bool ShowNoData
{
get => _showNoData;
set => SetProperty(ref _showNoData, value);
}
public bool ShowList
{
get => _showList;
set => SetProperty(ref _showList, value);
}
public string NoDataText
{
get => _noDataText;
set => SetProperty(ref _noDataText, value);
}
public bool WebsiteIconsEnabled
{
get => _websiteIconsEnabled;
set => SetProperty(ref _websiteIconsEnabled, value);
}
public void Init(AppOptions appOptions)
{
Uri = appOptions?.Uri;
_fillType = appOptions.FillType;
string name = null;
if (Uri?.StartsWith(Constants.AndroidAppProtocol) ?? false)
{
@@ -42,11 +104,14 @@ namespace Bit.App.Pages
NoDataText = string.Format(AppResources.NoItemsForUri, Name ?? "--");
}
protected override async Task<List<GroupingsPageListGroup>> LoadGroupedItemsAsync()
public async Task LoadAsync()
{
LoadedOnce = true;
ShowList = false;
ShowNoData = false;
WebsiteIconsEnabled = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
var groupedItems = new List<GroupingsPageListGroup>();
var ciphers = await _cipherService.GetAllDecryptedByUrlAsync(Uri, null);
var matching = ciphers.Item1?.Select(c => new GroupingsPageListItem { Cipher = c }).ToList();
var hasMatching = matching?.Any() ?? false;
if (matching?.Any() ?? false)
@@ -54,7 +119,6 @@ namespace Bit.App.Pages
groupedItems.Add(
new GroupingsPageListGroup(matching, AppResources.MatchingItems, matching.Count, false, true));
}
var fuzzy = ciphers.Item2?.Select(c =>
new GroupingsPageListItem { Cipher = c, FuzzyAutofill = true }).ToList();
if (fuzzy?.Any() ?? false)
@@ -64,88 +128,123 @@ namespace Bit.App.Pages
!hasMatching));
}
return 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();
ShowNoData = !ShowList;
}
protected override async Task SelectCipherAsync(IGroupingsPageListItem item)
public async Task SelectCipherAsync(CipherView cipher, bool fuzzy)
{
if (!(item is GroupingsPageListItem listItem) || listItem.Cipher is null)
if (cipher == null)
{
return;
}
var cipher = listItem.Cipher;
if (_deviceActionService.SystemMajorVersion() < 21)
{
await AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService);
return;
}
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync())
else
{
return;
}
var autofillResponse = AppResources.Yes;
if (listItem.FuzzyAutofill)
{
var options = new List<string> { AppResources.Yes };
if (cipher.Type == CipherType.Login &&
Xamarin.Essentials.Connectivity.NetworkAccess != Xamarin.Essentials.NetworkAccess.None)
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync())
{
options.Add(AppResources.YesAndSave);
return;
}
autofillResponse = await _deviceActionService.DisplayAlertAsync(null,
string.Format(AppResources.BitwardenAutofillServiceMatchConfirm, Name), AppResources.No,
options.ToArray());
}
if (autofillResponse == AppResources.YesAndSave && cipher.Type == CipherType.Login)
{
var uris = cipher.Login?.Uris?.ToList();
if (uris == null)
var autofillResponse = AppResources.Yes;
if (fuzzy)
{
uris = new List<LoginUriView>();
}
uris.Add(new LoginUriView
{
Uri = Uri,
Match = null
});
cipher.Login.Uris = uris;
try
{
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
await _cipherService.SaveWithServerAsync(await _cipherService.EncryptAsync(cipher));
await _deviceActionService.HideLoadingAsync();
}
catch (ApiException e)
{
await _deviceActionService.HideLoadingAsync();
if (e?.Error != null)
var options = new List<string> { AppResources.Yes };
if (cipher.Type == CipherType.Login &&
Xamarin.Essentials.Connectivity.NetworkAccess != Xamarin.Essentials.NetworkAccess.None)
{
await _platformUtilsService.ShowDialogAsync(e.Error.GetSingleMessage(),
AppResources.AnErrorHasOccurred);
options.Add(AppResources.YesAndSave);
}
autofillResponse = await _deviceActionService.DisplayAlertAsync(null,
string.Format(AppResources.BitwardenAutofillServiceMatchConfirm, Name), AppResources.No,
options.ToArray());
}
if (autofillResponse == AppResources.YesAndSave && cipher.Type == CipherType.Login)
{
var uris = cipher.Login?.Uris?.ToList();
if (uris == null)
{
uris = new List<LoginUriView>();
}
uris.Add(new LoginUriView
{
Uri = Uri,
Match = null
});
cipher.Login.Uris = uris;
try
{
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
await _cipherService.SaveWithServerAsync(await _cipherService.EncryptAsync(cipher));
await _deviceActionService.HideLoadingAsync();
}
catch (ApiException e)
{
await _deviceActionService.HideLoadingAsync();
if (e?.Error != null)
{
await _platformUtilsService.ShowDialogAsync(e.Error.GetSingleMessage(),
AppResources.AnErrorHasOccurred);
}
}
}
}
if (autofillResponse == AppResources.Yes || autofillResponse == AppResources.YesAndSave)
{
_autofillHandler.Autofill(cipher);
if (autofillResponse == AppResources.Yes || autofillResponse == AppResources.YesAndSave)
{
_autofillHandler.Autofill(cipher);
}
}
}
protected override async Task AddCipherAsync()
private async void CipherOptionsAsync(CipherView cipher)
{
if (_fillType.HasValue && _fillType != CipherType.Login)
if ((Page as BaseContentPage).DoOnce())
{
var pageForOther = new CipherAddEditPage(type: _fillType, fromAutofill: true);
await Page.Navigation.PushModalAsync(new NavigationPage(pageForOther));
return;
await AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService);
}
var pageForLogin = new CipherAddEditPage(null, CipherType.Login, uri: Uri, name: Name,
fromAutofill: true);
await Page.Navigation.PushModalAsync(new NavigationPage(pageForLogin));
}
}
}

View File

@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bit.App.Abstractions;
using Bit.App.Lists.ItemViewModels.CustomFields;
using Bit.App.Models;
using Bit.App.Resources;
@@ -31,7 +30,6 @@ namespace Bit.App.Pages
private readonly IClipboardService _clipboardService;
private readonly IAutofillHandler _autofillHandler;
private readonly IWatchDeviceService _watchDeviceService;
private readonly IAccountsManager _accountsManager;
private bool _showNotesSeparator;
private bool _showPassword;
@@ -46,8 +44,6 @@ namespace Bit.App.Pages
private bool _hasCollections;
private string _previousCipherId;
private List<Core.Models.View.CollectionView> _writeableCollections;
private bool _fromOtp;
protected override string[] AdditionalPropertiesToRaiseOnCipherChanged => new string[]
{
nameof(IsLogin),
@@ -86,8 +82,6 @@ namespace Bit.App.Pages
_clipboardService = ServiceContainer.Resolve<IClipboardService>("clipboardService");
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
_watchDeviceService = ServiceContainer.Resolve<IWatchDeviceService>();
_accountsManager = ServiceContainer.Resolve<IAccountsManager>();
GeneratePasswordCommand = new Command(GeneratePassword);
TogglePasswordCommand = new Command(TogglePassword);
@@ -121,7 +115,6 @@ namespace Bit.App.Pages
new KeyValuePair<string, string>("JCB", "JCB"),
new KeyValuePair<string, string>("Maestro", "Maestro"),
new KeyValuePair<string, string>("UnionPay", "UnionPay"),
new KeyValuePair<string, string>("RuPay", "RuPay"),
new KeyValuePair<string, string>(AppResources.Other, "Other")
};
CardExpMonthOptions = new List<KeyValuePair<string, string>>
@@ -309,7 +302,6 @@ namespace Bit.App.Pages
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
public bool HasTotpValue => IsLogin && !string.IsNullOrEmpty(Cipher?.Login?.Totp);
public string SetupTotpText => $"{BitwardenIcons.Camera} {AppResources.SetupTotp}";
public void Init()
{
PageTitle = EditMode && !CloneMode ? AppResources.EditItem : AppResources.AddItem;
@@ -317,8 +309,6 @@ namespace Bit.App.Pages
public async Task<bool> LoadAsync(AppOptions appOptions = null)
{
_fromOtp = appOptions?.OtpData != null;
var myEmail = await _stateService.GetEmailAsync();
OwnershipOptions.Add(new KeyValuePair<string, string>(myEmail, null));
var orgs = await _organizationService.GetAllAsync();
@@ -368,10 +358,6 @@ namespace Bit.App.Pages
Cipher.OrganizationId = OrganizationId;
}
}
if (appOptions?.OtpData != null && Cipher.Type == CipherType.Login)
{
Cipher.Login.Totp = appOptions.OtpData.Value.Uri;
}
}
else
{
@@ -394,7 +380,6 @@ namespace Bit.App.Pages
Cipher.Type = appOptions.SaveType.GetValueOrDefault(Cipher.Type);
Cipher.Login.Username = appOptions.SaveUsername;
Cipher.Login.Password = appOptions.SavePassword;
Cipher.Login.Totp = appOptions.OtpData?.Uri;
Cipher.Card.Code = appOptions.SaveCardCode;
if (int.TryParse(appOptions.SaveCardExpMonth, out int month) && month <= 12 && month >= 1)
{
@@ -439,11 +424,6 @@ namespace Bit.App.Pages
{
Fields.ResetWithRange(Cipher.Fields?.Select(f => _customFieldItemFactory.CreateCustomFieldItem(f, true, Cipher, null, null, FieldOptionsCommand)));
}
if (appOptions?.OtpData != null)
{
_platformUtilsService.ShowToast(null, AppResources.AuthenticatorKey, AppResources.AuthenticatorKeyAdded);
}
}
if (EditMode && _previousCipherId != CipherId)
@@ -537,10 +517,6 @@ namespace Bit.App.Pages
// Close and go back to app
_autofillHandler.CloseAutofill();
}
else if (_fromOtp)
{
await _accountsManager.StartDefaultNavigationFlowAsync(op => op.OtpData = null);
}
else
{
if (CloneMode)

View File

@@ -1,167 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.App.Controls;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public abstract class CipherSelectionPageViewModel : BaseViewModel
{
protected readonly IPlatformUtilsService _platformUtilsService;
protected readonly IDeviceActionService _deviceActionService;
protected readonly IAutofillHandler _autofillHandler;
protected readonly ICipherService _cipherService;
protected readonly IStateService _stateService;
protected readonly IPasswordRepromptService _passwordRepromptService;
protected readonly IMessagingService _messagingService;
protected readonly ILogger _logger;
protected bool _showNoData;
protected bool _showList;
protected string _noDataText;
protected bool _websiteIconsEnabled;
public CipherSelectionPageViewModel()
{
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>();
_cipherService = ServiceContainer.Resolve<ICipherService>();
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>();
_autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
_stateService = ServiceContainer.Resolve<IStateService>();
_passwordRepromptService = ServiceContainer.Resolve<IPasswordRepromptService>();
_messagingService = ServiceContainer.Resolve<IMessagingService>();
_logger = ServiceContainer.Resolve<ILogger>();
GroupedItems = new ObservableRangeCollection<IGroupingsPageListItem>();
CipherOptionsCommand = new AsyncCommand<CipherView>(cipher => AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
SelectCipherCommand = new AsyncCommand<IGroupingsPageListItem>(SelectCipherAsync,
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
AddCipherCommand = new AsyncCommand(AddCipherAsync,
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
AccountSwitchingOverlayViewModel = new AccountSwitchingOverlayViewModel(_stateService, _messagingService, _logger)
{
AllowAddAccountRow = false
};
}
public string Name { get; set; }
public bool LoadedOnce { get; set; }
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { get; set; }
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
public ICommand CipherOptionsCommand { get; set; }
public ICommand SelectCipherCommand { get; set; }
public ICommand AddCipherCommand { get; set; }
public bool ShowNoData
{
get => _showNoData;
set => SetProperty(ref _showNoData, value, additionalPropertyNames: new string[] { nameof(ShowCallout) });
}
public bool ShowList
{
get => _showList;
set => SetProperty(ref _showList, value);
}
public string NoDataText
{
get => _noDataText;
set => SetProperty(ref _noDataText, value);
}
public bool WebsiteIconsEnabled
{
get => _websiteIconsEnabled;
set => SetProperty(ref _websiteIconsEnabled, value);
}
public virtual bool ShowCallout => false;
public abstract void Init(Models.AppOptions options);
public async Task LoadAsync()
{
LoadedOnce = true;
ShowList = false;
ShowNoData = false;
WebsiteIconsEnabled = !(await _stateService.GetDisableFaviconAsync()).GetValueOrDefault();
var groupedItems = await LoadGroupedItemsAsync();
// 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);
}
await Device.InvokeOnMainThreadAsync(() =>
{
if (groupedItems.Any())
{
GroupedItems.ReplaceRange(new List<IGroupingsPageListItem> { new GroupingsPageHeaderListItem(groupedItems[0].Name, groupedItems[0].ItemCount) });
GroupedItems.AddRange(items);
}
else
{
GroupedItems.Clear();
}
});
}
await Device.InvokeOnMainThreadAsync(() =>
{
ShowList = groupedItems.Any();
ShowNoData = !ShowList;
});
}
protected abstract Task<List<GroupingsPageListGroup>> LoadGroupedItemsAsync();
protected abstract Task SelectCipherAsync(IGroupingsPageListItem item);
protected abstract Task AddCipherAsync();
}
}

View File

@@ -81,22 +81,12 @@
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center" />
<StackLayout
HorizontalOptions="Center"
VerticalOptions="StartAndExpand"
Margin="20, 80, 20, 0"
Spacing="20"
IsVisible="{Binding ShowNoData}">
<Image
Source="empty_items_state" />
<Label
Text="{u:I18n ThereAreNoItemsThatMatchTheSearch}"
HorizontalTextAlignment="Center" />
<Button
Text="{u:I18n AddAnItem}"
Command="{Binding AddCipherCommand}"
IsVisible="{Binding ShowAddCipher}"/>
</StackLayout>
<Label IsVisible="{Binding ShowNoData}"
Text="{u:I18n NoItemsToList}"
Margin="20, 0"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center" />
<controls:ExtendedCollectionView
IsVisible="{Binding ShowList}"
ItemsSource="{Binding Ciphers}"

View File

@@ -1,7 +1,6 @@
using System;
using System.Linq;
using Bit.App.Controls;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Models.View;
@@ -18,18 +17,15 @@ namespace Bit.App.Pages
private CiphersPageViewModel _vm;
private bool _hasFocused;
public CiphersPage(Func<CipherView, bool> filter,
string pageTitle = null,
string vaultFilterSelection = null,
bool deleted = false,
AppOptions appOptions = null)
public CiphersPage(Func<CipherView, bool> filter, string pageTitle = null, string vaultFilterSelection = null,
string autofillUrl = null, bool deleted = false)
{
InitializeComponent();
_vm = BindingContext as CiphersPageViewModel;
_vm.Page = this;
_autofillUrl = appOptions?.Uri;
_vm.Prepare(filter, deleted, appOptions);
_vm.Filter = filter;
_vm.AutofillUrl = _autofillUrl = autofillUrl;
_vm.Deleted = deleted;
if (pageTitle != null)
{
_vm.PageTitle = string.Format(AppResources.SearchGroup, pageTitle);

View File

@@ -3,16 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.View;
using Bit.Core.Utilities;
using Xamarin.CommunityToolkit.ObjectModel;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -34,7 +31,6 @@ namespace Bit.App.Pages
private bool _showNoData;
private bool _showList;
private bool _websiteIconsEnabled;
private AppOptions _appOptions;
public CiphersPageViewModel()
{
@@ -50,21 +46,14 @@ namespace Bit.App.Pages
_logger = ServiceContainer.Resolve<ILogger>("logger");
Ciphers = new ExtendedObservableCollection<CipherView>();
CipherOptionsCommand = new AsyncCommand<CipherView>(cipher => Utilities.AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
AddCipherCommand = new AsyncCommand(AddCipherAsync,
onException: ex => HandleException(ex),
allowsMultipleExecutions: false);
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
}
public ICommand CipherOptionsCommand { get; }
public ICommand AddCipherCommand { get; }
public Command CipherOptionsCommand { get; set; }
public ExtendedObservableCollection<CipherView> Ciphers { get; set; }
public Func<CipherView, bool> Filter { get; set; }
public string AutofillUrl { get; set; }
public bool Deleted { get; set; }
public bool ShowAllIfSearchTextEmpty { get; set; }
protected override ICipherService cipherService => _cipherService;
protected override IPolicyService policyService => _policyService;
@@ -76,8 +65,7 @@ namespace Bit.App.Pages
get => _showNoData;
set => SetProperty(ref _showNoData, value, additionalPropertyNames: new string[]
{
nameof(ShowSearchDirection),
nameof(ShowAddCipher)
nameof(ShowSearchDirection)
});
}
@@ -92,23 +80,12 @@ namespace Bit.App.Pages
public bool ShowSearchDirection => !ShowList && !ShowNoData;
public bool ShowAddCipher => ShowNoData && _appOptions?.OtpData != null;
public bool WebsiteIconsEnabled
{
get => _websiteIconsEnabled;
set => SetProperty(ref _websiteIconsEnabled, value);
}
internal void Prepare(Func<CipherView, bool> filter, bool deleted, AppOptions appOptions)
{
Filter = filter;
AutofillUrl = appOptions?.Uri;
Deleted = deleted;
ShowAllIfSearchTextEmpty = appOptions?.OtpData != null;
_appOptions = appOptions;
}
public async Task InitAsync()
{
await InitVaultFilterAsync(true);
@@ -124,33 +101,25 @@ namespace Bit.App.Pages
{
List<CipherView> ciphers = null;
var searchable = !string.IsNullOrWhiteSpace(searchText) && searchText.Length > 1;
var shouldShowAllWhenEmpty = ShowAllIfSearchTextEmpty && string.IsNullOrEmpty(searchText);
if (searchable || shouldShowAllWhenEmpty)
if (searchable)
{
if (timeout != null)
{
await Task.Delay(timeout.Value);
}
if (searchText != (Page as CiphersPage).SearchBar.Text
&&
!shouldShowAllWhenEmpty)
if (searchText != (Page as CiphersPage).SearchBar.Text)
{
return;
}
previousCts?.Cancel();
else
{
previousCts?.Cancel();
}
try
{
var vaultFilteredCiphers = await GetAllCiphersAsync();
if (!shouldShowAllWhenEmpty)
{
ciphers = await _searchService.SearchCiphersAsync(searchText,
Filter ?? (c => c.IsDeleted == Deleted), vaultFilteredCiphers, cts.Token);
}
else
{
ciphers = vaultFilteredCiphers;
}
ciphers = await _searchService.SearchCiphersAsync(searchText,
Filter ?? (c => c.IsDeleted == Deleted), vaultFilteredCiphers, cts.Token);
cts.Token.ThrowIfCancellationRequested();
}
catch (OperationCanceledException)
@@ -165,8 +134,8 @@ namespace Bit.App.Pages
Device.BeginInvokeOnMainThread(() =>
{
Ciphers.ResetWithRange(ciphers);
ShowNoData = !shouldShowAllWhenEmpty && searchable && Ciphers.Count == 0;
ShowList = (searchable || shouldShowAllWhenEmpty) && !ShowNoData;
ShowNoData = searchable && Ciphers.Count == 0;
ShowList = searchable && !ShowNoData;
});
}, cts.Token);
_searchCancellationTokenSource = cts;
@@ -175,7 +144,6 @@ namespace Bit.App.Pages
public async Task SelectCipherAsync(CipherView cipher)
{
string selection = null;
if (!string.IsNullOrWhiteSpace(AutofillUrl))
{
var options = new List<string> { AppResources.Autofill };
@@ -188,19 +156,6 @@ namespace Bit.App.Pages
selection = await Page.DisplayActionSheet(AppResources.AutofillOrView, AppResources.Cancel, null,
options.ToArray());
}
if (_appOptions?.OtpData != null)
{
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync())
{
return;
}
var editCipherPage = new CipherAddEditPage(cipher.Id, appOptions: _appOptions);
await Page.Navigation.PushModalAsync(new NavigationPage(editCipherPage));
return;
}
if (selection == AppResources.View || string.IsNullOrWhiteSpace(AutofillUrl))
{
var page = new CipherDetailsPage(cipher.Id);
@@ -250,7 +205,7 @@ namespace Bit.App.Pages
private void PerformSearchIfPopulated()
{
if (!string.IsNullOrWhiteSpace((Page as CiphersPage).SearchBar.Text) || ShowAllIfSearchTextEmpty)
if (!string.IsNullOrWhiteSpace((Page as CiphersPage).SearchBar.Text))
{
Search((Page as CiphersPage).SearchBar.Text, 200);
}
@@ -261,10 +216,12 @@ namespace Bit.App.Pages
PerformSearchIfPopulated();
}
private async Task AddCipherAsync()
private async void CipherOptionsAsync(CipherView cipher)
{
var pageForLogin = new CipherAddEditPage(null, CipherType.Login, name: _appOptions?.OtpData?.Issuer ?? _appOptions?.OtpData?.AccountName, appOptions: _appOptions);
await Page.Navigation.PushModalAsync(new NavigationPage(pageForLogin));
if ((Page as BaseContentPage).DoOnce())
{
await Utilities.AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService);
}
}
}
}

View File

@@ -78,9 +78,7 @@ namespace Bit.App.Pages
Refreshing = true;
await LoadAsync();
});
CipherOptionsCommand = new AsyncCommand<CipherView>(cipher => AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService),
onException: ex => _logger.Exception(ex),
allowsMultipleExecutions: false);
CipherOptionsCommand = new Command<CipherView>(CipherOptionsAsync);
VaultFilterCommand = new AsyncCommand(VaultFilterOptionsAsync,
onException: ex => _logger.Exception(ex),
allowsMultipleExecutions: false);
@@ -170,7 +168,7 @@ namespace Bit.App.Pages
public AccountSwitchingOverlayViewModel AccountSwitchingOverlayViewModel { get; }
public ObservableRangeCollection<IGroupingsPageListItem> GroupedItems { get; set; }
public Command RefreshCommand { get; set; }
public ICommand CipherOptionsCommand { get; }
public Command<CipherView> CipherOptionsCommand { get; set; }
public bool LoadedOnce { get; set; }
public async Task LoadAsync()
@@ -711,5 +709,13 @@ namespace Bit.App.Pages
var folders = decFolders.Where(f => _allCiphers.Any(c => c.FolderId == f.Id)).ToList();
return folders.Any() ? folders : null;
}
private async void CipherOptionsAsync(CipherView cipher)
{
if ((Page as BaseContentPage).DoOnce())
{
await AppHelpers.CipherListOptions(Page, cipher, _passwordRepromptService);
}
}
}
}

View File

@@ -1,79 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class OTPCipherSelectionPageViewModel : CipherSelectionPageViewModel
{
private readonly ISearchService _searchService = ServiceContainer.Resolve<ISearchService>();
private OtpData _otpData;
private Models.AppOptions _appOptions;
public override bool ShowCallout => !ShowNoData;
public override void Init(Models.AppOptions options)
{
_appOptions = options;
_otpData = options.OtpData.Value;
Name = _otpData.Issuer ?? _otpData.AccountName;
PageTitle = string.Format(AppResources.ItemsForUri, Name ?? "--");
NoDataText = string.Format(AppResources.ThereAreNoItemsInYourVaultThatMatchX, Name ?? "--")
+ Environment.NewLine
+ AppResources.SearchForAnItemOrAddANewItem;
}
protected override async Task<List<GroupingsPageListGroup>> LoadGroupedItemsAsync()
{
var groupedItems = new List<GroupingsPageListGroup>();
var allCiphers = await _cipherService.GetAllDecryptedAsync();
var ciphers = await _searchService.SearchCiphersAsync(_otpData.Issuer ?? _otpData.AccountName,
c => c.Type == CipherType.Login && !c.IsDeleted, allCiphers);
if (ciphers?.Any() ?? false)
{
groupedItems.Add(
new GroupingsPageListGroup(ciphers.Select(c => new GroupingsPageListItem { Cipher = c }).ToList(),
AppResources.MatchingItems,
ciphers.Count,
false,
true));
}
return groupedItems;
}
protected override async Task SelectCipherAsync(IGroupingsPageListItem item)
{
if (!(item is GroupingsPageListItem listItem) || listItem.Cipher is null)
{
return;
}
var cipher = listItem.Cipher;
if (cipher.Reprompt != CipherRepromptType.None && !await _passwordRepromptService.ShowPasswordPromptAsync())
{
return;
}
var editCipherPage = new CipherAddEditPage(cipher.Id, appOptions: _appOptions);
await Page.Navigation.PushModalAsync(new NavigationPage(editCipherPage));
return;
}
protected override async Task AddCipherAsync()
{
var pageForLogin = new CipherAddEditPage(null, CipherType.Login, name: Name, appOptions: _appOptions);
await Page.Navigation.PushModalAsync(new NavigationPage(pageForLogin));
}
}
}

View File

@@ -382,15 +382,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Add the key to an existing or new item.
/// </summary>
public static string AddTheKeyToAnExistingOrNewItem {
get {
return ResourceManager.GetString("AddTheKeyToAnExistingOrNewItem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Add TOTP.
/// </summary>
@@ -571,15 +562,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Are you sure you want to decline all pending login requests?.
/// </summary>
public static string AreYouSureYouWantToDeclineAllPendingLogInRequests {
get {
return ResourceManager.GetString("AreYouSureYouWantToDeclineAllPendingLogInRequests", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Are you sure you want to turn on screen capture?.
/// </summary>
@@ -1777,15 +1759,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Decline all requests.
/// </summary>
public static string DeclineAllRequests {
get {
return ResourceManager.GetString("DeclineAllRequests", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Default.
/// </summary>
@@ -1813,15 +1786,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Default (System).
/// </summary>
public static string DefaultSystem {
get {
return ResourceManager.GetString("DefaultSystem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Default URI match detection.
/// </summary>
@@ -2083,15 +2047,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to DuckDuckGo.
/// </summary>
public static string DuckDuckGo {
get {
return ResourceManager.GetString("DuckDuckGo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Edit.
/// </summary>
@@ -2587,15 +2542,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Fastmail.
/// </summary>
public static string Fastmail {
get {
return ResourceManager.GetString("Fastmail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Favorite.
/// </summary>
@@ -3388,33 +3334,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Language.
/// </summary>
public static string Language {
get {
return ResourceManager.GetString("Language", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Language change requires app restart.
/// </summary>
public static string LanguageChangeRequiresAppRestart {
get {
return ResourceManager.GetString("LanguageChangeRequiresAppRestart", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The language has been changed to {0}. Please restart the app to see the change.
/// </summary>
public static string LanguageChangeXDescription {
get {
return ResourceManager.GetString("LanguageChangeXDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Last name.
/// </summary>
@@ -3715,7 +3634,7 @@ namespace Bit.App.Resources {
}
/// <summary>
/// Looks up a localized string similar to Log in with device.
/// Looks up a localized string similar to Log In with another device.
/// </summary>
public static string LogInWithAnotherDevice {
get {
@@ -3832,11 +3751,11 @@ namespace Bit.App.Resources {
}
/// <summary>
/// Looks up a localized string similar to Master password must be at least {0} characters long..
/// Looks up a localized string similar to Master password must be at least 8 characters long..
/// </summary>
public static string MasterPasswordLengthValMessageX {
public static string MasterPasswordLengthValMessage {
get {
return ResourceManager.GetString("MasterPasswordLengthValMessageX", resourceCulture);
return ResourceManager.GetString("MasterPasswordLengthValMessage", resourceCulture);
}
}
@@ -4064,7 +3983,18 @@ namespace Bit.App.Resources {
return ResourceManager.GetString("Ms", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Mx.
/// </summary>
public static string Mx
{
get
{
return ResourceManager.GetString("Mx", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You must log into the main Bitwarden app before you can use the extension..
/// </summary>
@@ -4083,15 +4013,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Mx.
/// </summary>
public static string Mx {
get {
return ResourceManager.GetString("Mx", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to My vault.
/// </summary>
@@ -4344,15 +4265,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to No pending requests.
/// </summary>
public static string NoPendingRequests {
get {
return ResourceManager.GetString("NoPendingRequests", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nord.
/// </summary>
@@ -4606,15 +4518,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Organization SSO identifier required..
/// </summary>
public static string OrganizationSsoIdentifierRequired {
get {
return ResourceManager.GetString("OrganizationSsoIdentifierRequired", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Organization identifier.
/// </summary>
@@ -4849,15 +4752,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Pending login requests.
/// </summary>
public static string PendingLogInRequests {
get {
return ResourceManager.GetString("PendingLogInRequests", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An organization policy is affecting your ownership options..
/// </summary>
@@ -5210,15 +5104,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Requests declined.
/// </summary>
public static string RequestsDeclined {
get {
return ResourceManager.GetString("RequestsDeclined", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Resend code.
/// </summary>
@@ -5345,15 +5230,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Search for an item or add a new item.
/// </summary>
public static string SearchForAnItemOrAddANewItem {
get {
return ResourceManager.GetString("SearchForAnItemOrAddANewItem", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Search {0}.
/// </summary>
@@ -6047,24 +5923,6 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to There are no items in your vault that match &quot;{0}&quot;.
/// </summary>
public static string ThereAreNoItemsInYourVaultThatMatchX {
get {
return ResourceManager.GetString("ThereAreNoItemsInYourVaultThatMatchX", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to There are no items that match the search.
/// </summary>
public static string ThereAreNoItemsThatMatchTheSearch {
get {
return ResourceManager.GetString("ThereAreNoItemsThatMatchTheSearch", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 30 days.
/// </summary>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>n Hoofwagwoordwenk kan u help om u wagwoord te onthou indien u dit sou vergeet.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Die hoofwagwoord moet ten minste {0} karakters lank wees.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Hoofwagwoord moet ten minste 8 karakters lank wees.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Min. aantal syfers</value>
@@ -1103,9 +1103,6 @@ Skandering gebeur outomaties.</value>
<data name="Ms" xml:space="preserve">
<value>Mej.</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
</data>
@@ -2145,7 +2142,7 @@ Skandering gebeur outomaties.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>U kluisuittelling oorskry die beperkinge wat deur u organisasie daargestel is.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Een of meer organisasiebeleide verhoed u om u persoonlike kluis uit te stuur.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@ kies u Voeg TOTP toe om die sleutel veilig te bewaar</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API-toegangsteken</value>
</data>
@@ -2522,85 +2511,7 @@ Wil u na die rekening omskakel?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Hierdie versoek is nie langer gelding nie</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>In afwagting vir aantekeningsversoeke</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Weier alle versoeke</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Is jy seker dat jy alle hangende aantekeningsversoeke wil weier?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Versoeke geweier</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Geen hangende versoeke</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Laat die kamera versoek toe om die skandeerder te gebruik</value>
</data>
<data name="Language" xml:space="preserve">
<value>Taal</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Die taal is na {0} verander. Asseblief herbegin die toep om die veranderinge te sien</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Die taal verandering vereis 'n herbegin van die toep</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Verstek (Sisteem)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Belangrik</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Jou hoofwagwoord kan nie geherstel word as jy dit vergeet het nie! {0} karakters minimum.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Swak Hoofwagwoord</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Swak wagwoord geïdentifiseer. Gebruik 'n sterk wagwoord om jou rekening te beskerm. Is jy seker dat jy 'n swak wagwoord wil gebruik?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Swak</value>
</data>
<data name="Good" xml:space="preserve">
<value>Goed</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Sterk</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Ondersoek bekende data lekkasies vir dié wagwoord</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Blootgestelde Hoofwagwoord</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Dié wagwoord was in data lekkasie gevind. Gebruik 'n unieke wagwoord om jou rekening te beskerm. Is jy seker dat jy 'n blootgestelde wagwoord wil gebruik?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Swak en Blootgestelde Hoofwagwoord</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Swak wagwoord geïdentifiseer en in 'n data lekkasie gevind. Gebruik 'n sterk en unieke wagwoord om jou rekening te beskerm. Is jy seker dat jy hierdie wagwoord wil gebruik?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organisasie SSO identifiseerder vereis.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>يمكن أن تساعدك فكرة كلمة المرور الرئيسية على تذكر كلمة المرور الخاصة بك إذا نسيت.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>كلمة المرور الرئيسية يجب أن تكون على الأقل {0} حرفاً.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>يجب أن تكون كلمة المرور الرئيسية أكثر من 8 أحرف.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>الحد الأدنى للأرقام</value>
@@ -1103,9 +1103,6 @@
<data name="Ms" xml:space="preserve">
<value>آنسة</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>نوفمبر</value>
</data>
@@ -2146,7 +2143,7 @@
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>مهلة خزنتك تتجاوز القيود التي تضعها مؤسستك.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>واحدة أو أكثر من سياسات المؤسسة تمنعك من تصدير خزانتك الشخصية.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2423,14 +2420,6 @@
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>رمز الوصول API</value>
</data>
@@ -2523,85 +2512,7 @@
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>هذا الطلب لم يعد صالحًا</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>طلبات تسجيل الدخول المعلقة</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>رفض جميع الطلبات</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>هل أنت متأكد من أنك تريد رفض جميع طلبات تسجيل الدخول المعلقة؟</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>تم رفض الطلبات</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>لا توجد طلبات معلقة</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>تمكين إذن الكاميرا لاستخدام الماسح الضوئي</value>
</data>
<data name="Language" xml:space="preserve">
<value>اللّغة</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>تم تغيير اللغة إلى {0}. الرجاء إعادة تشغيل التطبيق لرؤية التغيير</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>تغيير اللّغة يتطلب إعادة تشغيل التطبيق</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>الافتراضي (النظام)</value>
</data>
<data name="Important" xml:space="preserve">
<value>مهم</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>لا يمكن استعادة كلمة المرور الرئيسية الخاصة بك إذا نسيت ذلك! {0} أحرف الحد الأدنى.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>كلمة المرور الرئيسية الضعيفة</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>تم تحديد كلمة المرور ضعيفة. استخدم كلمة مرور قوية لحماية حسابك. هل أنت متأكد من أنك تريد استخدام كلمة مرور ضعيفة؟</value>
</data>
<data name="Weak" xml:space="preserve">
<value>ضعيفة</value>
</data>
<data name="Good" xml:space="preserve">
<value>جيدة</value>
</data>
<data name="Strong" xml:space="preserve">
<value>قوية</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>تحقق من خروقات البيانات المعروفة لكلمة المرور هذه</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>كلمة المرور الرئيسية مكشوفة</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>كلمة المرور موجودة في خرق البيانات. استخدم كلمة مرور فريدة لحماية حسابك. هل أنت متأكد من أنك تريد استخدام كلمة مرور مكشوفة؟</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>كلمة المرور الرئيسية ضعيفة ومكشوفة</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>كلمة مرور ضعيفة محددة وموجودة في خرق البيانات. استخدم كلمة مرور قوية وفريدة لحماية حسابك. هل أنت متأكد من أنك تريد استخدام كلمة المرور هذه؟</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>معرف الـSSO للمنظمة مطلوب.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>إضافة المفتاح إلى عنصر موجود أو جديد</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>لا توجد عناصر في خزانتك تتطابق مع "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>البحث عن عنصر أو إضافة عنصر جديد</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>لا توجد عناصر تطابق البحث</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Ana parol məsləhəti, unutduğunuz parolu xatırlamağınıza kömək edir.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Ana parol ən azı {0} simvol uzunluğunda olmalıdır.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Ana parol ən azı 8 simvol uzunluğunda olmalıdır.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Minimum rəqəm</value>
@@ -1103,9 +1103,6 @@ Skan prosesi avtomatik baş tutacaq.</value>
<data name="Ms" xml:space="preserve">
<value>Hörmətli</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Hörmətli</value>
</data>
<data name="November" xml:space="preserve">
<value>Noyabr</value>
</data>
@@ -2140,12 +2137,12 @@ Skan prosesi avtomatik baş tutacaq.</value>
<value>Bu təşkilat, sizi "parol sıfırlama"da avtomatik olaraq qeydiyyata alan müəssisə siyasətinə sahibdir. Qeydiyyat, təşkilat administratorlarına ana parolunuzu dəyişdirmə icazəsi verəcək.</value>
</data>
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
<value>Təşkilatınızın siyasətləri, anbarınızın vaxt bitişinə təsir edir. Anbar vaxt bitişi üçün icazə verilən maksimum vaxt {0} saat {1} dəqiqədir</value>
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
</data>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Anbar vaxt bitişi, təşkilatınız tərəfindən tənzimlənən məhdudiyyətləri aşır.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<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">
@@ -2421,14 +2418,6 @@ Skan prosesi avtomatik baş tutacaq.</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API müraciət tokeni</value>
</data>
@@ -2521,85 +2510,7 @@ Bu hesaba keçmək istəyirsiniz?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Bu tələb artıq yararsızdır</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Giriş tələbləri gözlənilir</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Bütün tələbləri rədd et</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Gözləyən bütün giriş tələblərini rədd etmək istədiyinizə əminsiniz?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Tələblər rədd edildi</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Gözləyən heç bir tələb yoxdur</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Skaneri istifadə etmək üçün kamera icazəsini fəallaşdırın</value>
</data>
<data name="Language" xml:space="preserve">
<value>Dil</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Dil, {0} olaraq dəyişdirildi. Dəyişiklikləri görmək üçün zəhmət olmasa tətbiqi yenidən başladın</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Dil dəyişikliyi, tətbiqin yenidən başladılmasını tələb edir</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>İlkin (Sistem)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Vacib</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Ana parolunuzu unutsanız bərpa edə bilməzsiniz! Ən az {0} simvol.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Zəif ana parol</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Zəif parol aşkarlandı. Hesabınızı qorumaq üçün güclü bir parol istifadə edin. Zəif bir parol istifadə etmək istədiyinizə əminsiniz?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Zəif</value>
</data>
<data name="Good" xml:space="preserve">
<value>Yaxşı</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Güclü</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Bu parol üçün bilinən məlumat pozuntularını yoxlayın</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>İfşa olunmuş ana parol</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Parol, məlumat pozuntusunda tapıldı. Hesabınızı qorumaq üçün unikal bir parol istifadə edin. İfşa olunmuş bir parol istifadə etmək istədiyinizə əminsiniz?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Zəif və ifşa olunmuş ana parol</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Zəif parol məlumat pozuntusunda aşkarlandı və tapıldı. Hesabınızı qorumaq üçün güclü və unikal bir parol istifadə edin. Bu parolu istifadə etmək istədiyinizə əminsiniz?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Təşkilat SSO identifikatoru tələb olundu.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Açarı, mövcud və ya yeni bir elementə əlavə edin</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>Anbarınızda {0} ilə uyğunlaşan heç bir element yoxdur</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Bir element axtarın və ya yenisini əlavə edin</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Axtarışa uyğun gələn heç bir element yoxdur</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Падказка да асноўнага пароля можа дапамагчы вам успомніць яго, калі вы яго забылі.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Асноўны пароль павінен змяшчаць прынамсі {0} сімвалаў.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Асноўны пароль павінен змяшчаць прынамсі 8 сімвалаў.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Мінімум лічбаў</value>
@@ -1102,9 +1102,6 @@
<data name="Ms" xml:space="preserve">
<value>Пані</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>Лістапад</value>
</data>
@@ -2145,7 +2142,7 @@
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Час чакання вашага сховішча перавышае дазволеныя абмежаванні, якія прызначыла ваша арганізацыя.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Адна або больш палітык арганізацыі не дазваляюць вам экспартаваць асабістае сховішча.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>Токен доступу да API</value>
</data>
@@ -2522,85 +2511,7 @@
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Гэты запыт больш не дзейнічае</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Чаканне запыту на ўваход</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Адхіліць усе запыты</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Вы сапраўды хочаце адхіліць усе запыты, якія чакаюць уваходу?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Запыты адхілены</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Няма запытаў, якія чакаюць уваходу</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Каб выкарыстоўваць сканер дайце дазвол на выкарыстанне камеры</value>
</data>
<data name="Language" xml:space="preserve">
<value>Мова</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Мова была зменена на {0}. Перазапусціце праграму, каб убачыць змены</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Для змены мовы неабходна перазапусціць праграму</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Прадвызначана (сістэмная)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Важна</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Ваш асноўны пароль нельга будзе аднавіць, калі вы забудзеце яго! Мінімальная колькасць сімвалаў: {0}.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Ненадзейны асноўны пароль</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Вызначаны ненадзейны пароль. Выкарыстоўвайце надзейны пароль для абароны вашага ўліковага запісу. Вы сапраўды хочаце выкарыстоўваць ненадзейны пароль?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Ненадзейны</value>
</data>
<data name="Good" xml:space="preserve">
<value>Добры</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Надзейны</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Праверыць у вядомых уцечках даных для гэтага пароля</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Скампраметаваны асноўны пароль</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Пароль знойдзены ва ўцечках даных. Выкарыстоўвайце ўнікальныя паролі для абароны свайго ўліковага запісу. Вы сапраўды хочаце выкарыстоўваць скампраметаваны пароль?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Ненадзейны і скампраметаваны асноўны пароль</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Вызначаны ненадзейны пароль, які знойдзены ва ўцечках даных. Выкарыстоўвайце надзейныя і ўнікальныя паролі для абароны свайго ўліковага запісу. Вы сапраўды хочаце выкарыстоўваць гэты пароль?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Неабходны ідэнтыфікатар SSO арганізацыі.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Дадаць ключ да існуючага або новага элемента</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>У вашым сховішчы адсутнічаюць элементы, якія адпавядаюць "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Пошук або дабаўленне новага элемента</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Адсутнічаюць элементы, якія адпавядаюць пошуку</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Подсказката помага да си спомните паролата, ако сте я забравили.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Главната парола трябва да е дълга поне {0} знака.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Главната парола трябва да е дълга поне 8 знака.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Минимален брой цифри</value>
@@ -1103,9 +1103,6 @@
<data name="Ms" xml:space="preserve">
<value>Г-ца</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>ноември</value>
</data>
@@ -2083,10 +2080,11 @@
<value>Това действие е защитено. За да продължите, въведете отново главната си парола, за да потвърдите самоличността си.</value>
</data>
<data name="CaptchaRequired" xml:space="preserve">
<value>Проверката е задължителна</value>
<value>Адресът за hCaptcha е задължителен</value>
</data>
<data name="CaptchaFailed" xml:space="preserve">
<value>Грешка. Опитайте отново.</value>
<value>
Грешка. Моля опитайте пак</value>
</data>
<data name="UpdatedMasterPassword" xml:space="preserve">
<value>Главната парола е променена</value>
@@ -2145,7 +2143,7 @@
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Времето за достъп до трезора Ви превишава ограничението, определено от организацията Ви.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Една или повече от настройките на организацията Ви не позволяват да изнасяте личния си трезор.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2293,10 +2291,10 @@
<value>Ръчно въвеждане на кода</value>
</data>
<data name="AddTotp" xml:space="preserve">
<value>Добавяне на TOTP</value>
<value>Копиране на кода за потвърждаване</value>
</data>
<data name="SetupTotp" xml:space="preserve">
<value>Настройка на TOTP</value>
<value>Копиране на кода за потвърждаване</value>
</data>
<data name="OnceTheKeyIsSuccessfullyEntered" xml:space="preserve">
<value>Once the key is successfully entered,
@@ -2422,14 +2420,6 @@ select Add TOTP to store the key safely</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>Идентификатор за достъп до API</value>
</data>
@@ -2522,85 +2512,7 @@ select Add TOTP to store the key safely</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Тази зявка вече не е приложима</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Чакащи заявки за вписване</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Отказване на всички заявки</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Наистина ли искате да откажете всички чакащи заявки за вписване?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Заявките са отказани</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Няма чакащи заявки</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Разрешете достъпа до камерата, за да използвате скенера</value>
</data>
<data name="Language" xml:space="preserve">
<value>Език</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Езикът беше променен на {0}. Рестартирайте приложението, за да влезе промяната в сила</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Промяната на езика изисква рестартиране на приложението</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>По подразбиране (от системата)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Важно</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Главната парола не може да бъде възстановена, ако я забравите! Дължината трябва да е поне {0} знака.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Слаба главна парола</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Разпозната е слаба парола. Използвайте силна парола, за да защитете данните си. Наистина ли искате да използвате слаба парола?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Слаба</value>
</data>
<data name="Good" xml:space="preserve">
<value>Добра</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Силна</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Проверяване в известните случаи на изтекли данни за тази парола</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Идентификаторът за еднократн идентификация на организация е задължителен.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Добавяне на ключа към съществуващ или нов елемент</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>В трезора липсват елементи, които отговарят на „{0}“</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Търсене на елемент или добавяне на нов</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Няма елементи, които отговарят на търсенето</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>যদি আপনি আপনার পাসওয়ার্ড ভুলে যান তাহলে একটি প্রধান পাসওয়ার্ডের ইঙ্গিতটি আপনাকে মনে করাতে সাহায্য করতে পারে।</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>প্রধান পাসওয়ার্ড কমপক্ষে ৮ অক্ষর দীর্ঘ হওয়া উচিত।</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>সর্বনিম্ন সংখ্যা</value>
@@ -1103,9 +1103,6 @@ Scanning will happen automatically.</value>
<data name="Ms" xml:space="preserve">
<value>Ms</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
</data>
@@ -2146,7 +2143,7 @@ Scanning will happen automatically.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Your vault timeout exceeds the restrictions set by your organization.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>One or more organization policies prevents your from exporting your individual vault.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2423,14 +2420,6 @@ select Add TOTP to store the key safely</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API access token</value>
</data>
@@ -2500,7 +2489,7 @@ Do you want to switch to this account?</value>
<value>Log in with master password</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Log in with device</value>
<value>Log In with another device</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Log in initiated</value>
@@ -2523,85 +2512,7 @@ Do you want to switch to this account?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>This request is no longer valid</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Pending login requests</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Enable camera permission to use the scanner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Weak Master Password</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Weak password identified. Use a strong password to protect your account. Are you sure you want to use a weak password?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Weak</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
</root>

View File

@@ -300,7 +300,7 @@
<comment>The title for the vault page.</comment>
</data>
<data name="Authenticator" xml:space="preserve">
<value>Aplikacija za autentifikaciju</value>
<value>Authenticator</value>
<comment>Authenticator TOTP feature</comment>
</data>
<data name="Name" xml:space="preserve">
@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Nagoveštaj glavne lozinke može Vam pomoći da zapamtite lozinku ako je zaboravite.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Glavna lozinka mora imati najmanje 8 znakova.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Minimalno brojeva</value>
@@ -775,10 +775,10 @@
<value>Omogućeno</value>
</data>
<data name="Off" xml:space="preserve">
<value>Isključeno</value>
<value>Off</value>
</data>
<data name="On" xml:space="preserve">
<value>Uključeno</value>
<value>On</value>
</data>
<data name="Status" xml:space="preserve">
<value>Status</value>
@@ -900,8 +900,8 @@
<value>Ne može se pročitati ključ autentifikatora.</value>
</data>
<data name="PointYourCameraAtTheQRCode" xml:space="preserve">
<value>Usmjerite kameru prema QR kodu.
Skeniranje će biti izvršeno automatski.</value>
<value>Point your camera at the QR Code.
Scanning will happen automatically.</value>
</data>
<data name="ScanQrTitle" xml:space="preserve">
<value>Skenirajte QR kod</value>
@@ -916,10 +916,10 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Iskopirajte TOTP</value>
</data>
<data name="CopyTotpAutomaticallyDescription" xml:space="preserve">
<value>Ako je za Vašu prijavu priložen autentifikacioni ključ, TOTP verifikacioni kod se automatski kopira u Vašu memoriju kad god automatski popunite prijavu.</value>
<value>If a login has an authenticator key, copy the TOTP verification code to your clip-board when you auto-fill the login.</value>
</data>
<data name="CopyTotpAutomatically" xml:space="preserve">
<value>Kopiraj TOTP (autentifikacijski kod) automatski</value>
<value>Copy TOTP automatically</value>
</data>
<data name="PremiumRequired" xml:space="preserve">
<value>Za korišćenje ove funkcije potrebno je premium članstvo.</value>
@@ -1103,9 +1103,6 @@ Skeniranje će biti izvršeno automatski.</value>
<data name="Ms" xml:space="preserve">
<value>Gđica</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Rodno neutralan</value>
</data>
<data name="November" xml:space="preserve">
<value>Novembar</value>
</data>
@@ -1140,10 +1137,10 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Rok upotrebe</value>
</data>
<data name="ShowWebsiteIcons" xml:space="preserve">
<value>Pokaži ikone web stranica</value>
<value>Show website icons</value>
</data>
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
<value>Prikaži prepoznatljivu sliku pored svake prijave.</value>
<value>Show a recognizable image next to each login.</value>
</data>
<data name="IconsUrl" xml:space="preserve">
<value>URL adresa servera ikona</value>
@@ -1415,7 +1412,7 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Nema kolekcija za prikazati.</value>
</data>
<data name="MovedItemToOrg" xml:space="preserve">
<value>{0} premješteno u {1}.</value>
<value>{0} moved to {1}.</value>
<comment>ex: Item moved to Organization.</comment>
</data>
<data name="ItemShared" xml:space="preserve">
@@ -1556,7 +1553,7 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Zadana tamna tema</value>
</data>
<data name="DefaultDarkThemeDescription" xml:space="preserve">
<value>Odaberi korištenje tamne teme kada je uređaj već zadano koristi.</value>
<value>Choose the dark theme to use when using Default (System) theme while your device's dark mode is in use.</value>
</data>
<data name="CopyNotes" xml:space="preserve">
<value>Kopiraj bilješke</value>
@@ -1583,16 +1580,16 @@ Skeniranje će biti izvršeno automatski.</value>
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
</data>
<data name="AutofillBlockedUris" xml:space="preserve">
<value>Auto-popunjavanje blokiranih URI-ja</value>
<value>Auto-fill blocked URIs</value>
</data>
<data name="AutofillBlockedUrisDescription" xml:space="preserve">
<value>Auto-popunjavanje neće biti ponuđeno za blokirane URI-je. Odvoji višestruke URI-je zarezom. Npr. „https://twitter.com, androidapp://com.twitter.android.</value>
<value>Auto-fill will not be offered for blocked URIs. Separate multiple URIs with a comma. For example: "https://twitter.com, androidapp://com.twitter.android".</value>
</data>
<data name="AskToAddLogin" xml:space="preserve">
<value>Upitaj za dodavanje prijave</value>
<value>Ask to add login</value>
</data>
<data name="AskToAddLoginDescription" xml:space="preserve">
<value>Upitaj za dodavanje, ako se stavka već ne nalazi u trezoru.</value>
<value>Ask to add an item if one isn't found in your vault.</value>
</data>
<data name="OnRestart" xml:space="preserve">
<value>Kod ponovnog pokretanja</value>
@@ -1886,7 +1883,7 @@ Skeniranje će biti izvršeno automatski.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="Text" xml:space="preserve">
<value>Tekst</value>
<value>Text</value>
</data>
<data name="TypeText" xml:space="preserve">
<value>Tekst</value>
@@ -1905,16 +1902,16 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Datoteka koju želiš poslati</value>
</data>
<data name="FileTypeIsSelected" xml:space="preserve">
<value>Odabrana je vrsta datoteke.</value>
<value>File type is selected.</value>
</data>
<data name="FileTypeIsNotSelected" xml:space="preserve">
<value>Vrsta datoteke nije odabrana, dodirnite za odabir.</value>
<value>File type is not selected, tap to select.</value>
</data>
<data name="TextTypeIsSelected" xml:space="preserve">
<value>Vrsta teksta je odabrana.</value>
<value>Text type is selected.</value>
</data>
<data name="TextTypeIsNotSelected" xml:space="preserve">
<value>Vrsta teksta nije odabrana, dodirnite za odabir.</value>
<value>Text type is not selected, tap to select.</value>
</data>
<data name="DeletionDate" xml:space="preserve">
<value>Datum brisanja</value>
@@ -2145,7 +2142,7 @@ Skeniranje će biti izvršeno automatski.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Vrijeme isteka premašuje ograničenje koju je postavila tvoja organizacija.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Jedno ili više pravila organizacija onemogućuje izvoz osobnog trezora. </value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2221,88 +2218,89 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Unesi verifikacijski kod koji je poslan na tvoj E-Mail</value>
</data>
<data name="SubmitCrashLogs" xml:space="preserve">
<value>Pošaljite evidenciju o pogreškama u radu aplikacije</value>
<value>Submit crash logs</value>
</data>
<data name="SubmitCrashLogsDescription" xml:space="preserve">
<value>Pomozi Bitwardenu poboljšati stabilnost aplikacije šaljući evidenciju o pogreškama u radu aplikacije.</value>
<value>Help Bitwarden improve app stability by submitting crash reports.</value>
</data>
<data name="OptionsExpanded" xml:space="preserve">
<value>Opcije su proširene, dodirni za smanjivanje.</value>
<value>Options are expanded, tap to collapse.</value>
</data>
<data name="OptionsCollapsed" xml:space="preserve">
<value>Opcije su smanjene, dodirni za proširenje.</value>
<value>Options are collapsed, tap to expand.</value>
</data>
<data name="UppercaseAtoZ" xml:space="preserve">
<value>Velika slova (A-Z)</value>
<value>Uppercase (A to Z)</value>
</data>
<data name="LowercaseAtoZ" xml:space="preserve">
<value>Mala slova (a - z)</value>
<value>Lowercase (A to Z)</value>
</data>
<data name="NumbersZeroToNine" xml:space="preserve">
<value>Brojevi (0-9)</value>
<value>Numbers (0 to 9)</value>
</data>
<data name="SpecialCharacters" xml:space="preserve">
<value>Posebni znakovi (!@#$%^&amp;*)</value>
<value>Special characters (!@#$%^&amp;*)</value>
</data>
<data name="TapToGoBack" xml:space="preserve">
<value>Dodirnite za povratak</value>
<value>Tap to go back</value>
</data>
<data name="PasswordIsVisibleTapToHide" xml:space="preserve">
<value>Lozinka je vidljiva, dodirnite za skrivanje.</value>
<value>Password is visible, tap to hide.</value>
</data>
<data name="PasswordIsNotVisibleTapToShow" xml:space="preserve">
<value>Lozinka nije vidljiva, dodirnite za prikaz.</value>
<value>Password is not visible, tap to show.</value>
</data>
<data name="FilterByVault" xml:space="preserve">
<value>Filtrirajte stavke prema trezoru</value>
<value>Filter items by vault</value>
</data>
<data name="AllVaults" xml:space="preserve">
<value>Svi trezori</value>
<value>All vaults</value>
</data>
<data name="Vaults" xml:space="preserve">
<value>Trezori</value>
<value>Vaults</value>
</data>
<data name="VaultFilterDescription" xml:space="preserve">
<value>Trezor: {0}</value>
<value>Vault: {0}</value>
</data>
<data name="All" xml:space="preserve">
<value>Sve</value>
<value>All</value>
</data>
<data name="Totp" xml:space="preserve">
<value>TOTP</value>
</data>
<data name="VerificationCodes" xml:space="preserve">
<value>Autentifikacijski kodovi</value>
<value>Verification codes</value>
</data>
<data name="PremiumSubscriptionRequired" xml:space="preserve">
<value>Potrebna Premium pretplata</value>
<value>Premium subscription required</value>
</data>
<data name="CannotAddAuthenticatorKey" xml:space="preserve">
<value>Nije moguće dodati autentifikacijski ključ? </value>
<value>Cannot add authenticator key? </value>
</data>
<data name="ScanQRCode" xml:space="preserve">
<value>Skenirajte QR kod</value>
<value>Scan QR Code</value>
</data>
<data name="CannotScanQRCode" xml:space="preserve">
<value>Nije moguće skenirati QR kod? </value>
<value>Cannot scan QR Code? </value>
</data>
<data name="AuthenticatorKeyScanner" xml:space="preserve">
<value>Autentifikacijski ključ</value>
<value>Authenticator key</value>
</data>
<data name="EnterKeyManually" xml:space="preserve">
<value>Ručno unesi ključ</value>
<value>Enter key manually</value>
</data>
<data name="AddTotp" xml:space="preserve">
<value>Dodaj TOTP</value>
<value>Add TOTP</value>
</data>
<data name="SetupTotp" xml:space="preserve">
<value>Podesi TOTP</value>
<value>Set up TOTP</value>
</data>
<data name="OnceTheKeyIsSuccessfullyEntered" xml:space="preserve">
<value>Jednom kada je ključ uspješno unesen, odaberi „Dodaj TOTP” za sigurno spremanje ključa</value>
<value>Once the key is successfully entered,
select Add TOTP to store the key safely</value>
</data>
<data name="NeverLockWarning" xml:space="preserve">
<value>Postavljanje zaključavanja na „Nikad” čini tvoj trezor dostupnim svima koji imaju pristupom tvom uređaju. Ako koristiš ovu mogućnost, pobrini se da je uređaj adekvatno zaštićen.</value>
<value>Setting your lock options to “Never” keeps your vault available to anyone with access to your device. If you use this option, you should ensure that you keep your device properly protected.</value>
</data>
<data name="EnvironmentPageUrlsError" xml:space="preserve">
<value>One or more of the URLs entered are invalid. Please revise it and try to save again.</value>
@@ -2421,14 +2419,6 @@ Skeniranje će biti izvršeno automatski.</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API access token</value>
</data>
@@ -2460,146 +2450,68 @@ Skeniranje će biti izvršeno automatski.</value>
<value>Random</value>
</data>
<data name="ConnectToWatch" xml:space="preserve">
<value>Poveži se na Apple Watch</value>
<value>Connect to Watch</value>
</data>
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
<value>Odobrenje servisa pristupačnosti</value>
<value>Accessibility Service Disclosure</value>
</data>
<data name="AccessibilityDisclosureText" xml:space="preserve">
<value>Bitwarden koristi servis pristupačnosti za pretragu polja za prijavu u aplikacijama i na web stranicama, te potom određuje ID polja za unos korisničkog imena i lozinke kada su pronađeni odgovarajući podaci. Ne spremamo podatke koje servis daje, niti pokušavamo upravljati bilo kojim elementima na zaslonu osim tekstualnog unosa podataka.</value>
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username &amp; password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
</data>
<data name="Accept" xml:space="preserve">
<value>Prihvati</value>
<value>Accept</value>
</data>
<data name="Decline" xml:space="preserve">
<value>Odbij</value>
<value>Decline</value>
</data>
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
<value>Zahtjev za prijavu je već istekao.</value>
<value>Login request has already expired.</value>
</data>
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
<value>Pokušaj prijave od:
<value>Login attempt from:
{0}
Želiš li se prebaciti na ovaj račun?</value>
Do you want to switch to this account?</value>
</data>
<data name="NewAroundHere" xml:space="preserve">
<value>Novi ovdje?</value>
<value>New around here?</value>
</data>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Dobijte podsjetnik glavne lozinke</value>
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Prijava kao {0}</value>
<value>Logging in as {0}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Nisi ti?</value>
<value>Not you?</value>
</data>
<data name="LogInWithMasterPassword" xml:space="preserve">
<value>Prijava sa glavnom lozinkom</value>
<value>Log in with master password</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Prijava sa drugim uređajem</value>
<value>Log In with another device</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Prijava je pokrenuta</value>
<value>Log in initiated</value>
</data>
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
<value>Obavijest je poslana na tvoj uređaj.</value>
<value>A notification has been sent to your device.</value>
</data>
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
<value>Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem.</value>
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
</data>
<data name="ResendNotification" xml:space="preserve">
<value>Ponovno pošalji obavijest</value>
<value>Resend notification</value>
</data>
<data name="NeedAnotherOption" xml:space="preserve">
<value>Trebaš drugu opciju?</value>
<value>Need another option?</value>
</data>
<data name="ViewAllLoginOptions" xml:space="preserve">
<value>Pogledaj sve mogućnosti prijave</value>
<value>View all log in options</value>
</data>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Ovaj zahtjev više ne važi</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Zahtjevi za prijavu koji su na čekanju</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Odbij sve zahtjeve</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Jeste li sigurni da želite odbiti sve zahtjeve koji su na čekanju?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Zahtjevi odbijeni</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Nema zahtjeva na čekanju</value>
<value>This request is no longer valid</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Omogućite dozvolu za korištenje kamere da bi koristili skener</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Važno</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Tvoja glavna lozinka ne može biti oporavljena ukoliko je zaboraviš! {0} znakova najmanje.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Slaba glavna lozinka</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Slaba lozinka prepoznata. Koristite jaku lozinku za zaštitu Vašeg računa. Da li ste sigurni da želite koristiti slabu lozinku?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Slabo</value>
</data>
<data name="Good" xml:space="preserve">
<value>Dobro</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Jako</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Provjeri da li postoji kompromitovana baza podataka povezana sa ovom lozinkom</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Glavna lozinka je kompromitovana</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Lozinka je pronađena u bazama podataka koje su provaljene. Koristite jedinstvenu lozinku da zaštitite vaš račun. Da li ste sigurni da želite koritstiti već kompromitovanu lozinku?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Slaba i kompromitovana glavna lozinka</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Slaba lozinka prepoznata i pronađena u kompromitovanim bazama podataka. Koristite jaku lozinku za zaštitu Vašeg računa. Da li ste sigurni da želite koristiti ovu lozinku?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
<value>Enable camera permission to use the scanner</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Una pista de contrasenya mestra pot ajudar-vos a recordar-la si la oblideu.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>La contrasenya mestra ha de contenir almenys {0} caràcters.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>La contrasenya ha de contenir almenys 8 caràcters.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Mínim de caràcters numèrics</value>
@@ -1103,9 +1103,6 @@ L'escaneig es farà automàticament.</value>
<data name="Ms" xml:space="preserve">
<value>Srta.</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>Novembre</value>
</data>
@@ -2140,12 +2137,12 @@ L'escaneig es farà automàticament.</value>
<value>Aquesta organització té una política empresarial que us inscriurà automàticament al restabliment de la contrasenya. La inscripció permetrà als administradors de lorganització canviar la vostra contrasenya mestra.</value>
</data>
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
<value>Les polítiques de l'organització afecten el temps d'espera de la caixa forta. El temps d'espera màxim permès de la caixa forta és de {0} hores i {1} minuts</value>
<value>Les polítiques de la vostra organització afecten el temps d'espera de la vostra caixa forta. El temps d'espera màxim permès de la caixa forta és de {0} hores i {1} minuts</value>
</data>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>El temps d'espera de la caixa forta supera les restriccions establertes per la vostra organització.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Una o més polítiques d'organització us impedeixen exportar la vostra caixa forta.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@ seleccioneu Afegeix TOTP per emmagatzemar la clau de manera segura</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>Token d'accés a l'API</value>
</data>
@@ -2499,7 +2488,7 @@ Voleu canviar a aquest compte?</value>
<value>Inicia sessió amb la contrasenya mestra</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Inici de sessió amb un altre dispositiu</value>
<value>Inicia sessió amb un altre dispositiu</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>S'ha iniciat la sessió</value>
@@ -2522,85 +2511,7 @@ Voleu canviar a aquest compte?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Aquesta sol·licitud ja no és vàlida</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Sol·licituds d'inici de sessió pendents</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Rebutja totes les sol·licituds</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Esteu segur que voleu rebutjar totes les sol·licituds d'inici de sessió pendents?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Sol·licituds rebutjades</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Cap sol·licitud pendent</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Habilita el permís de la càmera per utilitzar l'escàner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Idioma</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>L'idioma s'ha canviat a {0}. Reinicieu l'aplicació per veure el canvi</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>El canvi d'idioma requereix un reinici de l'aplicació</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Per defecte (Sistema)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>La vostra contrasenya mestra no es pot recuperar si l'oblideu! {0} caràcters com a mínim.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Contrasenya mestra poc segura</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>S'ha identificat una contrasenya feble. Utilitzeu una contrasenya segura per protegir el vostre compte. Esteu segur que voleu utilitzar una contrasenya feble?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Poc segura</value>
</data>
<data name="Good" xml:space="preserve">
<value>Bona</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Forta</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Comproveu les infraccions de dades conegudes per a aquesta contrasenya</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Contrasenya mestra exposada</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>S'ha trobat la contrasenya en una filtració de dades. Utilitzeu una contrasenya única per protegir el vostre compte. Esteu segur que voleu utilitzar una contrasenya exposada?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Contrasenya mestra exposada i poc segura</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Contrasenya feble identificada i trobada en una filtració de dades. Utilitzeu una contrasenya única i segura per protegir el vostre compte. Esteu segur que voleu utilitzar aquesta contrasenya?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Lidentificador SSO de lorganització és obligatori.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Afig la clau a un element existent o nou</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>No hi ha cap element a la caixa forta que coincidisca amb "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Cerca un element o n'afig un nou</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>No hi ha elements que coincidisquen amb la cerca</value>
</data>
</root>

View File

@@ -285,7 +285,7 @@
<value>Účet byl již přidán</value>
</data>
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
<value>Chcete se na něj nyní přepnout?</value>
<value>Would you like to switch to it now?</value>
</data>
<data name="MasterPassword" xml:space="preserve">
<value>Hlavní heslo</value>
@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Nápověda k hlavnímu heslu vám pomůže zapamatovat si heslo, pokud ho zapomenete.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Hlavní heslo musí obsahovat alespoň 8 znaků.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Minimální počet číslic</value>
@@ -1103,9 +1103,6 @@ Načtení proběhne automaticky.</value>
<data name="Ms" xml:space="preserve">
<value>Slečna</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>Listopad</value>
</data>
@@ -2145,7 +2142,7 @@ Načtení proběhne automaticky.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Your vault timeout exceeds the restrictions set by your organization.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Jedna nebo více zásad organizace vám brání v exportu vašeho osobního trezoru.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@ select Add TOTP to store the key safely</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>Přístupový token API</value>
</data>
@@ -2522,85 +2511,7 @@ Chcete se přepnout na tento účet?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Tento požadavek již není platný</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Pending login requests</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Enable camera permission to use the scanner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Weak Master Password</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Weak password identified. Use a strong password to protect your account. Are you sure you want to use a weak password?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Weak</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Et hovedeadgangskodentip kan hjælpe dig med at huske din adgangskode, hvis du glemmer den.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Hovedadgangskoden skal udgøre mindst {0} tegn.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Hovedadgangskode skal være på minimum 8 tegn.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Mindste antal cifre</value>
@@ -1103,9 +1103,6 @@ Skanning vil ske automatisk.</value>
<data name="Ms" xml:space="preserve">
<value>Frk</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Neutral</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
</data>
@@ -2145,7 +2142,7 @@ Skanning vil ske automatisk.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Timeout for din boks overskrider de begrænsninger, der er angivet af din organisation.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>En eller flere organisationspolitikker forhindrer eksport af din personlige boks.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@ vælg Tilføj TOTP for at gemme nøglen sikkert</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API-adgangstoken</value>
</data>
@@ -2499,7 +2488,7 @@ Vil du skifte til denne konto?</value>
<value>Log ind med hovedadgangskoden</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Log ind med enhed</value>
<value>Log ind med en anden enhed</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Indlogning påbegyndt</value>
@@ -2522,85 +2511,7 @@ Vil du skifte til denne konto?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Anmodningen er ikke længere gyldig</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Afventende login-anmodninger</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Afvis alle anmodninger</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Sikker på, at alle afventende login-anmodninger skal afvises?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Anmodninger afvist</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Ingen afventende anmodninger</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Tildel kameratilladelse for brug af skanneren</value>
</data>
<data name="Language" xml:space="preserve">
<value>Sprog</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Sproget er blevet ændret til {0}. Genstart appen for at se ændringen</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Skift af sprog kræver app-genstart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Standard (system)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Vigtigt</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Hovedadgangskoden kan ikke gendannes, hvis du glemmer den! {0} tegn minimum.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Svag hovedadgangskode</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Svag adgangskode identificeret. Brug en stærk adgangskode til at beskytte din konto. Sikker på, at du vil bruge en svag adgangskode?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Svag</value>
</data>
<data name="Good" xml:space="preserve">
<value>God</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Stærk</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Tjek kendte datalæk for denne adgangskode</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Kompromitteret hovedadgangskode</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Adgangskode fundet i datalæk. Brug en unik adgangskode til at beskytte din konto. Sikker på, at du vil bruge en kompromitteret adgangskode?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Svag eller kompromitteret hovedadgangskode</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Svag adgangskode identificeret og fundet i datalæk. Brug en unik adgangskode til at beskytte din konto. Sikker på, at du vil bruge denne adgangskode?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organisations-SSO obligatorisk.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Føj nøglen til et eksisterende eller nyt emne</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>Der er ingen emner i boksen matchende "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Søg efter, eller tilføj et nyt, emne</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Ingen emner matcher søgningen</value>
</data>
</root>

View File

@@ -156,7 +156,7 @@
<comment>The button text that allows a user to copy the login's password to their clipboard.</comment>
</data>
<data name="CopyUsername" xml:space="preserve">
<value>Benutzername kopieren</value>
<value>Nutzernamen kopieren</value>
<comment>The button text that allows a user to copy the login's username to their clipboard.</comment>
</data>
<data name="Credits" xml:space="preserve">
@@ -229,10 +229,10 @@
<value>Ordner</value>
</data>
<data name="FolderUpdated" xml:space="preserve">
<value>Ordner gespeichert</value>
<value>Ordner aktualisiert</value>
</data>
<data name="GoToWebsite" xml:space="preserve">
<value>Zur Website</value>
<value>Webseite besuchen</value>
<comment>The button text that allows user to launch the website to their web browser.</comment>
</data>
<data name="HelpAndFeedback" xml:space="preserve">
@@ -285,10 +285,10 @@
<value>Konto bereits hinzugefügt</value>
</data>
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
<value>Möchtest du jetzt dazu wechseln?</value>
<value>Möchtest du jetzt darauf umschalten?</value>
</data>
<data name="MasterPassword" xml:space="preserve">
<value>Master-Passwort</value>
<value>Masterpasswort</value>
<comment>Label for a master password.</comment>
</data>
<data name="More" xml:space="preserve">
@@ -375,14 +375,14 @@
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
</data>
<data name="ValueHasBeenCopied" xml:space="preserve">
<value>{0} kopiert</value>
<value>{0} wurde kopiert</value>
<comment>Confirmation message after successfully copying a value to the clipboard.</comment>
</data>
<data name="VerifyFingerprint" xml:space="preserve">
<value>Fingerabdruck verifizieren</value>
<value>Fingerabdruck überprüfen</value>
</data>
<data name="VerifyMasterPassword" xml:space="preserve">
<value>Master-Passwort verifizieren</value>
<value>Masterpasswort überprüfen</value>
</data>
<data name="VerifyPIN" xml:space="preserve">
<value>PIN überprüfen</value>
@@ -394,7 +394,7 @@
<value>Ansicht</value>
</data>
<data name="VisitOurWebsite" xml:space="preserve">
<value>Besuche unsere Website</value>
<value>Besuchen Sie unsere Website</value>
</data>
<data name="VisitOurWebsiteDescription" xml:space="preserve">
<value>Besuche unsere Webseite um Hilfe zu erhalten, Neuigkeiten zu erfahren, Kontakt aufzunehmen und mehr über die Verwendung von Bitwarden zu lernen.</value>
@@ -422,7 +422,7 @@
<value>Verwende den Bitwarden Dienst in den Bedienungshilfen, um deine Zugangsdaten in Apps und im Web automatisch ausfüllen zu lassen.</value>
</data>
<data name="AutofillService" xml:space="preserve">
<value>Auto-Ausfüllen-Dienst</value>
<value>Auto-Ausfüllen Funktion</value>
</data>
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
<value>Mehrdeutige Zeichen vermeiden</value>
@@ -431,7 +431,7 @@
<value>Bitwarden App-Erweiterung</value>
</data>
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
<value>Die einfachste Möglichkeit, neue Zugangsdaten zu deinem Tresor hinzuzufügen, ist die Bitwarden App-Erweiterung. Erfahre mehr über die Benutzung der Bitwarden App-Erweiterung, indem du zu den "Einstellungen" wechselst.</value>
<value>Die einfachste Möglichkeit, neue Anmeldedaten zu Ihrem Tresor hinzuzufügen, ist die Bitwarden App Erweiterung. Erfahren Sie mehr über die Bitwarden App Erweiterung, indem Sie zu dem "Einstellungen"-Bildschirm navigieren.</value>
</data>
<data name="BitwardenAppExtensionDescription" xml:space="preserve">
<value>Nutze Bitwarden in Safari und anderen Apps, um Zugangsdaten automatisch einzufügen.</value>
@@ -443,7 +443,7 @@
<value>Verwende den Bitwarden Dienst in den Bedienungshilfen um deine Zugangsdaten automatisch einzufügen.</value>
</data>
<data name="ChangeEmail" xml:space="preserve">
<value>E-Mail-Adresse ändern</value>
<value>E-Mail Adresse ändern</value>
</data>
<data name="ChangeEmailConfirmation" xml:space="preserve">
<value>Du kannst deine E-Mail Adresse im Bitwarden.com Web-Tresor ändern. Möchtest du die Seite jetzt öffnen?</value>
@@ -471,13 +471,13 @@
<value>Eintrag bearbeiten</value>
</data>
<data name="EnableAutomaticSyncing" xml:space="preserve">
<value>Automatische Synchronisierung zulassen</value>
<value>Automatische Synchronisierung aktivieren</value>
</data>
<data name="EnterEmailForHint" xml:space="preserve">
<value>Gebe die E-Mail Adresse deines Kontos ein, um den Hinweis für dein Master-Passwort zu erhalten.</value>
</data>
<data name="ExntesionReenable" xml:space="preserve">
<value>App-Erweiterung reaktivieren</value>
<value>App-Erweiterung wieder aktivieren</value>
</data>
<data name="ExtensionAlmostDone" xml:space="preserve">
<value>Fast geschafft!</value>
@@ -514,7 +514,7 @@
<value>Fingerabdruck</value>
</data>
<data name="GeneratePassword" xml:space="preserve">
<value>Passwort generieren</value>
<value>Passwort erstellen</value>
</data>
<data name="GetPasswordHint" xml:space="preserve">
<value>Hinweis zum Masterpasswort zusenden</value>
@@ -566,7 +566,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="LoginOrCreateNewAccount" xml:space="preserve">
<value>Melde dich an oder erstelle ein neues Konto, um auf deinen Tresor zuzugreifen.</value>
<value>Melde dich an oder erstelle einen neuen Account, um auf Deinen Tresor zuzugreifen.</value>
</data>
<data name="Manage" xml:space="preserve">
<value>Verwalten</value>
@@ -583,11 +583,11 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Ein Hinweis auf dein Master-Passwort kann dir helfen, dich an das Passwort zu erinnern, solltest du es vergessen.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Das Master-Passwort muss mindestens {0} Zeichen lang sein.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Das Masterpasswort muss mindestens 8 Zeichen lang sein.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Mindestanzahl Ziffern</value>
<value>Mindestanzahl Zahlen</value>
<comment>Minimum numeric characters for password generator settings</comment>
</data>
<data name="MinSpecial" xml:space="preserve">
@@ -635,10 +635,10 @@
<value>Passwort generiert</value>
</data>
<data name="PasswordGenerator" xml:space="preserve">
<value>Passwort-Generator</value>
<value>Passwortgenerator</value>
</data>
<data name="PasswordHint" xml:space="preserve">
<value>Passwort-Hinweis</value>
<value>Passworthinweis</value>
</data>
<data name="PasswordHintAlert" xml:space="preserve">
<value>Wir haben Ihnen eine E-Mail mit Ihrem Masterpassworthinweis gesendet.</value>
@@ -647,7 +647,7 @@
<value>Bist du sicher, dass du das aktuelle Passwort überschreiben möchtest?</value>
</data>
<data name="PushNotificationAlert" xml:space="preserve">
<value>Bitwarden hält deinen Tresor durch Push-Benachrichtigungen automatisch synchronisiert. Für die bestmögliche Benutzererfahrung tippe im folgenden Dialogfenster auf "Erlauben", um Push-Benachrichtigungen zu erlauben.</value>
<value>Bitwarden aktualisiert deinen Tresor mit Push-Benachrichtigungen. Für die bestmögliche Benutzererfahrung tippe im folgenden Dialogfenster auf "Ok", um Push-Benachrichtigungen zu aktivieren.</value>
<comment>Push notifications for apple products</comment>
</data>
<data name="RateTheApp" xml:space="preserve">
@@ -678,10 +678,10 @@
<value>Gebe deine 4-stellige PIN ein, um die App zu entsperren.</value>
</data>
<data name="ItemInformation" xml:space="preserve">
<value>Eintragsinformationen</value>
<value>Eintrags-Information</value>
</data>
<data name="ItemUpdated" xml:space="preserve">
<value>Eintrag gespeichert</value>
<value>Eintrag aktualisiert</value>
</data>
<data name="Submitting" xml:space="preserve">
<value>Wird übermittelt...</value>
@@ -708,7 +708,7 @@
<value>Zwei-Faktor-Authentifizierung</value>
</data>
<data name="TwoStepLoginConfirmation" xml:space="preserve">
<value>Mit der Zwei-Faktor-Authentifizierung wird dein Konto zusätzlich abgesichert, da jede Anmeldung mit einem anderen Gerät wie einem Sicherheitsschlüssel, einer Authentifizierungs-App, einer SMS, einem Anruf oder einer E-Mail verifiziert werden muss. Die Zwei-Faktor-Authentifizierung kann im bitwarden.com Web-Tresor aktiviert werden. Möchtest du die Webseite jetzt öffnen?</value>
<value>Mit der Zwei-Faktor-Authentifizierung wird dein Account zusätzlich abgesichert, da jede Anmeldung durch einen Sicherheitscode, eine Authentifizierungs-App, SMS, einen Anruf oder eine E-Mail verifiziert werden muss. Die Zwei-Faktor-Authentifizierung kann im Web-Tresor unter bitwarden.com aktiviert werden. Möchtest du die Seite jetzt öffnen?</value>
</data>
<data name="UnlockWith" xml:space="preserve">
<value>Mit {0} entsperren</value>
@@ -721,7 +721,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="VerificationCode" xml:space="preserve">
<value>Verifizierungscode</value>
<value>Verifizierungscode </value>
</data>
<data name="ViewItem" xml:space="preserve">
<value>Eintrag anzeigen</value>
@@ -815,7 +815,7 @@
<comment>Message shown when trying to launch an app that does not exist on the user's device.</comment>
</data>
<data name="AuthenticatorAppTitle" xml:space="preserve">
<value>Authenticator App</value>
<value>Authentifizierungs-App</value>
<comment>For 2FA</comment>
</data>
<data name="EnterVerificationCodeApp" xml:space="preserve">
@@ -827,11 +827,11 @@
<comment>For 2FA</comment>
</data>
<data name="LoginUnavailable" xml:space="preserve">
<value>Anmeldung nicht verfügbar</value>
<value>Zugangsdaten nicht verfügbar</value>
<comment>For 2FA whenever there are no available providers on this device.</comment>
</data>
<data name="NoTwoStepAvailable" xml:space="preserve">
<value>Für dieses Konto ist eine aktive Zwei-Faktor-Authentifizierung eingerichtet, allerdings wird keiner der konfigurierten Zwei-Faktor-Anbieter von diesem Gerät unterstützt. Bitte nutze ein unterstütztes Gerät und / oder füge zusätzliche Anbieter hinzu, die von mehr Geräten unterstützt werden (wie eine Authentifizierungs-App).</value>
<value>Dieses Konto hat eine aktive Zwei-Faktor-Authentifizierung, allerdings wird keiner der konfigurierten Zwei-Faktor-Anbieter von diesem Gerät unterstützt. Bitte nutzen Sie ein unterstütztes Gerät und / oder fügen Sie zusätzliche Anbieter hinzu, die von mehr Geräten unterstützt werden (wie eine Authentifizierungs-App).</value>
</data>
<data name="RecoveryCodeTitle" xml:space="preserve">
<value>Wiederherstellungscode</value>
@@ -846,7 +846,7 @@
<comment>For 2FA</comment>
</data>
<data name="TwoStepLoginOptions" xml:space="preserve">
<value>Optionen für Zwei-Faktor-Authentifizierung</value>
<value>Optionen für Zwei-Faktor Authentifizierung</value>
</data>
<data name="UseAnotherTwoStepMethod" xml:space="preserve">
<value>Verwende eine andere Zwei-Faktor Authentifizierungsmethode</value>
@@ -856,18 +856,18 @@
<comment>For 2FA</comment>
</data>
<data name="VerificationEmailSent" xml:space="preserve">
<value>Verifizierung-E-Mail versendet</value>
<value>Bestätigungsmail wurde gesendet</value>
<comment>For 2FA</comment>
</data>
<data name="YubiKeyInstruction" xml:space="preserve">
<value>Halte deinen YubiKey NEO an die Rückseite des Geräts, um fortzufahren.</value>
</data>
<data name="YubiKeyTitle" xml:space="preserve">
<value>YubiKey Sicherheitsschlüssel</value>
<value>YubiKey NEO Sicherheitsschlüssel</value>
<comment>"YubiKey" is the product name and should not be translated.</comment>
</data>
<data name="AddNewAttachment" xml:space="preserve">
<value>Neuen Anhang hinzufügen</value>
<value>Anhang hinzufügen</value>
</data>
<data name="Attachments" xml:space="preserve">
<value>Anhänge</value>
@@ -916,7 +916,7 @@ Das Scannen erfolgt automatisch.</value>
<value>TOTP kopieren</value>
</data>
<data name="CopyTotpAutomaticallyDescription" xml:space="preserve">
<value>Ist ein Authentifizierungsschlüssel mit deinen Zugangsdaten verknüpft, wird der TOTP Verifizierungscode in die Zwischenablage kopiert, wenn du die Zugangsdaten automatisch einfügen lässt.</value>
<value>Falls Zugangsdaten einen Authentifizierungsschlüssel haben, den TOTP-Verifizierungsscode nach dem automatischen Ausfüllen in die Zwischenablage kopieren.</value>
</data>
<data name="CopyTotpAutomatically" xml:space="preserve">
<value>TOTP automatisch kopieren</value>
@@ -958,7 +958,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Mehr erfahren</value>
</data>
<data name="ApiUrl" xml:space="preserve">
<value>API Server-URL</value>
<value>API Server URL</value>
</data>
<data name="CustomEnvironment" xml:space="preserve">
<value>Benutzerdefinierte Umgebung</value>
@@ -974,11 +974,11 @@ Das Scannen erfolgt automatisch.</value>
<comment>Validation error when something is not formatted correctly, such as a URL or email address.</comment>
</data>
<data name="IdentityUrl" xml:space="preserve">
<value>URL des Identitätsservers</value>
<value>Identitätsserver-URL</value>
<comment>"Identity" refers to an identity server. See more context here https://en.wikipedia.org/wiki/Identity_management</comment>
</data>
<data name="SelfHostedEnvironment" xml:space="preserve">
<value>Selbst gehostete Umgebung</value>
<value>Selbstgehostete Umgebung</value>
</data>
<data name="SelfHostedEnvironmentFooter" xml:space="preserve">
<value>Bitte gebe die Basis-URL deiner selbst gehosteten Bitwarden-Installation an.</value>
@@ -987,7 +987,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Server URL</value>
</data>
<data name="WebVaultUrl" xml:space="preserve">
<value>URL des Web-Tresor-Servers</value>
<value>Web-Tresor Server URL</value>
</data>
<data name="BitwardenAutofillServiceNotificationContentOld" xml:space="preserve">
<value>Tippe auf diese Benachrichtigung um Einträge aus deinem Tresor anzusehen.</value>
@@ -1103,9 +1103,6 @@ Das Scannen erfolgt automatisch.</value>
<data name="Ms" xml:space="preserve">
<value>Frau</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Divers</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
</data>
@@ -1140,13 +1137,13 @@ Das Scannen erfolgt automatisch.</value>
<value>Gültig bis</value>
</data>
<data name="ShowWebsiteIcons" xml:space="preserve">
<value>Website-Symbole anzeigen</value>
<value>Zeige Webseiten-Icons</value>
</data>
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
<value>Ein wiedererkennbares Bild neben jeden Zugangsdaten anzeigen.</value>
</data>
<data name="IconsUrl" xml:space="preserve">
<value>URL des Icons-Servers</value>
<value>Icons Server URL</value>
</data>
<data name="AutofillWithBitwarden" xml:space="preserve">
<value>Mit Bitwarden automatisch ausfüllen</value>
@@ -1173,10 +1170,10 @@ Das Scannen erfolgt automatisch.</value>
<value>Auto-Fill Bedienungshilfe</value>
</data>
<data name="AutofillServiceDescription" xml:space="preserve">
<value>Der Auto-Ausfüllen-Dienst von Bitwarden benutzt das Android Autofill Framework, um Zugangsdaten in anderen Apps auf deinem Gerät auszufüllen.</value>
<value>Der Bitwarden Auto-Fill Service benutzt das Android Autofill Framework, um Logins, Kreditkarten und Identitätsinformationen in anderen Apps auf Ihrem Gerät zu befüllen.</value>
</data>
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
<value>Verwende den Auto-Ausfüllen-Dienst von Bitwarden, um Anmeldedaten in anderen Apps auszufüllen.</value>
<value>Verwende den Bitwarden Dienst in den Bedienungshilfen, um deine Zugangsdaten automatisch einzufügen.</value>
</data>
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
<value>Öffne Auto-Fill Einstellungen</value>
@@ -1201,7 +1198,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Die Android Auto-Fill Einstellungen konnten nicht automatisch geöffnet werden. Über Android Einstellungen &gt; Sprachen &amp; Eingabe &gt; AutoFill-Dienst kannst du manuell zu den Auto-Fill Einstellungen navigieren.</value>
</data>
<data name="CustomFieldName" xml:space="preserve">
<value>Name des benutzerdefinierten Feldes</value>
<value>Name Benutzerdefiniertes Feld</value>
</data>
<data name="FieldTypeBoolean" xml:space="preserve">
<value>Boolean</value>
@@ -1252,14 +1249,14 @@ Das Scannen erfolgt automatisch.</value>
<value>Beginnt mit</value>
</data>
<data name="URIMatchDetection" xml:space="preserve">
<value>URI-Übereinstimmungserkennung</value>
<value>Match-Erkennung</value>
</data>
<data name="MatchDetection" xml:space="preserve">
<value>Übereinstimmungserkennung</value>
<value>Match-Erkennung</value>
<comment>URI match detection for auto-fill.</comment>
</data>
<data name="YesAndSave" xml:space="preserve">
<value>Ja und speichern</value>
<value>Ja, und speichern</value>
</data>
<data name="AutofillAndSave" xml:space="preserve">
<value>Automatisch ausfüllen und speichern</value>
@@ -1289,7 +1286,7 @@ Das Scannen erfolgt automatisch.</value>
<comment>ex. Date this item was updated</comment>
</data>
<data name="AutofillActivated" xml:space="preserve">
<value>Auto-Ausfüllen aktiviert!</value>
<value>AutoFill aktiviert!</value>
</data>
<data name="MustLogInMainAppAutofill" xml:space="preserve">
<value>Du musst dich in der Bitwarden App einloggen, bevor du AutoFill nutzen kannst.</value>
@@ -1304,7 +1301,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Greife auf deinen Tressor direkt von deiner Tastatur aus zu um Passwörter schnell und automatisch auszufüllen.</value>
</data>
<data name="AutofillTurnOn" xml:space="preserve">
<value>Um das automatische Ausfüllen von Passwörtern auf deinem Gerät einzurichten, befolge bitte diese Anweisungen:</value>
<value>Um Autofill auf deinem Gerät zu aktivieren, befolge bitte diese Anweisungen:</value>
</data>
<data name="AutofillTurnOn1" xml:space="preserve">
<value>1. Gehe in die iOS Einstellungen</value>
@@ -1322,7 +1319,7 @@ Das Scannen erfolgt automatisch.</value>
<value>5. Wähle "Bitwarden"</value>
</data>
<data name="PasswordAutofill" xml:space="preserve">
<value>Passwort automatisch ausfüllen</value>
<value>Passwort AutoFill</value>
</data>
<data name="BitwardenAutofillAlert2" xml:space="preserve">
<value>Die einfachste Möglichkeit, neue Zugangsdaten zu deinemTresor hinzuzufügen, ist die Bitwarden Passwort Auto-Ausfüllen Erweiterung. Erfahre mehr über die Bitwarden Passwort Auto-Ausfüllen Funktion, indem du zur "Einstellungen" wechselst.</value>
@@ -1384,13 +1381,13 @@ Das Scannen erfolgt automatisch.</value>
<value>Sammlung durchsuchen</value>
</data>
<data name="SearchFileSends" xml:space="preserve">
<value>Datei-Sends durchsuchen</value>
<value>Versendete Dateien suchen</value>
</data>
<data name="SearchTextSends" xml:space="preserve">
<value>Text-Sends durchsuchen</value>
<value>Versendete Texte suchen</value>
</data>
<data name="SearchGroup" xml:space="preserve">
<value>{0} durchsuchen</value>
<value>Suche {0}</value>
<comment>ex: Search Logins</comment>
</data>
<data name="Type" xml:space="preserve">
@@ -1437,7 +1434,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Keine Organisationen vorhanden.</value>
</data>
<data name="MoveToOrgDesc" xml:space="preserve">
<value>Wähle eine Organisation aus, in die du diesen Eintrag verschieben möchtest. Das Verschieben in eine Organisation überträgt das Eigentum an diese Organisation. Du bist nicht mehr der direkte Eigentümer dieses Eintrags, sobald er verschoben wurde.</value>
<value>Wähle eine Organisation aus, in die du diesen Eintrag verschieben möchtest. Das Verschieben in eine Organisation überträgt das Eigentum an diese Organisation. Du bist nicht mehr der direkte Besitzer dieses Eintrags, sobald er verschoben wurde.</value>
</data>
<data name="NumberOfWords" xml:space="preserve">
<value>Anzahl der Wörter</value>
@@ -1502,7 +1499,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Dein Tresor ist gesperrt. Gebe deinen PIN-Code ein um fortzufahren.</value>
</data>
<data name="VaultLockedIdentity" xml:space="preserve">
<value>Dein Tresor ist gesperrt. Verifiziere deine Identität, um fortzufahren.</value>
<value>Dein Tresor ist gesperrt. Überprüfe deine Identität, um fortzufahren.</value>
</data>
<data name="Dark" xml:space="preserve">
<value>Dunkel</value>
@@ -1536,7 +1533,7 @@ Das Scannen erfolgt automatisch.</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">
<value>Standard URI-Übereinstimmungserkennung</value>
<value>Standard-URI-Match-Erkennung</value>
<comment>Default URI match detection for auto-fill.</comment>
</data>
<data name="DefaultUriMatchDetectionDescription" xml:space="preserve">
@@ -1553,13 +1550,13 @@ Das Scannen erfolgt automatisch.</value>
<value>Standard (System)</value>
</data>
<data name="DefaultDarkTheme" xml:space="preserve">
<value>Dunkles Standard-Design</value>
<value>Dunkles Standard Design</value>
</data>
<data name="DefaultDarkThemeDescription" xml:space="preserve">
<value>Wähle das zu verwendende dunkle Design aus, das bei der Auswahl vom Standard-(System)-Design verwendet werden soll, während der Dark Mode deines Geräts aktiviert ist.</value>
<value>Wähle das zu verwendende dunkle Design aus, das bei der Auswahl vom Standard (System) Design verwendet werden soll, während der Dunkelmodus deines Geräts aktiviert ist</value>
</data>
<data name="CopyNotes" xml:space="preserve">
<value>Notiz kopieren</value>
<value>Notizen kopieren</value>
</data>
<data name="Exit" xml:space="preserve">
<value>Beenden</value>
@@ -1589,16 +1586,16 @@ Das Scannen erfolgt automatisch.</value>
<value>Auto-Ausfüllen wird für blockierte URIs nicht angeboten. Trenne mehrere URIs mit einem Komma. Beispiel: "https://twitter.com, androidapp://com.twitter.android".</value>
</data>
<data name="AskToAddLogin" xml:space="preserve">
<value>Nach dem Hinzufügen von Zugangsdaten fragen</value>
<value>Danach fragen Zugangsdaten hinzuzufügen</value>
</data>
<data name="AskToAddLoginDescription" xml:space="preserve">
<value>Nach dem Hinzufügen eines Eintrags fragen, wenn dieser nicht in deinem Tresor gefunden wurde.</value>
<value>Wenn ein Eintrag nicht in deinem Tresor gefunden wurde, danach fragen.</value>
</data>
<data name="OnRestart" xml:space="preserve">
<value>Beim Neustart der App</value>
</data>
<data name="AutofillServiceNotEnabled" xml:space="preserve">
<value>Auto-Ausfüllen vereinfacht es, sicher auf deinen Bitwarden Tresor über andere Webseiten und Apps zuzugreifen. Es sieht aus, als ob du den Auto-Ausfüllen-Dienst für Bitwarden nicht eingerichtet hast. Richte Auto-Ausfüllen in den "Einstellungen" ein.</value>
<value>Automatisches Ausfüllen vereinfacht es, sicher auf deinen Bitwarden Tresor über andere Webseiten und Apps zuzugreifen. Es sieht aus, als ob du den automatischen Ausfülldienst für Bitwarden nicht aktiviert hast. Aktiviere automatisches Ausfüllen in der "Einstellungen" Ansicht.</value>
</data>
<data name="ThemeAppliedOnRestart" xml:space="preserve">
<value>Deine Änderungen am Aussehen der App werden beim nächsten Neustart der App angewendet.</value>
@@ -1608,7 +1605,7 @@ Das Scannen erfolgt automatisch.</value>
<comment>ex. Uppercase the first character of a word.</comment>
</data>
<data name="IncludeNumber" xml:space="preserve">
<value>Ziffern einschließen</value>
<value>Ziffer hinzufügen</value>
</data>
<data name="Download" xml:space="preserve">
<value>Herunterladen</value>
@@ -1623,19 +1620,19 @@ Das Scannen erfolgt automatisch.</value>
<value>Deine Sitzung ist abgelaufen.</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>Biometrische Verifizierung</value>
<value>Biometrische Daten zur Verifizierung nutzen.</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Biometrie</value>
</data>
<data name="UseBiometricsToUnlock" xml:space="preserve">
<value>Biometrie zum Entsperren verwenden</value>
<value>Biometrische Daten zum Entsperren verwenden</value>
</data>
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
<value>Bitwarden braucht Aufmerksamkeit - Siehe "Bedienungshilfen zum automatischen Ausfüllen" in den Bitwarden-Einstellungen</value>
<value>Bitwarden braucht Aufmerksamkeit - Siehe "Auto-Fill-Bedienungshilfe" in den Bitwarden-Einstellungen</value>
</data>
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
<value>3. Gehe in den Android App-Einstellungen für Bitwarden zur Option "Über anderen Apps einblenden" (unter Erweitert) und tippe auf den Schalter, um die Overlay-Unterstützung zu aktivieren.</value>
<value>3. Gehe unter Android in den App-Einstellungen für Bitwarden zur Option "Über anderen Apps einblenden" (unter Erweitert) und tippe auf den Schalter, um die Overlay-Unterstützung zu aktivieren.</value>
</data>
<data name="OverlayPermission" xml:space="preserve">
<value>Berechtigung</value>
@@ -1659,13 +1656,13 @@ Das Scannen erfolgt automatisch.</value>
<value>Gib das Masterpasswort ein, um deine Tresordaten zu exportieren.</value>
</data>
<data name="SendVerificationCodeToEmail" xml:space="preserve">
<value>Einen Verifizierungscode an deine E-Mail-Adresse senden</value>
<value>Einen Bestätigungscode an deine E-Mail senden</value>
</data>
<data name="CodeSent" xml:space="preserve">
<value>Code gesendet!</value>
</data>
<data name="ConfirmYourIdentity" xml:space="preserve">
<value>Verifiziere deine Identität, um fortzufahren.</value>
<value>Bestätige deine Identität, um fortzufahren.</value>
</data>
<data name="ExportVaultWarning" xml:space="preserve">
<value>Dieser Export enthält deine Tresordaten in einem unverschlüsseltem Format. Du solltest sie nicht speichern oder über unsichere Kanäle (z. B. E-Mail) senden. Lösche sie sofort nach ihrer Verwendung.</value>
@@ -1707,7 +1704,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Anhang erfolgreich gespeichert</value>
</data>
<data name="AutofillTileAccessibilityRequired" xml:space="preserve">
<value>Bitte aktiviere "Bedienungshilfen zum automatischen Ausfüllen" in den Bitwarden-Einstellungen, um die Auto-Ausfüllen-Kachel zu verwenden.</value>
<value>Bitte aktivieren Sie "Auto-Fill-Bedienungshilfe" in den Bitwarden-Einstellungen, um die Auto-Fill-Kachel zu verwenden.</value>
</data>
<data name="AutofillTileUriNotFound" xml:space="preserve">
<value>Keine Passwortfelder erkannt</value>
@@ -1765,10 +1762,10 @@ Das Scannen erfolgt automatisch.</value>
<value>Tresor durch Runterziehen Geste synchronisieren.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single-Sign-On</value>
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Melde dich schnell über das Single Sign-on-Portal deiner Organisation an. Bitte gib die Organisationskennung ein, um zu beginnen.</value>
<value>Schnell über den Single Sign-on deiner Organisation anmelden. Bitte gib deine Organisationskennung an, um zu beginnen.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisationskennung</value>
@@ -1777,7 +1774,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Anmeldung mit SSO derzeit nicht möglich</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Master-Passwort festlegen</value>
<value>Masterpasswort festlegen</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Bitte lege ein Masterpasswort für den Schutz deines Tresors fest, um die Anmeldung über SSO abzuschließen.</value>
@@ -1825,10 +1822,10 @@ Das Scannen erfolgt automatisch.</value>
<value>Datenschutzbestimmungen</value>
</data>
<data name="AccessibilityDrawOverPermissionAlert" xml:space="preserve">
<value>Bitwarden braucht Aufmerksamkeit - Aktiviere "Überschreiben" im "Auto-Ausfüllen-Dienst" in den Bitwarden-Einstellungen</value>
<value>Bitwarden braucht Aufmerksamkeit - Aktiviere "Überschreiben" in dem "Auto-Ausfüllen-Dienst" in den Bitwarden-Einstellungen</value>
</data>
<data name="AutofillServices" xml:space="preserve">
<value>Auto-Ausfüllen-Dienst</value>
<value>Auto-Ausfüllen Dienst</value>
</data>
<data name="InlineAutofill" xml:space="preserve">
<value>Inline Auto-Ausfüllen verwenden</value>
@@ -1840,28 +1837,28 @@ Das Scannen erfolgt automatisch.</value>
<value>Bedienungshilfen verwenden</value>
</data>
<data name="AccessibilityDescription" xml:space="preserve">
<value>Verwende die Bitwarden Bedienungshilfe, um deine Zugangsdaten innerhalb von Apps und dem Web automatisch auszufüllen. Wenn aktiviert, werden wir ein Pop-up anzeigen, falls Anmeldefelder ausgewählt sind.</value>
<value>Verwende die Bitwarden Bedienungshilfe, um deine Zugangsdaten innerhalb von Apps und dem Web automatisch auszufüllen. Wenn aktiviert, werden wir ein Popup anzeigen, falls Login-Felder ausgewählt sind.</value>
</data>
<data name="AccessibilityDescription2" xml:space="preserve">
<value>Verwende die Bitwarden Bedienungshilfe, um deine Zugangsdaten in Apps und im Web automatisch auszufüllen. (Benötigt das Überschreiben ebenfalls aktiviert ist)</value>
<value>Verwende die Bitwarden Bedienungshilfe, um deine Zugangsdaten in Apps und im Web automatisch auszufüllen. (Benötigt das Überschreiben ebenfalls aktiviertes ist)</value>
</data>
<data name="AccessibilityDescription3" xml:space="preserve">
<value>Verwende die Bitwarden Bedienungshilfe, um die Auto-Ausfüllen-Schnellaktionskachel zu verwenden und/oder ein Pop-up mit Überschreiben anzuzeigen (wenn aktiviert).</value>
<value>Verwende die Bitwarden Bedienungshilfe, um die Auto-Ausfüllen Schnellaktionskachel zu verwenden und/oder ein Popup mit Überschreiben anzuzeigen (wenn aktiviert).</value>
</data>
<data name="AccessibilityDescription4" xml:space="preserve">
<value>Benötigt, um die Auto-Ausfüllen-Schnellaktionskachel zu verwenden oder um die Auto-Ausfüllen-Funktion durch Überschreiben (falls aktiviert) zu ermöglichen.</value>
<value>Benötigt um die Auto-Ausfüllen Schnellaktionskachel zu verwenden oder um den Auto-Ausfüllen Service durch Überschreiben(falls aktiviert) zu ermöglichen.</value>
</data>
<data name="DrawOver" xml:space="preserve">
<value>Überschreiben verwenden</value>
</data>
<data name="DrawOverDescription" xml:space="preserve">
<value>Erlaubt es der Bitwarden Bedienungshilfe ein Pop-up anzuzeigen, wenn Anmeldefelder ausgewählt sind.</value>
<value>Falls aktiviert, erlaubt es der Bitwarden Bedienungshilfe ein Popup anzuzeigen, wenn Anmeldefelder ausgewählt sind.</value>
</data>
<data name="DrawOverDescription2" xml:space="preserve">
<value>Wenn aktiviert, wird die Bitwarden Bedienungshilfe ein Pop-up anzeigen, falls Anmeldefelder ausgewählt sind, um bei der automatischen Ausfüllung deiner Zugangsdaten zu helfen.</value>
<value>Wenn aktiviert, wird die Bitwarden Bedienungshilfe, falls Anmeldefelder ausgewählt sind, ein Popup anzeigen, um bei der automatischen Ausfüllung deiner Zugangsdaten zu helfen.</value>
</data>
<data name="DrawOverDescription3" xml:space="preserve">
<value>Wenn aktiviert, wird die Bedienungshilfe ein Pop-up anzeigen, um das automatische Ausfüllen in älteren Apps zu ermöglichen, die das Android Autofill Framework nicht unterstützen.</value>
<value>Wenn aktiviert, wird die Bedienungshilfe ein Popup anzeigen, um das automatische Ausfüllen in älteren Anwendungen zu ermöglichen, die das Android Auto-Ausfüllen Framework nicht unterstützen. </value>
</data>
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
<value>Aufgrund einer Unternehmensrichtlinie darfst du keine Einträge in deinem persönlichen Tresor speichern. Ändere die Eigentümer-Option in eine Organisation und wähle aus den verfügbaren Sammlungen.</value>
@@ -1933,7 +1930,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Ablaufdatum</value>
</data>
<data name="ExpirationTime" xml:space="preserve">
<value>Ablaufzeitpunkt</value>
<value>Ablaufzeit</value>
</data>
<data name="ExpirationDateInfo" xml:space="preserve">
<value>Falls aktiviert, verfällt der Zugriff auf diesen Send zur angegebenen Datum und Uhrzeit.</value>
@@ -2009,7 +2006,7 @@ Das Scannen erfolgt automatisch.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="AddSend" xml:space="preserve">
<value>Neues Send</value>
<value>Send hinzufügen</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="AreYouSureDeleteSend" xml:space="preserve">
@@ -2017,11 +2014,11 @@ Das Scannen erfolgt automatisch.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="SendDeleted" xml:space="preserve">
<value>Send gelöscht</value>
<value>Send wurde gelöscht</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="SendUpdated" xml:space="preserve">
<value>Send gespeichert</value>
<value>Send aktualisiert</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="NewSendCreated" xml:space="preserve">
@@ -2070,7 +2067,7 @@ Das Scannen erfolgt automatisch.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="SendFileEmailVerificationRequired" xml:space="preserve">
<value>Du musst deine E-Mail-Adresse verifizieren, um Dateien mit Send zu verwenden. Du kannst deine E-Mail-Adresse im Web-Tresor verifizieren.</value>
<value>Du musst deine E-Mail verifizieren, um Dateien mit Send zu verwenden. Du kannst deine E-Mail im Web-Tresor verifizieren.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="PasswordPrompt" xml:space="preserve">
@@ -2080,7 +2077,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Master-Passwort bestätigen</value>
</data>
<data name="PasswordConfirmationDesc" xml:space="preserve">
<value>Diese Aktion ist geschützt. Um fortzufahren, gib bitte dein Master-Passwort erneut ein, um deine Identität zu verifizieren.</value>
<value>Diese Aktion ist geschützt. Um fortzufahren, gib bitte dein Master-Passwort erneut ein, um deine Identität zu bestätigen.</value>
</data>
<data name="CaptchaRequired" xml:space="preserve">
<value>Captcha erforderlich</value>
@@ -2095,7 +2092,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Master-Passwort aktualisieren</value>
</data>
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
<value>Dein Master-Passwort wurde kürzlich von einem Administrator deiner Organisation geändert. Um auf den Tresor zuzugreifen, musst du dein Master-Passwort jetzt aktualisieren. Wenn Du fortfährst, wirst du aus der aktuellen Sitzung abgemeldet und eine erneute Anmeldung ist erforderlich. Aktive Sitzungen auf anderen Geräten können bis zu einer Stunde weiterhin aktiv bleiben.</value>
<value>Dein Master-Passwort wurde kürzlich von einem Administrator Deiner Organisation geändert. Um auf den Tresor zuzugreifen, musst Du Dein Master-Passwort jetzt aktualisieren. Wenn Du fortfährst, wirst Du aus der aktuellen Sitzung abgemeldet und wirst Dich erneut anmelden müssen. Aktive Sitzungen auf anderen Geräten können bis zu einer Stunde weiterhin aktiv bleiben.</value>
</data>
<data name="UpdatingPassword" xml:space="preserve">
<value>Passwort wird aktualisiert</value>
@@ -2122,13 +2119,13 @@ Das Scannen erfolgt automatisch.</value>
<value>FIDO2 WebAuthn</value>
</data>
<data name="Fido2Instruction" xml:space="preserve">
<value>Um fortzufahren, halte deinen FIDO2 WebAuthn-kompatiblen Sicherheitsschlüssel bereit und folge dann den Anweisungen, nachdem du auf der nächsten Seite auf 'WebAuthn authentifizieren' geklickt hast.</value>
<value>Um fortzufahren, halte deinen FIDO2 WebAuthn kompatiblen Sicherheitsschlüssel bereit und folge dann den Anweisungen, nachdem du auf der nächsten Seite auf 'Authentifiziere WebAuthn' geklickt hast.</value>
</data>
<data name="Fido2Desc" xml:space="preserve">
<value>Authentifizierung mit FIDO2 WebAuthn. Du kannst dich mit einem externen Sicherheitsschlüssel authentifizieren.</value>
<value>Authentifizierung mit FIDO2 WebAuthn, du kannst dich mit einem externen Sicherheitsschlüssel authentifizieren.</value>
</data>
<data name="Fido2AuthenticateWebAuthn" xml:space="preserve">
<value>WebAuthn authentifizieren</value>
<value>Authentifiziere WebAuthn</value>
</data>
<data name="Fido2ReturnToApp" xml:space="preserve">
<value>Zurück zur App</value>
@@ -2137,7 +2134,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Bitte stelle sicher, dass dein Standardbrowser WebAuthn unterstützt und versuche es erneut.</value>
</data>
<data name="ResetPasswordAutoEnrollInviteWarning" xml:space="preserve">
<value>Diese Organisation hat eine Unternehmensrichtlinie, die dich automatisch für die Passwortzurücksetzung registriert. Die Registrierung wird es Administratoren der Organisation erlauben, dein Master-Passwort zu ändern.</value>
<value>Diese Organisation hat eine Unternehmensrichtlinie, die dich automatisch für die Passwort Zurücksetzung registriert. Die Registrierung wird es Administratoren der Organisation erlauben, dein Master-Passwort zu ändern.</value>
</data>
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
<value>Deine Organisationsrichtlinien haben Auswirkungen auf dein Tresor-Timeout. Das maximal zulässige Tresor-Timeout beträgt {0} Stunde(n) und {1} Minute(n)</value>
@@ -2145,7 +2142,7 @@ Das Scannen erfolgt automatisch.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Dein Tresor-Timeout überschreitet die von deinem Unternehmen festgelegten Beschränkungen.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Eine oder mehrere Unternehmensrichtlinien verhindern es, dass du deinen persönlichen Tresor exportieren kannst.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2158,7 +2155,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Gesperrt</value>
</data>
<data name="AccountLoggedOut" xml:space="preserve">
<value>Abgemeldet</value>
<value>Ausgeloggt</value>
</data>
<data name="AccountSwitchedAutomatically" xml:space="preserve">
<value>Zum nächsten verfügbaren Konto gewechselt</value>
@@ -2182,7 +2179,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Dein Konto und alle damit verbundenen Daten werden gelöscht und sind nicht wiederherstellbar. Bist du sicher, dass du fortfahren möchtest?</value>
</data>
<data name="DeletingYourAccount" xml:space="preserve">
<value>Dein Konto wird gelöscht</value>
<value>Löschen deines Kontos</value>
</data>
<data name="YourAccountHasBeenPermanentlyDeleted" xml:space="preserve">
<value>Dein Konto wurde unwiderruflich gelöscht</value>
@@ -2194,19 +2191,19 @@ Das Scannen erfolgt automatisch.</value>
<value>Einmalpasswort anfordern</value>
</data>
<data name="SendCode" xml:space="preserve">
<value>Code senden</value>
<value>Send Code</value>
</data>
<data name="Sending" xml:space="preserve">
<value>Wird gesendet</value>
<value>Sende</value>
</data>
<data name="CopySendLinkOnSave" xml:space="preserve">
<value>Send-Link beim Speichern kopieren</value>
<value>Send Link beim Speichern kopieren</value>
</data>
<data name="SendingCode" xml:space="preserve">
<value>Code wird gesendet</value>
<value>Sende code</value>
</data>
<data name="Verifying" xml:space="preserve">
<value>Wird verifiziert</value>
<value>Überprüfen</value>
</data>
<data name="ResendCode" xml:space="preserve">
<value>Code erneut senden</value>
@@ -2218,7 +2215,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Beim Senden des Bestätigungscodes an deine E-Mail-Adresse ist ein Fehler aufgetreten. Bitte versuche es erneut</value>
</data>
<data name="EnterTheVerificationCodeThatWasSentToYourEmail" xml:space="preserve">
<value>Gib den Verifizierungscode ein, der an deine E-Mail-Adresse gesendet wurde</value>
<value>Gib den Bestätigungscode ein, der an deine E-Mail-Adresse gesendet wurde</value>
</data>
<data name="SubmitCrashLogs" xml:space="preserve">
<value>Absturzprotokolle senden</value>
@@ -2227,10 +2224,10 @@ Das Scannen erfolgt automatisch.</value>
<value>Hilf Bitwarden die Stabilität der App zu verbessern, indem du Absturzberichte sendest.</value>
</data>
<data name="OptionsExpanded" xml:space="preserve">
<value>Optionen sind ausgeklappt, tippen zum Einklappen.</value>
<value>Optionen sind ausgeklappt, tippen zum einklappen.</value>
</data>
<data name="OptionsCollapsed" xml:space="preserve">
<value>Optionen sind eingeklappt, tippe zum Ausklappen.</value>
<value>Optionen sind eingeklappt, tippe zum ausklappen.</value>
</data>
<data name="UppercaseAtoZ" xml:space="preserve">
<value>Großbuchstaben (A bis Z)</value>
@@ -2245,7 +2242,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Sonderzeichen (!@#$%^&amp;*)</value>
</data>
<data name="TapToGoBack" xml:space="preserve">
<value>Tippen, um zurückzugehen</value>
<value>Tippen, um zurück zu gehen</value>
</data>
<data name="PasswordIsVisibleTapToHide" xml:space="preserve">
<value>Passwort ist sichtbar, tippen um es auszublenden.</value>
@@ -2254,7 +2251,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Passwort ist nicht sichtbar, tippen um es einzublenden.</value>
</data>
<data name="FilterByVault" xml:space="preserve">
<value>Einträge nach Tresor filtern</value>
<value>Objekte nach Tresor filtern</value>
</data>
<data name="AllVaults" xml:space="preserve">
<value>Alle Tresore</value>
@@ -2284,7 +2281,7 @@ Das Scannen erfolgt automatisch.</value>
<value>QR Code scannen</value>
</data>
<data name="CannotScanQRCode" xml:space="preserve">
<value>QR-Code kann nicht gescannt werden? </value>
<value>QR Code kann nicht gescannt werden? </value>
</data>
<data name="AuthenticatorKeyScanner" xml:space="preserve">
<value>Authentifizierungsschlüssel</value>
@@ -2305,7 +2302,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Wenn du deine Sperroptionen auf „Nie“ einstellst, bleibt dein Tresor für jeden zugänglich, der Zugriff auf dein Gerät hat. Wenn du diese Option verwendest, solltest du sicherstellen, dass du dein Gerät angemessen schützt.</value>
</data>
<data name="EnvironmentPageUrlsError" xml:space="preserve">
<value>Eine oder mehrere der eingegebenen URLs sind ungültig. Bitte überarbeite diese und versuche erneut zu speichern.</value>
<value>Eine oder mehrere der eingegebenen URLs sind ungültig. Bitte überprüfe sie und versuche erneut zu speichern.</value>
</data>
<data name="GenericErrorMessage" xml:space="preserve">
<value>Wir konnten deine Anfrage nicht bearbeiten. Bitte versuche es erneut oder kontaktiere uns.</value>
@@ -2317,13 +2314,13 @@ Das Scannen erfolgt automatisch.</value>
<value>Bist du sicher, dass du die Bildschirmaufnahme aktivieren möchtest?</value>
</data>
<data name="LogInRequested" xml:space="preserve">
<value>Anmeldung angefordert</value>
<value>Zugangsdaten angefordert</value>
</data>
<data name="AreYouTryingToLogIn" xml:space="preserve">
<value>Versuchst du dich anzumelden?</value>
</data>
<data name="LogInAttemptByXOnY" xml:space="preserve">
<value>Anmeldeversuch von {0} auf {1}</value>
<value>Anmeldeversuch von {0} am {1}</value>
</data>
<data name="DeviceType" xml:space="preserve">
<value>Gerätetyp</value>
@@ -2338,22 +2335,22 @@ Das Scannen erfolgt automatisch.</value>
<value>Nahe</value>
</data>
<data name="ConfirmLogIn" xml:space="preserve">
<value>Anmeldung genehmigen</value>
<value>Anmeldung bestätigen</value>
</data>
<data name="DenyLogIn" xml:space="preserve">
<value>Anmeldung ablehnen</value>
<value>Anmeldung verweigern</value>
</data>
<data name="JustNow" xml:space="preserve">
<value>Gerade eben</value>
</data>
<data name="XMinutesAgo" xml:space="preserve">
<value>vor {0} Minuten</value>
<value>vor {0} Minute(n)</value>
</data>
<data name="LogInAccepted" xml:space="preserve">
<value>Anmeldung genehmigt</value>
<value>Anmeldung bestätigt</value>
</data>
<data name="LogInDenied" xml:space="preserve">
<value>Anmeldung abgelehnt</value>
<value>Anmeldung verweigert</value>
</data>
<data name="ApproveLoginRequests" xml:space="preserve">
<value>Anmeldeanfragen genehmigen</value>
@@ -2368,7 +2365,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Push-Benachrichtigungen für neue Anmeldeanfragen erhalten</value>
</data>
<data name="NoThanks" xml:space="preserve">
<value>Nein danke</value>
<value>Nein, danke</value>
</data>
<data name="ConfimLogInAttempForX" xml:space="preserve">
<value>Anmeldeversuch für {0} bestätigen</value>
@@ -2383,10 +2380,10 @@ Das Scannen erfolgt automatisch.</value>
<value>Was möchtest du generieren?</value>
</data>
<data name="UsernameType" xml:space="preserve">
<value>Benutzernamenstyp</value>
<value>Benutzernamentyp</value>
</data>
<data name="PlusAddressedEmail" xml:space="preserve">
<value>Plus-adressierte E-Mail-Adresse</value>
<value>Mit Plus adressierte E-Mail</value>
</data>
<data name="CatchAllEmail" xml:space="preserve">
<value>Catch-All E-Mail-Adresse</value>
@@ -2401,7 +2398,7 @@ Das Scannen erfolgt automatisch.</value>
<value>E-Mail (erforderlich)</value>
</data>
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
<value>Domainname (erforderlich)</value>
<value>Domain-Name (erforderlich)</value>
</data>
<data name="APIKeyRequiredParenthesis" xml:space="preserve">
<value>API-Schlüssel (erforderlich)</value>
@@ -2421,22 +2418,14 @@ Das Scannen erfolgt automatisch.</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API-Zugriffstoken</value>
<value>API-Zugangs-Token</value>
</data>
<data name="AreYouSureYouWantToOverwriteTheCurrentUsername" xml:space="preserve">
<value>Bist Du sicher, dass Du den aktuellen Benutzernamen überschreiben möchtest?</value>
</data>
<data name="GenerateUsername" xml:space="preserve">
<value>Benutzername generieren</value>
<value>Benutzernamen generieren</value>
</data>
<data name="EmailType" xml:space="preserve">
<value>E-Mail-Typ</value>
@@ -2466,7 +2455,7 @@ Das Scannen erfolgt automatisch.</value>
<value>Bedienungshilfen Offenlegung</value>
</data>
<data name="AccessibilityDisclosureText" xml:space="preserve">
<value>Bitwarden verwendet die Bedienungshilfen, um nach Anmeldefeldern in Apps und auf Webseiten zu suchen und legt dann die entsprechenden Feld-IDs fest, um einen Benutzernamen und Passwort einzugeben, wenn eine Übereinstimmung mit der App oder der Seite gefunden wird. Wir speichern keine der Informationen, die uns der Dienst zur Verfügung stellt. Ebenso wenig versuchen wir beliebige Elemente auf dem Bildschirm außer der Texteingabe von Anmeldedaten zu kontrollieren.</value>
<value>Bitwarden verwendet die Bedienungshilfen, um nach Anmeldefeldern in Apps und Webseiten zu suchen und legt dann die entsprechenden Feld-IDs fest, um Benutzername und Passwort einzugeben, wenn eine Übereinstimmung mit der App oder der Seite gefunden wird. Wir speichern keine der Informationen, die uns der Dienst zur Verfügung stellt. Ebenso wenig versuchen wir beliebige Elemente auf dem Bildschirm außer der Texteingabe von Anmeldedaten zu kontrollieren.</value>
</data>
<data name="Accept" xml:space="preserve">
<value>Akzeptieren</value>
@@ -2498,10 +2487,10 @@ Möchtest du zu diesem Konto wechseln?</value>
<value>Mit Master-Passwort anmelden</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Mit Gerät anmelden</value>
<value>Mit einem anderen Gerät anmelden</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Anmeldung eingeleitet</value>
<value>Anmeldung initiiert</value>
</data>
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
<value>Eine Benachrichtigung wurde an dein Gerät gesendet.</value>
@@ -2516,90 +2505,12 @@ Möchtest du zu diesem Konto wechseln?</value>
<value>Brauchst du eine andere Option?</value>
</data>
<data name="ViewAllLoginOptions" xml:space="preserve">
<value>Alle Anmeldeoptionen anzeigen</value>
<value>Alle Anmelde-Optionen anzeigen</value>
</data>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Diese Anfrage ist nicht mehr gültig</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Ausstehende Anmeldeanfragen</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Alle Anfragen ablehnen</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Bist du sicher, dass du alle ausstehenden Anmeldeanfragen ablehnen möchtest?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Anfragen abgelehnt</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Keine ausstehenden Anfragen</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Kamerazugriff gewähren, um den Scanner zu verwenden</value>
</data>
<data name="Language" xml:space="preserve">
<value>Sprache</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Die Sprache wurde auf {0} geändert. Bitte starte die App neu, um die Änderung zu sehen</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Sprachänderung erfordert einen App-Neustart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Standard (System)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Wichtig</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Dein Master-Passwort kann nicht wiederhergestellt werden, wenn du es vergisst! Mindestens {0} Zeichen.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Schwaches Master-Passwort</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Schwaches Passwort erkannt. Verwende ein starkes Passwort, um dein Konto zu schützen. Bist du sicher, dass du ein schwaches Passwort verwenden möchtest?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Schwach</value>
</data>
<data name="Good" xml:space="preserve">
<value>Gut</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Stark</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Bekannte Datendiebstähle auf dieses Passwort überprüfen</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Kompromittiertes Master-Passwort</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Passwort in einem Datendiebstahl gefunden. Verwende ein einzigartiges Passwort, um dein Konto zu schützen. Bist du sicher, dass du ein kompromittiertes Passwort verwenden möchtest?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Schwaches und kompromittiertes Master-Passwort</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Schwaches Passwort erkannt und in einem Datendiebstahl gefunden. Verwende ein starkes und einzigartiges Passwort, um dein Konto zu schützen. Bist du sicher, dass du dieses Passwort verwenden möchtest?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>SSO-Kennung der Organisation erforderlich.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Den Schlüssel zu einem bestehenden oder neuen Eintrag hinzufügen</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>Es gibt keine Einträge in deinem Tresor, die mit "{0}" übereinstimmen</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Nach einem Eintrag suchen oder einen neuen Eintrag hinzufügen</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Es gibt keine Einträge, die mit der Suche übereinstimmen</value>
<value>Kamerazugriff aktivieren, um den Scanner zu verwenden</value>
</data>
</root>

View File

@@ -584,8 +584,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Η υπόδειξη κύριου κωδικού μπορεί να σας βοηθήσει να θυμηθείτε τον κωδικό σας αν τον ξεχάσετε.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Ο κύριος κωδικός πρέπει να έχει μήκος τουλάχιστον {0} χαρακτήρες.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Ο κύριος κωδικός πρέπει να έχει μήκος τουλάχιστον 8 χαρακτήρων.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Ελάχιστα Αριθμητικά Ψηφία</value>
@@ -1103,9 +1103,6 @@
<data name="Ms" xml:space="preserve">
<value>Κα</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx στα Ελληνικά</value>
</data>
<data name="November" xml:space="preserve">
<value>Νοέμβριος</value>
</data>
@@ -2145,7 +2142,7 @@
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Το χρονικό όριο του vault σας υπερβαίνει τους περιορισμούς που έχει ορίσει ο οργανισμός σας.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Μία ή περισσότερες οργανωτικές πολιτικές αποτρέπουν την εξαγωγή του προσωπικού vault.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API Access Token</value>
</data>
@@ -2467,140 +2456,62 @@
<value>Γνωστοποίηση Υπηρεσίας Προσβασιμότητας</value>
</data>
<data name="AccessibilityDisclosureText" xml:space="preserve">
<value>Το Bitwarden χρησιμοποιεί την Υπηρεσία Προσβασιμότητας για να αναζητήσει πεδία σύνδεσης σε εφαρμογές και ιστότοπους και στη συνέχεια να δημιουργήσει τα κατάλληλα αναγνωριστικά πεδίου για την εισαγωγή ονόματος χρήστη και κωδικού πρόσβασης όταν βρεθεί αντιστοιχία για την εφαρμογή ή τον ιστότοπο. Δεν αποθηκεύουμε καμία από τις πληροφορίες που μας παρέχονται από την υπηρεσία, ούτε κάνουμε καμία προσπάθεια ελέγχου οποιωνδήποτε στοιχείων στην οθόνη πέραν της εισαγωγής του κειμένου των διαπιστευτηρίων.</value>
<value>Bitwarden uses the Accessibility Service to search for login fields in apps and websites, then establish the appropriate field IDs for entering a username &amp; password when a match for the app or site is found. We do not store any of the information presented to us by the service, nor do we make any attempt to control any on-screen elements beyond text entry of credentials.</value>
</data>
<data name="Accept" xml:space="preserve">
<value>Αποδοχή</value>
<value>Accept</value>
</data>
<data name="Decline" xml:space="preserve">
<value>Απόρριψη</value>
<value>Decline</value>
</data>
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
<value>Το αίτημα σύνδεσης έχει ήδη λήξει.</value>
<value>Login request has already expired.</value>
</data>
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
<value>Προσπάθεια σύνδεσης από:
<value>Login attempt from:
{0}
Θέλετε να μεταβείτε σε αυτόν τον λογαριασμό;</value>
Do you want to switch to this account?</value>
</data>
<data name="NewAroundHere" xml:space="preserve">
<value>Είστε νέος/α εδώ;</value>
<value>New around here?</value>
</data>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Λάβετε υπόδειξη κύριου κωδικού</value>
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Σύνδεση ως {0}</value>
<value>Logging in as {0}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Δεν είστε εσείς;</value>
<value>Not you?</value>
</data>
<data name="LogInWithMasterPassword" xml:space="preserve">
<value>Σύνδεση με κύριο κωδικό</value>
<value>Log in with master password</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Σύνδεση με τη χρήση συσκευής</value>
<value>Log In with another device</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Η σύνδεση ξεκίνησε</value>
<value>Log in initiated</value>
</data>
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
<value>Μια ειδοποίηση έχει σταλεί στη συσκευή σας.</value>
<value>A notification has been sent to your device.</value>
</data>
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
<value>Βεβαιωθείτε ότι το vault σας είναι ξεκλείδωτο και ότι η Φράση δακτυλικών αποτυπωμάτων ταιριάζει στην άλλη συσκευή.</value>
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
</data>
<data name="ResendNotification" xml:space="preserve">
<value>Επαναποστολή ειδοποίησης</value>
<value>Resend notification</value>
</data>
<data name="NeedAnotherOption" xml:space="preserve">
<value>Προσθέστε μια άλλη επιλογή</value>
<value>Need another option?</value>
</data>
<data name="ViewAllLoginOptions" xml:space="preserve">
<value>Δείτε όλες τις επιλογές σύνδεσης</value>
<value>View all log in options</value>
</data>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Αυτό το αίτημα δεν είναι πλέον έγκυρο</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Εκκρεμούν αιτήματα σύνδεσης</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Απόρριψη όλων των αιτημάτων</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Είστε σίγουροι ότι θέλετε να απορρίψετε όλα τα εκκρεμή αιτήματα σύνδεσης;</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Τα αιτήματα απορρίφθηκαν</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>Δεν υπάρχουν εκκρεμή αιτήματα</value>
<value>This request is no longer valid</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Ενεργοποιήστε την άδεια της κάμερας για χρήση του σαρωτή</value>
</data>
<data name="Language" xml:space="preserve">
<value>Γλώσσα</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>Η γλώσσα έχει αλλάξει σε {0}. Παρακαλούμε επανεκκινήστε την εφαρμογή για να δείτε την αλλαγή</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Η αλλαγή γλώσσας απαιτεί επανεκκίνηση της εφαρμογής</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Προεπιλογή (σύστημα)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Σημαντικό</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Ο κύριος κωδικός δεν μπορεί να ανακτηθεί αν τον ξεχάσετε! Απαιτούνται τουλάχιστον {0} χαρακτήρες.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Αδύναμος Κύριος Κωδικός</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Αδύναμος κωδικός. Χρησιμοποιήστε έναν ισχυρό κωδικό για την προστασία του λογαριασμού σας. Είστε βέβαιοι ότι θέλετε να χρησιμοποιήσετε έναν αδύναμο κωδικό πρόσβασης;</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Αδύναμος</value>
</data>
<data name="Good" xml:space="preserve">
<value>Καλός</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Ισχυρός</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Ελέγξτε γνωστές παραβιάσεις δεδομένων για αυτόν τον κωδικό</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Εκτεθειμένος Κύριος Κωδικός Πρόσβασης</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Ο κωδικός έχει βρεθεί σε παραβίαση δεδομένων. Χρησιμοποιήστε έναν μοναδικό κωδικό για την προστασία του λογαριασμού σας. Είστε σίγουροι ότι θέλετε να χρησιμοποιήσετε έναν εκτεθειμένο κωδικό πρόσβασης;</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Αδύναμος και Εκτεθειμένος Κύριος Κωδικός</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Αδύναμος κωδικός που έχει εντοπιστεί σε παραβίαση δεδομένων. Χρησιμοποιήστε έναν ισχυρό και μοναδικό κωδικό για την προστασία του λογαριασμού σας. Είστε σίγουροι ότι θέλετε να χρησιμοποιήσετε αυτόν τον κωδικό;</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Απαιτείται αναγνωριστικό οργανισμού SSO.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Προσθέστε το κλειδί σε ένα υπάρχον ή νέο στοιχείο</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>Δεν υπάρχουν αντικείμενα στη κρύπτη σας που ταιριάζουν με "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Αναζητήστε ένα στοιχείο ή προσθέστε ένα νέο</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>Δεν υπάρχουν στοιχεία που να ταιριάζουν με την αναζήτηση</value>
<value>Enable camera permission to use the scanner</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>A master password hint can help you remember your password if you forget it.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Master password must be at least 8 characters long.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Minimum numbers</value>
@@ -1103,9 +1103,6 @@ Scanning will happen automatically.</value>
<data name="Ms" xml:space="preserve">
<value>Ms</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
</data>
@@ -2137,7 +2134,7 @@ Scanning will happen automatically.</value>
<value>Please make sure your default browser supports WebAuthn and try again.</value>
</data>
<data name="ResetPasswordAutoEnrollInviteWarning" xml:space="preserve">
<value>This organisation has an enterprise policy that will automatically enrol you in password reset. Enrolment will allow organisation administrators to change your master password.</value>
<value>This organisation has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organisation administrators to change your master password.</value>
</data>
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
<value>Your organisation policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
@@ -2145,7 +2142,7 @@ Scanning will happen automatically.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Your vault timeout exceeds the restrictions set by your organisation.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>One or more organisation policies prevents your from exporting your individual vault.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2422,14 +2419,6 @@ select Add TOTP to store the key safely</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API access token</value>
</data>
@@ -2522,85 +2511,7 @@ Do you want to switch to this account?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>This request is no longer valid</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Pending login requests</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Enable camera permission to use the scanner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Weak Master Password</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Weak password identified. Use a strong password to protect your account. Are you sure you want to use a weak password?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Weak</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organisation SSO identifier required.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
</root>

View File

@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>A master password hint can help you remember your password if you forget it.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>Master password must be at least 8 characters long.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Minimum numbers</value>
@@ -1103,9 +1103,6 @@ Scanning will happen automatically.</value>
<data name="Ms" xml:space="preserve">
<value>Ms</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
</data>
@@ -1579,7 +1576,7 @@ Scanning will happen automatically.</value>
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
</data>
<data name="SolarizedDark" xml:space="preserve">
<value>Solarised Dark</value>
<value>Solarized Dark</value>
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
</data>
<data name="AutofillBlockedUris" xml:space="preserve">
@@ -2159,7 +2156,7 @@ Scanning will happen automatically.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Your vault timeout exceeds the restrictions set by your organization.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>One or more organization policies prevents your from exporting your individual vault.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2436,14 +2433,6 @@ select Add TOTP to store the key safely</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>API access token</value>
</data>
@@ -2513,7 +2502,7 @@ Do you want to switch to this account?</value>
<value>Log in with master password</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Log in with device</value>
<value>Log In with another device</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Log in initiated</value>
@@ -2536,85 +2525,7 @@ Do you want to switch to this account?</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>This request is no longer valid</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Pending login requests</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Enable camera permission to use the scanner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Weak master password</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Weak password identified. Use a strong password to protect your account. Are you sure you want to use a weak password?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Weak</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
</root>

View File

@@ -236,7 +236,7 @@
<comment>The button text that allows user to launch the website to their web browser.</comment>
</data>
<data name="HelpAndFeedback" xml:space="preserve">
<value>Ayuda y comentarios</value>
<value>Ayuda &amp; Comentarios</value>
</data>
<data name="Hide" xml:space="preserve">
<value>Ocultar</value>
@@ -583,8 +583,8 @@
<data name="MasterPasswordHintDescription" xml:space="preserve">
<value>Una pista de tu contraseña maestra puede ayudarte a recordarla en caso de que la olvides.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>La contraseña maestra debe tener al menos {0} caracteres.</value>
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
<value>La contraseña maestra debe tener al menos 8 caracteres.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Mínimo de caracteres numéricos</value>
@@ -987,7 +987,7 @@ El escaneo se realizará automáticamente.</value>
<value>URL del servidor</value>
</data>
<data name="WebVaultUrl" xml:space="preserve">
<value>URL del servidor de la caja fuerte web</value>
<value>URL del servidor de la bóveda web</value>
</data>
<data name="BitwardenAutofillServiceNotificationContentOld" xml:space="preserve">
<value>Pulsa en esta notificación para ver las entradas de tu caja fuerte.</value>
@@ -1103,9 +1103,6 @@ El escaneo se realizará automáticamente.</value>
<data name="Ms" xml:space="preserve">
<value>Srta</value>
</data>
<data name="Mx" xml:space="preserve">
<value>"Mx" = "Sr./Sra</value>
</data>
<data name="November" xml:space="preserve">
<value>Noviembre</value>
</data>
@@ -1483,7 +1480,7 @@ El escaneo se realizará automáticamente.</value>
<value>Desbloquear</value>
</data>
<data name="UnlockVault" xml:space="preserve">
<value>Desbloquear caja fuerte</value>
<value>Desbloquear bóveda</value>
</data>
<data name="ThirtyMinutes" xml:space="preserve">
<value>30 minutos</value>
@@ -1592,7 +1589,7 @@ El escaneo se realizará automáticamente.</value>
<value>Pedir que se añada el inicio de sesión</value>
</data>
<data name="AskToAddLoginDescription" xml:space="preserve">
<value>Pedir que se añada un elemento si no se encuentra uno en tu caja fuerte.</value>
<value>Pedir que se añada un elemento si no se encuentra uno en tu bóveda.</value>
</data>
<data name="OnRestart" xml:space="preserve">
<value>Al reiniciar la aplicación</value>
@@ -1626,7 +1623,7 @@ El escaneo se realizará automáticamente.</value>
<value>Verificación biométrica</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>biometría</value>
<value>Biometría</value>
</data>
<data name="UseBiometricsToUnlock" xml:space="preserve">
<value>Utilizar biometría para desbloquear</value>
@@ -1677,7 +1674,7 @@ El escaneo se realizará automáticamente.</value>
<value>Las claves de cifrado de cuenta son únicas para cada cuenta de usuario de Bitwarden, por lo que no puede importar una exportación cifrada a una cuenta diferente.</value>
</data>
<data name="ExportVaultConfirmationTitle" xml:space="preserve">
<value>Confirmar exportación de la caja fuerte</value>
<value>Confirmar exportación de bóveda</value>
<comment>Title for the alert to confirm vault exports.</comment>
</data>
<data name="Warning" xml:space="preserve">
@@ -1762,7 +1759,7 @@ El escaneo se realizará automáticamente.</value>
<value>Habilitar sincronización al actualizar</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronizar caja fuerte deslizando hacia abajo.</value>
<value>Sincronizando caja fuerte con gesto desplegable.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Inicio de sesión único empresarial</value>
@@ -1786,7 +1783,7 @@ El escaneo se realizará automáticamente.</value>
<value>Una o más políticas de la organización requieren que su contraseña maestra cumpla con los siguientes requisitos:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Puntuación de complejidad mínima {0}</value>
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Longitud mínima de {0}</value>
@@ -1801,7 +1798,7 @@ El escaneo se realizará automáticamente.</value>
<value>Contiene uno o más números</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contienen uno o más de los siguientes caracteres especiales {0}</value>
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Contraseña no válida</value>
@@ -1864,7 +1861,7 @@ El escaneo se realizará automáticamente.</value>
<value>Si está activado, la accesibilidad mostrará una ventana emergente para aumentar el servicio de autorelleno para aplicaciones antiguas que no soportan la estructura de autorelleno de Android.</value>
</data>
<data name="PersonalOwnershipSubmitError" xml:space="preserve">
<value>Debido a una política empresarial, usted está restringido a guardar elementos en su caja fuerte personal. Cambie la opción Propiedad a una organización y elija de entre las colecciones disponibles.</value>
<value>Debido a una Política Empresarial, usted está restringido a guardar elementos en su bóveda personal. Cambie la opción Propiedad a una organización y elija de entre las colecciones disponibles.</value>
</data>
<data name="PersonalOwnershipPolicyInEffect" xml:space="preserve">
<value>Una política de organización está afectando sus opciones de propiedad.</value>
@@ -2070,7 +2067,7 @@ El escaneo se realizará automáticamente.</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">
<value>Debes verificar tu correo electrónico para usar archivos con el Send. Puedes verificar tu correo electrónico en la caja fuerte web.</value>
<value>Debes verificar tu correo electrónico para usar archivos con el Send. Puedes verificar tu correo electrónico en la bóveda web.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="PasswordPrompt" xml:space="preserve">
@@ -2145,7 +2142,7 @@ El escaneo se realizará automáticamente.</value>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>El tiempo de espera de tu caja fuerte excede las restricciones establecidas por tu organización.</value>
</data>
<data name="DisablePersonalVaultExportPolicyInEffect" xml:space="preserve">
<data name="DisablePersonalVaultExportPolicyInEffect">
<value>Una o más políticas de organización impiden que usted exporte su caja fuerte personal.</value>
</data>
<data name="AddAccount" xml:space="preserve">
@@ -2255,16 +2252,16 @@ El escaneo se realizará automáticamente.</value>
<value>La contraseña no está visible, toque para mostrar.</value>
</data>
<data name="FilterByVault" xml:space="preserve">
<value>Filtrar elementos por caja fuerte</value>
<value>Filtrar elementos por bóveda</value>
</data>
<data name="AllVaults" xml:space="preserve">
<value>Todas las cajas fuertes</value>
<value>Todas las bóvedas</value>
</data>
<data name="Vaults" xml:space="preserve">
<value>Cajas fuertes</value>
<value>Bóvedas</value>
</data>
<data name="VaultFilterDescription" xml:space="preserve">
<value>Caja fuerte: {0}</value>
<value>Bóveda: {0}</value>
</data>
<data name="All" xml:space="preserve">
<value>Todo</value>
@@ -2304,7 +2301,7 @@ El escaneo se realizará automáticamente.</value>
seleccione Agregar TOTP para almacenar la clave de forma segura</value>
</data>
<data name="NeverLockWarning" xml:space="preserve">
<value>Configurar las opciones de bloqueo a "Nunca" mantiene la caja fuerte disponible para cualquier persona con acceso a su dispositivo. Si utiliza esta opción, debe asegurarse de que mantiene su dispositivo debidamente protegido.</value>
<value>Configurar las opciones de bloqueo a "Nunca" mantiene la bóveda disponible para cualquier persona con acceso a su dispositivo. Si utiliza esta opción, debe asegurarse de que mantiene su dispositivo debidamente protegido.</value>
</data>
<data name="EnvironmentPageUrlsError" xml:space="preserve">
<value>Una o más de las URLs introducidas no son válidas. Por favor, revisala e intenta guardar de nuevo.</value>
@@ -2423,14 +2420,6 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
<value>SimpleLogin</value>
<comment>"SimpleLogin" is the product name and should not be translated.</comment>
</data>
<data name="DuckDuckGo" xml:space="preserve">
<value>DuckDuckGo</value>
<comment>"DuckDuckGo" is the product name and should not be translated.</comment>
</data>
<data name="Fastmail" xml:space="preserve">
<value>Fastmail</value>
<comment>"Fastmail" is the product name and should not be translated.</comment>
</data>
<data name="APIAccessToken" xml:space="preserve">
<value>Token de acceso API</value>
</data>
@@ -2509,7 +2498,7 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
<value>Se ha enviado una notificación a tu dispositivo.</value>
</data>
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
<value>Por favor, asegúrese de que su caja fuerte está desbloqueada y la frase de huella dactilar coincide en el otro dispositivo.</value>
<value>Por favor, asegúrese de que su bóveda está desbloqueada y la frase de huella dactilar coincide en el otro dispositivo.</value>
</data>
<data name="ResendNotification" xml:space="preserve">
<value>Enviar nueva notificación</value>
@@ -2523,85 +2512,7 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>Esta solicitud ya no es válida</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Solicitudes de acceso pendientes</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Rechazar todas las solicitudes</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>¿Está seguro de que desea rechazar todas las solicitudes de inicio de sesión pendientes?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Solicitudes rechazadas</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No hay solicitudes pendientes</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Habilitar el permiso de la cámara para usar el escáner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Idioma</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>El idioma se ha cambiado a {0}. Por favor, reinicia la aplicación para aplicar los cambios</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>El cambio de idioma requiere reiniciar la aplicación</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Por defecto (Sistema)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Importante</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Tu contraseña maestra no se puede recuperar si la olvidas! {0} caracteres como mínimo.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Contraseña maestra débil</value>
</data>
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
<value>Contraseña débil identificada. Utilice una contraseña fuerte para proteger su cuenta. ¿Está seguro de que desea utilizar una contraseña débil?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Débil</value>
</data>
<data name="Good" xml:space="preserve">
<value>Bueno</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Fuerte</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Comprobar filtración de datos conocidos para esta contraseña</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Contraseña maestra comprometida</value>
</data>
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Contraseña encontrada en una violación de datos. Utilice una contraseña única para proteger su cuenta. ¿Está seguro de que desea utilizar una contraseña comprometida?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Contraseña maestra débil y comprometida</value>
</data>
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
<value>Contraseña débil encontrada en una violación de datos. Utilice una contraseña única para proteger su cuenta. ¿Está seguro de que desea utilizar una contraseña comprometida?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Se requiere un inicio de sesión único de la organización.</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Añadir la clave a un elemento existente o nuevo</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>No hay artículos en su caja fuerte que coincidan con "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Buscar un elemento o añadir uno nuevo</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>No hay elementos que coincidan con la búsqueda</value>
</data>
</root>

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