1
0
mirror of https://github.com/bitwarden/mobile synced 2025-12-15 15:53:44 +00:00

Merge branch 'master' into PM-2149-improve-attachment-uiux

This commit is contained in:
Federico Maccaroni
2023-05-19 18:32:52 +03:00
72 changed files with 1213 additions and 939 deletions

10
.github/labeler.yml vendored
View File

@@ -8,11 +8,11 @@ iOS:
- src/Core/*
- lib/ios/*
- src/iOS/*
- src/iOS.Autofill/*
- src/iOS.Core/*
- src/iOS.Extension/*
- src/iOS.ShareExtension/*
- src/iOS.Widget/*
- 'src/iOS.Autofill/*'
- 'src/iOS.Core/*'
- 'src/iOS.Extension/*'
- 'src/iOS.ShareExtension/*'
- 'src/iOS.Widget/*'
- src/watchOS/*
watchOS:

View File

@@ -14,7 +14,7 @@ jobs:
# Feature request
- if: github.event.label.name == 'feature-request'
name: Feature request
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
with:
comment: |
We use GitHub issues as a place to track bugs and other development related issues. The [Bitwarden Community Forums](https://community.bitwarden.com/) has a [Feature Requests](https://community.bitwarden.com/c/feature-requests) section for submitting, voting for, and discussing requests like this one.
@@ -25,7 +25,7 @@ jobs:
# Intended behavior
- if: github.event.label.name == 'intended-behavior'
name: Intended behaviour
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
with:
comment: |
Your issue appears to be describing the intended behavior of the software. If you want this to be changed, it would be a feature request.
@@ -38,7 +38,7 @@ jobs:
# Customer support request
- if: github.event.label.name == 'customer-support'
name: Customer Support request
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
with:
comment: |
We use GitHub issues as a place to track bugs and other development related issues. Your issue appears to be a support request, or would otherwise be better handled by our dedicated Customer Success team.
@@ -49,14 +49,14 @@ jobs:
# Resolved
- if: github.event.label.name == 'resolved'
name: Resolved
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
with:
comment: |
Weve closed this issue, as it appears the original problem has been resolved. If this happens again or continues to be an problem, please respond to this issue with any additional detail to assist with reproduction and root cause analysis.
# Stale
- if: github.event.label.name == 'stale'
name: Stale
uses: peter-evans/close-issue@849549ba7c3a595a064c4b2c56f206ee78f93515 # v2.0.0
uses: peter-evans/close-issue@276d7966e389d888f011539a86c8920025ea0626 # v3.0.1
with:
comment: |
As we havent heard from you about this problem in some time, this issue will now be closed.

View File

@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Set up CLOC
run: |
@@ -36,7 +36,7 @@ jobs:
hotfix_branch_exists: ${{ steps.branch-check.outputs.hotfix_branch_exists }}
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
submodules: 'true'
@@ -67,12 +67,12 @@ jobs:
variant: ["prod", "qa"]
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
with:
nuget-version: 5.9.0
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # v1.3.1
- name: Setup Windows builder
run: choco install checksum --no-progress
@@ -105,7 +105,7 @@ jobs:
echo "GitHub event: $GITHUB_EVENT"
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
fetch-depth: 0
- name: Decrypt secrets
@@ -157,7 +157,7 @@ jobs:
shell: pwsh
- name: Report test results
uses: dorny/test-reporter@c9b3d0e2bd2a4e96aaf424dbaa31c46b42318226
uses: dorny/test-reporter@c9b3d0e2bd2a4e96aaf424dbaa31c46b42318226 # v1.6.0
if: always()
with:
name: Test Results
@@ -232,7 +232,7 @@ jobs:
shell: pwsh
- name: Upload Prod .aab artifact
if: ${{ matrix.variant == 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: com.x8bit.bitwarden.aab
path: ./com.x8bit.bitwarden.aab
@@ -240,7 +240,7 @@ jobs:
- name: Upload Prod .apk artifact
if: ${{ matrix.variant == 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: com.x8bit.bitwarden.apk
path: ./com.x8bit.bitwarden.apk
@@ -248,7 +248,7 @@ jobs:
- name: Upload Other .apk artifact
if: ${{ matrix.variant != 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk
@@ -268,7 +268,7 @@ jobs:
- name: Upload .apk sha file for prod
if: ${{ matrix.variant == 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: bw-android-apk-sha256.txt
path: ./bw-android-apk-sha256.txt
@@ -276,7 +276,7 @@ jobs:
- name: Upload .apk sha file for other
if: ${{ matrix.variant != 'prod' }}
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: bw-android-${{ matrix.variant }}-apk-sha256.txt
path: ./bw-android-${{ matrix.variant }}-apk-sha256.txt
@@ -303,12 +303,12 @@ jobs:
runs-on: windows-2022
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
with:
nuget-version: 5.9.0
- name: Set up MSBuild
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # v1.3.1
- name: Setup Windows builder
run: choco install checksum --no-progress
@@ -342,7 +342,7 @@ jobs:
echo "GitHub event: $GITHUB_EVENT"
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Decrypt secrets
env:
@@ -477,7 +477,7 @@ jobs:
shell: pwsh
- name: Upload F-Droid .apk artifact
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: com.x8bit.bitwarden-fdroid.apk
path: ./com.x8bit.bitwarden-fdroid.apk
@@ -489,7 +489,7 @@ jobs:
-t sha256 | Out-File -Encoding ASCII ./bw-fdroid-apk-sha256.txt
- name: Upload F-Droid sha file
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: bw-fdroid-apk-sha256.txt
path: ./bw-fdroid-apk-sha256.txt
@@ -502,7 +502,7 @@ jobs:
needs: setup
steps:
- name: Setup NuGet
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
uses: nuget/setup-nuget@296fd3ccf8528660c91106efefe2364482f86d6f # v1.2.0
with:
nuget-version: 5.9.0
@@ -515,12 +515,12 @@ jobs:
echo "GitHub event: $GITHUB_EVENT"
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
with:
submodules: 'true'
- name: Login to Azure - CI Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf # v1.4.3
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
@@ -698,7 +698,7 @@ jobs:
shell: bash
- name: Upload App Store .ipa & dSYMs artifacts
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535 # v3.0.0
with:
name: Bitwarden iOS
path: |
@@ -771,10 +771,10 @@ jobs:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Checkout repo
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Login to Azure - CI Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf # v1.4.3
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
@@ -793,7 +793,7 @@ jobs:
done
- name: Upload Sources
uses: crowdin/github-action@9237b4cb361788dfce63feb2e2f15c09e2fe7415
uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
@@ -840,7 +840,7 @@ jobs:
fi
- name: Login to Azure - CI Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf # v1.4.3
if: failure()
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
@@ -861,7 +861,7 @@ jobs:
done
- name: Notify Slack on failure
uses: act10ns/slack@da3191ebe2e67f49b46880b4633f5591a96d1d33
uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0
if: failure()
env:
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}

View File

@@ -15,22 +15,22 @@ jobs:
_CROWDIN_PROJECT_ID: "269690"
steps:
- name: Checkout repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Login to Azure - CI Subscription
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf # v1.4.3
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
uses: bitwarden/gh-actions/get-keyvault-secrets@34ecb67b2a357795dc893549df0795e7383ff50f
with:
keyvault: "bitwarden-ci"
secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Download translations
uses: crowdin/github-action@12143a68c213f3c6d9913c9e5023224f7231face
uses: crowdin/github-action@ecd7eb0ef6f3cfa16293c79e9cbc4bc5b5fd9c49 # v1.4.9
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}

View File

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

View File

@@ -38,11 +38,11 @@ jobs:
fi
- name: Checkout repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Check Release Version
id: version
uses: bitwarden/gh-actions/release-version-check@8f055ef543c7433c967a1b9b04a0f230923233bb
uses: bitwarden/gh-actions/release-version-check@34ecb67b2a357795dc893549df0795e7383ff50f
with:
release-type: ${{ github.event.inputs.release_type }}
project-type: xamarin
@@ -56,7 +56,7 @@ jobs:
- name: Create GitHub deployment
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: chrnorm/deployment-action@1b599fe41a0ef1f95191e7f2eec4743f2d7dfc48
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
id: deployment
with:
token: '${{ secrets.GITHUB_TOKEN }}'
@@ -104,7 +104,7 @@ jobs:
- name: Update deployment status to Success
if: ${{ github.event.inputs.release_type != 'Dry Run' && success() }}
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'success'
@@ -112,7 +112,7 @@ jobs:
- name: Update deployment status to Failure
if: ${{ github.event.inputs.release_type != 'Dry Run' && failure() }}
uses: chrnorm/deployment-status@07b3930847f65e71c9c6802ff5a402f6dfb46b86
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
with:
token: '${{ secrets.GITHUB_TOKEN }}'
state: 'failure'
@@ -126,7 +126,7 @@ jobs:
if: inputs.fdroid_publish
steps:
- name: Checkout repo
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2.4.0
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Download F-Droid .apk artifact
if: ${{ github.event.inputs.release_type != 'Dry Run' }}

View File

@@ -14,7 +14,7 @@ jobs:
version_number: ${{ steps.version.outputs.new-version }}
steps:
- name: Checkout Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Calculate bumped version
id: version

View File

@@ -22,22 +22,22 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3.3.0
- name: Login to Azure - CI Subscription
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf # v1.4.3
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@c3b3285993151c5af47cefcb3b9134c28ab479af
uses: bitwarden/gh-actions/get-keyvault-secrets@34ecb67b2a357795dc893549df0795e7383ff50f
with:
keyvault: "bitwarden-ci"
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@c8bb57c57e8df1be8c73ff3d59deab1dbc00e0d1
uses: crazy-max/ghaction-import-gpg@111c56156bcc6918c056dbef52164cfa583dc549 # v5.2.0
with:
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
@@ -48,31 +48,31 @@ jobs:
run: git switch -c version_bump_${{ github.event.inputs.version_number }}
- name: Bump Version - Android XML
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
uses: bitwarden/gh-actions/version-bump@34ecb67b2a357795dc893549df0795e7383ff50f
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/Android/Properties/AndroidManifest.xml"
- name: Bump Version - iOS.Autofill
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
uses: bitwarden/gh-actions/version-bump@34ecb67b2a357795dc893549df0795e7383ff50f
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.Autofill/Info.plist"
- name: Bump Version - iOS.Extension
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
uses: bitwarden/gh-actions/version-bump@34ecb67b2a357795dc893549df0795e7383ff50f
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.Extension/Info.plist"
- name: Bump Version - iOS.ShareExtension
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
uses: bitwarden/gh-actions/version-bump@34ecb67b2a357795dc893549df0795e7383ff50f
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS.ShareExtension/Info.plist"
- name: Bump Version - iOS
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
uses: bitwarden/gh-actions/version-bump@34ecb67b2a357795dc893549df0795e7383ff50f
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/iOS/Info.plist"

View File

@@ -8,4 +8,4 @@ on:
jobs:
call-workflow:
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@master
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@34ecb67b2a357795dc893549df0795e7383ff50f

View File

@@ -78,21 +78,20 @@
<Version>1.9.0</Version>
</PackageReference>
<PackageReference Include="Xamarin.AndroidX.AppCompat" Version="1.5.1.1" />
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.14" />
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.17" />
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.9.0.1" />
<PackageReference Include="Xamarin.AndroidX.Legacy.Support.V4" Version="1.0.0.15" />
<PackageReference Include="Xamarin.AndroidX.AutoFill" Version="1.1.0.16" />
<PackageReference Include="Xamarin.AndroidX.CardView" Version="1.0.0.19" />
<PackageReference Include="Xamarin.AndroidX.Core" Version="1.10.0" />
<PackageReference Include="Xamarin.AndroidX.MediaRouter" Version="1.3.1.1" />
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.3</Version>
<Version>1.7.5</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>123.0.8</Version>
<Version>123.1.1.1</Version>
</PackageReference>
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.6.1.1" />
<PackageReference Include="Xamarin.Google.Dagger" Version="2.41.0.2" />
<PackageReference Include="Xamarin.Google.Android.Material" Version="1.8.0" />
<PackageReference Include="Xamarin.Google.Dagger" Version="2.44.2.1" />
<PackageReference Include="Xamarin.GooglePlayServices.SafetyNet">
<Version>118.0.1.2</Version>
<Version>118.0.1.3</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

View File

@@ -14,11 +14,11 @@
<ItemGroup>
<PackageReference Include="Plugin.Fingerprint" Version="2.1.5" />
<PackageReference Include="SkiaSharp.Views.Forms" Version="2.88.2" />
<PackageReference Include="Xamarin.CommunityToolkit" Version="2.0.5" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.3" />
<PackageReference Include="SkiaSharp.Views.Forms" Version="2.88.3" />
<PackageReference Include="Xamarin.CommunityToolkit" Version="2.0.6" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.5" />
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.11.982" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2515" />
<PackageReference Include="Xamarin.Forms" Version="5.0.0.2578" />
<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" />

View File

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

View File

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

View File

@@ -25,10 +25,6 @@
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Account}" />
<ToolbarItem x:Name="_closeButton" Text="{u:I18n Close}" Command="{Binding CloseCommand}" Order="Primary" Priority="-1"/>
<ToolbarItem
Icon="cog_environment.png" Clicked="Environment_Clicked" Order="Primary"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}" />
</ContentPage.ToolbarItems>
<ContentPage.Resources>
@@ -66,7 +62,27 @@
</Entry>
<StackLayout
Orientation="Horizontal"
Margin="0, 16, 0 ,0">
Margin="0, 6, 0 ,0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ShowEnvironmentPickerCommand}" />
</StackLayout.GestureRecognizers>
<Label
Text="{Binding RegionText}"
FontSize="13"
TextColor="{DynamicResource MutedColor}"
VerticalOptions="Center"
VerticalTextAlignment="Center"/>
<controls:IconLabel
Text="{Binding SelectedEnvironmentName}"
FontSize="13"
TextColor="{DynamicResource PrimaryColor}"
VerticalOptions="Center"
VerticalTextAlignment="Center"/>
</StackLayout>
<StackLayout
Orientation="Horizontal"
Margin="0, 20, 0 ,0">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding RememberEmailCommand}" />

View File

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

View File

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

View File

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

View File

@@ -121,9 +121,8 @@ namespace Bit.App.Pages
var ssoToken = response.Token;
var passwordOptions = new PasswordGenerationOptions(true);
passwordOptions.Length = 64;
var passwordOptions = PasswordGenerationOptions.CreateDefault
.WithLength(64);
var codeVerifier = await _passwordGenerationService.GeneratePasswordAsync(passwordOptions);
var codeVerifierHash = await _cryptoFunctionService.HashAsync(codeVerifier, CryptoHashAlgorithm.Sha256);

View File

@@ -827,7 +827,7 @@ namespace Bit.App.Pages
private void SetOptions()
{
_options.AllowAmbiguousChar = AllowAmbiguousChars;
_options.Type = PasswordTypeSelectedIndex == 1 ? "passphrase" : "password";
_options.Type = PasswordTypeSelectedIndex == 1 ? PasswordGenerationOptions.TYPE_PASSPHRASE : PasswordGenerationOptions.TYPE_PASSWORD;
_options.MinNumber = MinNumber;
_options.MinSpecial = MinSpecial;
_options.Special = Special;

View File

@@ -131,7 +131,7 @@ namespace Bit.App.Pages
{
// if we have a vault timeout policy, we need to filter the timeout options
_vaultTimeoutPolicy = (await _policyService.GetAll(PolicyType.MaximumVaultTimeout)).First();
var policyMinutes = _policyService.GetPolicyInt(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_MINUTES);
var policyMinutes = _vaultTimeoutPolicy.GetInt(Policy.MINUTES_KEY);
_vaultTimeoutOptions = _vaultTimeoutOptions.Where(t =>
t.Value <= policyMinutes &&
(t.Value > 0 || t.Value == CustomVaultTimeoutValue) &&
@@ -302,7 +302,7 @@ namespace Bit.App.Pages
if (_vaultTimeoutPolicy != null)
{
var maximumTimeout = _policyService.GetPolicyInt(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_MINUTES);
var maximumTimeout = _vaultTimeoutPolicy.GetInt(Policy.MINUTES_KEY);
if (newTimeout > maximumTimeout)
{
@@ -382,7 +382,7 @@ namespace Bit.App.Pages
public async Task VaultTimeoutActionAsync()
{
if (_vaultTimeoutPolicy != null &&
!string.IsNullOrEmpty(_policyService.GetPolicyString(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_ACTION)))
!string.IsNullOrEmpty(_vaultTimeoutPolicy.GetString(Policy.ACTION_KEY)))
{
// do nothing if we have a policy set
return;
@@ -610,8 +610,8 @@ namespace Bit.App.Pages
}
if (_vaultTimeoutPolicy != null)
{
var policyMinutes = _policyService.GetPolicyInt(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_MINUTES);
var policyAction = _policyService.GetPolicyString(_vaultTimeoutPolicy, PolicyService.TIMEOUT_POLICY_ACTION);
var policyMinutes = _vaultTimeoutPolicy.GetInt(Policy.MINUTES_KEY);
var policyAction = _vaultTimeoutPolicy.GetString(Policy.ACTION_KEY);
if (policyMinutes.HasValue || !string.IsNullOrWhiteSpace(policyAction))
{
@@ -625,14 +625,14 @@ namespace Bit.App.Pages
else if (!policyMinutes.HasValue && !string.IsNullOrWhiteSpace(policyAction))
{
policyAlert = string.Format(AppResources.VaultTimeoutActionPolicyInEffect,
policyAction == PolicyService.TIMEOUT_POLICY_ACTION_LOCK ? AppResources.Lock : AppResources.LogOut);
policyAction == Policy.ACTION_LOCK ? AppResources.Lock : AppResources.LogOut);
}
else
{
policyAlert = string.Format(AppResources.VaultTimeoutPolicyWithActionInEffect,
Math.Floor((float)policyMinutes / 60),
policyMinutes % 60,
policyAction == PolicyService.TIMEOUT_POLICY_ACTION_LOCK ? AppResources.Lock : AppResources.LogOut);
policyAction == Policy.ACTION_LOCK ? AppResources.Lock : AppResources.LogOut);
}
securityItems.Insert(0, new SettingsPageListItem
{

View File

@@ -1750,6 +1750,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Data region.
/// </summary>
public static string DataRegion {
get {
return ResourceManager.GetString("DataRegion", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Password updated.
/// </summary>
@@ -2326,6 +2335,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to EU.
/// </summary>
public static string EU {
get {
return ResourceManager.GetString("EU", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Exact.
/// </summary>
@@ -3569,11 +3587,11 @@ namespace Bit.App.Resources {
}
/// <summary>
/// Looks up a localized string similar to Logging in as {0}.
/// Looks up a localized string similar to Logging in as {0} on {1}.
/// </summary>
public static string LoggingInAsX {
public static string LoggingInAsXOnY {
get {
return ResourceManager.GetString("LoggingInAsX", resourceCulture);
return ResourceManager.GetString("LoggingInAsXOnY", resourceCulture);
}
}
@@ -5129,6 +5147,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Region.
/// </summary>
public static string Region {
get {
return ResourceManager.GetString("Region", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Remember me.
/// </summary>
@@ -5462,6 +5489,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Self-hosted.
/// </summary>
public static string SelfHosted {
get {
return ResourceManager.GetString("SelfHosted", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Self-hosted environment.
/// </summary>
@@ -6524,6 +6560,15 @@ namespace Bit.App.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to US.
/// </summary>
public static string US {
get {
return ResourceManager.GetString("US", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Use another two-step login method.
/// </summary>

View File

@@ -160,7 +160,7 @@
<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">
<value>Credits</value>
<value>কৃতিত্ব</value>
<comment>Title for page that we use to give credit to resources that we use.</comment>
</data>
<data name="Delete" xml:space="preserve">
@@ -168,11 +168,11 @@
<comment>Delete an entity (verb).</comment>
</data>
<data name="Deleting" xml:space="preserve">
<value>Deleting...</value>
<value>মোছা হচ্ছে...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="DoYouReallyWantToDelete" xml:space="preserve">
<value>Do you really want to delete? This cannot be undone.</value>
<value>আপনি কি সত্যিই মুছে ফেলতে চান? এটিকে পূর্বের মত করা যাবে না।.</value>
<comment>Confirmation alert message when deleteing something.</comment>
</data>
<data name="Edit" xml:space="preserve">
@@ -190,16 +190,16 @@
<comment>Full label for a email address.</comment>
</data>
<data name="EmailUs" xml:space="preserve">
<value>Email us</value>
<value>আমাদের ইমেইল করুন</value>
</data>
<data name="EmailUsDescription" xml:space="preserve">
<value>Email us directly to get help or leave feedback.</value>
<value>সাহায্য পেতে বা মতামত দিতে সরাসরি আমাদের ইমেল করুন।</value>
</data>
<data name="EnterPIN" xml:space="preserve">
<value>Enter your PIN code.</value>
<value>আপনার পিন কোডটি প্রবেশ করান</value>
</data>
<data name="Favorites" xml:space="preserve">
<value>Favorites</value>
<value>পছন্দসমূহ</value>
<comment>Title for your favorite items in the vault.</comment>
</data>
<data name="FileBugReport" xml:space="preserve">
@@ -216,7 +216,7 @@
<comment>Label for a folder.</comment>
</data>
<data name="FolderCreated" xml:space="preserve">
<value>New folder created.</value>
<value>নতুন ফোল্ডার তৈরি হয়েছে।</value>
</data>
<data name="FolderDeleted" xml:space="preserve">
<value>Folder deleted.</value>
@@ -276,7 +276,7 @@
<value>আপনি লগ আউট করতে চান?</value>
</data>
<data name="RemoveAccount" xml:space="preserve">
<value>Remove account</value>
<value>অ্যাকাউন্ট অপসারণ করুন</value>
</data>
<data name="RemoveAccountConfirmation" xml:space="preserve">
<value>Are you sure you want to remove this account?</value>
@@ -315,30 +315,30 @@
<comment>Label for notes.</comment>
</data>
<data name="Ok" xml:space="preserve">
<value>Ok</value>
<value>ঠিক আছে</value>
<comment>Acknowledgement.</comment>
</data>
<data name="Password" xml:space="preserve">
<value>Password</value>
<value>পাসওয়ার্ড</value>
<comment>Label for a password.</comment>
</data>
<data name="Save" xml:space="preserve">
<value>Save</value>
<value>সংরক্ষণ করুন</value>
<comment>Button text for a save operation (verb).</comment>
</data>
<data name="Move" xml:space="preserve">
<value>Move</value>
<value>স্থানান্তর করুন</value>
</data>
<data name="Saving" xml:space="preserve">
<value>Saving...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="Settings" xml:space="preserve">
<value>Settings</value>
<value>সেটিংস</value>
<comment>The title for the settings page.</comment>
</data>
<data name="Show" xml:space="preserve">
<value>Show</value>
<value>দেখান</value>
<comment>Reveal a hidden value (password).</comment>
</data>
<data name="ItemDeleted" xml:space="preserve">
@@ -346,17 +346,17 @@
<comment>Confirmation message after successfully deleting a login.</comment>
</data>
<data name="Submit" xml:space="preserve">
<value>Submit</value>
<value>জমা দিন</value>
</data>
<data name="Sync" xml:space="preserve">
<value>Sync</value>
<comment>The title for the sync page.</comment>
</data>
<data name="ThankYou" xml:space="preserve">
<value>Thank you</value>
<value>ধন্যবাদ</value>
</data>
<data name="Tools" xml:space="preserve">
<value>Tools</value>
<value>টুলস</value>
<comment>The title for the tools page.</comment>
</data>
<data name="URI" xml:space="preserve">
@@ -379,7 +379,7 @@
<comment>Confirmation message after successfully copying a value to the clipboard.</comment>
</data>
<data name="VerifyFingerprint" xml:space="preserve">
<value>Verify fingerprint</value>
<value>আঙ্গুলের ছাপ যাচাই করুন</value>
</data>
<data name="VerifyMasterPassword" xml:space="preserve">
<value>প্রধান পাসওয়ার্ড যাচাইকরণ</value>
@@ -388,32 +388,32 @@
<value>Verify PIN</value>
</data>
<data name="Version" xml:space="preserve">
<value>Version</value>
<value>সংস্করণ</value>
</data>
<data name="View" xml:space="preserve">
<value>View</value>
</data>
<data name="VisitOurWebsite" xml:space="preserve">
<value>Visit our website</value>
<value>আমাদের ওয়েবসাইটে ঢু মেরে আসুন</value>
</data>
<data name="VisitOurWebsiteDescription" xml:space="preserve">
<value>Visit our website to get help, news, email us, and/or learn more about how to use Bitwarden.</value>
<value>সাহায্য পেতে, খবর পেতে, আমাদের ইমেল করতে এবং/অথবা বিটওয়ার্ডেন কীভাবে ব্যবহার করবেন সে সম্পর্কে আরও জানতে আমাদের ওয়েবসাইট দেখুন।</value>
</data>
<data name="Website" xml:space="preserve">
<value>Website</value>
<value>ওয়েবসাইট</value>
<comment>Label for a website.</comment>
</data>
<data name="Yes" xml:space="preserve">
<value>Yes</value>
<value>হ্যাঁ</value>
</data>
<data name="Account" xml:space="preserve">
<value>Account</value>
<value>অ্যাকাউন্ট</value>
</data>
<data name="AccountCreated" xml:space="preserve">
<value>Your new account has been created! You may now log in.</value>
<value>আপনার নতুন অ্যাকাউন্ট তৈরি করা হয়েছে! আপনি এখন লগইন করতে পারবেন।</value>
</data>
<data name="AddAnItem" xml:space="preserve">
<value>Add an Item</value>
<value>একটি আইটেম যোগ করুন</value>
</data>
<data name="AppExtension" xml:space="preserve">
<value>App extension</value>
@@ -425,7 +425,7 @@
<value>Auto-fill service</value>
</data>
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
<value>Avoid ambiguous characters</value>
<value>অস্পষ্ট বর্ণগুলি বাদ দিয়ে যান</value>
</data>
<data name="BitwardenAppExtension" xml:space="preserve">
<value>Bitwarden app extension</value>
@@ -440,13 +440,13 @@
<value>Bitwarden Auto-fill Service</value>
</data>
<data name="BitwardenAutofillAccessibilityServiceDescription" xml:space="preserve">
<value>Use the Bitwarden accessibility service to auto-fill your logins.</value>
<value>আপনার লগইনগুলি স্বয়ংক্রিয়ভাবে পূরণ করতে বিটওয়ার্ডেন অ্যাক্সেসিবিলিটি পরিষেবা ব্যবহার করুন৷</value>
</data>
<data name="ChangeEmail" xml:space="preserve">
<value>Change email</value>
<value>ইমেইল পরিবর্তন করুন</value>
</data>
<data name="ChangeEmailConfirmation" xml:space="preserve">
<value>You can change your email address on the bitwarden.com web vault. Do you want to visit the website now?</value>
<value>আপনি bitwarden.com ওয়েব ভল্টে আপনার ইমেল ঠিকানা পরিবর্তন করতে পারেন। আপনি কি এখনই ওয়েবসাইট ভিজিট করতে চান?</value>
</data>
<data name="ChangeMasterPassword" xml:space="preserve">
<value>প্রধান পাসওয়ার্ড পরিবর্তন</value>
@@ -455,7 +455,7 @@
<value>আপনি bitwarden.com ওয়েব ভল্ট থেকে প্রধান পাসওয়ার্ডটি পরিবর্তন করতে পারেন। আপনি কি এখনই ওয়েবসাইটটি দেখতে চান?</value>
</data>
<data name="Close" xml:space="preserve">
<value>Close</value>
<value>বন্ধ করুন</value>
</data>
<data name="Continue" xml:space="preserve">
<value>অবিরত</value>
@@ -480,7 +480,7 @@
<value>Reactivate app extension</value>
</data>
<data name="ExtensionAlmostDone" xml:space="preserve">
<value>Almost done!</value>
<value>প্রায় হয়ে গেছে!</value>
</data>
<data name="ExtensionEnable" xml:space="preserve">
<value>Activate app extension</value>
@@ -493,7 +493,7 @@
<value>Get instant access to your passwords!</value>
</data>
<data name="ExtensionReady" xml:space="preserve">
<value>You're ready to log in!</value>
<value>আপনি লগইন করার জন্য একদম তৈরি!</value>
</data>
<data name="ExtensionSetup" xml:space="preserve">
<value>Your logins are now easily accessible from Safari, Chrome, and other supported apps.</value>
@@ -511,7 +511,7 @@
<value>প্রিয়</value>
</data>
<data name="Fingerprint" xml:space="preserve">
<value>Fingerprint</value>
<value>আঙুলের ছাপ</value>
</data>
<data name="GeneratePassword" xml:space="preserve">
<value>পাসওয়ার্ড তৈরি করুন</value>
@@ -584,7 +584,7 @@
<value>যদি আপনি আপনার পাসওয়ার্ড ভুলে যান তাহলে একটি প্রধান পাসওয়ার্ডের ইঙ্গিতটি আপনাকে মনে করাতে সাহায্য করতে পারে।</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<value>মাস্টার পাসওয়ার্ড কমপক্ষে {0} অক্ষরের হতে হবে।</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>সর্বনিম্ন সংখ্যা</value>
@@ -595,7 +595,7 @@
<comment>Minimum special characters for password generator settings</comment>
</data>
<data name="MoreSettings" xml:space="preserve">
<value>More settings</value>
<value>আরও সেটিংস</value>
</data>
<data name="MustLogInMainApp" xml:space="preserve">
<value>You must log into the main Bitwarden app before you can use the extension.</value>
@@ -651,7 +651,7 @@
<comment>Push notifications for apple products</comment>
</data>
<data name="RateTheApp" xml:space="preserve">
<value>Rate the app</value>
<value>অ্যাপ্লিকেশনটকে রেট দিন</value>
</data>
<data name="RateTheAppDescription" xml:space="preserve">
<value>দয়া করে একটি ভাল পর্যালোচনার মাধ্যমে সাহায্য করতে আমাদের বিবেচনা করুন!</value>
@@ -684,7 +684,7 @@
<value>Item saved</value>
</data>
<data name="Submitting" xml:space="preserve">
<value>Submitting...</value>
<value>জমা দেওয়া হচ্ছে...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="Syncing" xml:space="preserve">
@@ -701,7 +701,7 @@
<value>Sync vault now</value>
</data>
<data name="TouchID" xml:space="preserve">
<value>Touch ID</value>
<value>টাচ আইডি</value>
<comment>What Apple calls their fingerprint reader.</comment>
</data>
<data name="TwoStepLogin" xml:space="preserve">
@@ -717,17 +717,17 @@
<value>Unlock with PIN code</value>
</data>
<data name="Validating" xml:space="preserve">
<value>Validating</value>
<value>কার্যকর করা হচ্ছে</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="VerificationCode" xml:space="preserve">
<value>Verification code</value>
<value>যাচাইকরণ কোড</value>
</data>
<data name="ViewItem" xml:space="preserve">
<value>View item</value>
</data>
<data name="WebVault" xml:space="preserve">
<value>Bitwarden web vault</value>
<value>বিটওয়ার্ডেন ওয়েব ভল্ট</value>
</data>
<data name="Lost2FAApp" xml:space="preserve">
<value>Lost authenticator app?</value>
@@ -740,10 +740,10 @@
<value>Extension activated!</value>
</data>
<data name="Icons" xml:space="preserve">
<value>Icons</value>
<value>আইকন</value>
</data>
<data name="Translations" xml:space="preserve">
<value>Translations</value>
<value>অনুবাদসমূহ</value>
</data>
<data name="ItemsForUri" xml:space="preserve">
<value>Items for {0}</value>
@@ -769,19 +769,19 @@
<value>2. Switch on the toggle and press OK to accept.</value>
</data>
<data name="Disabled" xml:space="preserve">
<value>Disabled</value>
<value>নিষ্ক্রিয়</value>
</data>
<data name="Enabled" xml:space="preserve">
<value>Enabled</value>
<value>সক্রিয়</value>
</data>
<data name="Off" xml:space="preserve">
<value>Off</value>
<value>বন্ধ</value>
</data>
<data name="On" xml:space="preserve">
<value>On</value>
<value>চালু</value>
</data>
<data name="Status" xml:space="preserve">
<value>Status</value>
<value>অবস্থা</value>
</data>
<data name="BitwardenAutofillServiceAlert2" xml:space="preserve">
<value>The easiest way to add new logins to your vault is from the Bitwarden Auto-fill Service. Learn more about using the Bitwarden Auto-fill Service by navigating to the "Settings" screen.</value>
@@ -876,7 +876,7 @@
<value>Unable to download file.</value>
</data>
<data name="UnableToOpenFile" xml:space="preserve">
<value>Your device cannot open this type of file.</value>
<value>আপনার ডিভাইস এই ধরনের ফাইল খুলতে পারে না।</value>
</data>
<data name="Downloading" xml:space="preserve">
<value>ডাউনলোড হচ্ছে...</value>
@@ -904,13 +904,13 @@
Scanning will happen automatically.</value>
</data>
<data name="ScanQrTitle" xml:space="preserve">
<value>Scan QR Code</value>
<value>QR কোড স্ক্যান করুন</value>
</data>
<data name="Camera" xml:space="preserve">
<value>Camera</value>
<value>ক্যামেরা</value>
</data>
<data name="Photos" xml:space="preserve">
<value>Photos</value>
<value>ছবিসমূহ</value>
</data>
<data name="CopyTotp" xml:space="preserve">
<value>Copy TOTP</value>
@@ -934,7 +934,7 @@ Scanning will happen automatically.</value>
<value>Choose file</value>
</data>
<data name="File" xml:space="preserve">
<value>File</value>
<value>ফাইল</value>
</data>
<data name="NoFileChosen" xml:space="preserve">
<value>No file chosen</value>
@@ -1080,7 +1080,7 @@ Scanning will happen automatically.</value>
<value>নামের শেষাংশ</value>
</data>
<data name="FullName" xml:space="preserve">
<value>Full name</value>
<value>পুরো নাম</value>
</data>
<data name="LicenseNumber" xml:space="preserve">
<value>লাইসেন্স নম্বর</value>
@@ -1107,34 +1107,34 @@ Scanning will happen automatically.</value>
<value>Mx</value>
</data>
<data name="November" xml:space="preserve">
<value>November</value>
<value>নভেম্বর</value>
</data>
<data name="October" xml:space="preserve">
<value>October</value>
<value>অক্টোবর</value>
</data>
<data name="PassportNumber" xml:space="preserve">
<value>Passport number</value>
<value>পাসপোর্ট নম্বর</value>
</data>
<data name="Phone" xml:space="preserve">
<value>Phone</value>
<value>ফোন</value>
</data>
<data name="September" xml:space="preserve">
<value>September</value>
<value>সেপ্টেম্বর</value>
</data>
<data name="SSN" xml:space="preserve">
<value>Social Security number</value>
<value>সামাজিক সুরক্ষা নম্বর</value>
</data>
<data name="StateProvince" xml:space="preserve">
<value>State / Province</value>
<value>রাজ্য / প্রদেশ</value>
</data>
<data name="Title" xml:space="preserve">
<value>Title</value>
<value>শিরোনাম</value>
</data>
<data name="ZipPostalCode" xml:space="preserve">
<value>Zip / Postal code</value>
<value>জিপ / পোস্টকোড</value>
</data>
<data name="Address" xml:space="preserve">
<value>Address</value>
<value>ঠিকানা</value>
</data>
<data name="Expiration" xml:space="preserve">
<value>Expiration</value>
@@ -1204,7 +1204,7 @@ Scanning will happen automatically.</value>
<value>Custom field name</value>
</data>
<data name="FieldTypeBoolean" xml:space="preserve">
<value>Boolean</value>
<value>বুলিয়ান</value>
</data>
<data name="FieldTypeHidden" xml:space="preserve">
<value>Hidden</value>
@@ -1225,7 +1225,7 @@ Scanning will happen automatically.</value>
<value>Remove</value>
</data>
<data name="NewUri" xml:space="preserve">
<value>New URI</value>
<value>নতুন URI</value>
</data>
<data name="URIPosition" xml:space="preserve">
<value>URI {0}</value>
@@ -1272,7 +1272,7 @@ Scanning will happen automatically.</value>
<value>Hold your Yubikey near the top of the device.</value>
</data>
<data name="TryAgain" xml:space="preserve">
<value>Try again</value>
<value>আবার চেষ্টা করুন</value>
</data>
<data name="YubiKeyInstructionIos" xml:space="preserve">
<value>To continue, hold your YubiKey NEO against the back of the device.</value>
@@ -1440,16 +1440,16 @@ Scanning will happen automatically.</value>
<value>Choose an organization that you wish to move this item to. Moving to an organization transfers ownership of the item to that organization. You will no longer be the direct owner of this item once it has been moved.</value>
</data>
<data name="NumberOfWords" xml:space="preserve">
<value>Number of words</value>
<value>শব্দসংখ্যা</value>
</data>
<data name="Passphrase" xml:space="preserve">
<value>Passphrase</value>
<value>গুপ্ত-বাক্যাংশ</value>
</data>
<data name="WordSeparator" xml:space="preserve">
<value>Word separator</value>
<value>শব্দ বিভাজক</value>
</data>
<data name="Clear" xml:space="preserve">
<value>Clear</value>
<value>পরিষ্কার করুন</value>
<comment>To clear something out. example: To clear browser history.</comment>
</data>
<data name="Generator" xml:space="preserve">
@@ -1474,42 +1474,42 @@ Scanning will happen automatically.</value>
<value>Export vault</value>
</data>
<data name="LockNow" xml:space="preserve">
<value>Lock now</value>
<value>এখনই লক করুন</value>
</data>
<data name="PIN" xml:space="preserve">
<value>PIN</value>
<value>পিন</value>
</data>
<data name="Unlock" xml:space="preserve">
<value>Unlock</value>
<value>আনলক করুন</value>
</data>
<data name="UnlockVault" xml:space="preserve">
<value>Unlock vault</value>
</data>
<data name="ThirtyMinutes" xml:space="preserve">
<value>30 minutes</value>
<value>৩০ মিনিট</value>
</data>
<data name="SetPINDescription" xml:space="preserve">
<value>Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if you ever fully log out of the application.</value>
<value>Bitwarden আনলক করার জন্য আপনার পিন কোডটি সেট করুন। আপনি যদি অ্যাপ্লিকেশনটি থেকে পুরোপুরি লগ আউট করেন তবে আপনার পিন সেটিংস রিসেট করা হবে।</value>
</data>
<data name="LoggedInAsOn" xml:space="preserve">
<value>Logged in as {0} on {1}.</value>
<value>{1}-এ {0} হিসেবে লগইন করা হয়েছে।</value>
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
</data>
<data name="VaultLockedMasterPassword" xml:space="preserve">
<value>আপনার ভল্ট লক করা আছে। চালিয়ে যেতে আপনার প্রধান পাসওয়ার্ডটি যাচাই করান।</value>
</data>
<data name="VaultLockedPIN" xml:space="preserve">
<value>Your vault is locked. Verify your PIN code to continue.</value>
<value>আপনার ভল্ট লক করা আছে। চালিয়ে যেতে আপনার পিন কোড যাচাই করান।</value>
</data>
<data name="VaultLockedIdentity" xml:space="preserve">
<value>Your vault is locked. Verify your identity to continue.</value>
<value>আপনার ভল্ট লক করা আছে। চালিয়ে যেতে আপনার পরিচয় যাচাই করান।</value>
</data>
<data name="Dark" xml:space="preserve">
<value>Dark</value>
<value>গাঢ়</value>
<comment>A dark color</comment>
</data>
<data name="Light" xml:space="preserve">
<value>Light</value>
<value>উজ্জ্বল</value>
<comment>A light color</comment>
</data>
<data name="FiveMinutes" xml:space="preserve">
@@ -1887,10 +1887,10 @@ Scanning will happen automatically.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="Text" xml:space="preserve">
<value>Text</value>
<value>লেখা</value>
</data>
<data name="TypeText" xml:space="preserve">
<value>Text</value>
<value>লেখা</value>
</data>
<data name="TypeTextInfo" xml:space="preserve">
<value>The text you want to send.</value>
@@ -1900,7 +1900,7 @@ Scanning will happen automatically.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="TypeFile" xml:space="preserve">
<value>File</value>
<value>ফাইল</value>
</data>
<data name="TypeFileInfo" xml:space="preserve">
<value>The file you want to send.</value>
@@ -1918,7 +1918,7 @@ Scanning will happen automatically.</value>
<value>Text type is not selected, tap to select.</value>
</data>
<data name="DeletionDate" xml:space="preserve">
<value>Deletion date</value>
<value>মুছে ফেলার তারিখ</value>
</data>
<data name="DeletionTime" xml:space="preserve">
<value>Deletion time</value>
@@ -1957,7 +1957,7 @@ Scanning will happen automatically.</value>
<value>Current access count</value>
</data>
<data name="NewPassword" xml:space="preserve">
<value>New password</value>
<value>নতুন পাসওয়ার্ড</value>
</data>
<data name="PasswordInfo" xml:space="preserve">
<value>Optionally require a password for users to access this Send.</value>
@@ -2030,19 +2030,19 @@ Scanning will happen automatically.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="OneDay" xml:space="preserve">
<value>1 day</value>
<value>১ দিন</value>
</data>
<data name="TwoDays" xml:space="preserve">
<value>2 days</value>
<value>২ দিন</value>
</data>
<data name="ThreeDays" xml:space="preserve">
<value>3 days</value>
</data>
<data name="SevenDays" xml:space="preserve">
<value>7 days</value>
<value> দিন</value>
</data>
<data name="ThirtyDays" xml:space="preserve">
<value>30 days</value>
<value>৩০ দিন</value>
</data>
<data name="Custom" xml:space="preserve">
<value>Custom</value>
@@ -2240,16 +2240,16 @@ Scanning will happen automatically.</value>
<value>Options are collapsed, tap to expand.</value>
</data>
<data name="UppercaseAtoZ" xml:space="preserve">
<value>Uppercase (A to Z)</value>
<value>বড় হাতের অক্ষর (A-Z)</value>
</data>
<data name="LowercaseAtoZ" xml:space="preserve">
<value>Lowercase (A to Z)</value>
</data>
<data name="NumbersZeroToNine" xml:space="preserve">
<value>Numbers (0 to 9)</value>
<value>সংখ্যা (0-9)</value>
</data>
<data name="SpecialCharacters" xml:space="preserve">
<value>Special characters (!@#$%^&amp;*)</value>
<value>বিশেষ অক্ষর (!@#$%^&amp;*)</value>
</data>
<data name="TapToGoBack" xml:space="preserve">
<value>Tap to go back</value>
@@ -2352,10 +2352,10 @@ select Add TOTP to store the key safely</value>
<value>Deny login</value>
</data>
<data name="JustNow" xml:space="preserve">
<value>Just now</value>
<value>এইমাত্র</value>
</data>
<data name="XMinutesAgo" xml:space="preserve">
<value>{0} minutes ago</value>
<value>{0} মিনিট আগে</value>
</data>
<data name="LogInAccepted" xml:space="preserve">
<value>Login confirmed</value>
@@ -2548,7 +2548,7 @@ Do you want to switch to this account?</value>
<value>Enable camera permission to use the scanner</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
<value>ভাষা</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>
@@ -2575,10 +2575,10 @@ Do you want to switch to this account?</value>
<value>Weak</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
<value>ভালো</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
<value>শক্তিশালী</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>

View File

@@ -1753,7 +1753,7 @@ Das Scannen erfolgt automatisch.</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometrie zum Entsperren ist für dieses Konto deaktiviert, bis das Master-Passwort verifiziert wurde.</value>
<value>Das Entsperren über Biometrie ist für dieses Konto deaktiviert, bis das Master-Passwort verifiziert wurde.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Das Entsperren von Auto-Ausfüllen über Biometrie ist für dieses Konto deaktiviert, bis das Master-Passwort verifiziert wurde.</value>

View File

@@ -1753,10 +1753,10 @@
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Το βιομετρικό ξεκλείδωμα για αυτόν τον λογαριασμό είναι απενεργοποιημένο εν αναμονή της επαλήθευσης του κύριου κωδικού πρόσβασης.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Το βιομετρικό ξεκλείδωμα αυτόματης συμπλήρωσης για αυτό το λογαριασμό είναι απενεργοποιημένο εν αναμονή της επαλήθευσης του κύριου κωδικού πρόσβασης.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Ενεργοποίηση συγχρονισμού κατά την ανανέωση</value>
@@ -2143,10 +2143,10 @@
<value>Οι πολιτικές του οργανισμού σας επηρεάζουν το χρονικό όριο vault σας. Το μέγιστο επιτρεπόμενο Χρονικό όριο Vault είναι {0} ώρα(ες) και {1} λεπτό(ά)</value>
</data>
<data name="VaultTimeoutPolicyWithActionInEffect" xml:space="preserve">
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s). Your vault timeout action is set to {2}.</value>
<value>Οι πολιτικές του οργανισμού σας επηρεάζουν το χρονικό όριο του vault σας. Το μέγιστο επιτρεπόμενο χρονικό όριο vault είναι {0} ώρα(ες) και {1} λεπτό(ά). Το χρονικό όριο του vault σας έχει οριστεί σε {2}.</value>
</data>
<data name="VaultTimeoutActionPolicyInEffect" xml:space="preserve">
<value>Your organization policies have set your vault timeout action to {0}.</value>
<value>Οι πολιτικές του οργανισμού σας έχουν ορίσει την ενέργεια χρονικού ορίου vault σε {0}.</value>
</data>
<data name="VaultTimeoutToLarge" xml:space="preserve">
<value>Το χρονικό όριο του vault σας υπερβαίνει τους περιορισμούς που έχει ορίσει ο οργανισμός σας.</value>
@@ -2610,9 +2610,9 @@
<value>Δεν υπάρχουν στοιχεία που να ταιριάζουν με την αναζήτηση</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
<value>Ο κύριος κωδικός πρόσβασής σας δεν πληροί μία ή περισσότερες πολιτικές του οργανισμού σας. Για να αποκτήσετε πρόσβαση στο Vault σας, πρέπει να ενημερώσετε τον κύριο κωδικό πρόσβασής σας τώρα. Η διαδικασία θα σας αποσυνδέσει από την τρέχουσα συνεδρία σας, απαιτώντας από εσάς να συνδεθείτε ξανά. Οι ενεργές συνεδρίες σε άλλες συσκευές ενδέχεται να συνεχίσουν να είναι ενεργές εώς και μία ώρα.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
<value>Τρέχων κύριος κωδικός</value>
</data>
</root>

View File

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

View File

@@ -1753,10 +1753,10 @@ Koodi luetaan automaattisesti.</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Biometrinen avaus on poistettu käytöstä tältä tililtä, kunnes pääsalasana on vahvistettu.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Automaattisen täytön biometrinen avaus on poistettu käytöstä tältä tililtä, kunnes pääsalasana on vahvistettu.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Synkronoi holvi päivityksen yhteydessä</value>
@@ -2602,7 +2602,7 @@ Haluatko vaihtaa tähän tiliin?</value>
<value>Lisää avain olemassa olevaan tai uuteen kohteeseen</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>Holvissasi ei ole kohteita osoitteelle "{0}"</value>
<value>Holvissasi ei ole kohdetta "{0}" vastavia tietoja</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Etsi kohdetta tai lisää uusi kohde</value>

View File

@@ -1753,10 +1753,10 @@ La numérisation se fera automatiquement.</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Le déverrouillage biométrique pour ce compte est désactivé en attente de vérification du mot de passe maître.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Le déverrouillage biométrique de saisie automatique pour ce compte est désactivé en attente de vérification du mot de passe maître.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Autoriser la synchronisation au rafraîchissement</value>

View File

@@ -118,14 +118,14 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="About" xml:space="preserve">
<value>बारे में</value>
<value>हमारे बारे में</value>
</data>
<data name="Add" xml:space="preserve">
<value>जोड़ें</value>
<comment>Add/create a new entity (verb).</comment>
</data>
<data name="AddFolder" xml:space="preserve">
<value>नया फोल्डर जोड़ें</value>
<value>फोल्डर जोड़ें</value>
</data>
<data name="AddItem" xml:space="preserve">
<value>चीज़ जोड़ें</value>
@@ -136,11 +136,11 @@
<comment>Alert title when something goes wrong.</comment>
</data>
<data name="Back" xml:space="preserve">
<value>वापस जाएं</value>
<value>पीछे जाएं</value>
<comment>Navigate back to the previous screen.</comment>
</data>
<data name="Bitwarden" xml:space="preserve">
<value>bitwarden</value>
<value>बिटवार्डन</value>
<comment>App name. Shouldn't ever change.</comment>
</data>
<data name="Cancel" xml:space="preserve">
@@ -156,105 +156,105 @@
<comment>The button text that allows a user to copy the login's password to their clipboard.</comment>
</data>
<data name="CopyUsername" xml:space="preserve">
<value>उपयोगकर्ता नाम की प्रतिलिपि बनाएँ</value>
<value>यूज़रनाम कॉपी करें</value>
<comment>The button text that allows a user to copy the login's username to their clipboard.</comment>
</data>
<data name="Credits" xml:space="preserve">
<value>क्रेडिट्स</value>
<value>क्रेडिट</value>
<comment>Title for page that we use to give credit to resources that we use.</comment>
</data>
<data name="Delete" xml:space="preserve">
<value>मिटाए</value>
<value>मिटाए</value>
<comment>Delete an entity (verb).</comment>
</data>
<data name="Deleting" xml:space="preserve">
<value>मिटाया जा रहा हैं</value>
<value>मिटाया जा रहा हैं...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="DoYouReallyWantToDelete" xml:space="preserve">
<value>क्आप वास्तव में हटाना चाहते हैं? इसे नष्ट नहीं किया जा सकता है</value>
<value>क्मिटाएं? इसे अंडू नहीं किया जा सकता</value>
<comment>Confirmation alert message when deleteing something.</comment>
</data>
<data name="Edit" xml:space="preserve">
<value>संशोधन करें</value>
<value>बदलाव करें</value>
</data>
<data name="EditFolder" xml:space="preserve">
<value>फोल्डर संपादित करें</value>
<value>फोल्डर बदलाव करें</value>
</data>
<data name="Email" xml:space="preserve">
<value>ईमेल</value>
<comment>Short label for an email address.</comment>
</data>
<data name="EmailAddress" xml:space="preserve">
<value>ई-मेल पता</value>
<value>ईमेल पता</value>
<comment>Full label for a email address.</comment>
</data>
<data name="EmailUs" xml:space="preserve">
<value>हमें ईमेल करें</value>
</data>
<data name="EmailUsDescription" xml:space="preserve">
<value>सहायता प्राप्त करने या प्रतिक्रिया छोड़ने के लिए हमें ईमेल करें।</value>
<value>मदद लेने या फीडबैक देने के लिए हमें ईमेल करें।</value>
</data>
<data name="EnterPIN" xml:space="preserve">
<value>अपना पिन डालें</value>
<value>अपना पिन कोड डालें</value>
</data>
<data name="Favorites" xml:space="preserve">
<value>पसंदीदा</value>
<value>मनपसंद</value>
<comment>Title for your favorite items in the vault.</comment>
</data>
<data name="FileBugReport" xml:space="preserve">
<value>बग रिपोर्ट दर्ज करें</value>
<value>बग रिपोर्ट भेजें</value>
</data>
<data name="FileBugReportDescription" xml:space="preserve">
<value>हमारे GitHub भंडार में एक मुद्दे को बताएं।</value>
<value>हमारे गिटहब रिपॉज़िटरी में समस्या बताएं।</value>
</data>
<data name="FingerprintDirection" xml:space="preserve">
<value>फिंगरप्रिंट से सत्यापन करें</value>
<value>फिंगरप्रिंट से सत्यापन करें</value>
</data>
<data name="Folder" xml:space="preserve">
<value>फोल्डर</value>
<value>फोल्डर</value>
<comment>Label for a folder.</comment>
</data>
<data name="FolderCreated" xml:space="preserve">
<value>नया फोल्डर बनाया गया</value>
<value>नया फोल्डर बनाया गया</value>
</data>
<data name="FolderDeleted" xml:space="preserve">
<value>फोल्डर को हटाया</value>
<value>फोल्डर मिटाया गया।</value>
</data>
<data name="FolderNone" xml:space="preserve">
<value>कोई फोल्डर नहीं है</value>
<value>कोई फोल्डर नहीं है</value>
<comment>Items that have no folder specified go in this special "catch-all" folder.</comment>
</data>
<data name="Folders" xml:space="preserve">
<value>फोल्डर्स</value>
<value>फोल्डर</value>
</data>
<data name="FolderUpdated" xml:space="preserve">
<value>फोल्डर अद्यतन हुआ</value>
<value>फोल्डर सेव हुआ</value>
</data>
<data name="GoToWebsite" xml:space="preserve">
<value>वेबसाइट पर जाए</value>
<value>वेबसाइट पर जाए</value>
<comment>The button text that allows user to launch the website to their web browser.</comment>
</data>
<data name="HelpAndFeedback" xml:space="preserve">
<value>सहायता और सुझाव</value>
<value>मदद और फीडबैक</value>
</data>
<data name="Hide" xml:space="preserve">
<value>छुपायें</value>
<value>छुपां</value>
<comment>Hide a secret value that is currently shown (password).</comment>
</data>
<data name="InternetConnectionRequiredMessage" xml:space="preserve">
<value>जारी रखने से पहले कृपया इंटरनेट से जुड़े।</value>
<value>जारी रखने से पहले इंटरनेट से जुड़े।</value>
<comment>Description message for the alert when internet connection is required to continue.</comment>
</data>
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
<value>इंटरनेट से जुड़िए</value>
<value>इंटरनेट कनेक्शन चाहिए</value>
<comment>Title for the alert when internet connection is required to continue.</comment>
</data>
<data name="InvalidMasterPassword" xml:space="preserve">
<value>मास्टर पासवर्ड गलत है। फिर कोशिश करें।</value>
<value>मुख्य पासवर्ड गलत है। वापस कोशिश करें।</value>
</data>
<data name="InvalidPIN" xml:space="preserve">
<value>पिन गलत है। फिर कोशिश करें।</value>
<value>पिन गलत है। वापस कोशिश करें।</value>
</data>
<data name="Launch" xml:space="preserve">
<value>खोलें</value>
@@ -269,38 +269,38 @@
<comment>Title for login page. (noun)</comment>
</data>
<data name="LogOut" xml:space="preserve">
<value>लॉग आउट</value>
<value>लॉग आउट करें</value>
<comment>The log out button text (verb).</comment>
</data>
<data name="LogoutConfirmation" xml:space="preserve">
<value>क्या आप वाकई लॉग आउट करना चाहते हैं?</value>
<value>क्का लॉग आउट करं?</value>
</data>
<data name="RemoveAccount" xml:space="preserve">
<value>खाता हटाएं</value>
</data>
<data name="RemoveAccountConfirmation" xml:space="preserve">
<value>क्या आप वाकई यह खाता हटाना चाहते हैं?</value>
<value>क्का खाता हटाएं?</value>
</data>
<data name="AccountAlreadyAdded" xml:space="preserve">
<value>Account already added</value>
<value>खाता पहले से जोड़ा गया</value>
</data>
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
<value>Would you like to switch to it now?</value>
<value>अभी खाता इस्तेमाल करें?</value>
</data>
<data name="MasterPassword" xml:space="preserve">
<value>मास्टर / मुख्य पासवर्ड</value>
<value>मुख्य पासवर्ड</value>
<comment>Label for a master password.</comment>
</data>
<data name="More" xml:space="preserve">
<value>अतिरिक्त</value>
<value>और</value>
<comment>Text to define that there are more options things to see.</comment>
</data>
<data name="MyVault" xml:space="preserve">
<value>मेर तिजोरी</value>
<value>मेर तिजोरी</value>
<comment>The title for the vault page.</comment>
</data>
<data name="Authenticator" xml:space="preserve">
<value>Authenticator</value>
<value>सत्यापन करनेवाला</value>
<comment>Authenticator TOTP feature</comment>
</data>
<data name="Name" xml:space="preserve">
@@ -311,11 +311,11 @@
<value>नहीं</value>
</data>
<data name="Notes" xml:space="preserve">
<value>टिप्पणियाँ</value>
<value>नोट</value>
<comment>Label for notes.</comment>
</data>
<data name="Ok" xml:space="preserve">
<value>ठीक</value>
<value>ठीक है</value>
<comment>Acknowledgement.</comment>
</data>
<data name="Password" xml:space="preserve">
@@ -323,69 +323,69 @@
<comment>Label for a password.</comment>
</data>
<data name="Save" xml:space="preserve">
<value>सहेजें</value>
<value>सेव करें</value>
<comment>Button text for a save operation (verb).</comment>
</data>
<data name="Move" xml:space="preserve">
<value>Move</value>
<value>ले जाएं</value>
</data>
<data name="Saving" xml:space="preserve">
<value>सेव हो रहा है...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="Settings" xml:space="preserve">
<value>सेटिंग्स</value>
<value>सेटिंग</value>
<comment>The title for the settings page.</comment>
</data>
<data name="Show" xml:space="preserve">
<value>दिखाए</value>
<value>दिखाए</value>
<comment>Reveal a hidden value (password).</comment>
</data>
<data name="ItemDeleted" xml:space="preserve">
<value>आइटम हटा दिया गया है।</value>
<value>चीज़ मिटाया गया।</value>
<comment>Confirmation message after successfully deleting a login.</comment>
</data>
<data name="Submit" xml:space="preserve">
<value>जमा करें</value>
</data>
<data name="Sync" xml:space="preserve">
<value>संकालन</value>
<value>सिंक</value>
<comment>The title for the sync page.</comment>
</data>
<data name="ThankYou" xml:space="preserve">
<value>धन्यवाद</value>
<value>शुक्रिया</value>
</data>
<data name="Tools" xml:space="preserve">
<value>उपकरण</value>
<value>औज़ार</value>
<comment>The title for the tools page.</comment>
</data>
<data name="URI" xml:space="preserve">
<value>URI</value>
<value>यूआरआई</value>
<comment>Label for a uri/url.</comment>
</data>
<data name="UseFingerprintToUnlock" xml:space="preserve">
<value>अंगुलिछाप से खोलें</value>
<value>फिंगरप्रिंट से खोलें</value>
</data>
<data name="Username" xml:space="preserve">
<value>उपयोगकर्ता नाम:</value>
<value>यूज़रनाम</value>
<comment>Label for a username.</comment>
</data>
<data name="ValidationFieldRequired" xml:space="preserve">
<value>{0} की आश्यकता है।</value>
<value>{0} फील्ड चाहिए।</value>
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
</data>
<data name="ValueHasBeenCopied" xml:space="preserve">
<value>{0} कॉपी कर लिया गया है।</value>
<value>{0} कॉपी किया</value>
<comment>Confirmation message after successfully copying a value to the clipboard.</comment>
</data>
<data name="VerifyFingerprint" xml:space="preserve">
<value>अंगुलिछाप दें</value>
<value>फिंगरप्रिंट सत्यापित करें</value>
</data>
<data name="VerifyMasterPassword" xml:space="preserve">
<value>मास्टर पासवर्ड बताएं।</value>
<value>मुख्य पासवर्ड सत्यापित करें</value>
</data>
<data name="VerifyPIN" xml:space="preserve">
<value>पिन बताएं।</value>
<value>पिन सत्यापित करें।</value>
</data>
<data name="Version" xml:space="preserve">
<value>संस्करण</value>
@@ -394,29 +394,29 @@
<value>देखें</value>
</data>
<data name="VisitOurWebsite" xml:space="preserve">
<value>हमारी वेबसाइट पर जाए</value>
<value>हमारी वेबसाइट पर जाए</value>
</data>
<data name="VisitOurWebsiteDescription" xml:space="preserve">
<value>Visit our website to get help, news, email us, and/or learn more about how to use bitwarden.</value>
<value>मदद लेने, खबर लेने, हमें ईमेल करने, और/या बिटवार्डन के इस्तेमाल के बारे में ज़्यादा जानने के लिए हमारी वेबसाइट पर जाएं।</value>
</data>
<data name="Website" xml:space="preserve">
<value>वेबसाइट</value>
<comment>Label for a website.</comment>
</data>
<data name="Yes" xml:space="preserve">
<value>हा</value>
<value>हा</value>
</data>
<data name="Account" xml:space="preserve">
<value>खाता</value>
</data>
<data name="AccountCreated" xml:space="preserve">
<value>अपना नया खाता बनाया गया है! अब आप लॉग न कर सकते हैं।</value>
<value>आपका नया खाता बनाया गया! अब आप लॉग न कर सकते हैं।</value>
</data>
<data name="AddAnItem" xml:space="preserve">
<value>आइटम जोड़ें</value>
<value>चीज़ जोड़ें</value>
</data>
<data name="AppExtension" xml:space="preserve">
<value>ऐप का विस्तारण</value>
<value>ऐप एक्सटेंशन</value>
</data>
<data name="AutofillAccessibilityDescription" xml:space="preserve">
<value>Use the bitwarden accessibility service to auto-fill your logins across apps and the web.</value>
@@ -776,10 +776,10 @@
<value>सक्षम</value>
</data>
<data name="Off" xml:space="preserve">
<value>Off</value>
<value>बंद</value>
</data>
<data name="On" xml:space="preserve">
<value>On</value>
<value>चालू</value>
</data>
<data name="Status" xml:space="preserve">
<value>स्थिति</value>
@@ -1096,16 +1096,16 @@ Scanning will happen automatically.</value>
<value>मध्य नाम</value>
</data>
<data name="Mr" xml:space="preserve">
<value>Mr</value>
<value>श्री</value>
</data>
<data name="Mrs" xml:space="preserve">
<value>Mrs</value>
<value>श्रीमती</value>
</data>
<data name="Ms" xml:space="preserve">
<value>Ms</value>
<value>श्रीमती</value>
</data>
<data name="Mx" xml:space="preserve">
<value>Mx</value>
<value>मैक्स</value>
</data>
<data name="November" xml:space="preserve">
<value>नवंबर</value>
@@ -2274,7 +2274,7 @@ Scanning will happen automatically.</value>
<value>Vault: {0}</value>
</data>
<data name="All" xml:space="preserve">
<value>All</value>
<value>सब</value>
</data>
<data name="Totp" xml:space="preserve">
<value>TOTP</value>
@@ -2365,13 +2365,13 @@ select Add TOTP to store the key safely</value>
<value>Login denied</value>
</data>
<data name="ApproveLoginRequests" xml:space="preserve">
<value>Approve login requests</value>
<value>लॉगइन मांग माने</value>
</data>
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
<value>Use this device to approve login requests made from other devices.</value>
</data>
<data name="AllowNotifications" xml:space="preserve">
<value>Allow notifications</value>
<value>सूचना देने दें</value>
</data>
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
<value>Receive push notifications for new login requests</value>
@@ -2522,99 +2522,99 @@ Do you want to switch to this account?</value>
<value>Resend notification</value>
</data>
<data name="NeedAnotherOption" xml:space="preserve">
<value>Need another option?</value>
<value>दूसरा ऑप्शन चाहिए?</value>
</data>
<data name="ViewAllLoginOptions" xml:space="preserve">
<value>View all log in options</value>
<value>ऑप्शन में सारे लॉग देखें</value>
</data>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>This request is no longer valid</value>
<value>ये मांग अब मान्य नहीं है</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Pending login requests</value>
<value>लंबित लॉगइन मांगे</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
<value>सारे मांग नकारे</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
<value>सारे लंबित लॉगइन मांग पक्का नकारें?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
<value>मांग नकारे गए</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
<value>कोई लंबित मांग नहीं</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Enable camera permission to use the scanner</value>
<value>स्कैनर इस्तेमाल करने के लिए कैमरा अनुमति दें</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
<value>भाषा</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
<value>भाषा {0} में बदली गई। बदलाव देखने के लिए ऐप बंद करके वापस खोलें।</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
<value>भाषा बदलाव के लिए ऐप बंद करके खोलना पड़ेगा</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
<value>डिफॉल्ट (सिस्टम)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
<value>ज़रूरी</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
<value>आप अपना मुख्य पासवर्ड भूलने के बाद वापस नहीं ले सकते। {0} अक्षर कम-से-कम।</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Weak Master Password</value>
<value>कमज़ोर मुख्य पासवर्ड</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>
<value>पासवर्ड कमज़ोर है। अपना खाता महफूज़ रखने के लिए एक ताकतवर पासवर्ड इस्तेमाल करें। कमज़ोर पासवर्ड पक्का इस्तेमाल करें?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Weak</value>
<value>कमज़ोर</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
<value>अच्छा</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
<value>ताकतवर</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>
<value>पुराने डाटा लीक में इस पासवर्ड को खोजें</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
<value>मुख्य पासवर्ड लीक हुआ था</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>
<value>पासवर्ड एक डाटा लीक में मिला। अपना खाता महफूज़ रखने के लिए एक खास पासवर्ड इस्तेमाल करें। लीक हुआ पासवर्ड इस्तेमाल करें?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
<value>कमज़ोर और लीक हुआ मुख्य पासवर्ड</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>
<value>पासवर्ड कमज़ोर है और एक डाटा लीक में मिला। अपना खाता महफूज़ रखने के लिए एक ताकतवर और खास पासवर्ड इस्तेमाल करें। ये पासवर्ड पक्का इस्तेमाल करें?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
<value>संगठन एसएसओ पहचान चाहिए।</value>
</data>
<data name="AddTheKeyToAnExistingOrNewItem" xml:space="preserve">
<value>Add the key to an existing or new item</value>
<value>चाबी एक मौजूदा या नए चीज़ में जोड़ें</value>
</data>
<data name="ThereAreNoItemsInYourVaultThatMatchX" xml:space="preserve">
<value>There are no items in your vault that match "{0}"</value>
<value>आपके तिजोरी में ऐसी कोई भी चीज़ नहीं है जो "{0}" से मेल खाती है</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
<value>चीज़ खोजें या नया चीज़ जोड़ें</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
<value>कोई भी चीज़ खोज शब्द से मेल नहीं खाता</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
<value>आपका मुख्य पासवर्ड आपके संगठन के एक या उससे ज़्यादा नीति को नहीं मानता। तिजोरी एक्सेस करने के लिए आपको अपना मुख्य पासवर्ड अभी बदलना होगा। ये करने से आप अपने चालू सत्र से लॉग आउट हो जाएंगे, जिसके वजह से आपको वापस लॉग इन करना पड़ेगा। दूसरे डिवाइसों पर चालू सत्र एक घंटे तक सक्रिय रह सकते हैं।</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
<value>चालू मुख्य पासवर्ड</value>
</data>
</root>

View File

@@ -2496,8 +2496,8 @@ Do you want to switch to this account?</value>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<data name="LoggingInAsXOnY" xml:space="preserve">
<value>Logging in as {0} on {1}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
@@ -2610,6 +2610,21 @@ Do you want to switch to this account?</value>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
</data>
<data name="US" xml:space="preserve">
<value>US</value>
</data>
<data name="EU" xml:space="preserve">
<value>EU</value>
</data>
<data name="SelfHosted" xml:space="preserve">
<value>Self-hosted</value>
</data>
<data name="DataRegion" xml:space="preserve">
<value>Data region</value>
</data>
<data name="Region" xml:space="preserve">
<value>Region</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>

View File

@@ -1753,10 +1753,10 @@ Scanarea se va face automat.</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Deblocarea biometrică pentru acest cont este dezactivată în așteptarea verificării parolei principale.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Completarea automată a deblocării biometrice pentru acest cont este dezactivată în așteptarea verificării parolei principale.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Activare sincronizare la reîmprospătare</value>

View File

@@ -269,7 +269,7 @@
<comment>Title for login page. (noun)</comment>
</data>
<data name="LogOut" xml:space="preserve">
<value>Izpiši se</value>
<value>Odjavi se</value>
<comment>The log out button text (verb).</comment>
</data>
<data name="LogoutConfirmation" xml:space="preserve">
@@ -296,7 +296,7 @@
<comment>Text to define that there are more options things to see.</comment>
</data>
<data name="MyVault" xml:space="preserve">
<value>Moj sef</value>
<value>Moj trezor</value>
<comment>The title for the vault page.</comment>
</data>
<data name="Authenticator" xml:space="preserve">
@@ -342,7 +342,7 @@
<comment>Reveal a hidden value (password).</comment>
</data>
<data name="ItemDeleted" xml:space="preserve">
<value>Vnos je bil izbrisan.</value>
<value>Element je bil izbrisan.</value>
<comment>Confirmation message after successfully deleting a login.</comment>
</data>
<data name="Submit" xml:space="preserve">
@@ -413,7 +413,7 @@
<value>Vas novi račun je bil ustvarjen! Lahko se vpišete. </value>
</data>
<data name="AddAnItem" xml:space="preserve">
<value>Dodaj vnos</value>
<value>Dodaj Element</value>
</data>
<data name="AppExtension" xml:space="preserve">
<value>Razširitev aplikacije</value>
@@ -425,7 +425,7 @@
<value>Storitev samodejnega izpolnjevanja</value>
</data>
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
<value>Izogib dvoumnih znakov</value>
<value>Brez dvoumnih znakov</value>
</data>
<data name="BitwardenAppExtension" xml:space="preserve">
<value>Razširitev aplikacije Bitwarden</value>
@@ -468,7 +468,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="EditItem" xml:space="preserve">
<value>Uredi vnos</value>
<value>Uredi element</value>
</data>
<data name="EnableAutomaticSyncing" xml:space="preserve">
<value>Omogoči samodejno sinhronizacijo</value>
@@ -514,13 +514,13 @@
<value>Prstni odtis </value>
</data>
<data name="GeneratePassword" xml:space="preserve">
<value>Ustvari geslo</value>
<value>Generiraj geslo</value>
</data>
<data name="GetPasswordHint" xml:space="preserve">
<value>Pridobi namig za glavno geslo</value>
</data>
<data name="ImportItems" xml:space="preserve">
<value>Uvozi zapise</value>
<value>Uvozi elemente</value>
</data>
<data name="ImportItemsConfirmation" xml:space="preserve">
<value>You can bulk import items from the bitwarden.com web vault. Do you want to visit the website now?</value>
@@ -566,7 +566,7 @@
<comment>Message shown when interacting with the server</comment>
</data>
<data name="LoginOrCreateNewAccount" xml:space="preserve">
<value>Vpišite se ali ustvarite nov račun za dostop do sefa.</value>
<value>Prijavite se ali ustvarite nov račun za dostop do trezorja.</value>
</data>
<data name="Manage" xml:space="preserve">
<value>Upravljaj</value>
@@ -584,7 +584,7 @@
<value>Namig glavnega gesla se vam lahko pomaga spomniti geslo, v kolikor bi ga pozabili.</value>
</data>
<data name="MasterPasswordLengthValMessageX" xml:space="preserve">
<value>Master password must be at least {0} characters long.</value>
<value>Glavno geslo mora vsebovati vsaj {0} znakov.</value>
</data>
<data name="MinNumbers" xml:space="preserve">
<value>Minimalno števil</value>
@@ -604,13 +604,13 @@
<value>Nikoli</value>
</data>
<data name="NewItemCreated" xml:space="preserve">
<value>Nov vnos ustvarjen.</value>
<value>Nov element ustvarjen.</value>
</data>
<data name="NoFavorites" xml:space="preserve">
<value>V vašem sefu ni priljubljenih vnosov. </value>
<value>V vašem trezorju ni priljubljenih elementov. </value>
</data>
<data name="NoItems" xml:space="preserve">
<value>V vašem sefu ni vnosov. </value>
<value>V vašem trezorju ni elementov. </value>
</data>
<data name="NoItemsTap" xml:space="preserve">
<value>There are no items in your vault for this website/app. Tap to add one.</value>
@@ -632,7 +632,7 @@
<value>Drugo</value>
</data>
<data name="PasswordGenerated" xml:space="preserve">
<value>Geslo ustvarjeno.</value>
<value>Geslo generirano.</value>
</data>
<data name="PasswordGenerator" xml:space="preserve">
<value>Ustvarjalnik gesel</value>
@@ -678,24 +678,24 @@
<value>Vnesite 4 mestno PIN številko za odklep aplikacije.</value>
</data>
<data name="ItemInformation" xml:space="preserve">
<value>Informacije o vnosu</value>
<value>Informacije o elementu</value>
</data>
<data name="ItemUpdated" xml:space="preserve">
<value>Vnos je posodobljen.</value>
<value>Element shranjen.</value>
</data>
<data name="Submitting" xml:space="preserve">
<value>Pošiljanje...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="Syncing" xml:space="preserve">
<value>Sinhronizacija...</value>
<value>Sinhroniziram...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="SyncingComplete" xml:space="preserve">
<value>Sinhronizacija končana.</value>
</data>
<data name="SyncingFailed" xml:space="preserve">
<value>Sinhronizacija neuspešna.</value>
<value>Sinhronizacija spodletela.</value>
</data>
<data name="SyncVaultNow" xml:space="preserve">
<value>Sinhroniziraj trezor zdaj</value>
@@ -714,7 +714,7 @@
<value>Odkleni z {0}</value>
</data>
<data name="UnlockWithPIN" xml:space="preserve">
<value>Odklepanje s PIN kodo</value>
<value>Odkleni s PIN kodo</value>
</data>
<data name="Validating" xml:space="preserve">
<value>Preverjanje veljavnosti</value>
@@ -724,16 +724,16 @@
<value>Verifikacijska koda</value>
</data>
<data name="ViewItem" xml:space="preserve">
<value>Ogled vnosa</value>
<value>Prikaži element</value>
</data>
<data name="WebVault" xml:space="preserve">
<value>Bitwarden spletni sef </value>
<value>Spletni trezor Bitwarden</value>
</data>
<data name="Lost2FAApp" xml:space="preserve">
<value>Izgubili aplikacijo za avtentikacijo? </value>
</data>
<data name="Items" xml:space="preserve">
<value>Vnosi</value>
<value>Elementi</value>
<comment>Screen title</comment>
</data>
<data name="ExtensionActivated" xml:space="preserve">
@@ -746,11 +746,11 @@
<value>Prevodi </value>
</data>
<data name="ItemsForUri" xml:space="preserve">
<value>Vnosov za {0}</value>
<value>Elementi za {0}</value>
<comment>This is used for the autofill service. ex. "Logins for twitter.com"</comment>
</data>
<data name="NoItemsForUri" xml:space="preserve">
<value>V vašem sefu ni vnosov za {0}.</value>
<value>V vašem trezorju ni elementov za {0}.</value>
<comment>This is used for the autofill service. ex. "There are no items in your vault for twitter.com".</comment>
</data>
<data name="BitwardenAutofillServiceOverlay" xml:space="preserve">
@@ -790,16 +790,16 @@
<value>Samodejno izpolnjevanje</value>
</data>
<data name="AutofillOrView" xml:space="preserve">
<value>Želite samodejno izpolniti ali videti ta vnos?</value>
<value>Želite samodejno izpolniti ali prikazati ta element?</value>
</data>
<data name="BitwardenAutofillServiceMatchConfirm" xml:space="preserve">
<value>Ali ste prepričani, da želite samodejno izpolniti ta element? Ujemanje ni popolno za "{0}".</value>
</data>
<data name="MatchingItems" xml:space="preserve">
<value>Ujemajoči vnosi</value>
<value>Ujemajoči elementi</value>
</data>
<data name="PossibleMatchingItems" xml:space="preserve">
<value>Možni ujemajoči vnosi</value>
<value>Možni ujemajoči elementi</value>
</data>
<data name="Search" xml:space="preserve">
<value>Iskanje</value>
@@ -1017,7 +1017,7 @@ Scanning will happen automatically.</value>
<value>Prijava</value>
</data>
<data name="TypeSecureNote" xml:space="preserve">
<value>Varni zapisek</value>
<value>Zavarovan zapisek</value>
</data>
<data name="Address1" xml:space="preserve">
<value>Naslov 1</value>
@@ -1140,10 +1140,10 @@ Scanning will happen automatically.</value>
<value>Datum poteka</value>
</data>
<data name="ShowWebsiteIcons" xml:space="preserve">
<value>Show website icons</value>
<value>Prikaži ikone spletnih strani</value>
</data>
<data name="ShowWebsiteIconsDescription" xml:space="preserve">
<value>Show a recognizable image next to each login.</value>
<value>Pri vsaki prijavi prikaži prepoznavno sliko.</value>
</data>
<data name="IconsUrl" xml:space="preserve">
<value>Ikone URL strežnikov</value>
@@ -1161,10 +1161,10 @@ Scanning will happen automatically.</value>
<value>Zbirke</value>
</data>
<data name="NoItemsCollection" xml:space="preserve">
<value>Ta zbirka še nima zapisov.</value>
<value>Ta zbirka še nima elementov.</value>
</data>
<data name="NoItemsFolder" xml:space="preserve">
<value>V tej mapi ni zapisov.</value>
<value>V tej mapi ni elementov.</value>
</data>
<data name="NoItemsTrash" xml:space="preserve">
<value>Koš je prazen.</value>
@@ -1182,7 +1182,7 @@ Scanning will happen automatically.</value>
<value>Nastavitve samodejnega izpolnjevanja</value>
</data>
<data name="FaceID" xml:space="preserve">
<value>Obrazni ID</value>
<value>obraznim ID</value>
<comment>What Apple calls their facial recognition reader.</comment>
</data>
<data name="FaceIDDirection" xml:space="preserve">
@@ -1322,7 +1322,7 @@ Scanning will happen automatically.</value>
<value>5. Select "Bitwarden"</value>
</data>
<data name="PasswordAutofill" xml:space="preserve">
<value>Password auto-fill</value>
<value>Samodejno izpolnjevanje gesel</value>
</data>
<data name="BitwardenAutofillAlert2" xml:space="preserve">
<value>The easiest way to add new logins to your vault is by using the Bitwarden Password AutoFill extension. Learn more about using the Bitwarden Password AutoFill extension by navigating to the "Settings" screen.</value>
@@ -1340,13 +1340,13 @@ Scanning will happen automatically.</value>
<value>Prijave</value>
</data>
<data name="SecureNotes" xml:space="preserve">
<value>Varni zapiski</value>
<value>Zavarovani zapiski</value>
</data>
<data name="AllItems" xml:space="preserve">
<value>Vsi elementi</value>
</data>
<data name="URIs" xml:space="preserve">
<value>URIs</value>
<value>URI-ji</value>
<comment>Plural form of a URI</comment>
</data>
<data name="CheckingPassword" xml:space="preserve">
@@ -1369,7 +1369,7 @@ Scanning will happen automatically.</value>
<value>Vrednost</value>
</data>
<data name="PasswordHistory" xml:space="preserve">
<value>Zgodovina gesla</value>
<value>Zgodovina gesel</value>
</data>
<data name="Types" xml:space="preserve">
<value>Vrste</value>
@@ -1378,7 +1378,7 @@ Scanning will happen automatically.</value>
<value>Ni gesel za prikazat.</value>
</data>
<data name="NoItemsToList" xml:space="preserve">
<value>Ni vnosov za prikazat.</value>
<value>Ni elementov za prikaz.</value>
</data>
<data name="SearchCollection" xml:space="preserve">
<value>Preišči zbirko</value>
@@ -1409,7 +1409,7 @@ Scanning will happen automatically.</value>
<value>Lastništvo</value>
</data>
<data name="WhoOwnsThisItem" xml:space="preserve">
<value>Kdo je lastnik tega vnosa?</value>
<value>Kdo je lastnik tega elementa?</value>
</data>
<data name="NoCollectionsToList" xml:space="preserve">
<value>Ni zbirk za prikazat.</value>
@@ -1419,7 +1419,7 @@ Scanning will happen automatically.</value>
<comment>ex: Item moved to Organization.</comment>
</data>
<data name="ItemShared" xml:space="preserve">
<value>Vnos je bil deljen.</value>
<value>Element je bil dan v skupno rabo.</value>
</data>
<data name="SelectOneCollection" xml:space="preserve">
<value>Izbrati moraš vsaj eno zbirko.</value>
@@ -1428,10 +1428,10 @@ Scanning will happen automatically.</value>
<value>Deli</value>
</data>
<data name="ShareItem" xml:space="preserve">
<value>Delite vnos</value>
<value>Delite element</value>
</data>
<data name="MoveToOrganization" xml:space="preserve">
<value>Move to Organization</value>
<value>Premakni v organizacijo</value>
</data>
<data name="NoOrgsToList" xml:space="preserve">
<value>Ni organizacij za prikazat.</value>
@@ -1562,7 +1562,7 @@ Scanning will happen automatically.</value>
<value>Kopiraj opombo</value>
</data>
<data name="Exit" xml:space="preserve">
<value>Zapri</value>
<value>Izhod</value>
</data>
<data name="ExitConfirmation" xml:space="preserve">
<value>Ali res želite zapustiti Bitwarden?</value>
@@ -1583,16 +1583,16 @@ Scanning will happen automatically.</value>
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
</data>
<data name="AutofillBlockedUris" xml:space="preserve">
<value>Auto-fill blocked URIs</value>
<value>URI-ji brez samodejnega izpolnjevanja</value>
</data>
<data name="AutofillBlockedUrisDescription" xml:space="preserve">
<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>
<value>Za te URI-je Bitwarden ne bo ponujal samodejnega izpolnjevanja. URI-je ločite z vejicami, n.pr.: "https://twitter.com, androidapp://com.twitter.android".</value>
</data>
<data name="AskToAddLogin" xml:space="preserve">
<value>Ask to add login</value>
<value>Ponudi shranjevanje prijav</value>
</data>
<data name="AskToAddLoginDescription" xml:space="preserve">
<value>Ask to add an item if one isn't found in your vault.</value>
<value>Ponudi, da se shrani nova prijava, če je v trezorju še ni.</value>
</data>
<data name="OnRestart" xml:space="preserve">
<value>Ob ponovnem zagonu aplikacije</value>
@@ -1626,7 +1626,7 @@ Scanning will happen automatically.</value>
<value>Biometrična avtentikacija</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Biometrično preverjanje</value>
<value>biometričnim preverjanjem</value>
</data>
<data name="UseBiometricsToUnlock" xml:space="preserve">
<value>Uporabi biometrično preverjanje za odklep</value>
@@ -1729,7 +1729,7 @@ Scanning will happen automatically.</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="ItemRestored" xml:space="preserve">
<value>Vnos je bil obnovljen.</value>
<value>Element je bil obnovljen.</value>
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
</data>
<data name="Trash" xml:space="preserve">
@@ -1745,7 +1745,7 @@ Scanning will happen automatically.</value>
<comment>Confirmation alert message when permanently deleteing a cipher.</comment>
</data>
<data name="DoYouReallyWantToRestoreCipher" xml:space="preserve">
<value>Ali res želite povrniti ta vnos?</value>
<value>Ali res želite povrniti ta element?</value>
<comment>Confirmation alert message when restoring a soft-deleted cipher.</comment>
</data>
<data name="DoYouReallyWantToSoftDeleteCipher" xml:space="preserve">
@@ -1759,10 +1759,10 @@ Scanning will happen automatically.</value>
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Allow sync on refresh</value>
<value>Dovoli sihnronizacijo ob osvežitvi</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
<value>Sinhroniziraj ob potegu navzdol</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise single sign-on</value>
@@ -1829,7 +1829,7 @@ Scanning will happen automatically.</value>
<value>Bitwarden needs attention - Turn on "Draw-Over" in "Auto-fill Services" from Bitwarden Settings</value>
</data>
<data name="AutofillServices" xml:space="preserve">
<value>Auto-fill services</value>
<value>Storitve samodejnega izpolnjevanja</value>
</data>
<data name="InlineAutofill" xml:space="preserve">
<value>Use inline autofill</value>
@@ -1871,7 +1871,7 @@ Scanning will happen automatically.</value>
<value>An organization policy is affecting your ownership options.</value>
</data>
<data name="Send" xml:space="preserve">
<value>Pošlji</value>
<value>Pošiljke</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="AllSends" xml:space="preserve">
@@ -1887,23 +1887,23 @@ Scanning will happen automatically.</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="Text" xml:space="preserve">
<value>Text</value>
<value>Besedilo</value>
</data>
<data name="TypeText" xml:space="preserve">
<value>Text</value>
<value>Besedilo</value>
</data>
<data name="TypeTextInfo" xml:space="preserve">
<value>The text you want to send.</value>
<value>Besedilo, ki ga želite poslati</value>
</data>
<data name="HideTextByDefault" xml:space="preserve">
<value>When accessing the Send, hide the text by default</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="TypeFile" xml:space="preserve">
<value>File</value>
<value>Datoteka</value>
</data>
<data name="TypeFileInfo" xml:space="preserve">
<value>The file you want to send.</value>
<value>Datoteka, ki jo želite poslati</value>
</data>
<data name="FileTypeIsSelected" xml:space="preserve">
<value>File type is selected.</value>
@@ -1998,7 +1998,7 @@ Scanning will happen automatically.</value>
<value>Deli povezavo</value>
</data>
<data name="SendLink" xml:space="preserve">
<value>Pošlji povezavo</value>
<value>Povezava pošiljke</value>
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
</data>
<data name="SearchSends" xml:space="preserve">
@@ -2156,22 +2156,22 @@ Scanning will happen automatically.</value>
<value>One or more organization policies prevents your from exporting your individual vault.</value>
</data>
<data name="AddAccount" xml:space="preserve">
<value>Add account</value>
<value>Dodaj račun</value>
</data>
<data name="AccountUnlocked" xml:space="preserve">
<value>Unlocked</value>
<value>Odklenjen</value>
</data>
<data name="AccountLocked" xml:space="preserve">
<value>Locked</value>
<value>Zaklenjen</value>
</data>
<data name="AccountLoggedOut" xml:space="preserve">
<value>Logged out</value>
<value>Odjavljen</value>
</data>
<data name="AccountSwitchedAutomatically" xml:space="preserve">
<value>Switched to next available account</value>
</data>
<data name="AccountLockedSuccessfully" xml:space="preserve">
<value>Account locked</value>
<value>Račun je zaklenjen</value>
</data>
<data name="AccountLoggedOutSuccessfully" xml:space="preserve">
<value>Account logged out successfully</value>
@@ -2195,7 +2195,7 @@ Scanning will happen automatically.</value>
<value>Vaš račun je bil trajno izbrisan</value>
</data>
<data name="InvalidVerificationCode" xml:space="preserve">
<value>Invalid verification code</value>
<value>Neveljavna koda za preverjanje</value>
</data>
<data name="RequestOTP" xml:space="preserve">
<value>Request one-time password</value>
@@ -2228,7 +2228,7 @@ Scanning will happen automatically.</value>
<value>Enter the verification code that was sent to your email</value>
</data>
<data name="SubmitCrashLogs" xml:space="preserve">
<value>Submit crash logs</value>
<value>Pošlji zapisnike ob sesutju</value>
</data>
<data name="SubmitCrashLogsDescription" xml:space="preserve">
<value>Help Bitwarden improve app stability by submitting crash reports.</value>
@@ -2240,16 +2240,16 @@ Scanning will happen automatically.</value>
<value>Options are collapsed, tap to expand.</value>
</data>
<data name="UppercaseAtoZ" xml:space="preserve">
<value>Uppercase (A to Z)</value>
<value>Velike črke (A-Z)</value>
</data>
<data name="LowercaseAtoZ" xml:space="preserve">
<value>Lowercase (A to Z)</value>
<value>Male črke (a-z)</value>
</data>
<data name="NumbersZeroToNine" xml:space="preserve">
<value>Numbers (0 to 9)</value>
</data>
<data name="SpecialCharacters" xml:space="preserve">
<value>Special characters (!@#$%^&amp;*)</value>
<value>Posebni znaki (!@#$%^&amp;*)</value>
</data>
<data name="TapToGoBack" xml:space="preserve">
<value>Tap to go back</value>
@@ -2264,31 +2264,31 @@ Scanning will happen automatically.</value>
<value>Filter items by vault</value>
</data>
<data name="AllVaults" xml:space="preserve">
<value>All vaults</value>
<value>Vsi trezorji</value>
</data>
<data name="Vaults" xml:space="preserve">
<value>Vaults</value>
<value>Trezorji</value>
</data>
<data name="VaultFilterDescription" xml:space="preserve">
<value>Vault: {0}</value>
<value>Trezor: {0}</value>
</data>
<data name="All" xml:space="preserve">
<value>All</value>
<value>Vsi</value>
</data>
<data name="Totp" xml:space="preserve">
<value>TOTP</value>
</data>
<data name="VerificationCodes" xml:space="preserve">
<value>Verification codes</value>
<value>Kode za preverjanje</value>
</data>
<data name="PremiumSubscriptionRequired" xml:space="preserve">
<value>Premium subscription required</value>
<value>Potrebna je naročnina Premium.</value>
</data>
<data name="CannotAddAuthenticatorKey" xml:space="preserve">
<value>Cannot add authenticator key? </value>
</data>
<data name="ScanQRCode" xml:space="preserve">
<value>Scan QR Code</value>
<value>Skeniraj QR-kodo</value>
</data>
<data name="CannotScanQRCode" xml:space="preserve">
<value>Cannot scan QR Code? </value>
@@ -2319,10 +2319,10 @@ select Add TOTP to store the key safely</value>
<value>We were unable to process your request. Please try again or contact us.</value>
</data>
<data name="AllowScreenCapture" xml:space="preserve">
<value>Allow screen capture</value>
<value>Dovoli posnetke zaslona</value>
</data>
<data name="AreYouSureYouWantToEnableScreenCapture" xml:space="preserve">
<value>Are you sure you want to turn on screen capture?</value>
<value>Ste prepričani, da želite dovoliti zajemanje zaslona?</value>
</data>
<data name="LogInRequested" xml:space="preserve">
<value>Login requested</value>
@@ -2337,46 +2337,46 @@ select Add TOTP to store the key safely</value>
<value>Device type</value>
</data>
<data name="IpAddress" xml:space="preserve">
<value>IP address</value>
<value>IP-naslov</value>
</data>
<data name="Time" xml:space="preserve">
<value>Time</value>
<value>Čas</value>
</data>
<data name="Near" xml:space="preserve">
<value>Near</value>
<value>Blizu</value>
</data>
<data name="ConfirmLogIn" xml:space="preserve">
<value>Confirm login</value>
<value>Potrdi prijavo</value>
</data>
<data name="DenyLogIn" xml:space="preserve">
<value>Deny login</value>
<value>Zavrni prijavo</value>
</data>
<data name="JustNow" xml:space="preserve">
<value>Just now</value>
<value>Pravkar</value>
</data>
<data name="XMinutesAgo" xml:space="preserve">
<value>{0} minutes ago</value>
<value>Pred {0} minutami</value>
</data>
<data name="LogInAccepted" xml:space="preserve">
<value>Login confirmed</value>
<value>Prijava potrjena</value>
</data>
<data name="LogInDenied" xml:space="preserve">
<value>Login denied</value>
<value>Prijava zavrnjena</value>
</data>
<data name="ApproveLoginRequests" xml:space="preserve">
<value>Approve login requests</value>
<value>Odobri zahtevke za prijavo</value>
</data>
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
<value>Use this device to approve login requests made from other devices.</value>
<value>S to napravo odobri zahtevke za prijavo, ki pridejo z drugih naprav.</value>
</data>
<data name="AllowNotifications" xml:space="preserve">
<value>Allow notifications</value>
<value>Dovoli obvestila</value>
</data>
<data name="ReceivePushNotificationsForNewLoginRequests" xml:space="preserve">
<value>Receive push notifications for new login requests</value>
</data>
<data name="NoThanks" xml:space="preserve">
<value>No thanks</value>
<value>Ne, hvala</value>
</data>
<data name="ConfimLogInAttempForX" xml:space="preserve">
<value>Confirm login attempt for {0}</value>
@@ -2385,10 +2385,10 @@ select Add TOTP to store the key safely</value>
<value>All notifications</value>
</data>
<data name="PasswordType" xml:space="preserve">
<value>Password type</value>
<value>Vrsta gesla</value>
</data>
<data name="WhatWouldYouLikeToGenerate" xml:space="preserve">
<value>What would you like to generate?</value>
<value>Kaj želite generirati?</value>
</data>
<data name="UsernameType" xml:space="preserve">
<value>Username type</value>
@@ -2444,7 +2444,7 @@ select Add TOTP to store the key safely</value>
<value>Are you sure you want to overwrite the current username?</value>
</data>
<data name="GenerateUsername" xml:space="preserve">
<value>Generate username</value>
<value>Generiraj uporabniško ime</value>
</data>
<data name="EmailType" xml:space="preserve">
<value>Email Type</value>
@@ -2477,13 +2477,13 @@ select Add TOTP to store the key safely</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>Accept</value>
<value>Sprejmi</value>
</data>
<data name="Decline" xml:space="preserve">
<value>Decline</value>
<value>Zavrni</value>
</data>
<data name="LoginRequestHasAlreadyExpired" xml:space="preserve">
<value>Login request has already expired.</value>
<value>Zahtevek za prijavo je že potekel.</value>
</data>
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
<value>Login attempt from:
@@ -2491,109 +2491,109 @@ select Add TOTP to store the key safely</value>
Do you want to switch to this account?</value>
</data>
<data name="NewAroundHere" xml:space="preserve">
<value>New around here?</value>
<value>Ste novi tukaj?</value>
</data>
<data name="GetMasterPasswordwordHint" xml:space="preserve">
<value>Get master password hint</value>
<value>Pridobi namig za glavno geslo</value>
</data>
<data name="LoggingInAsX" xml:space="preserve">
<value>Logging in as {0}</value>
<value>Prijavljate se kot {0}</value>
</data>
<data name="NotYou" xml:space="preserve">
<value>Not you?</value>
<value>To niste vi?</value>
</data>
<data name="LogInWithMasterPassword" xml:space="preserve">
<value>Log in with master password</value>
<value>Prijava z glavnim geslom</value>
</data>
<data name="LogInWithAnotherDevice" xml:space="preserve">
<value>Log in with device</value>
<value>Prijava z napravo</value>
</data>
<data name="LogInInitiated" xml:space="preserve">
<value>Log in initiated</value>
<value>Prijava sprožena</value>
</data>
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
<value>A notification has been sent to your device.</value>
<value>Na vašo napravo smo poslali obvestilo.</value>
</data>
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
<value>Prosimo, preverite, da je vaš trezor odklenjem in da se identifikacijski gesli na tej in drugi napravi ujemata.</value>
</data>
<data name="ResendNotification" xml:space="preserve">
<value>Resend notification</value>
<value>Ponovno pošlji obvestilo</value>
</data>
<data name="NeedAnotherOption" xml:space="preserve">
<value>Need another option?</value>
<value>Potrebujete drugačno možnost?</value>
</data>
<data name="ViewAllLoginOptions" xml:space="preserve">
<value>View all log in options</value>
<value>Prikaži vse možnosti prijave</value>
</data>
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
<value>This request is no longer valid</value>
<value>Ta zahtevek ni več veljaven</value>
</data>
<data name="PendingLogInRequests" xml:space="preserve">
<value>Pending login requests</value>
<value>Čakajoči zahtevki za prijavo</value>
</data>
<data name="DeclineAllRequests" xml:space="preserve">
<value>Decline all requests</value>
<value>Zavrni vse zahtevke</value>
</data>
<data name="AreYouSureYouWantToDeclineAllPendingLogInRequests" xml:space="preserve">
<value>Are you sure you want to decline all pending login requests?</value>
<value>Ste prepričani, da želite zavrniti vse čakajoče zahtevke za prijavo?</value>
</data>
<data name="RequestsDeclined" xml:space="preserve">
<value>Requests declined</value>
<value>Zahtevki zavrnjeni</value>
</data>
<data name="NoPendingRequests" xml:space="preserve">
<value>No pending requests</value>
<value>Ni zahtevkov</value>
</data>
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
<value>Enable camera permission to use the scanner</value>
<value>Za uporabo skenerja dovolite uporabo kamere</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
<value>Jezik</value>
</data>
<data name="LanguageChangeXDescription" xml:space="preserve">
<value>The language has been changed to {0}. Please restart the app to see the change</value>
<value>Spremenjeno v jezik {0}. Prosimo, ponovno zaženite aplikacijo za prikaz sprememb.</value>
</data>
<data name="LanguageChangeRequiresAppRestart" xml:space="preserve">
<value>Language change requires app restart</value>
<value>Za spremembo jezika je potrebno ponovno zagnati aplikacijo.</value>
</data>
<data name="DefaultSystem" xml:space="preserve">
<value>Default (System)</value>
<value>Privzet (sistemski)</value>
</data>
<data name="Important" xml:space="preserve">
<value>Important</value>
<value>Pomembno</value>
</data>
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
<value>Če pozabite glavno geslo, ga ne bo mogoče obnoviti! Vsaj {0} znakov.</value>
</data>
<data name="WeakMasterPassword" xml:space="preserve">
<value>Weak Master Password</value>
<value>Šibko glavno geslo</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>
<value>Vaše geslo je šibko. Za zaščito svojega računa potrebujete močno geslo. Ste prepričani, da želite uporabiti šibko geslo?</value>
</data>
<data name="Weak" xml:space="preserve">
<value>Weak</value>
<value>Šibko</value>
</data>
<data name="Good" xml:space="preserve">
<value>Good</value>
<value>Dobro</value>
</data>
<data name="Strong" xml:space="preserve">
<value>Strong</value>
<value>Močno</value>
</data>
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
<value>Check known data breaches for this password</value>
<value>Preveri, ali je bilo geslo izpostavljeno v krajah podatkov</value>
</data>
<data name="ExposedMasterPassword" xml:space="preserve">
<value>Exposed Master Password</value>
<value>Izpostavljeno glavno geslo</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>
<value>To geslo smo našli med ukradenimi gesli. Za zaščito svojega računa uporabite edinstveno geslo. Ste prepričani, da želite uporabiti izpostavljeno geslo?</value>
</data>
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
<value>Weak and Exposed Master Password</value>
<value>Šibko in izpostavljeno glavno geslo</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>
<value>Vaše geslo je šibko, poleg tega smo ga našli med ukradenimi gesli. Za zaščito svojega računa potrebujete močno in edinstveno geslo. Ste prepričani, da želite uporabiti to šibko geslo?</value>
</data>
<data name="OrganizationSsoIdentifierRequired" xml:space="preserve">
<value>Organization SSO identifier required.</value>
@@ -2602,18 +2602,18 @@ Do you want to switch to this account?</value>
<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>
<value>V vašem trezorju ni elementov, ki bi ustrezali "{0}"</value>
</data>
<data name="SearchForAnItemOrAddANewItem" xml:space="preserve">
<value>Search for an item or add a new item</value>
<value>Poišči element ali dodaj novega</value>
</data>
<data name="ThereAreNoItemsThatMatchTheSearch" xml:space="preserve">
<value>There are no items that match the search</value>
<value>Ni elementov, ki bi ustrezali iskanju</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour.</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>Current master password</value>
<value>Trenutno glavno geslo</value>
</data>
</root>

View File

@@ -1753,10 +1753,10 @@
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Биометријско откључавање је онемогућено до верификације главне лозинке.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Биометријско откључавање аутоматског попуњавања за овај налог је онемогућено до верификације главне лозинке.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Омогући синхронизацију при освежавању</value>

View File

@@ -1753,10 +1753,10 @@
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="AccountBiometricInvalidated" xml:space="preserve">
<value>Biometric unlock for this account is disabled pending verification of master password.</value>
<value>Біометричне розблокування для цього облікового запису вимкнено. Очікується перевірка головного пароля.</value>
</data>
<data name="AccountBiometricInvalidatedExtension" xml:space="preserve">
<value>Autofill biometric unlock for this account is disabled pending verification of master password.</value>
<value>Біометричне розблокування під час автозаповнення для цього облікового запису вимкнено. Очікується перевірка головного пароля.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Дозволити синхронізацію жестом</value>

View File

@@ -2610,7 +2610,7 @@
<value>没有匹配搜索条件的项目</value>
</data>
<data name="UpdateWeakMasterPasswordWarning" xml:space="preserve">
<value>您的主密码不符合您的组织策略要求。要访问密码库,必须立即更新您的主密码。继续操作将使您退出当前会话,要求您重新登录。其他设备上的活动会话可能会继续保持活动状态长达一小时。</value>
<value>您的主密码不符合某一项或多项组织策略要求。要访问密码库,必须立即更新您的主密码。继续操作将使您退出当前会话,要求您重新登录。其他设备上的活动会话可能会继续保持活动状态长达一小时。</value>
</data>
<data name="CurrentMasterPassword" xml:space="preserve">
<value>当前主密码</value>

View File

@@ -93,5 +93,6 @@ namespace Bit.Core.Abstractions
Task<string> GetUsernameFromAsync(ForwardedEmailServiceType service, UsernameGeneratorConfig config);
Task<bool> GetKnownDeviceAsync(string email, string deviceIdentifier);
Task<OrganizationDomainSsoDetailsResponse> GetOrgDomainSsoDetailsAsync(string email);
Task<ConfigResponse> GetConfigsAsync();
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Threading.Tasks;
using Bit.Core.Models.Response;
namespace Bit.Core.Abstractions
{
public interface IConfigService
{
Task<ConfigResponse> GetAsync(bool forceRefresh = false);
Task<bool> GetFeatureFlagBoolAsync(string key, bool forceRefresh = false, bool defaultValue = false);
Task<string> GetFeatureFlagStringAsync(string key, bool forceRefresh = false, string defaultValue = null);
Task<int> GetFeatureFlagIntAsync(string key, bool forceRefresh = false, int defaultValue = 0);
}
}

View File

@@ -15,8 +15,6 @@ namespace Bit.Core.Abstractions
Task<string> GeneratePasswordAsync(PasswordGenerationOptions options);
Task<List<GeneratedPasswordHistory>> GetHistoryAsync();
Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)> GetOptionsAsync();
Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)>
EnforcePasswordGeneratorPoliciesOnOptionsAsync(PasswordGenerationOptions options);
Result PasswordStrength(string password, List<string> userInputs = null);
Task SaveOptionsAsync(PasswordGenerationOptions options);
void NormalizeOptions(PasswordGenerationOptions options, PasswordGeneratorPolicyOptions enforcedPolicyOptions);

View File

@@ -19,8 +19,7 @@ namespace Bit.Core.Abstractions
Tuple<ResetPasswordPolicyOptions, bool> GetResetPasswordPolicyOptions(IEnumerable<Policy> policies,
string orgId);
Task<bool> PolicyAppliesToUser(PolicyType policyType, Func<Policy, bool> policyFilter = null, string userId = null);
int? GetPolicyInt(Policy policy, string key);
string GetPolicyString(Policy policy, string key);
Task<bool> ShouldShowVaultFilterAsync();
Task<PasswordGeneratorPolicyOptions> GetPasswordGeneratorPolicyOptionsAsync();
}
}

View File

@@ -174,5 +174,7 @@ namespace Bit.Core.Abstractions
Task SetPreLoginEmailAsync(string value);
string GetLocale();
void SetLocale(string locale);
ConfigResponse GetConfigs();
void SetConfigs(ConfigResponse value);
}
}

View File

@@ -41,6 +41,9 @@
public const string NotificationDataType = "Type";
public const string PasswordlessLoginRequestKey = "passwordlessLoginRequest";
public const string PreLoginEmailKey = "preLoginEmailKey";
public const string ConfigsKey = "configsKey";
public const string DisplayEuEnvironmentFlag = "display-eu-environment";
/// <summary>
/// This key is used to store the value of "ShouldConnectToWatch" of the last user that had logged in
/// which is used to handle Apple Watch state logic

View File

@@ -28,12 +28,12 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="28.0.1" />
<PackageReference Include="LiteDB" Version="5.0.12" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="LiteDB" Version="5.0.16" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="zxcvbn-core" Version="7.0.92" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.3" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="5.0.1" />
<PackageReference Include="MessagePack" Version="2.4.59" />
<PackageReference Include="MessagePack.MSBuild.Tasks" Version="2.4.59">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -2,6 +2,9 @@
{
public class EnvironmentUrlData
{
public static EnvironmentUrlData DefaultUS = new EnvironmentUrlData { Base = "https://vault.bitwarden.com" };
public static EnvironmentUrlData DefaultEU = new EnvironmentUrlData { Base = "https://vault.bitwarden.eu" };
public string Base { get; set; }
public string Api { get; set; }
public string Identity { get; set; }
@@ -9,5 +12,13 @@
public string Notifications { get; set; }
public string WebVault { get; set; }
public string Events { get; set; }
public bool IsEmpty => string.IsNullOrEmpty(Base)
&& string.IsNullOrEmpty(Api)
&& string.IsNullOrEmpty(Identity)
&& string.IsNullOrEmpty(Icons)
&& string.IsNullOrEmpty(Notifications)
&& string.IsNullOrEmpty(WebVault)
&& string.IsNullOrEmpty(Events);
}
}

View File

@@ -2,29 +2,29 @@
{
public class PasswordGenerationOptions
{
public PasswordGenerationOptions() { }
public const string TYPE_PASSWORD = "password";
public const string TYPE_PASSPHRASE = "passphrase";
public PasswordGenerationOptions(bool defaultOptions)
public static PasswordGenerationOptions CreateDefault => new PasswordGenerationOptions
{
if (defaultOptions)
{
Length = 14;
AllowAmbiguousChar = true;
Number = true;
MinNumber = 1;
Uppercase = true;
MinUppercase = 0;
Lowercase = true;
MinLowercase = 0;
Special = false;
MinSpecial = 1;
Type = "password";
NumWords = 3;
WordSeparator = "-";
Capitalize = false;
IncludeNumber = false;
}
}
Length = 14,
AllowAmbiguousChar = true,
Number = true,
MinNumber = 1,
Uppercase = true,
MinUppercase = 0,
Lowercase = true,
MinLowercase = 0,
Special = false,
MinSpecial = 1,
Type = TYPE_PASSWORD,
NumWords = 3,
WordSeparator = "-",
Capitalize = false,
IncludeNumber = false
};
public PasswordGenerationOptions() { }
public int? Length { get; set; }
public bool? AllowAmbiguousChar { get; set; }
@@ -42,6 +42,12 @@
public bool? Capitalize { get; set; }
public bool? IncludeNumber { get; set; }
public PasswordGenerationOptions WithLength(int? length)
{
Length = length;
return this;
}
public void Merge(PasswordGenerationOptions defaults)
{
Length = Length ?? defaults.Length;
@@ -60,5 +66,75 @@
Capitalize = Capitalize ?? defaults.Capitalize;
IncludeNumber = IncludeNumber ?? defaults.IncludeNumber;
}
public void EnforcePolicy(PasswordGeneratorPolicyOptions enforcedPolicyOptions)
{
if (enforcedPolicyOptions is null)
{
return;
}
if (Length < enforcedPolicyOptions.MinLength)
{
Length = enforcedPolicyOptions.MinLength;
}
if (enforcedPolicyOptions.UseUppercase)
{
Uppercase = true;
}
if (enforcedPolicyOptions.UseLowercase)
{
Lowercase = true;
}
if (enforcedPolicyOptions.UseNumbers)
{
Number = true;
}
if (MinNumber < enforcedPolicyOptions.NumberCount)
{
MinNumber = enforcedPolicyOptions.NumberCount;
}
if (enforcedPolicyOptions.UseSpecial)
{
Special = true;
}
if (MinSpecial < enforcedPolicyOptions.SpecialCount)
{
MinSpecial = enforcedPolicyOptions.SpecialCount;
}
// Must normalize these fields because the receiving call expects all options to pass the current rules
if (MinSpecial + MinNumber > Length)
{
MinSpecial = Length - MinNumber;
}
if (NumWords < enforcedPolicyOptions.MinNumberOfWords)
{
NumWords = enforcedPolicyOptions.MinNumberOfWords;
}
if (enforcedPolicyOptions.Capitalize)
{
Capitalize = true;
}
if (enforcedPolicyOptions.IncludeNumber)
{
IncludeNumber = true;
}
// Force default type if password/passphrase selected via policy
if (enforcedPolicyOptions.DefaultType == TYPE_PASSWORD || enforcedPolicyOptions.DefaultType == TYPE_PASSPHRASE)
{
Type = enforcedPolicyOptions.DefaultType;
}
}
}
}

View File

@@ -6,6 +6,11 @@ namespace Bit.Core.Models.Domain
{
public class Policy : Domain
{
public const string MINUTES_KEY = "minutes";
public const string ACTION_KEY = "action";
public const string ACTION_LOCK = "lock";
public const string ACTION_LOGOUT = "logOut";
public Policy() { }
public Policy(PolicyData obj)
@@ -22,5 +27,32 @@ namespace Bit.Core.Models.Domain
public PolicyType Type { get; set; }
public Dictionary<string, object> Data { get; set; }
public bool Enabled { get; set; }
public int? GetInt(string key)
{
if (Data.TryGetValue(key, out var val) && val != null)
{
return (int)(long)val;
}
return null;
}
public bool? GetBool(string key)
{
if (Data.TryGetValue(key, out var val) && val != null)
{
return (bool)val;
}
return null;
}
public string GetString(string key)
{
if (Data.TryGetValue(key, out var val))
{
return (string)val;
}
return null;
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace Bit.Core.Models.Response
{
public class ConfigResponse
{
public string Version { get; set; }
public string GitHash { get; set; }
public ServerConfigResponse Server { get; set; }
public EnvironmentConfigResponse Environment { get; set; }
public IDictionary<string, object> FeatureStates { get; set; }
public DateTime ExpiresOn { get; set; }
}
public class ServerConfigResponse
{
public string Name { get; set; }
public string Url { get; set; }
}
public class EnvironmentConfigResponse
{
public string Vault { get; set; }
public string Api { get; set; }
public string Identity { get; set; }
public string Notifications { get; set; }
public string Sso { get; set; }
}
}

View File

@@ -586,6 +586,16 @@ namespace Bit.Core.Services
#endregion
#region Configs
public async Task<ConfigResponse> GetConfigsAsync()
{
var accessToken = await _tokenService.GetTokenAsync();
return await SendAsync<object, ConfigResponse>(HttpMethod.Get, "/config/", null, !string.IsNullOrEmpty(accessToken), true);
}
#endregion
#region Helpers
public async Task<string> GetActiveBearerTokenAsync()

View File

@@ -605,7 +605,7 @@ namespace Bit.Core.Services
var generatedFingerprintPhrase = await _cryptoService.GetFingerprintAsync(email, keyPair.Item1);
var fingerprintPhrase = string.Join("-", generatedFingerprintPhrase);
var publicB64 = Convert.ToBase64String(keyPair.Item1);
var accessCode = await _passwordGenerationService.GeneratePasswordAsync(new PasswordGenerationOptions(true) { Length = 25 });
var accessCode = await _passwordGenerationService.GeneratePasswordAsync(PasswordGenerationOptions.CreateDefault.WithLength(25));
var passwordlessCreateLoginRequest = new PasswordlessCreateLoginRequest(email, publicB64, deviceId, accessCode, AuthRequestType.AuthenticateAndUnlock, fingerprintPhrase);
var response = await _apiService.PostCreateRequestAsync(passwordlessCreateLoginRequest);

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Exceptions;
using Bit.Core.Models.Domain;
using Bit.Core.Models.Response;
using Bit.Core.Models.View;
namespace Bit.Core.Services
{
public class ConfigService : IConfigService
{
private const int UPDATE_INTERVAL_MINS = 60;
private ConfigResponse _configs;
private readonly IApiService _apiService;
private readonly IStateService _stateService;
private readonly ILogger _logger;
public ConfigService(IApiService apiService, IStateService stateService, ILogger logger)
{
_apiService = apiService;
_stateService = stateService;
_logger = logger;
}
public async Task<ConfigResponse> GetAsync(bool forceRefresh = false)
{
try
{
_configs = _stateService.GetConfigs();
if (forceRefresh || _configs?.ExpiresOn is null || _configs.ExpiresOn <= DateTime.UtcNow)
{
_configs = await _apiService.GetConfigsAsync();
_configs.ExpiresOn = DateTime.UtcNow.AddMinutes(UPDATE_INTERVAL_MINS);
_stateService.SetConfigs(_configs);
}
}
catch (ApiException ex) when (ex.Error.StatusCode == System.Net.HttpStatusCode.BadGateway)
{
// ignore if there is no internet connection and return local configs
}
catch (Exception ex)
{
_logger.Exception(ex);
}
return _configs;
}
public async Task<bool> GetFeatureFlagBoolAsync(string key, bool forceRefresh = false, bool defaultValue = false) => await GetFeatureFlagAsync<bool>(key, forceRefresh, defaultValue);
public async Task<string> GetFeatureFlagStringAsync(string key, bool forceRefresh = false, string defaultValue = null) => await GetFeatureFlagAsync<string>(key, forceRefresh, defaultValue);
public async Task<int> GetFeatureFlagIntAsync(string key, bool forceRefresh = false, int defaultValue = 0) => await GetFeatureFlagAsync<int>(key, forceRefresh, defaultValue);
private async Task<T> GetFeatureFlagAsync<T>(string key, bool forceRefresh = false, T defaultValue = default)
{
await GetAsync(forceRefresh);
if (_configs == null || _configs.FeatureStates == null)
{
return defaultValue;
}
if (_configs.FeatureStates.TryGetValue(key, out var val) == true
&&
val is T actualValue)
{
return actualValue;
}
return defaultValue;
}
}
}

View File

@@ -6,7 +6,6 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using Zxcvbn;
@@ -15,17 +14,17 @@ namespace Bit.Core.Services
{
public class PasswordGenerationService : IPasswordGenerationService
{
private const int MaxPasswordsInHistory = 100;
private const string LowercaseCharSet = "abcdefghijkmnopqrstuvwxyz";
private const string UppercaseCharSet = "ABCDEFGHJKLMNPQRSTUVWXYZ";
private const string NumberCharSet = "23456789";
private const string SpecialCharSet = "!@#$%^&*";
private const int MAX_PASSWORDS_IN_HISTORY = 100;
private const string LOWERCASE_CHAR_SET = "abcdefghijkmnopqrstuvwxyz";
private const string UPPERCASE_CHAR_SET = "ABCDEFGHJKLMNPQRSTUVWXYZ";
private const string NUMER_CHAR_SET = "23456789";
private const string SPECIAL_CHAR_SET = "!@#$%^&*";
private readonly ICryptoService _cryptoService;
private readonly IStateService _stateService;
private readonly ICryptoFunctionService _cryptoFunctionService;
private readonly IPolicyService _policyService;
private PasswordGenerationOptions _defaultOptions = new PasswordGenerationOptions(true);
private PasswordGenerationOptions _defaultOptions = PasswordGenerationOptions.CreateDefault;
private PasswordGenerationOptions _optionsCache;
private List<GeneratedPasswordHistory> _history;
@@ -45,7 +44,7 @@ namespace Bit.Core.Services
{
// Overload defaults with given options
options.Merge(_defaultOptions);
if (options.Type == "passphrase")
if (options.Type == PasswordGenerationOptions.TYPE_PASSPHRASE)
{
return await GeneratePassphraseAsync(options);
}
@@ -54,30 +53,30 @@ namespace Bit.Core.Services
SanitizePasswordLength(options, true);
var positionsBuilder = new StringBuilder();
if (options.Lowercase.GetValueOrDefault() && options.MinLowercase.GetValueOrDefault() > 0)
if (options.Lowercase.GetValueOrDefault() && options.MinLowercase > 0)
{
for (int i = 0; i < options.MinLowercase.GetValueOrDefault(); i++)
for (int i = 0; i < options.MinLowercase; i++)
{
positionsBuilder.Append("l");
}
}
if (options.Uppercase.GetValueOrDefault() && options.MinUppercase.GetValueOrDefault() > 0)
if (options.Uppercase.GetValueOrDefault() && options.MinUppercase > 0)
{
for (int i = 0; i < options.MinUppercase.GetValueOrDefault(); i++)
for (int i = 0; i < options.MinUppercase; i++)
{
positionsBuilder.Append("u");
}
}
if (options.Number.GetValueOrDefault() && options.MinNumber.GetValueOrDefault() > 0)
if (options.Number.GetValueOrDefault() && options.MinNumber > 0)
{
for (int i = 0; i < options.MinNumber.GetValueOrDefault(); i++)
for (int i = 0; i < options.MinNumber; i++)
{
positionsBuilder.Append("n");
}
}
if (options.Special.GetValueOrDefault() && options.MinSpecial.GetValueOrDefault() > 0)
if (options.Special.GetValueOrDefault() && options.MinSpecial > 0)
{
for (int i = 0; i < options.MinSpecial.GetValueOrDefault(); i++)
for (int i = 0; i < options.MinSpecial; i++)
{
positionsBuilder.Append("s");
}
@@ -92,68 +91,68 @@ namespace Bit.Core.Services
.OrderBy(a => _cryptoFunctionService.RandomNumber()).ToArray();
// Build out other character sets
var allCharSet = string.Empty;
var lowercaseCharSet = LowercaseCharSet;
var allCharSet = new StringBuilder();
var lowercaseCharSet = LOWERCASE_CHAR_SET;
if (options.AllowAmbiguousChar.GetValueOrDefault())
{
lowercaseCharSet = string.Concat(lowercaseCharSet, "l");
}
if (options.Lowercase.GetValueOrDefault())
{
allCharSet = string.Concat(allCharSet, lowercaseCharSet);
allCharSet.Append(lowercaseCharSet);
}
var uppercaseCharSet = UppercaseCharSet;
var uppercaseCharSet = UPPERCASE_CHAR_SET;
if (options.AllowAmbiguousChar.GetValueOrDefault())
{
uppercaseCharSet = string.Concat(uppercaseCharSet, "IO");
}
if (options.Uppercase.GetValueOrDefault())
{
allCharSet = string.Concat(allCharSet, uppercaseCharSet);
allCharSet.Append(uppercaseCharSet);
}
var numberCharSet = NumberCharSet;
var numberCharSet = NUMER_CHAR_SET;
if (options.AllowAmbiguousChar.GetValueOrDefault())
{
numberCharSet = string.Concat(numberCharSet, "01");
}
if (options.Number.GetValueOrDefault())
{
allCharSet = string.Concat(allCharSet, numberCharSet);
allCharSet.Append(numberCharSet);
}
var specialCharSet = SpecialCharSet;
if (options.Special.GetValueOrDefault())
{
allCharSet = string.Concat(allCharSet, specialCharSet);
allCharSet.Append(SPECIAL_CHAR_SET);
}
var password = new StringBuilder();
for (var i = 0; i < options.Length.GetValueOrDefault(); i++)
{
var positionChars = string.Empty;
var charSetOnCurrentPosition = string.Empty;
switch (positions[i])
{
case 'l':
positionChars = lowercaseCharSet;
charSetOnCurrentPosition = lowercaseCharSet;
break;
case 'u':
positionChars = uppercaseCharSet;
charSetOnCurrentPosition = uppercaseCharSet;
break;
case 'n':
positionChars = numberCharSet;
charSetOnCurrentPosition = numberCharSet;
break;
case 's':
positionChars = specialCharSet;
charSetOnCurrentPosition = SPECIAL_CHAR_SET;
break;
case 'a':
positionChars = allCharSet;
charSetOnCurrentPosition = allCharSet.ToString();
break;
}
var randomCharIndex = await _cryptoService.RandomNumberAsync(0, positionChars.Length - 1);
password.Append(positionChars[randomCharIndex]);
var randomCharIndex = await _cryptoService.RandomNumberAsync(0, charSetOnCurrentPosition.Length - 1);
password.Append(charSetOnCurrentPosition[randomCharIndex]);
}
return password.ToString();
@@ -168,7 +167,7 @@ namespace Bit.Core.Services
public async Task<string> GeneratePassphraseAsync(PasswordGenerationOptions options)
{
options.Merge(_defaultOptions);
if (options.NumWords.GetValueOrDefault() <= 2)
if (options.NumWords <= 2)
{
options.NumWords = _defaultOptions.NumWords;
}
@@ -221,179 +220,10 @@ namespace Bit.Core.Services
}
}
var (enforcedOptions, enforcedPolicyOptions) = await EnforcePasswordGeneratorPoliciesOnOptionsAsync(
_optionsCache);
_optionsCache = enforcedOptions;
return (_optionsCache, enforcedPolicyOptions);
}
var policyOptions = await _policyService.GetPasswordGeneratorPolicyOptionsAsync();
_optionsCache.EnforcePolicy(policyOptions);
public async Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)>
EnforcePasswordGeneratorPoliciesOnOptionsAsync(PasswordGenerationOptions options)
{
var enforcedPolicyOptions = await GetPasswordGeneratorPolicyOptions();
if (enforcedPolicyOptions != null)
{
if (options.Length < enforcedPolicyOptions.MinLength)
{
options.Length = enforcedPolicyOptions.MinLength;
}
if (enforcedPolicyOptions.UseUppercase)
{
options.Uppercase = true;
}
if (enforcedPolicyOptions.UseLowercase)
{
options.Lowercase = true;
}
if (enforcedPolicyOptions.UseNumbers)
{
options.Number = true;
}
if (options.MinNumber < enforcedPolicyOptions.NumberCount)
{
options.MinNumber = enforcedPolicyOptions.NumberCount;
}
if (enforcedPolicyOptions.UseSpecial)
{
options.Special = true;
}
if (options.MinSpecial < enforcedPolicyOptions.SpecialCount)
{
options.MinSpecial = enforcedPolicyOptions.SpecialCount;
}
// Must normalize these fields because the receiving call expects all options to pass the current rules
if (options.MinSpecial + options.MinNumber > options.Length)
{
options.MinSpecial = options.Length - options.MinNumber;
}
if (options.NumWords < enforcedPolicyOptions.MinNumberOfWords)
{
options.NumWords = enforcedPolicyOptions.MinNumberOfWords;
}
if (enforcedPolicyOptions.Capitalize)
{
options.Capitalize = true;
}
if (enforcedPolicyOptions.IncludeNumber)
{
options.IncludeNumber = true;
}
// Force default type if password/passphrase selected via policy
if (enforcedPolicyOptions.DefaultType == "password" || enforcedPolicyOptions.DefaultType == "passphrase")
{
options.Type = enforcedPolicyOptions.DefaultType;
}
}
else
{
// UI layer expects an instantiated object to prevent more explicit null checks
enforcedPolicyOptions = new PasswordGeneratorPolicyOptions();
}
return (options, enforcedPolicyOptions);
}
public async Task<PasswordGeneratorPolicyOptions> GetPasswordGeneratorPolicyOptions()
{
var policies = await _policyService.GetAll(PolicyType.PasswordGenerator);
PasswordGeneratorPolicyOptions enforcedOptions = null;
if (policies == null || !policies.Any())
{
return enforcedOptions;
}
foreach (var currentPolicy in policies)
{
if (!currentPolicy.Enabled || currentPolicy.Data == null)
{
continue;
}
if (enforcedOptions == null)
{
enforcedOptions = new PasswordGeneratorPolicyOptions();
}
var defaultType = GetPolicyString(currentPolicy, "defaultType");
if (defaultType != null && enforcedOptions.DefaultType != "password")
{
enforcedOptions.DefaultType = defaultType;
}
var minLength = GetPolicyInt(currentPolicy, "minLength");
if (minLength != null && (int)(long)minLength > enforcedOptions.MinLength)
{
enforcedOptions.MinLength = (int)(long)minLength;
}
var useUpper = GetPolicyBool(currentPolicy, "useUpper");
if (useUpper != null && (bool)useUpper)
{
enforcedOptions.UseUppercase = true;
}
var useLower = GetPolicyBool(currentPolicy, "useLower");
if (useLower != null && (bool)useLower)
{
enforcedOptions.UseLowercase = true;
}
var useNumbers = GetPolicyBool(currentPolicy, "useNumbers");
if (useNumbers != null && (bool)useNumbers)
{
enforcedOptions.UseNumbers = true;
}
var minNumbers = GetPolicyInt(currentPolicy, "minNumbers");
if (minNumbers != null && (int)(long)minNumbers > enforcedOptions.NumberCount)
{
enforcedOptions.NumberCount = (int)(long)minNumbers;
}
var useSpecial = GetPolicyBool(currentPolicy, "useSpecial");
if (useSpecial != null && (bool)useSpecial)
{
enforcedOptions.UseSpecial = true;
}
var minSpecial = GetPolicyInt(currentPolicy, "minSpecial");
if (minSpecial != null && (int)(long)minSpecial > enforcedOptions.SpecialCount)
{
enforcedOptions.SpecialCount = (int)(long)minSpecial;
}
var minNumberWords = GetPolicyInt(currentPolicy, "minNumberWords");
if (minNumberWords != null && (int)(long)minNumberWords > enforcedOptions.MinNumberOfWords)
{
enforcedOptions.MinNumberOfWords = (int)(long)minNumberWords;
}
var capitalize = GetPolicyBool(currentPolicy, "capitalize");
if (capitalize != null && (bool)capitalize)
{
enforcedOptions.Capitalize = true;
}
var includeNumber = GetPolicyBool(currentPolicy, "includeNumber");
if (includeNumber != null && (bool)includeNumber)
{
enforcedOptions.IncludeNumber = true;
}
}
return enforcedOptions;
return (_optionsCache, policyOptions ?? new PasswordGeneratorPolicyOptions());
}
public List<string> GetPasswordStrengthUserInput(string email)
@@ -409,45 +239,6 @@ namespace Bit.Core.Services
return new List<string>(data);
}
private int? GetPolicyInt(Policy policy, string key)
{
if (policy.Data.ContainsKey(key))
{
var value = policy.Data[key];
if (value != null)
{
return (int)(long)value;
}
}
return null;
}
private bool? GetPolicyBool(Policy policy, string key)
{
if (policy.Data.ContainsKey(key))
{
var value = policy.Data[key];
if (value != null)
{
return (bool)value;
}
}
return null;
}
private string GetPolicyString(Policy policy, string key)
{
if (policy.Data.ContainsKey(key))
{
var value = policy.Data[key];
if (value != null)
{
return (string)value;
}
}
return null;
}
public async Task SaveOptionsAsync(PasswordGenerationOptions options)
{
await _stateService.SetPasswordGenerationOptionsAsync(options);
@@ -485,7 +276,7 @@ namespace Bit.Core.Services
token.ThrowIfCancellationRequested();
currentHistory.Insert(0, new GeneratedPasswordHistory { Password = password, Date = DateTime.UtcNow });
// Remove old items.
if (currentHistory.Count > MaxPasswordsInHistory)
if (currentHistory.Count > MAX_PASSWORDS_IN_HISTORY)
{
currentHistory.RemoveAt(currentHistory.Count - 1);
}

View File

@@ -17,11 +17,6 @@ namespace Bit.Core.Services
private IEnumerable<Policy> _policyCache;
public const string TIMEOUT_POLICY_MINUTES = "minutes";
public const string TIMEOUT_POLICY_ACTION = "action";
public const string TIMEOUT_POLICY_ACTION_LOCK = "lock";
public const string TIMEOUT_POLICY_ACTION_LOGOUT = "logOut";
public PolicyService(
IStateService stateService,
IOrganizationService organizationService)
@@ -51,10 +46,8 @@ namespace Bit.Core.Services
{
return _policyCache.Where(p => p.Type == type).ToList();
}
else
{
return _policyCache;
}
return _policyCache;
}
public async Task Replace(Dictionary<string, PolicyData> policies, string userId = null)
@@ -77,7 +70,7 @@ namespace Bit.Core.Services
public async Task UpdateVaultTimeoutFromPolicyAsync(Policy policy, string userId = null)
{
var policyTimeout = GetPolicyInt(policy, PolicyService.TIMEOUT_POLICY_MINUTES);
var policyTimeout = policy.GetInt(Policy.MINUTES_KEY);
if (policyTimeout != null)
{
var vaultTimeout = await _stateService.GetVaultTimeoutAsync(userId);
@@ -92,11 +85,11 @@ namespace Bit.Core.Services
}
}
var policyAction = GetPolicyString(policy, PolicyService.TIMEOUT_POLICY_ACTION);
var policyAction = policy.GetString(Policy.ACTION_KEY);
if (!string.IsNullOrEmpty(policyAction))
{
var vaultTimeoutAction = await _stateService.GetVaultTimeoutActionAsync(userId);
var action = policyAction == PolicyService.TIMEOUT_POLICY_ACTION_LOCK ? VaultTimeoutAction.Lock : VaultTimeoutAction.Logout;
var action = policyAction == Policy.ACTION_LOCK ? VaultTimeoutAction.Lock : VaultTimeoutAction.Logout;
if (vaultTimeoutAction != action)
{
await _stateService.SetVaultTimeoutActionAsync(action, userId);
@@ -107,71 +100,63 @@ namespace Bit.Core.Services
public async Task<MasterPasswordPolicyOptions> GetMasterPasswordPolicyOptions(
IEnumerable<Policy> policies = null, string userId = null)
{
MasterPasswordPolicyOptions enforcedOptions = null;
if (policies == null)
{
policies = await GetAll(PolicyType.MasterPassword, userId);
if (policies == null)
{
return null;
}
}
else
{
policies = policies.Where(p => p.Type == PolicyType.MasterPassword);
}
if (policies == null || !policies.Any())
policies = policies.Where(p => p.Enabled && p.Data != null);
if (!policies.Any())
{
return enforcedOptions;
return null;
}
var enforcedOptions = new MasterPasswordPolicyOptions();
foreach (var currentPolicy in policies)
{
if (!currentPolicy.Enabled || currentPolicy.Data == null)
var minComplexity = currentPolicy.GetInt("minComplexity");
if (minComplexity > enforcedOptions.MinComplexity)
{
continue;
enforcedOptions.MinComplexity = minComplexity.Value;
}
if (enforcedOptions == null)
var minLength = currentPolicy.GetInt("minLength");
if (minLength > enforcedOptions.MinLength)
{
enforcedOptions = new MasterPasswordPolicyOptions();
enforcedOptions.MinLength = minLength.Value;
}
var minComplexity = GetPolicyInt(currentPolicy, "minComplexity");
if (minComplexity != null && (int)(long)minComplexity > enforcedOptions.MinComplexity)
{
enforcedOptions.MinComplexity = (int)(long)minComplexity;
}
var minLength = GetPolicyInt(currentPolicy, "minLength");
if (minLength != null && (int)(long)minLength > enforcedOptions.MinLength)
{
enforcedOptions.MinLength = (int)(long)minLength;
}
var requireUpper = GetPolicyBool(currentPolicy, "requireUpper");
if (requireUpper == true)
if (currentPolicy.GetBool("requireUpper") == true)
{
enforcedOptions.RequireUpper = true;
}
var requireLower = GetPolicyBool(currentPolicy, "requireLower");
if (requireLower == true)
if (currentPolicy.GetBool("requireLower") == true)
{
enforcedOptions.RequireLower = true;
}
var requireNumbers = GetPolicyBool(currentPolicy, "requireNumbers");
if (requireNumbers == true)
if (currentPolicy.GetBool("requireNumbers") == true)
{
enforcedOptions.RequireNumbers = true;
}
var requireSpecial = GetPolicyBool(currentPolicy, "requireSpecial");
if (requireSpecial == true)
if (currentPolicy.GetBool("requireSpecial") == true)
{
enforcedOptions.RequireSpecial = true;
}
var enforceOnLogin = GetPolicyBool(currentPolicy, "enforceOnLogin");
var enforceOnLogin = currentPolicy.GetBool("enforceOnLogin");
if (enforceOnLogin == true)
{
enforcedOptions.EnforceOnLogin = true;
@@ -234,7 +219,7 @@ namespace Bit.Core.Services
var policy = policies.FirstOrDefault(p =>
p.OrganizationId == orgId && p.Type == PolicyType.ResetPassword && p.Enabled);
resetPasswordPolicyOptions.AutoEnrollEnabled = GetPolicyBool(policy, "autoEnrollEnabled") ?? false;
resetPasswordPolicyOptions.AutoEnrollEnabled = policy.GetBool("autoEnrollEnabled") ?? false;
return new Tuple<ResetPasswordPolicyOptions, bool>(resetPasswordPolicyOptions, policy != null);
}
@@ -280,23 +265,6 @@ namespace Bit.Core.Services
return organization.isExemptFromPolicies;
}
public int? GetPolicyInt(Policy policy, string key)
{
if (policy.Data.ContainsKey(key))
{
var value = policy.Data[key];
if (value != null)
{
return (int)(long)value;
}
}
return null;
}
public string GetPolicyString(Policy policy, string key) =>
policy.Data.TryGetValue(key, out var val) ? val as string : null;
public async Task<bool> ShouldShowVaultFilterAsync()
{
var personalOwnershipPolicyApplies = await PolicyAppliesToUser(PolicyType.PersonalOwnership);
@@ -309,19 +277,86 @@ namespace Bit.Core.Services
return organizations?.Any() ?? false;
}
private bool? GetPolicyBool(Policy policy, string key)
public async Task<PasswordGeneratorPolicyOptions> GetPasswordGeneratorPolicyOptionsAsync()
{
if (policy.Data.ContainsKey(key))
var policies = await GetAll(PolicyType.PasswordGenerator);
if (policies == null)
{
var value = policy.Data[key];
if (value != null)
return null;
}
var actualPolicies = policies.Where(p => p.Enabled && p.Data != null);
if (!actualPolicies.Any())
{
return null;
}
var enforcedOptions = new PasswordGeneratorPolicyOptions();
foreach (var currentPolicy in actualPolicies)
{
var defaultType = currentPolicy.GetString("defaultType");
if (defaultType != null && enforcedOptions.DefaultType != PasswordGenerationOptions.TYPE_PASSWORD)
{
return (bool)value;
enforcedOptions.DefaultType = defaultType;
}
var minLength = currentPolicy.GetInt("minLength");
if (minLength > enforcedOptions.MinLength)
{
enforcedOptions.MinLength = minLength.Value;
}
if (currentPolicy.GetBool("useUpper") == true)
{
enforcedOptions.UseUppercase = true;
}
if (currentPolicy.GetBool("useLower") == true)
{
enforcedOptions.UseLowercase = true;
}
if (currentPolicy.GetBool("useNumbers") == true)
{
enforcedOptions.UseNumbers = true;
}
var minNumbers = currentPolicy.GetInt("minNumbers");
if (minNumbers > enforcedOptions.NumberCount)
{
enforcedOptions.NumberCount = minNumbers.Value;
}
if (currentPolicy.GetBool("useSpecial") == true)
{
enforcedOptions.UseSpecial = true;
}
var minSpecial = currentPolicy.GetInt("minSpecial");
if (minSpecial > enforcedOptions.SpecialCount)
{
enforcedOptions.SpecialCount = minSpecial.Value;
}
var minNumberWords = currentPolicy.GetInt("minNumberWords");
if (minNumberWords > enforcedOptions.MinNumberOfWords)
{
enforcedOptions.MinNumberOfWords = minNumberWords.Value;
}
if (currentPolicy.GetBool("capitalize") == true)
{
enforcedOptions.Capitalize = true;
}
if (currentPolicy.GetBool("includeNumber") == true)
{
enforcedOptions.IncludeNumber = true;
}
}
return null;
return enforcedOptions;
}
}
}

View File

@@ -1280,6 +1280,16 @@ namespace Bit.Core.Services
await SetValueAsync(Constants.PreLoginEmailKey, value, options);
}
public ConfigResponse GetConfigs()
{
return _storageMediatorService.Get<ConfigResponse>(Constants.ConfigsKey);
}
public void SetConfigs(ConfigResponse value)
{
_storageMediatorService.Save(Constants.ConfigsKey, value);
}
// Helpers
[Obsolete("Use IStorageMediatorService instead")]

View File

@@ -3,6 +3,7 @@ using System.Linq;
using System.Threading.Tasks;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Models.Domain;
namespace Bit.Core.Services
{

View File

@@ -75,8 +75,7 @@ namespace Bit.Core.Utilities
messagingService.Send("logout", extras);
return Task.CompletedTask;
});
var passwordGenerationService = new PasswordGenerationService(cryptoService, stateService,
cryptoFunctionService, policyService);
var passwordGenerationService = new PasswordGenerationService(cryptoService, stateService, cryptoFunctionService, policyService);
var totpService = new TotpService(cryptoFunctionService);
var authService = new AuthService(cryptoService, cryptoFunctionService, apiService, stateService,
tokenService, appIdService, i18nService, platformUtilsService, messagingService, vaultTimeoutService,
@@ -88,6 +87,7 @@ namespace Bit.Core.Utilities
var userVerificationService = new UserVerificationService(apiService, platformUtilsService, i18nService,
cryptoService);
var usernameGenerationService = new UsernameGenerationService(cryptoService, apiService, stateService);
var configService = new ConfigService(apiService, stateService, logger);
Register<IConditionedAwaiterManager>(conditionedRunner);
Register<ITokenService>("tokenService", tokenService);
@@ -113,6 +113,7 @@ namespace Bit.Core.Utilities
Register<IKeyConnectorService>("keyConnectorService", keyConnectorService);
Register<IUserVerificationService>("userVerificationService", userVerificationService);
Register<IUsernameGenerationService>(usernameGenerationService);
Register<IConfigService>(configService);
}
public static void Register<T>(string serviceName, T obj)

View File

@@ -266,7 +266,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>4.5.3</Version>
<Version>5.0.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>11.0</string>
<key>CFBundleDisplayName</key>
<string>Bitwarden</string>
<key>CFBundleName</key>

View File

@@ -242,7 +242,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>4.5.3</Version>
<Version>5.0.1</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.AppExtension.CSharp.targets" />

View File

@@ -19,7 +19,7 @@
<key>CFBundleVersion</key>
<string>1</string>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>11.0</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionMainStoryboard</key>

View File

@@ -167,7 +167,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes">
<Version>4.5.3</Version>
<Version>5.0.1</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>

View File

@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>MinimumOSVersion</key>
<string>10.0</string>
<string>11.0</string>
<key>CFBundleDisplayName</key>
<string>Bitwarden</string>
<key>CFBundleName</key>

View File

@@ -195,7 +195,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Xamarin.Essentials">
<Version>1.7.3</Version>
<Version>1.7.5</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />

View File

@@ -2,7 +2,7 @@ import Foundation
struct CipherMock {
static let ciphers:[Cipher] = [
Cipher(id: "0", name: "1933", userId: "123123", login: Login(username: "thisisatest@testing.com", totp: "otpauth://account?period=10&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "0", name: "MySite", userId: "123123", login: Login(username: "test@testing.com", totp: "otpauth://account?period=10&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "1", name: "GitHub", userId: "123123", login: Login(username: "thisisatest@testing.com", totp: "LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "2", name: "No user", userId: "123123", login: Login(username: nil, totp: "otpauth://account?period=10&digits=8&algorithm=sha256&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),
Cipher(id: "3", name: "Site 2", userId: "123123", login: Login(username: "longtestemail000000@fastmailasdfasdf.com", totp: "otpauth://account?period=10&digits=7&algorithm=sha512&secret=LLLLLLLLLLLLLLLL", uris: cipherLoginUris)),

View File

@@ -34,30 +34,34 @@ class CipherDetailsViewModel: ObservableObject{
self.counter = self.period - mod
self.progress = Double(self.counter) / Double(self.period)
}
if mod == 0 || self.totpFormatted == "" {
do {
var totpF = try TotpService.shared.GetCodeAsync(key: self.key) ?? ""
if totpF.count > 4 {
let halfIndex = totpF.index(totpF.startIndex, offsetBy: totpF.count / 2)
totpF = "\(totpF[totpF.startIndex..<halfIndex]) \(totpF[halfIndex..<totpF.endIndex])"
}
DispatchQueue.main.async {
self.totpFormatted = totpF
}
try self.regenerateTotp()
} catch {
DispatchQueue.main.async {
self.totpFormatted = "error"
t.invalidate()
}
}
}
})
RunLoop.current.add(timer!, forMode: .common)
timer?.fire()
}
func stopGeneration(){
func stopGeneration() {
self.timer?.invalidate()
}
func regenerateTotp() throws {
var totpF = try TotpService.shared.GetCodeAsync(key: self.key) ?? ""
if totpF.count > 4 {
let halfIndex = totpF.index(totpF.startIndex, offsetBy: totpF.count / 2)
totpF = "\(totpF[totpF.startIndex..<halfIndex]) \(totpF[halfIndex..<totpF.endIndex])"
}
DispatchQueue.main.async {
self.totpFormatted = totpF
}
}
}

View File

@@ -2,6 +2,7 @@ import SwiftUI
struct CipherDetailsView: View {
@ObservedObject var cipherDetailsViewModel: CipherDetailsViewModel
@Environment(\.scenePhase) var scenePhase
let iconSize: CGSize = CGSize(width: 30, height: 30)
@@ -49,6 +50,7 @@ struct CipherDetailsView: View {
.fontWeight(.bold)
.lineLimit(1)
.truncationMode(.tail)
.privacySensitive()
}
if cipherDetailsViewModel.totpFormatted == "" {
ProgressView()
@@ -61,6 +63,7 @@ struct CipherDetailsView: View {
.minimumScaleFactor(0.01)
.lineLimit(1)
.id(cipherDetailsViewModel.totpFormatted)
.privacySensitive()
.transition(transition)
.animation(.default.speed(0.7), value: cipherDetailsViewModel.totpFormatted)
Spacer()
@@ -70,6 +73,7 @@ struct CipherDetailsView: View {
Text("\(cipherDetailsViewModel.counter)")
.font(.title3)
.fontWeight(.semibold)
.privacySensitive()
}
}
.padding(.top, 20)
@@ -83,6 +87,11 @@ struct CipherDetailsView: View {
.onDisappear{
self.cipherDetailsViewModel.stopGeneration()
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
try? self.cipherDetailsViewModel.regenerateTotp()
}
}
}
var iconPlaceholderImage: some View{

View File

@@ -36,6 +36,7 @@ struct CipherItemView: View {
.truncationMode(.tail)
.foregroundColor(Color.ui.darkTextMuted)
.frame(maxWidth: .infinity, alignment: .leading)
.privacySensitive()
}
}
.padding()

View File

@@ -87,6 +87,7 @@ struct CipherListView: View {
.font(.headline)
.lineLimit(1)
.truncationMode(.tail)
.privacySensitive()
}
}

View File

@@ -118,55 +118,55 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Name" xml:space="preserve">
<value>Bitwarden पासवर्ड मैनेजर</value>
<value>बिटवार्डन पासवर्ड मैनेजर</value>
<comment>Max 30 characters</comment>
</data>
<data name="Description" xml:space="preserve">
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
<value>बिटवार्डन अंतरराष्ट्रीय कॉरपोरेशन, 8बिट सॉल्यूश्नस एलएलसी की मूल कंपनी है।
NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS &amp; WORLD REPORT, CNET, AND MORE.
द वर्ज, यूएस न्यूज़ एंड वर्ल्ड रिपोर्ट, सीनेट, और कई दूसरे मीडिया संगठन द्वारा बोला गया दुनिया का सबसे बेहतरीन पासवर्ड मैनेजर।
Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go.
अनगिनत पासवर्ड मैनेज, स्टोर, महफूज़, और शेयर करें कही से भी। बिटवार्डन देता है ओपन सोर्स पासवर्ड मैनेजमेंट सुविधा सबको, चाहे वो घर पर हो, दफ्तर पर हो, या घूम रहे हो।
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
आप जिन वेबसाइट पर जाते है उनके लिए बनाएं ताकतवर, खास, और बेतरतीब पासवर्ड उनकी सुरक्षा ज़रूरतो के हिसाब से।
Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone.
बिटवार्डन सेंड किसी को भी एन्क्रिप्टेड जानकारी, फाइल और सादा टेक्सट, तुरंत भेजें।
Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues.
बिटवार्डन कंपनियों के लिए टीम और बिज़नेस प्लान भी देता है ताकि आप अपने साथ काम करनेवालो के साथ पासवर्ड शेयर करे सुरक्षित होकर।
Why Choose Bitwarden:
बिटवार्डन को क्यों चुनें:
World-Class Encryption
Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private.
ताकतवर एन्क्रिप्शन
पासवर्ड एडवांस एंड-टू-एंड एन्क्रिप्शन (एईएस-256 बिट, सॉल्टेड हैशटैग, और पीबीकेडीएफ2 शा-256) के साथ सुरक्षित रखा जाता है ताकि आपका डाटा महफूज़ और निजी रहे।
Built-in Password Generator
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
पहले से बना पासवर्ड जेनरेटर
आप जिन वेबसाइट पर जाते है उनके लिए बनाएं ताकतवर, खास, और बेतरतीब पासवर्ड उनकी सुरक्षा ज़रूरतो के हिसाब से।
Global Translations
Bitwarden translations exist in 40 languages and are growing, thanks to our global community.
अंतरराष्ट्रीय अनुवाद
40 से ज़्यादा भाषा में बिटवार्डन इस्तेमाल करें, जिसे लिखा है हमारी अंतरराष्ट्रीय दोस्तो ने।
Cross-Platform Applications
Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.
कई प्लेनफॉर्म पर मौजूद
अपने बिटवार्डन तिजोरी से संवेदनशील डाटा महफूज़ और शेयर करें किसी भी ब्राउज़र, फोन, या डेस्कटॉप जैसे डिवाइसो से।
</value>
<comment>Max 4000 characters</comment>
</data>
<data name="Keywords" xml:space="preserve">
<value>बिटवर्डन, 8 बिट, पासवर्ड, फ्री पासवर्ड मैनेजर, पासवर्ड मैनेजर, लॉगिन मैनेजर</value>
<value>बिटवर्डन, 8 बिट, पासवर्ड, मुफ्त पासवर्ड मैनेजर, पासवर्ड मैनेजर, लॉगन मैनेजर</value>
<comment>Max 100 characters</comment>
</data>
<data name="Screenshot1" xml:space="preserve">
<value>एक सुरक्षित तिजोरी से अपने सभी लॉगिन और पासवर्ड प्रबंधित करें</value>
<value>एक सुरक्षित तिजोरी से अपने सारे लॉगन और पासवर्ड मैनेज करें</value>
</data>
<data name="Screenshot2" xml:space="preserve">
<value>स्वचालित रूप से मजबूत, यादृच्छिक और सुरक्षित पासवर्ड उत्पन्न करते हैं</value>
<value>अपनेआप ताकतवर, बेतरतीब, और महफूज़ पासवर्ड बनाएं</value>
</data>
<data name="Screenshot3" xml:space="preserve">
<value>टच आईडी, पिन कोड या मास्टर पासवर्ड से अपनी तिजोरी को सुरक्षित रखें</value>
<value>टच आईडी, पिन कोड, या मुख्य पासवर्ड से अपनी तिजोरी सुरक्षित रखें</value>
</data>
<data name="Screenshot4" xml:space="preserve">
<value>सफारी, क्रोम और अन्य सैकड़ों ऐप्स से ऑटो-फिल लॉगिन करें</value>
<value>सफारी, क्रोम, और सैकड़ों दूसरे ऐप से अपनेआप भरकर लॉगन करें</value>
</data>
<data name="Screenshot5" xml:space="preserve">
<value>कई उपकरणों से अपने Vault को सिंक और एक्सेस करें</value>
<value>अपने तिजोरी को अलग-अलग डिवाइसो से सिंक और एक्सेस करें</value>
</data>
</root>

View File

@@ -122,51 +122,50 @@
<comment>Max 30 characters</comment>
</data>
<data name="Description" xml:space="preserve">
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
<value>Bitwarden, Inc. je matično podjetje podjetja 8bit Solutions LLC.
NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS &amp; WORLD REPORT, CNET, AND MORE.
NAJBOŠJI UPRAVLJALNIK GESEL PO MNEJU THE VERGE, U.S. NEWS &amp; WORLD REPORT, CNET IN DRUGIH.
Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go.
Upravljajte, shranjujte, varujte in delite neomejeno število gesel na neomejenem številu naprav, kjerkoli. Bitwarden ponuja odprtokodne rešitve za upravljanje gesel vsem, tako doma kot v službi ali na poti.
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
Za vas ustvari močna, edinstvena in naključna gesla, skladna z varnostnimi zahtevami za vsako spletno mesto, ki ga obiščete.
Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone.
S pošiljkami Bitwarden Send hitro prenesite šifrirane informacije --- datoteke in navadno besedilo -- neposredno komurkoli.
Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues.
Bitwarden ponuja storitvi za organizacije Teams in Enterprise, s katerima lahko gesla varno souporabljate s sodelavci.
Why Choose Bitwarden:
Zakaj izbrati Bitwarden:
World-Class Encryption
Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private.
Vrhunsko šifriranje
Gesla so zaščitena z naprednim šifriranjem (AES-256, soljene hash-vrednosti in PBKDF2 SHA-256), tako da vaši podatki ostanejo varni in zasebni.
Built-in Password Generator
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
Vgrajen generator gesel
Ustvarite močna, edinstvena in naključna gesla v skladu z varnostnimi zahtevami za vsako spletno mesto, ki ga obiščete.
Global Translations
Bitwarden translations exist in 40 languages and are growing, thanks to our global community.
Prevodi za ves svet
Bitwarden je preveden že v 40 jezikov, naša globalna skupnost pa ves čas posodabljan in ustvarja nove prevede.
Cross-Platform Applications
Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.
</value>
Deluje na vseh platformah
Varujte in souporabljajte svoje občutljive podatke znotraj vašega Bitwarden trezorja v katerem koli brskalniku, mobilni napravi, namiznem računalniku in drugje.</value>
<comment>Max 4000 characters</comment>
</data>
<data name="Keywords" xml:space="preserve">
<value>bit warden,8bit,password,free password manager,password manager,login manager</value>
<value>bit warden,8bit,password,free password manager,password manager,login manager,upravljalnik gesel,shranjevalnik gesel,geslo,upravljalnik prijav</value>
<comment>Max 100 characters</comment>
</data>
<data name="Screenshot1" xml:space="preserve">
<value>Manage all your logins and passwords from a secure vault</value>
<value>Urejajte vse svoje prijavne podatke in gesla v zavarovanem trezorju</value>
</data>
<data name="Screenshot2" xml:space="preserve">
<value>Automatically generate strong, random, and secure passwords</value>
<value>Samodejno ustvari močna, naključna in varna gesla</value>
</data>
<data name="Screenshot3" xml:space="preserve">
<value>Protect your vault with Touch ID, PIN code, or master password</value>
<value>Zaščitite svoj trezor s pristnim odtisom, PIN-kodo ali glavnim geslom</value>
</data>
<data name="Screenshot4" xml:space="preserve">
<value>Auto-fill logins from Safari, Chrome, and hundreds of other apps</value>
<value>Samodejno izpolnjevanje prijav v aplikacijah Safari, Chrome in stotinah drugih</value>
</data>
<data name="Screenshot5" xml:space="preserve">
<value>Sync and access your vault from multiple devices</value>
<value>Sinhronizirajte svoj trezor gesel in dostopajte do njega z več naprav</value>
</data>
</root>

View File

@@ -118,61 +118,61 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Title" xml:space="preserve">
<value>bitwarden Password Manager</value>
<value>बिटवार्डन पासवर्ड मैनेजर</value>
<comment>Max 30 characters</comment>
</data>
<data name="ShortDescription" xml:space="preserve">
<value>bitwarden is a login and password manager that helps keep you safe while online.</value>
<value>बिटवाडर्न एक लॉगइन और पासवर्ड मैनेजर है जो आपको ऑनलाइन महफूज़ रखता है।</value>
<comment>Max 80 characters</comment>
</data>
<data name="FullDesciption" xml:space="preserve">
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
<value>बिटवार्डन अंतरराष्ट्रीय कॉरपोरेशन, 8बिट सॉल्यूश्नस एलएलसी की मूल कंपनी है।
NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS &amp; WORLD REPORT, CNET, AND MORE.
द वर्ज, यूएस न्यूज़ एंड वर्ल्ड रिपोर्ट, सीनेट, और कई दूसरे मीडिया संगठन द्वारा बोला गया दुनिया का सबसे बेहतरीन पासवर्ड मैनेजर।
Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go.
अनगिनत पासवर्ड मैनेज, स्टोर, महफूज़, और शेयर करें कही से भी। बिटवार्डन देता है ओपन सोर्स पासवर्ड मैनेजमेंट सुविधा सबको, चाहे वो घर पर हो, दफ्तर पर हो, या घूम रहे हो।
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
आप जिन वेबसाइट पर जाते है उनके लिए बनाएं ताकतवर, खास, और बेतरतीब पासवर्ड उनकी सुरक्षा ज़रूरतो के हिसाब से।
Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone.
बिटवार्डन सेंड किसी को भी एन्क्रिप्टेड जानकारी, फाइल और सादा टेक्सट, तुरंत भेजें।
Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues.
बिटवार्डन कंपनियों के लिए टीम और बिज़नेस प्लान भी देता है ताकि आप अपने साथ काम करनेवालो के साथ पासवर्ड शेयर करे सुरक्षित होकर।
Why Choose Bitwarden:
बिटवार्डन को क्यों चुनें:
World-Class Encryption
Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private.
ताकतवर एन्क्रिप्शन
पासवर्ड एडवांस एंड-टू-एंड एन्क्रिप्शन (एईएस-256 बिट, सॉल्टेड हैशटैग, और पीबीकेडीएफ2 शा-256) के साथ सुरक्षित रखा जाता है ताकि आपका डाटा महफूज़ और निजी रहे।
Built-in Password Generator
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
पहले से बना पासवर्ड जेनरेटर
आप जिन वेबसाइट पर जाते है उनके लिए बनाएं ताकतवर, खास, और बेतरतीब पासवर्ड उनकी सुरक्षा ज़रूरतो के हिसाब से।
Global Translations
Bitwarden translations exist in 40 languages and are growing, thanks to our global community.
अंतरराष्ट्रीय अनुवाद
40 से ज़्यादा भाषा में बिटवार्डन इस्तेमाल करें, जिसे लिखा है हमारी अंतरराष्ट्रीय दोस्तो ने।
Cross-Platform Applications
Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.
कई प्लेनफॉर्म पर मौजूद
अपने बिटवार्डन तिजोरी से संवेदनशील डाटा महफूज़ और शेयर करें किसी भी ब्राउज़र, फोन, या डेस्कटॉप जैसे डिवाइसो से।
</value>
<comment>Max 4000 characters</comment>
</data>
<data name="FeatureGraphic" xml:space="preserve">
<value>आपके सभी उपकरणों के लिए एक सुरक्षित और मुफ्त पासवर्ड प्रबंधक</value>
<value>आपके सारे डिवाइसो के लिए एक सुरक्षित और मुफ्त पासवर्ड मैनेजर</value>
</data>
<data name="Screenshot1" xml:space="preserve">
<value>एक सुरक्षित तिजोरी से अपने सभी लॉगिन और पासवर्ड प्रबंधित करें</value>
<value>एक सुरक्षित तिजोरी से अपने सारे लॉगन और पासवर्ड मैनेज करें</value>
</data>
<data name="Screenshot2" xml:space="preserve">
<value>स्वचालित रूप से मजबूत, यादृच्छिक और सुरक्षित पासवर्ड उत्पन्न करते हैं</value>
<value>अपनेआप ताकतवर, बेतरतीब, और महफूज़ पासवर्ड बनाएं</value>
</data>
<data name="Screenshot3" xml:space="preserve">
<value>टच आईडी, पिन कोड या मास्टर पासवर्ड से अपनी तिजोरी को सुरक्षित रखें</value>
<value>फिंगरप्रिंट, पिन कोड, या मुख्य पासवर्ड से अपनी तिजोरी सुरक्षित रखें</value>
</data>
<data name="Screenshot4" xml:space="preserve">
<value>अपने वेब ब्राउज़र और अन्य एप्लिकेशन के भीतर से जल्दी से लॉगिन करें</value>
<value>अपने वेब ब्राउज़र और दूसरे ऐप से जल्दी लॉगन करें</value>
</data>
<data name="Screenshot5" xml:space="preserve">
<value>कई उपकरणों से अपने वॉल्ट को सिंक और एक्सेस करें
<value>अपने तिजोरी को अलग-अलग डिवाइसों से सिंक और एक्सेस करें
- फोन
- फोन
- टैबलेट
- डेस्कटॉप
- वेब</value>

View File

@@ -118,61 +118,61 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Title" xml:space="preserve">
<value>Bitwarden shranjevalnik gesel</value>
<value>Bitwarden - upravitelj gesel</value>
<comment>Max 30 characters</comment>
</data>
<data name="ShortDescription" xml:space="preserve">
<value>Bitwarden je shranjevalnik dostopnih podatkov in gesel, ki vam pomaga ostati varen na spletu.</value>
<value>Bitwarden je upravitelj prijavnih podatkov in gesel, ki vam pomaga ohraniti varnost na spletu.</value>
<comment>Max 80 characters</comment>
</data>
<data name="FullDesciption" xml:space="preserve">
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
<value>Bitwarden, Inc. je matično podjetje podjetja 8bit Solutions LLC.
NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS &amp; WORLD REPORT, CNET, AND MORE.
NAJBOŠJI UPRAVLJALNIK GESEL PO MNEJU THE VERGE, U.S. NEWS &amp; WORLD REPORT, CNET IN DRUGIH.
Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go.
Upravljajte, shranjujte, varujte in delite neomejeno število gesel na neomejenem številu naprav, kjerkoli. Bitwarden ponuja odprtokodne rešitve za upravljanje gesel vsem, tako doma kot v službi ali na poti.
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
Za vas ustvari močna, edinstvena in naključna gesla, skladna z varnostnimi zahtevami za vsako spletno mesto, ki ga obiščete.
Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone.
S pošiljkami Bitwarden Send hitro prenesite šifrirane informacije --- datoteke in navadno besedilo -- neposredno komurkoli.
Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues.
Bitwarden ponuja storitvi za organizacije Teams in Enterprise, s katerima lahko gesla varno souporabljate s sodelavci.
Why Choose Bitwarden:
Zakaj izbrati Bitwarden:
World-Class Encryption
Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private.
Vrhunsko šifriranje
Gesla so zaščitena z naprednim šifriranjem (AES-256, soljene hash-vrednosti in PBKDF2 SHA-256), tako da vaši podatki ostanejo varni in zasebni.
Built-in Password Generator
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
Vgrajen generator gesel
Ustvarite močna, edinstvena in naključna gesla v skladu z varnostnimi zahtevami za vsako spletno mesto, ki ga obiščete.
Global Translations
Bitwarden translations exist in 40 languages and are growing, thanks to our global community.
Prevodi za ves svet
Bitwarden je preveden že v 40 jezikov, naša globalna skupnost pa ves čas posodabljan in ustvarja nove prevede.
Cross-Platform Applications
Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.
</value>
Deluje na vseh platformah
Varujte in souporabljajte svoje občutljive podatke znotraj vašega Bitwarden trezorja v katerem koli brskalniku, mobilni napravi, namiznem računalniku in drugje.</value>
<comment>Max 4000 characters</comment>
</data>
<data name="FeatureGraphic" xml:space="preserve">
<value>Varen in brezplačen shranjevalnik gesel za vse vaše naprave</value>
<value>Varen in brezplačen upravitelj gesel za vse vaše naprave</value>
</data>
<data name="Screenshot1" xml:space="preserve">
<value>Urejate vse svoje dostopne podatke in gesla iz varnega sefa</value>
<value>Urejajte vse svoje prijavne podatke in gesla v zavarovanem trezorju</value>
</data>
<data name="Screenshot2" xml:space="preserve">
<value>Samodejni ustvari močna, naključna in varna gesla</value>
<value>Samodejno ustvari močna, naključna in varna gesla</value>
</data>
<data name="Screenshot3" xml:space="preserve">
<value>Zaščitite svoj sef s pristnim odtisom, kodo PIN ali glavnim geslom</value>
<value>Zaščitite svoj trezor s pristnim odtisom, PIN-kodo ali glavnim geslom</value>
</data>
<data name="Screenshot4" xml:space="preserve">
<value>Hitro vnašanje prijavnih podatkov na spletu in v drugih aplikacijah</value>
<value>Hitro samodejno vnašanje prijavnih podatkov na spletu in v drugih aplikacijah</value>
</data>
<data name="Screenshot5" xml:space="preserve">
<value>- Telefon
<value>Dostopajte do svojega sefa z različnih naprav:
- Telefon
- Tablica
- Namizje
- Računalnik
- Splet</value>
</data>
</root>

View File

@@ -7,15 +7,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NSubstitute" Version="4.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoNSubstitute" Version="4.17.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.18.0" />
<PackageReference Include="AutoFixture.AutoNSubstitute" Version="4.18.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
</ItemGroup>
</Project>

View File

@@ -7,15 +7,15 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="NSubstitute" Version="4.4.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="AutoFixture.Xunit2" Version="4.17.0" />
<PackageReference Include="AutoFixture.AutoNSubstitute" Version="4.17.0" />
<PackageReference Include="AutoFixture.Xunit2" Version="4.18.0" />
<PackageReference Include="AutoFixture.AutoNSubstitute" Version="4.18.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -14,7 +14,7 @@ namespace Bit.Core.Test.Models.Request
{
[Theory]
[InlineCustomAutoData(new[] { typeof(TextSendCustomization) }, null)]
[InlineCustomAutoData(new[] { typeof(FileSendCustomization) }, 100)]
[InlineCustomAutoData(new[] { typeof(FileSendCustomization) }, 100L)]
public void SendRequest_FromSend_Success(long? fileLength, Send send)
{
var request = new SendRequest(send, fileLength);