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

Compare commits

...

29 Commits

Author SHA1 Message Date
Kyle Spearrin
52261f99d7 New Crowdin updates (#1071)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Bulgarian)
2020-09-15 12:54:53 -04:00
Kyle Spearrin
692dc154ef New Crowdin updates (#1070)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations copy.resx (Chinese Simplified)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations copy.resx (Korean)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Malayalam)
2020-09-14 10:49:42 -04:00
Matt Portune
22101d8f4a fix for passphrase generator persistent settings (#1065) 2020-09-10 12:19:02 -04:00
Matt Portune
f68db90b1f fix state comparison (value vs instance) (#1063) 2020-09-09 11:51:28 -04:00
Kyle Spearrin
5e680531da New Crowdin updates (#1062)
* New translations AppResources.resx (Romanian)

* New translations AppResources.resx (Portuguese)

* New translations AppResources.resx (Polish)

* New translations AppResources.resx (Dutch)

* New translations AppResources.resx (Korean)

* New translations AppResources.resx (Japanese)

* New translations AppResources.resx (Slovak)

* New translations AppResources.resx (Italian)

* New translations AppResources.resx (Vietnamese)

* New translations AppResources.resx (Chinese Traditional)

* New translations AppResources.resx (Chinese Simplified)

* New translations AppResources.resx (Ukrainian)

* New translations AppResources.resx (Turkish)

* New translations AppResources.resx (Swedish)

* New translations AppResources.resx (Russian)

* New translations AppResources.resx (Catalan)

* New translations AppResources.resx (Bulgarian)

* New translations AppResources.resx (Belarusian)

* New translations AppResources.resx (Afrikaans)

* New translations AppResources.resx (Spanish)

* New translations AppResources.resx (French)

* New translations AppResources.resx (Czech)

* New translations AppResources.resx (Hebrew)

* New translations AppResources.resx (Finnish)

* New translations AppResources.resx (Hungarian)

* New translations AppResources.resx (German)

* New translations AppResources.resx (Danish)

* New translations AppResources.resx (Greek)

* New translations copy.resx (Latvian)

* New translations copy.resx (Latvian)

* New translations AppResources.resx (Hindi)

* New translations copy.resx (Hindi)

* New translations AppResources.resx (English, United Kingdom)

* New translations AppResources.resx (Sinhala)

* New translations AppResources.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations copy.resx (Malayalam)

* New translations AppResources.resx (Norwegian Bokmal)

* New translations AppResources.resx (Latvian)

* New translations AppResources.resx (Portuguese, Brazilian)

* New translations AppResources.resx (Indonesian)

* New translations AppResources.resx (Persian)

* New translations AppResources.resx (Estonian)

* New translations AppResources.resx (Thai)

* New translations AppResources.resx (Croatian)
2020-09-08 11:30:08 -04:00
Matt Portune
93cd31018e publish to google play internal test track (#1061)
publish directly to internal test track to skip play store approval process for internal testers (artifact can then be manually promoted to alpha > beta > prod like before).  This should bring the testing experience up to speed with TestFlight for iOS (i.e. push code > ci build > immediate availability)
2020-09-06 20:18:44 -04:00
Chad Scharf
277c570723 version bump (#1060) 2020-09-05 21:50:38 -04:00
Matt Portune
f1419a75f6 Added SSO flows and functionality (#1047)
* SSO login flow for pre-existing user and no 2FA

* 2FA progress

* 2FA support

* Added SSO flows and functionality

* Handle webauthenticator cancellation gracefully

* updates & bugfixes

* Added state validation to web auth response handling

* SSO auth, account registration, and environment settings support for iOS extensions

* Added SSO prevalidation to auth process

* prevalidation now hitting identity service base url

* additional error handling

* Requested changes

* fixed case
2020-09-03 12:30:40 -04:00
Contribucious
3af08a4727 [KnownUsernameField] Entries update (Yandex) (#1044)
This adds all missing entries for Yandex (exhaustive list of Yandex domain names obtained by contacting their support).
2020-08-20 09:56:11 -04:00
Contribucious
a535cea85f [KnownUsernameField] Fix for the special case "eBay India" (#1041)
See explanations in the PR.
2020-08-17 15:13:13 -04:00
Kyle Spearrin
29e443ed76 base64 url encode/decode heleprs (#1038) 2020-08-14 10:08:50 -04:00
Oscar Hinton
f95cddd05a Return the correct value for valid biometric (#1037) 2020-08-12 15:55:15 -04:00
Oscar Hinton
ae28de4159 Invalidate biometric on change (#1026)
* Initial working version for Android

* Add a fallback for when upgrading from older app version.

* Ensure biometric validity is re-checked on focus

* Only setup biometric integrity key if biometric is turned on.

* Fix styling according to comments

* Fallback for Android 5.

* Improve comment

* Add boilerplate for iOS

* Change BiometricService to public

* Untested iOS implementation.

* Convert IBiometricService to async. Fix code style for iOS.

* Base64 NSData.

* Review comments for Android BiometricService.

* Rename methods in BiometricService to append Async

* Ensure we wait for async SetupBiometricAsync.

* Update BiometricService.cs

Co-authored-by: Kyle Spearrin <kspearrin@users.noreply.github.com>
2020-08-08 21:33:49 -04:00
Contribucious
39de2c1d25 [KnownUsernameField] Entries update (main ones) (#1034)
* [KUF] Fix Google; Add natl/dskp Amazon/eBay & Atlassian+Bitly ENT.+Tumblr+Yandex

... also, add missing OAuth support for PayPal. And add "My docomo" from NTT DOCOMO, as part of a Top 20 Japan.

* Less spacing

* Even less spacing

* Additional reduction of spacing

* [Perf. optim.] Google: most frequently used entry in first position
2020-08-07 11:02:08 -04:00
Contribucious
22570e08aa [KnownUsernameField] Engine update (make the system more flexible) (#1011)
* [KnownUsernameField] Engine update (make the system more flexible)

* [KnownUsernameField] Engine update (make the system more flexible)

* Use of tuples array instead of multidimensional array (string[,])

* Use of tuples array instead of multidimensional array (string[,])

* [FIX] IndexOf -> Contains
2020-08-06 12:38:25 -04:00
aaxdev
3b4ef4d238 Feature sync on refresh (#937)
* Added new option: Sync on refresh

* Removed unused field

* Fixed refreshing on disappearing & unnecessary codes removed

* Requested changes

* Calling storage service instead of a dedicated service function (mobile-specific)
2020-08-05 13:19:27 -04:00
Chad Scharf
c5a71c4304 Fix Pin cannot be hidden after showing it #1025 (#1027) 2020-07-30 13:46:06 -04:00
K. Sasa
4f37c2cb73 Replace copy value button fa-clipboard(&#xf0ea;) to fa-clone(&#xf24d;) (#1024) 2020-07-27 13:22:27 -04:00
Chad Scharf
c1ec97055c Added android:installLocation=internalOnly (#1019) 2020-07-23 09:19:11 -04:00
Matt Smith
086c71126f Allow only non-deleted creds to be added to autofill (#1015) 2020-07-16 11:53:02 -05:00
Matt Smith
10a78c1c94 Modified listing of website from Hostname to Host (#1012)
* Modified listing of website from Hostname to Host

* Removed last _hostname artifact.
2020-07-14 13:17:08 -05:00
Gal Szkolnik
cf6021d898 Don't break when CipherType data is null (#1008)
as explained in issue https://github.com/bitwarden/mobile/issues/1006
2020-07-11 09:06:48 -04:00
Matt Smith
ff322cd2dd Modified Permissions Flow (#1005)
Permissions flow for Android was causing the white screen on initial permission grant on occasion. Moved permission grant to pre-TOTP page load.
2020-07-08 14:09:08 -05:00
Kyle Spearrin
1a96d3c38e bump version 2020-07-06 14:36:10 -04:00
Kyle Spearrin
cfe84963fa switch to access token, bump version 2020-07-06 13:54:44 -04:00
Kyle Spearrin
d908a599b1 bump version and build fixes 2020-07-06 13:28:19 -04:00
Kyle Spearrin
9b3ddb8da3 bump version via hub release command 2020-07-06 11:56:00 -04:00
Kyle Spearrin
56d994a69d bump version 2020-07-06 11:27:19 -04:00
Kyle Spearrin
67cd17c604 do actions on master push or release event 2020-07-06 11:26:51 -04:00
128 changed files with 9080 additions and 464 deletions

View File

@@ -4,6 +4,6 @@ $homePath = Resolve-Path "~" | Select-Object -ExpandProperty Path;
$publisherPath = $($rootPath + "/store/google/Publisher/bin/Release/netcoreapp2.0/Publisher.dll");
$credsPath = $($homePath + "/secrets/play_creds.json");
$aabPath = $($rootPath + "/com.x8bit.bitwarden.aab");
$track = "alpha";
$track = "internal";
dotnet $publisherPath $credsPath $aabPath $track

View File

@@ -54,14 +54,14 @@ jobs:
uses: actions/checkout@v2
- name: Decrypt secrets
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/android/decrypt-secrets.ps1
shell: pwsh
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
- name: Increment version
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/android/increment-version.ps1
shell: pwsh
@@ -76,7 +76,7 @@ jobs:
shell: pwsh
- name: Sign for Play Store
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/android/sign-play.ps1
shell: pwsh
env:
@@ -84,14 +84,14 @@ jobs:
UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
- name: Upload Play Store .aab artifact
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
uses: actions/upload-artifact@v2
with:
name: com.x8bit.bitwarden.aab
path: ./com.x8bit.bitwarden.aab
- name: Upload Play Store .apk artifact
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
uses: actions/upload-artifact@v2
with:
name: com.x8bit.bitwarden.apk
@@ -109,21 +109,21 @@ jobs:
shell: pwsh
- name: Sign for F-Droid
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/android/sign-fdroid.ps1
shell: pwsh
env:
FDROID_KEYSTORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }}
- name: Upload F-Droid .apk artifact
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
uses: actions/upload-artifact@v2
with:
name: com.x8bit.bitwarden-fdroid.apk
path: ./com.x8bit.bitwarden-fdroid.apk
- name: Deploy to Play Store
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/android/deploy-play.ps1
shell: pwsh
@@ -134,6 +134,7 @@ jobs:
-a ./com.x8bit.bitwarden.aab `
-a ./com.x8bit.bitwarden.apk `
-a ./com.x8bit.bitwarden-fdroid.apk `
-m "Version $($env:RELEASE_TAG_NAME.TrimStart('v'))" `
$env:RELEASE_TAG_NAME
shell: pwsh
env:
@@ -160,10 +161,10 @@ jobs:
- name: Set up git credentials
if: github.event_name == 'release'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
git config --global credential.helper store
echo "https://${GITHUB_TOKEN}:x-oauth-basic@github.com" >> ~/.git-credentials
echo "https://${ACCESS_TOKEN}:x-oauth-basic@github.com" >> ~/.git-credentials
git config --global user.email "ci@bitwarden.com"
git config --global user.name "Bitwarden CI"
@@ -199,7 +200,9 @@ jobs:
- name: Compile for F-Droid Store
if: github.event_name == 'release'
run: ./.github/scripts/android/compile-fdroid.sh
run: |
sudo chmod +x ./.github/scripts/android/compile-fdroid.sh
./.github/scripts/android/compile-fdroid.sh
env:
FDROID_STORE_KEYSTORE_PASSWORD: ${{ secrets.FDROID_STORE_KEYSTORE_PASSWORD }}
RELEASE_TAG_NAME: ${{ github.event.release.tag_name }}
@@ -234,7 +237,7 @@ jobs:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
- name: Increment version
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/ios/increment-version.ps1
shell: pwsh
@@ -254,7 +257,7 @@ jobs:
run: nuget restore
- name: Archive Build for App Store
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/ios/build.ps1 -configuration AppStore -platform iPhone -archive
shell: pwsh
@@ -264,19 +267,19 @@ jobs:
shell: pwsh
- name: Export .ipa for App Store
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/ios/export-ipa.ps1 -method app-store
shell: pwsh
- name: Upload App Store .ipa artifact
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
uses: actions/upload-artifact@v2
with:
name: Bitwarden.ipa
path: ./bitwarden-export/Bitwarden.ipa
- name: Deploy to App Store
if: github.ref == 'refs/heads/master' && github.event_name == 'push'
if: github.ref == 'refs/heads/master' || github.event_name == 'release'
run: ./.github/scripts/ios/deploy-app-store.ps1
shell: pwsh
env:
@@ -288,6 +291,7 @@ jobs:
run: |
hub release edit `
-a ./bitwarden-export/Bitwarden.ipa `
-m "Version $($env:RELEASE_TAG_NAME.TrimStart('v'))" `
$env:RELEASE_TAG_NAME
shell: pwsh
env:

View File

@@ -129,16 +129,196 @@ namespace Bit.Droid.Accessibility
"com.ss.squarehome2",
"com.treydev.pns"
};
// Be sure to keep these entries sorted alphabetically
// Be sure to keep these sections sorted alphabetically
public static Dictionary<string, KnownUsernameField> KnownUsernameFields => new List<KnownUsernameField>
{
new KnownUsernameField("accounts.google.com", "ServiceLogin", "Email"),
new KnownUsernameField("amazon.com", "signin", "ap_email_login"),
new KnownUsernameField("github.com", "", "user[login]-footer"),
new KnownUsernameField("paypal.com", "signin", "email"),
new KnownUsernameField("signin.aws.amazon.com", "signin", "resolving_input"),
new KnownUsernameField("signin.ebay.com", "eBayISAPI.dll", "userid"),
/**************************************************************************************
* SECTION A ——— World-renowned web sites/applications
*************************************************************************************/
// REM.: For this type of web sites/applications, the Top 100 (SimilarWeb, 2019)
// and the Top 50 (Alexa Internet, 2020) are covered. National variants
// have been added when available. Mobile and desktop versions supported.
//
// A few other popular web sites/applications have also been added.
//
// Could not be added, however:
// web sites/applications that don't use an "id" attribute for their login field.
// NOTE: The case of OAuth compatible web sites/applications that also provide
// a "user ID only" login page in this situation
// was taken into account in the tests as well.
/*
* A
*/
// Amazon ——— ap_email_login = mobile / ap_email = desktop (amazon.co.jp currently uses ap_email in both cases, as of July 2020).
new KnownUsernameField("amazon.ae", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.ca", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.cn", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.co.jp", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.co.uk", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.au", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.br", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.mx", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.com.tr", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.de", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.es", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.fr", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.in", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.it", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.nl", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.sa", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
new KnownUsernameField("amazon.sg", new (string, string)[] { ("contains:/ap/signin", "ap_email_login,ap_email") }),
// Amazon Web Services
new KnownUsernameField("signin.aws.amazon.com", new (string, string)[] { ("signin", "resolving_input") }),
// Atlassian
new KnownUsernameField("id.atlassian.com", new (string, string)[] { ("login", "username") }),
/*
* B
*/
// Bitly ——— enterprise users.
new KnownUsernameField("bitly.com", new (string, string)[] { ("/sso/url_slug", "url_slug") }),
/*
* E
*/
// eBay ——— 1st = traditional access / 2nd = direct access (i.e. https://signin.ebay.tld/).
new KnownUsernameField("signin.befr.ebay.be", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.benl.ebay.be", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.cafr.ebay.ca", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.at", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.be", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ca", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ch", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.co.uk", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.au", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.hk", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.my", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.com.sg", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.de", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.es", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.fr", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ie", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.in", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.it", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.nl", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.ph", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
new KnownUsernameField("signin.ebay.pl", new (string, string)[] { ("iendswith:eBayISAPI.dll", "userid"), ("icontains:/signin/", "userid") }),
/*
* G
*/
// Google ——— 1st = used in most cases (v2) / 2nd = used in some cases (v1).
new KnownUsernameField("accounts.google.com", new (string, string)[] { ("identifier", "identifierId"), ("ServiceLogin", "Email") }),
/*
* P
*/
// PayPal ——— 1st = traditional access / 2nd = access using OAuth.
new KnownUsernameField("paypal.com", new (string, string)[] { ("signin", "email"), ("contains:/connect/", "email") }),
/*
* T
*/
// Tumblr ——— despite "signup" in its ID, it's the login field (the website offers registration if the account doesn't exist).
new KnownUsernameField("tumblr.com", new (string, string)[] { ("login", "signup_determine_email") }),
/*
* Y
*/
// Yandex
new KnownUsernameField("passport.yandex.az", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.by", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.co.il", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com.am", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com.ge", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.com.tr", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.ee", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.fi", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.fr", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.kg", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.kz", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.lt", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.lv", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.md", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.pl", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.ru", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.tj", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.tm", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.ua", new (string, string)[] { ("auth", "passp-field-login") }),
new KnownUsernameField("passport.yandex.uz", new (string, string)[] { ("auth", "passp-field-login") }),
/**************************************************************************************
* SECTION B ——— Top 100 worldwide
*************************************************************************************/
// As of July 2020, all entries that needed to be added from
// Top 100 (SimilarWeb, 2019) and Top 50 (Alexa Internet, 2020)
// matched section A.
//
// Therefore, no entry currently.
/**************************************************************************************
* SECTION C ——— Top 20 for selected countries
*************************************************************************************/
// REM.: For these selected countries, the Top 20 (SimilarWeb, 2020)
// and the Top 20 (Alexa Internet, 2020) are covered.
// Mobile and desktop versions supported.
//
// Could not be added, however:
// web sites/applications that don't use an "id" attribute for their login field.
/*
* Japan
*/
// NTT DOCOMO ——— mainly used for "My docomo".
new KnownUsernameField("cfg.smt.docomo.ne.jp", new (string, string)[] { ("contains:/auth/", "Di_Uid") }),
/**************************************************************************************
* SECTION D ——— Miscellaneous
*************************************************************************************/
/*
* Various entries ——— Following user requests, etc.
*/
// No entry, currently.
/**************************************************************************************
* SECTION Z ——— Special forms
*
* Despite "user ID + password" fields both visible, detection rules required.
*************************************************************************************/
/*
* Main
*/
// No entry, currently.
/*
* Test/example purposes only
*/
// GitHub ——— VERY special case (signup form, just to test the proper functioning of special forms).
new KnownUsernameField("github.com", new (string, string)[] { ("", "user[login]-footer") }),
}.ToDictionary(n => n.UriAuthority);
public static void PrintTestData(AccessibilityNodeInfo root, AccessibilityEvent e)
@@ -314,7 +494,7 @@ namespace Bit.Droid.Accessibility
if (Uri.TryCreate(uriString, UriKind.Absolute, out var uri))
{
uriAuthority = uri.Authority;
uriKey = uriAuthority.StartsWith("www.") ? uriAuthority.Substring(4) : uriAuthority;
uriKey = uriAuthority.StartsWith("www.", StringComparison.Ordinal) ? uriAuthority.Substring(4) : uriAuthority;
uriLocalPath = uri.LocalPath;
}
@@ -330,15 +510,64 @@ namespace Bit.Droid.Accessibility
if (KnownUsernameFields.ContainsKey(uriKey))
{
var usernameField = KnownUsernameFields[uriKey];
if (uriLocalPath.EndsWith(usernameField.UriPathEnd))
(string UriPathWanted, string UsernameViewId)[] accessOptions = usernameField.AccessOptions;
for (int i = 0; i < accessOptions.Length; i++)
{
foreach (var editText in allEditTexts)
string curUriPathWanted = accessOptions[i].UriPathWanted;
string curUsernameViewId = accessOptions[i].UsernameViewId;
bool uriLocalPathMatches = false;
// Case-sensitive comparison
if (curUriPathWanted.StartsWith("startswith:", StringComparison.Ordinal))
{
foreach (var usernameViewId in usernameField.UsernameViewId.Split(","))
curUriPathWanted = curUriPathWanted.Substring(11);
uriLocalPathMatches = uriLocalPath.StartsWith(curUriPathWanted, StringComparison.Ordinal);
}
else if (curUriPathWanted.StartsWith("contains:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(9);
uriLocalPathMatches = uriLocalPath.Contains(curUriPathWanted, StringComparison.Ordinal);
}
else if (curUriPathWanted.StartsWith("endswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(9);
uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.Ordinal);
}
// Case-insensitive comparison
else if (curUriPathWanted.StartsWith("istartswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(12);
uriLocalPathMatches = uriLocalPath.StartsWith(curUriPathWanted, StringComparison.OrdinalIgnoreCase);
}
else if (curUriPathWanted.StartsWith("icontains:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(10);
uriLocalPathMatches = uriLocalPath.Contains(curUriPathWanted, StringComparison.OrdinalIgnoreCase);
}
else if (curUriPathWanted.StartsWith("iendswith:", StringComparison.Ordinal))
{
curUriPathWanted = curUriPathWanted.Substring(10);
uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.OrdinalIgnoreCase);
}
// Default type of comparison
else
{
uriLocalPathMatches = uriLocalPath.EndsWith(curUriPathWanted, StringComparison.Ordinal);
}
if (uriLocalPathMatches)
{
foreach (var editText in allEditTexts)
{
if (usernameViewId == editText.ViewIdResourceName)
foreach (var usernameViewId in curUsernameViewId.Split(","))
{
return editText;
if (usernameViewId == editText.ViewIdResourceName)
{
return editText;
}
}
}
}

View File

@@ -2,15 +2,13 @@
{
public class KnownUsernameField
{
public KnownUsernameField(string uriAuthority, string uriPathEnd, string usernameViewId)
public KnownUsernameField(string uriAuthority, (string UriPathWanted, string UsernameViewId)[] accessOptions)
{
UriAuthority = uriAuthority;
UriPathEnd = uriPathEnd;
UsernameViewId = usernameViewId;
AccessOptions = accessOptions;
}
public string UriAuthority { get; set; }
public string UriPathEnd { get; set; }
public string UsernameViewId { get; set; }
public (string UriPathWanted, string UsernameViewId)[] AccessOptions { get; set; }
}
}

View File

@@ -78,7 +78,7 @@
<Version>1.8.6.7</Version>
</PackageReference>
<PackageReference Include="Xamarin.Essentials">
<Version>1.5.3.1</Version>
<Version>1.5.3.2</Version>
</PackageReference>
<PackageReference Include="Xamarin.Firebase.Messaging">
<Version>71.1740.0</Version>
@@ -133,6 +133,7 @@
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\BiometricService.cs" />
<Compile Include="Services\CryptoPrimitiveService.cs" />
<Compile Include="Services\DeviceActionService.cs" />
<Compile Include="Services\LocalizeService.cs" />
@@ -141,6 +142,7 @@
<Compile Include="Tiles\MyVaultTileService.cs" />
<Compile Include="Utilities\AndroidHelpers.cs" />
<Compile Include="Utilities\AppCenterHelper.cs" />
<Compile Include="WebAuthCallbackActivity.cs" />
</ItemGroup>
<ItemGroup>
<AndroidAsset Include="Assets\FontAwesome.ttf" />

View File

@@ -18,6 +18,7 @@ using Android.Nfc;
using Bit.App.Utilities;
using System.Threading.Tasks;
using AndroidX.Core.Content;
using ZXing.Net.Mobile.Android;
namespace Bit.Droid
{
@@ -143,6 +144,7 @@ namespace Bit.Droid
protected override void OnResume()
{
base.OnResume();
Xamarin.Essentials.Platform.OnResume();
if (_deviceActionService.SupportsNfc())
{
try
@@ -193,8 +195,7 @@ namespace Bit.Droid
else
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult(
requestCode, permissions, grantResults);
PermissionsHandler.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

View File

@@ -98,6 +98,7 @@ namespace Bit.Droid
broadcasterService, () => ServiceContainer.Resolve<IEventService>("eventService"));
var platformUtilsService = new MobilePlatformUtilsService(deviceActionService, messagingService,
broadcasterService);
var biometricService = new BiometricService();
ServiceContainer.Register<IBroadcasterService>("broadcasterService", broadcasterService);
ServiceContainer.Register<IMessagingService>("messagingService", messagingService);
@@ -108,6 +109,7 @@ namespace Bit.Droid
ServiceContainer.Register<IStorageService>("secureStorageService", secureStorageService);
ServiceContainer.Register<IDeviceActionService>("deviceActionService", deviceActionService);
ServiceContainer.Register<IPlatformUtilsService>("platformUtilsService", platformUtilsService);
ServiceContainer.Register<IBiometricService>("biometricService", biometricService);
// Push
#if FDROID

View File

@@ -3,7 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="1"
android:versionName="2.5.1"
android:versionName="2.6.0"
android:installLocation="internalOnly"
package="com.x8bit.bitwarden">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />

View File

@@ -40,19 +40,23 @@ namespace Bit.Droid.Renderers
{
// Check if field type is text, otherwise ignore (numeric passwords, etc.)
EditText.InputType = Element.Keyboard.ToInputType();
if ((EditText.InputType & InputTypes.ClassText) == InputTypes.ClassText)
bool isText = (EditText.InputType & InputTypes.ClassText) == InputTypes.ClassText,
isNumber = (EditText.InputType & InputTypes.ClassNumber) == InputTypes.ClassNumber;
if (isText || isNumber)
{
if (Element.IsPassword)
{
// Element is a password field, set inputType to TextVariationPassword which disables
// predictive text by default
EditText.InputType = EditText.InputType | InputTypes.TextVariationPassword;
EditText.InputType = EditText.InputType |
(isText ? InputTypes.TextVariationPassword : InputTypes.NumberVariationPassword);
}
else
{
// Element is not a password field, set inputType to TextVariationVisiblePassword to
// disable predictive text while still displaying the content.
EditText.InputType = EditText.InputType | InputTypes.TextVariationVisiblePassword;
EditText.InputType = EditText.InputType |
(isText ? InputTypes.TextVariationVisiblePassword : InputTypes.NumberVariationNormal);
}
// The workaround above forces a reset of the style properties, so we need to re-apply the font.

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Android.OS;
using Android.Security.Keystore;
using Bit.Core.Abstractions;
using Java.Security;
using Javax.Crypto;
namespace Bit.Droid.Services
{
public class BiometricService : IBiometricService
{
private const string KeyName = "com.8bit.bitwarden.biometric_integrity";
private const string KeyStoreName = "AndroidKeyStore";
private const string KeyAlgorithm = KeyProperties.KeyAlgorithmAes;
private const string BlockMode = KeyProperties.BlockModeCbc;
private const string EncryptionPadding = KeyProperties.EncryptionPaddingPkcs7;
private const string Transformation = KeyAlgorithm + "/" + BlockMode + "/" + EncryptionPadding;
private readonly KeyStore _keystore;
public BiometricService()
{
_keystore = KeyStore.GetInstance(KeyStoreName);
_keystore.Load(null);
}
public Task<bool> SetupBiometricAsync()
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.M)
{
CreateKey();
}
return Task.FromResult(true);
}
public Task<bool> ValidateIntegrityAsync()
{
if (Build.VERSION.SdkInt < BuildVersionCodes.M)
{
return Task.FromResult(true);
}
_keystore.Load(null);
IKey key = _keystore.GetKey(KeyName, null);
Cipher cipher = Cipher.GetInstance(Transformation);
try
{
cipher.Init(CipherMode.EncryptMode, key);
}
catch (KeyPermanentlyInvalidatedException e)
{
// Biometric has changed
return Task.FromResult(false);
}
catch (UnrecoverableKeyException e)
{
// Biometric was disabled and re-enabled
return Task.FromResult(false);
}
catch (InvalidKeyException e)
{
// Fallback for old bitwarden users without a key
CreateKey();
}
return Task.FromResult(true);
}
private void CreateKey()
{
KeyGenerator keyGen = KeyGenerator.GetInstance(KeyAlgorithm, KeyStoreName);
KeyGenParameterSpec keyGenSpec =
new KeyGenParameterSpec.Builder(KeyName, KeyStorePurpose.Encrypt | KeyStorePurpose.Decrypt)
.SetBlockModes(BlockMode)
.SetEncryptionPaddings(EncryptionPadding)
.SetUserAuthenticationRequired(true)
.Build();
keyGen.Init(keyGenSpec);
keyGen.GenerateKey();
}
}
}

View File

@@ -0,0 +1,11 @@
using Android.App;
using Android.Content.PM;
namespace Bit.Droid
{
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop)]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
DataScheme = "bitwarden")]
public class WebAuthCallbackActivity : Xamarin.Essentials.WebAuthenticatorCallbackActivity { }
}

View File

@@ -15,7 +15,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="3.2.1" />
<PackageReference Include="Plugin.Fingerprint" Version="2.1.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.1" />
<PackageReference Include="Xamarin.Essentials" Version="1.5.3.2" />
<PackageReference Include="Xamarin.FFImageLoading.Forms" Version="2.4.11.982" />
<PackageReference Include="Xamarin.Forms" Version="4.5.0.725" />
<PackageReference Include="ZXing.Net.Mobile" Version="2.4.1" />
@@ -111,6 +111,14 @@
<Compile Update="Pages\Vault\GroupingsPage\GroupingsPage.xaml.cs">
<DependentUpon>GroupingsPage.xaml</DependentUpon>
</Compile>
<Compile Update="Pages\Accounts\LoginSsoPage.xaml.cs">
<DependentUpon>LoginSsoPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Update="Pages\Accounts\SetPasswordPage.xaml.cs">
<DependentUpon>ResetMasterPasswordPage.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>

View File

@@ -19,5 +19,28 @@ namespace Bit.App.Models
public string SaveCardExpYear { get; set; }
public string SaveCardCode { get; set; }
public bool IosExtension { get; set; }
public void SetAllFrom(AppOptions o)
{
if (o == null)
{
return;
}
MyVaultTile = o.MyVaultTile;
GeneratorTile = o.GeneratorTile;
FromAutofillFramework = o.FromAutofillFramework;
FillType = o.FillType;
Uri = o.Uri;
SaveType = o.SaveType;
SaveName = o.SaveName;
SaveUsername = o.SaveUsername;
SavePassword = o.SavePassword;
SaveCardName = o.SaveCardName;
SaveCardNumber = o.SaveCardNumber;
SaveCardExpMonth = o.SaveCardExpMonth;
SaveCardExpYear = o.SaveCardExpYear;
SaveCardCode = o.SaveCardCode;
IosExtension = o.IosExtension;
}
}
}

View File

@@ -1,17 +1,21 @@
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Resources;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public partial class EnvironmentPage : BaseContentPage
{
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IMessagingService _messagingService;
private readonly EnvironmentPageViewModel _vm;
public EnvironmentPage()
{
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_messagingService.Send("showStatusBar", true);
InitializeComponent();
@@ -28,6 +32,12 @@ namespace Bit.App.Pages
_apiEntry.ReturnCommand = new Command(() => _identityEntry.Focus());
_identityEntry.ReturnType = ReturnType.Next;
_identityEntry.ReturnCommand = new Command(() => _iconsEntry.Focus());
_vm.SubmitSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await SubmitSuccessAsync());
_vm.CloseAction = async () =>
{
_messagingService.Send("showStatusBar", false);
await Navigation.PopModalAsync();
};
}
private async void Submit_Clicked(object sender, EventArgs e)
@@ -38,12 +48,17 @@ namespace Bit.App.Pages
}
}
private async void Close_Clicked(object sender, EventArgs e)
private async Task SubmitSuccessAsync()
{
_platformUtilsService.ShowToast("success", null, AppResources.EnvironmentSaved);
await Navigation.PopModalAsync();
}
private void Close_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_messagingService.Send("showStatusBar", false);
await Navigation.PopModalAsync();
_vm.CloseAction();
}
}
}

View File

@@ -1,6 +1,7 @@
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
@@ -8,12 +9,10 @@ namespace Bit.App.Pages
{
public class EnvironmentPageViewModel : BaseViewModel
{
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IEnvironmentService _environmentService;
public EnvironmentPageViewModel()
{
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
PageTitle = AppResources.Settings;
@@ -33,6 +32,8 @@ namespace Bit.App.Pages
public string WebVaultUrl { get; set; }
public string IconsUrl { get; set; }
public string NotificationsUrls { get; set; }
public Action SubmitSuccessAction { get; set; }
public Action CloseAction { get; set; }
public async Task SubmitAsync()
{
@@ -54,8 +55,7 @@ namespace Bit.App.Pages
IconsUrl = resUrls.Icons;
NotificationsUrls = resUrls.Notifications;
_platformUtilsService.ShowToast("success", null, AppResources.EnvironmentSaved);
await Page.Navigation.PopModalAsync();
SubmitSuccessAction?.Invoke();
}
}
}

View File

@@ -11,12 +11,16 @@
<ContentPage.BindingContext>
<pages:HomeViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
</ContentPage.ToolbarItems>
<StackLayout Spacing="0" Padding="10, 5">
<controls:FaButton Text="&#xf013;"
StyleClass="btn-muted, btn-icon, btn-icon-platform"
HorizontalOptions="Start"
Clicked="Settings_Clicked"
Clicked="Environment_Clicked"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n Options}">
<controls:FaButton.Margin>
@@ -39,6 +43,8 @@
Clicked="LogIn_Clicked"></Button>
<Button Text="{u:I18n CreateAccount}"
Clicked="Register_Clicked"></Button>
<Button Text="{u:I18n LogInSso}"
Clicked="LogInSso_Clicked"></Button>
</StackLayout>
</StackLayout>
</StackLayout>

View File

@@ -10,6 +10,7 @@ namespace Bit.App.Pages
{
public partial class HomePage : BaseContentPage
{
private readonly HomeViewModel _vm;
private readonly AppOptions _appOptions;
private IMessagingService _messagingService;
@@ -19,6 +20,12 @@ namespace Bit.App.Pages
_messagingService.Send("showStatusBar", false);
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as HomeViewModel;
_vm.Page = this;
_vm.StartLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartLoginAsync());
_vm.StartRegisterAction = () => Device.BeginInvokeOnMainThread(async () => await StartRegisterAsync());
_vm.StartSsoLoginAction = () => Device.BeginInvokeOnMainThread(async () => await StartSsoLoginAsync());
_vm.StartEnvironmentAction = () => Device.BeginInvokeOnMainThread(async () => await StartEnvironmentAsync());
_logo.Source = !ThemeManager.UsingLightTheme ? "logo_white.png" : "logo.png";
}
@@ -33,29 +40,69 @@ namespace Bit.App.Pages
base.OnAppearing();
_messagingService.Send("showStatusBar", false);
}
private void Close_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.CloseAction();
}
}
private void LogIn_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
Navigation.PushModalAsync(new NavigationPage(new LoginPage(null, _appOptions)));
_vm.StartLoginAction();
}
}
private async Task StartLoginAsync()
{
var page = new LoginPage(null, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private void Register_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
Navigation.PushModalAsync(new NavigationPage(new RegisterPage(this)));
_vm.StartRegisterAction();
}
}
private async Task StartRegisterAsync()
{
var page = new RegisterPage(this);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private void Settings_Clicked(object sender, EventArgs e)
private void LogInSso_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
Navigation.PushModalAsync(new NavigationPage(new EnvironmentPage()));
_vm.StartSsoLoginAction();
}
}
private async Task StartSsoLoginAsync()
{
var page = new LoginSsoPage(_appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private void Environment_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.StartEnvironmentAction();
}
}
private async Task StartEnvironmentAsync()
{
var page = new EnvironmentPage();
await Navigation.PushModalAsync(new NavigationPage(page));
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Bit.App.Resources;
namespace Bit.App.Pages
{
@@ -6,7 +7,13 @@ namespace Bit.App.Pages
{
public HomeViewModel()
{
PageTitle = "Home Page";
PageTitle = AppResources.Bitwarden;
}
public Action StartLoginAction { get; set; }
public Action StartRegisterAction { get; set; }
public Action StartSsoLoginAction { get; set; }
public Action StartEnvironmentAction { get; set; }
public Action CloseAction { get; set; }
}
}

View File

@@ -106,8 +106,12 @@
Margin="0, 10, 0, 0" />
</StackLayout>
<StackLayout Padding="10, 0">
<Label
Text="{u:I18n BiometricInvalidated}"
StyleClass="box-footer-label,text-danger,text-bold"
IsVisible="{Binding BiometricIntegrityValid, Converter={StaticResource inverseBool}}" />
<Button Text="{Binding BiometricButtonText}" Clicked="Biometric_Clicked"
IsVisible="{Binding BiometricLock}"></Button>
IsVisible="{Binding BiometricLock}" IsEnabled="{Binding BiometricIntegrityValid}"></Button>
<Button Text="{u:I18n LogOut}" Clicked="LogOut_Clicked"></Button>
</StackLayout>
</StackLayout>

View File

@@ -1,9 +1,9 @@
using Bit.App.Models;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -99,24 +99,11 @@ namespace Bit.App.Pages
private async Task UnlockedAsync()
{
if (_appOptions != null)
if (AppHelpers.SetAlternateMainPage(_appOptions))
{
if (_appOptions.FromAutofillFramework && _appOptions.SaveType.HasValue)
{
Application.Current.MainPage = new NavigationPage(new AddEditPage(appOptions: _appOptions));
return;
}
if (_appOptions.Uri != null)
{
Application.Current.MainPage = new NavigationPage(new AutofillCiphersPage(_appOptions));
return;
}
}
var previousPage = await _storageService.GetAsync<PreviousPageInfo>(Constants.PreviousPageKey);
if (previousPage != null)
{
await _storageService.RemoveAsync(Constants.PreviousPageKey);
return;
}
var previousPage = await AppHelpers.ClearPreviousPage();
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
}
}

View File

@@ -8,12 +8,14 @@ using Bit.Core.Models.Domain;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.Core.Models.Request;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class LockPageViewModel : BaseViewModel
{
private readonly IApiService _apiService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IDeviceActionService _deviceActionService;
private readonly IVaultTimeoutService _vaultTimeoutService;
@@ -24,11 +26,13 @@ namespace Bit.App.Pages
private readonly IStorageService _secureStorageService;
private readonly IEnvironmentService _environmentService;
private readonly IStateService _stateService;
private readonly IBiometricService _biometricService;
private string _email;
private bool _showPassword;
private bool _pinLock;
private bool _biometricLock;
private bool _biometricIntegrityValid = true;
private string _biometricButtonText;
private string _loggedInAsText;
private string _lockedVerifyText;
@@ -37,6 +41,7 @@ namespace Bit.App.Pages
public LockPageViewModel()
{
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
@@ -47,6 +52,7 @@ namespace Bit.App.Pages
_secureStorageService = ServiceContainer.Resolve<IStorageService>("secureStorageService");
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_biometricService = ServiceContainer.Resolve<IBiometricService>("biometricService");
PageTitle = AppResources.VerifyMasterPassword;
TogglePasswordCommand = new Command(TogglePassword);
@@ -75,6 +81,12 @@ namespace Bit.App.Pages
set => SetProperty(ref _biometricLock, value);
}
public bool BiometricIntegrityValid
{
get => _biometricIntegrityValid;
set => SetProperty(ref _biometricIntegrityValid, value);
}
public string BiometricButtonText
{
get => _biometricButtonText;
@@ -133,7 +145,8 @@ namespace Bit.App.Pages
BiometricButtonText = supportsFace ? AppResources.UseFaceIDToUnlock :
AppResources.UseFingerprintToUnlock;
}
if (autoPromptBiometric)
BiometricIntegrityValid = await _biometricService.ValidateIntegrityAsync();
if (autoPromptBiometric & _biometricIntegrityValid)
{
var tasks = Task.Run(async () =>
{
@@ -214,18 +227,33 @@ namespace Bit.App.Pages
{
var key = await _cryptoService.MakeKeyAsync(MasterPassword, _email, kdf, kdfIterations);
var keyHash = await _cryptoService.HashPasswordAsync(MasterPassword, key);
var storedKeyHash = await _cryptoService.GetKeyHashAsync();
if (storedKeyHash == null)
var passwordValid = false;
if (keyHash != null)
{
var oldKey = await _secureStorageService.GetAsync<string>("oldKey");
if (key.KeyB64 == oldKey)
var storedKeyHash = await _cryptoService.GetKeyHashAsync();
if (storedKeyHash != null)
{
await _secureStorageService.RemoveAsync("oldKey");
await _cryptoService.SetKeyHashAsync(keyHash);
storedKeyHash = keyHash;
passwordValid = storedKeyHash == keyHash;
}
else
{
await _deviceActionService.ShowLoadingAsync(AppResources.Loading);
var request = new PasswordVerificationRequest();
request.MasterPasswordHash = keyHash;
try
{
await _apiService.PostAccountVerifyPasswordAsync(request);
passwordValid = true;
await _cryptoService.SetKeyHashAsync(keyHash);
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(">>> {0}: {1}", e.GetType(), e.StackTrace);
}
await _deviceActionService.HideLoadingAsync();
}
}
if (storedKeyHash != null && keyHash != null && storedKeyHash == keyHash)
if (passwordValid)
{
if (_pinSet.Item1)
{
@@ -238,6 +266,12 @@ namespace Bit.App.Pages
}
MasterPassword = string.Empty;
await SetKeyAndContinueAsync(key);
// Re-enable biometrics
if (BiometricLock & !BiometricIntegrityValid)
{
await _biometricService.SetupBiometricAsync();
}
}
else
{
@@ -267,7 +301,8 @@ namespace Bit.App.Pages
public async Task PromptBiometricAsync()
{
if (!BiometricLock)
BiometricIntegrityValid = await _biometricService.ValidateIntegrityAsync();
if (!BiometricLock || !BiometricIntegrityValid)
{
return;
}

View File

@@ -1,9 +1,9 @@
using Bit.App.Models;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -25,7 +25,7 @@ namespace Bit.App.Pages
_vm = BindingContext as LoginPageViewModel;
_vm.Page = this;
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
_vm.LoggedInAction = () => Device.BeginInvokeOnMainThread(async () => await LoggedInAsync());
_vm.LogInSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await LogInSuccessAsync());
_vm.CloseAction = async () =>
{
_messagingService.Send("showStatusBar", false);
@@ -74,7 +74,7 @@ namespace Bit.App.Pages
}
}
private async void Close_Clicked(object sender, EventArgs e)
private void Close_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
@@ -84,30 +84,17 @@ namespace Bit.App.Pages
private async Task StartTwoFactorAsync()
{
var page = new TwoFactorPage();
var page = new TwoFactorPage(false, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private async Task LoggedInAsync()
private async Task LogInSuccessAsync()
{
if (_appOptions != null)
if (AppHelpers.SetAlternateMainPage(_appOptions))
{
if (_appOptions.FromAutofillFramework && _appOptions.SaveType.HasValue)
{
Application.Current.MainPage = new NavigationPage(new AddEditPage(appOptions: _appOptions));
return;
}
if (_appOptions.Uri != null)
{
Application.Current.MainPage = new NavigationPage(new AutofillCiphersPage(_appOptions));
return;
}
}
var previousPage = await _storageService.GetAsync<PreviousPageInfo>(Constants.PreviousPageKey);
if (previousPage != null)
{
await _storageService.RemoveAsync(Constants.PreviousPageKey);
return;
}
var previousPage = await AppHelpers.ClearPreviousPage();
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
}
}

View File

@@ -68,7 +68,7 @@ namespace Bit.App.Pages
public string ShowPasswordIcon => ShowPassword ? "" : "";
public bool RememberEmail { get; set; }
public Action StartTwoFactorAction { get; set; }
public Action LoggedInAction { get; set; }
public Action LogInSuccessAction { get; set; }
public Action CloseAction { get; set; }
public bool HideHintButton
@@ -142,7 +142,7 @@ namespace Bit.App.Pages
var disableFavicon = await _storageService.GetAsync<bool?>(Constants.DisableFaviconKey);
await _stateService.SaveAsync(Constants.DisableFaviconKey, disableFavicon.GetValueOrDefault());
var task = Task.Run(async () => await _syncService.FullSyncAsync(true));
LoggedInAction?.Invoke();
LogInSuccessAction?.Invoke();
}
}
catch (ApiException e)

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.LoginSsoPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
xmlns:u="clr-namespace:Bit.App.Utilities"
x:DataType="pages:LoginSsoPageViewModel"
Title="{Binding PageTitle}">
<ContentPage.BindingContext>
<pages:LoginSsoPageViewModel />
</ContentPage.BindingContext>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
<ToolbarItem Text="{u:I18n LogIn}" Clicked="LogIn_Clicked" />
</ContentPage.ToolbarItems>
<ScrollView>
<StackLayout Spacing="20" Margin="0,10,0,0">
<StackLayout StyleClass="box">
<Label Text="{u:I18n LogInSsoSummary}"
StyleClass="text-md"
HorizontalTextAlignment="Start"></Label>
<StackLayout StyleClass="box-row">
<Label
Text="{u:I18n OrgIdentifier}"
StyleClass="box-label" />
<Entry
x:Name="_orgIdentifier"
Text="{Binding OrgIdentifier}"
Keyboard="Default"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding LogInCommand}" />
</StackLayout>
</StackLayout>
</StackLayout>
</ScrollView>
</pages:BaseContentPage>

View File

@@ -0,0 +1,114 @@
using Bit.App.Models;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public partial class LoginSsoPage : BaseContentPage
{
private readonly IStorageService _storageService;
private readonly IMessagingService _messagingService;
private readonly IVaultTimeoutService _vaultTimeoutService;
private readonly LoginSsoPageViewModel _vm;
private readonly AppOptions _appOptions;
private AppOptions _appOptionsCopy;
public LoginSsoPage(AppOptions appOptions = null)
{
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
_messagingService.Send("showStatusBar", true);
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as LoginSsoPageViewModel;
_vm.Page = this;
_vm.StartTwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await StartTwoFactorAsync());
_vm.StartSetPasswordAction = () =>
Device.BeginInvokeOnMainThread(async () => await StartSetPasswordAsync());
_vm.SsoAuthSuccessAction = () => Device.BeginInvokeOnMainThread(async () => await SsoAuthSuccessAsync());
_vm.CloseAction = async () =>
{
_messagingService.Send("showStatusBar", false);
await Navigation.PopModalAsync();
};
if (Device.RuntimePlatform == Device.Android)
{
ToolbarItems.RemoveAt(0);
}
}
protected override async void OnAppearing()
{
base.OnAppearing();
await _vm.InitAsync();
if (string.IsNullOrWhiteSpace(_vm.OrgIdentifier))
{
RequestFocus(_orgIdentifier);
}
}
private void CopyAppOptions()
{
if (_appOptions != null)
{
// create an object copy of _appOptions to persist values when app is exited during web auth flow
_appOptionsCopy = new AppOptions();
_appOptionsCopy.SetAllFrom(_appOptions);
}
}
private void RestoreAppOptionsFromCopy()
{
if (_appOptions != null)
{
// restore values to original readonly _appOptions object from copy
_appOptions.SetAllFrom(_appOptionsCopy);
_appOptionsCopy = null;
}
}
private async void LogIn_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
CopyAppOptions();
await _vm.LogInAsync();
}
}
private void Close_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.CloseAction();
}
}
private async Task StartTwoFactorAsync()
{
RestoreAppOptionsFromCopy();
var page = new TwoFactorPage(true, _appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private async Task StartSetPasswordAsync()
{
RestoreAppOptionsFromCopy();
var page = new SetPasswordPage(_appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private async Task SsoAuthSuccessAsync()
{
RestoreAppOptionsFromCopy();
await AppHelpers.ClearPreviousPage();
Application.Current.MainPage = new NavigationPage(new LockPage(_appOptions));
}
}
}

View File

@@ -0,0 +1,218 @@
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Domain;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class LoginSsoPageViewModel : BaseViewModel
{
private const string Keys_RememberedOrgIdentifier = "rememberedOrgIdentifier";
private const string Keys_RememberOrgIdentifier = "rememberOrgIdentifier";
private readonly IDeviceActionService _deviceActionService;
private readonly IAuthService _authService;
private readonly ISyncService _syncService;
private readonly IApiService _apiService;
private readonly IPasswordGenerationService _passwordGenerationService;
private readonly ICryptoFunctionService _cryptoFunctionService;
private readonly IStorageService _storageService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IStateService _stateService;
private string _orgIdentifier;
public LoginSsoPageViewModel()
{
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_authService = ServiceContainer.Resolve<IAuthService>("authService");
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
_passwordGenerationService =
ServiceContainer.Resolve<IPasswordGenerationService>("passwordGenerationService");
_cryptoFunctionService = ServiceContainer.Resolve<ICryptoFunctionService>("cryptoFunctionService");
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
PageTitle = AppResources.Bitwarden;
LogInCommand = new Command(async () => await LogInAsync());
}
public string OrgIdentifier
{
get => _orgIdentifier;
set => SetProperty(ref _orgIdentifier, value);
}
public Command LogInCommand { get; }
public bool RememberOrgIdentifier { get; set; }
public Action StartTwoFactorAction { get; set; }
public Action StartSetPasswordAction { get; set; }
public Action SsoAuthSuccessAction { get; set; }
public Action CloseAction { get; set; }
public async Task InitAsync()
{
if (string.IsNullOrWhiteSpace(OrgIdentifier))
{
OrgIdentifier = await _storageService.GetAsync<string>(Keys_RememberedOrgIdentifier);
}
var rememberOrgIdentifier = await _storageService.GetAsync<bool?>(Keys_RememberOrgIdentifier);
RememberOrgIdentifier = rememberOrgIdentifier.GetValueOrDefault(true);
}
public async Task LogInAsync()
{
if (Connectivity.NetworkAccess == NetworkAccess.None)
{
await _platformUtilsService.ShowDialogAsync(AppResources.InternetConnectionRequiredMessage,
AppResources.InternetConnectionRequiredTitle);
return;
}
if (string.IsNullOrWhiteSpace(OrgIdentifier))
{
await _platformUtilsService.ShowDialogAsync(
string.Format(AppResources.ValidationFieldRequired, AppResources.OrgIdentifier),
AppResources.AnErrorHasOccurred,
AppResources.Ok);
return;
}
await _deviceActionService.ShowLoadingAsync(AppResources.LoggingIn);
try
{
await _apiService.PreValidateSso(OrgIdentifier);
}
catch (ApiException e)
{
await _deviceActionService.HideLoadingAsync();
await _platformUtilsService.ShowDialogAsync(
(e?.Error != null ? e.Error.GetSingleMessage() : AppResources.LoginSsoError),
AppResources.AnErrorHasOccurred);
return;
}
var passwordOptions = new PasswordGenerationOptions(true);
passwordOptions.Length = 64;
var codeVerifier = await _passwordGenerationService.GeneratePasswordAsync(passwordOptions);
var codeVerifierHash = await _cryptoFunctionService.HashAsync(codeVerifier, CryptoHashAlgorithm.Sha256);
var codeChallenge = CoreHelpers.Base64UrlEncode(codeVerifierHash);
var state = await _passwordGenerationService.GeneratePasswordAsync(passwordOptions);
var redirectUri = "bitwarden://sso-callback";
var url = _apiService.IdentityBaseUrl + "/connect/authorize?" +
"client_id=" + _platformUtilsService.IdentityClientId + "&" +
"redirect_uri=" + Uri.EscapeDataString(redirectUri) + "&" +
"response_type=code&scope=api%20offline_access&" +
"state=" + state + "&code_challenge=" + codeChallenge + "&" +
"code_challenge_method=S256&response_mode=query&" +
"domain_hint=" + Uri.EscapeDataString(OrgIdentifier);
WebAuthenticatorResult authResult = null;
bool cancelled = false;
try
{
authResult = await WebAuthenticator.AuthenticateAsync(new Uri(url),
new Uri(redirectUri));
}
catch (TaskCanceledException taskCanceledException)
{
await _deviceActionService.HideLoadingAsync();
cancelled = true;
}
catch (Exception e)
{
// WebAuthenticator throws NSErrorException if iOS flow is cancelled - by setting cancelled to true
// here we maintain the appearance of a clean cancellation (we don't want to do this across the board
// because we still want to present legitimate errors). If/when this is fixed, we can remove this
// particular catch block (catching taskCanceledException above must remain)
// https://github.com/xamarin/Essentials/issues/1240
if (Device.RuntimePlatform == Device.iOS)
{
await _deviceActionService.HideLoadingAsync();
cancelled = true;
}
}
if (!cancelled)
{
var code = GetResultCode(authResult, state);
if (!string.IsNullOrEmpty(code))
{
await LogIn(code, codeVerifier, redirectUri);
}
else
{
await _deviceActionService.HideLoadingAsync();
await _platformUtilsService.ShowDialogAsync(AppResources.LoginSsoError,
AppResources.AnErrorHasOccurred);
}
}
}
private string GetResultCode(WebAuthenticatorResult authResult, string state)
{
string code = null;
if (authResult != null)
{
authResult.Properties.TryGetValue("state", out var resultState);
if (resultState == state)
{
authResult.Properties.TryGetValue("code", out var resultCode);
code = resultCode;
}
}
return code;
}
private async Task LogIn(string code, string codeVerifier, string redirectUri)
{
try
{
var response = await _authService.LogInSsoAsync(code, codeVerifier, redirectUri);
if (RememberOrgIdentifier)
{
await _storageService.SaveAsync(Keys_RememberedOrgIdentifier, OrgIdentifier);
}
else
{
await _storageService.RemoveAsync(Keys_RememberedOrgIdentifier);
}
await _deviceActionService.HideLoadingAsync();
if (response.TwoFactor)
{
StartTwoFactorAction?.Invoke();
}
else if (response.ResetMasterPassword)
{
StartSetPasswordAction?.Invoke();
}
else
{
var disableFavicon = await _storageService.GetAsync<bool?>(Constants.DisableFaviconKey);
await _stateService.SaveAsync(Constants.DisableFaviconKey, disableFavicon.GetValueOrDefault());
var task = Task.Run(async () => await _syncService.FullSyncAsync(true));
SsoAuthSuccessAction?.Invoke();
}
}
catch (Exception e)
{
await _deviceActionService.HideLoadingAsync();
await _platformUtilsService.ShowDialogAsync(AppResources.LoginSsoError,
AppResources.AnErrorHasOccurred);
}
}
}
}

View File

@@ -1,6 +1,7 @@
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -17,12 +18,11 @@ namespace Bit.App.Pages
InitializeComponent();
_vm = BindingContext as RegisterPageViewModel;
_vm.Page = this;
_vm.RegistrationSuccess = async () =>
_vm.RegistrationSuccess = () => Device.BeginInvokeOnMainThread(async () => await RegistrationSuccessAsync(homePage));
_vm.CloseAction = async () =>
{
if (homePage != null)
{
await homePage.DismissRegisterPageAndLogInAsync(_vm.Email);
}
_messagingService.Send("showStatusBar", false);
await Navigation.PopModalAsync();
};
MasterPasswordEntry = _masterPassword;
ConfirmMasterPasswordEntry = _confirmMasterPassword;
@@ -55,13 +55,20 @@ namespace Bit.App.Pages
await _vm.SubmitAsync();
}
}
private async Task RegistrationSuccessAsync(HomePage homePage)
{
if (homePage != null)
{
await homePage.DismissRegisterPageAndLogInAsync(_vm.Email);
}
}
private async void Close_Clicked(object sender, EventArgs e)
private void Close_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_messagingService.Send("showStatusBar", false);
await Navigation.PopModalAsync();
_vm.CloseAction();
}
}
}

View File

@@ -52,6 +52,7 @@ namespace Bit.App.Pages
public string ConfirmMasterPassword { get; set; }
public string Hint { get; set; }
public Action RegistrationSuccess { get; set; }
public Action CloseAction { get; set; }
public async Task SubmitAsync()
{

View File

@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8" ?>
<pages:BaseContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Bit.App.Pages.SetPasswordPage"
xmlns:pages="clr-namespace:Bit.App.Pages"
xmlns:controls="clr-namespace:Bit.App.Controls"
xmlns:u="clr-namespace:Bit.App.Utilities"
x:DataType="pages:SetPasswordPageViewModel"
Title="{Binding PageTitle}">
<ContentPage.BindingContext>
<pages:SetPasswordPageViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<u:InverseBoolConverter x:Key="inverseBool" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.ToolbarItems>
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
<ToolbarItem Text="{u:I18n Submit}" Clicked="Submit_Clicked" />
</ContentPage.ToolbarItems>
<ScrollView>
<StackLayout Spacing="20">
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row">
<Label Text="{u:I18n SetMasterPasswordSummary}"
StyleClass="text-md"
HorizontalTextAlignment="Start"></Label>
</StackLayout>
<Grid IsVisible="{Binding IsPolicyInEffect}"
RowSpacing="0"
ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Frame Padding="10"
Margin="0"
HasShadow="False"
BackgroundColor="Transparent"
BorderColor="Accent">
<Label
Text="{Binding PolicySummary}"
StyleClass="text-muted, text-sm, text-bold"
HorizontalTextAlignment="Start" />
</Frame>
</Grid>
<Grid StyleClass="box-row">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label
Text="{u:I18n MasterPassword}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
<controls:MonoEntry
x:Name="_masterPassword"
Text="{Binding MasterPassword}"
StyleClass="box-value"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False"
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
Grid.Row="1"
Grid.Column="0" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
Command="{Binding TogglePasswordCommand}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
</Grid>
<Label
Text="{u:I18n MasterPasswordDescription}"
StyleClass="box-footer-label" />
</StackLayout>
<StackLayout StyleClass="box">
<Grid StyleClass="box-row">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label
Text="{u:I18n RetypeMasterPassword}"
StyleClass="box-label"
Grid.Row="0"
Grid.Column="0" />
<controls:MonoEntry
x:Name="_confirmMasterPassword"
Text="{Binding ConfirmMasterPassword}"
StyleClass="box-value"
IsSpellCheckEnabled="False"
IsTextPredictionEnabled="False"
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
Grid.Row="1"
Grid.Column="0" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="{Binding ShowPasswordIcon}"
Command="{Binding ToggleConfirmPasswordCommand}"
Grid.Row="0"
Grid.Column="1"
Grid.RowSpan="2"
AutomationProperties.IsInAccessibleTree="True"
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
</Grid>
<StackLayout StyleClass="box-row">
<Label
Text="{u:I18n MasterPasswordHint}"
StyleClass="box-label" />
<Entry
x:Name="_hint"
Text="{Binding Hint}"
StyleClass="box-value"
ReturnType="Go"
ReturnCommand="{Binding SubmitCommand}" />
</StackLayout>
<Label
Text="{u:I18n MasterPasswordHintDescription}"
StyleClass="box-footer-label" />
</StackLayout>
</StackLayout>
</ScrollView>
</pages:BaseContentPage>

View File

@@ -0,0 +1,82 @@
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Models;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public partial class SetPasswordPage : BaseContentPage
{
private readonly IMessagingService _messagingService;
private readonly SetPasswordPageViewModel _vm;
private readonly AppOptions _appOptions;
public SetPasswordPage(AppOptions appOptions = null)
{
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_messagingService.Send("showStatusBar", true);
_appOptions = appOptions;
InitializeComponent();
_vm = BindingContext as SetPasswordPageViewModel;
_vm.Page = this;
_vm.SetPasswordSuccessAction =
() => Device.BeginInvokeOnMainThread(async () => await SetPasswordSuccessAsync());
_vm.CloseAction = async () =>
{
_messagingService.Send("showStatusBar", false);
await Navigation.PopModalAsync();
};
if (Device.RuntimePlatform == Device.Android)
{
ToolbarItems.RemoveAt(0);
}
MasterPasswordEntry = _masterPassword;
ConfirmMasterPasswordEntry = _confirmMasterPassword;
_masterPassword.ReturnType = ReturnType.Next;
_masterPassword.ReturnCommand = new Command(() => _confirmMasterPassword.Focus());
_confirmMasterPassword.ReturnType = ReturnType.Next;
_confirmMasterPassword.ReturnCommand = new Command(() => _hint.Focus());
}
public Entry MasterPasswordEntry { get; set; }
public Entry ConfirmMasterPasswordEntry { get; set; }
protected override async void OnAppearing()
{
base.OnAppearing();
await _vm.InitAsync();
RequestFocus(_masterPassword);
}
private async void Submit_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
await _vm.SubmitAsync();
}
}
private async void Close_Clicked(object sender, EventArgs e)
{
if (DoOnce())
{
_vm.CloseAction();
}
}
private async Task SetPasswordSuccessAsync()
{
if (AppHelpers.SetAlternateMainPage(_appOptions))
{
return;
}
var previousPage = await AppHelpers.ClearPreviousPage();
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
}
}
}

View File

@@ -0,0 +1,259 @@
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Request;
using Bit.Core.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Bit.Core.Models.Domain;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Bit.App.Pages
{
public class SetPasswordPageViewModel : BaseViewModel
{
private readonly IDeviceActionService _deviceActionService;
private readonly IApiService _apiService;
private readonly ICryptoService _cryptoService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IUserService _userService;
private readonly IPolicyService _policyService;
private readonly IPasswordGenerationService _passwordGenerationService;
private readonly II18nService _i18nService;
private bool _showPassword;
private bool _isPolicyInEffect;
private string _policySummary;
private MasterPasswordPolicyOptions _policy;
public SetPasswordPageViewModel()
{
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_apiService = ServiceContainer.Resolve<IApiService>("apiService");
_cryptoService = ServiceContainer.Resolve<ICryptoService>("cryptoService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_userService = ServiceContainer.Resolve<IUserService>("userService");
_policyService = ServiceContainer.Resolve<IPolicyService>("policyService");
_passwordGenerationService =
ServiceContainer.Resolve<IPasswordGenerationService>("passwordGenerationService");
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
PageTitle = AppResources.SetMasterPassword;
TogglePasswordCommand = new Command(TogglePassword);
ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword);
SubmitCommand = new Command(async () => await SubmitAsync());
}
public bool ShowPassword
{
get => _showPassword;
set => SetProperty(ref _showPassword, value,
additionalPropertyNames: new[] { nameof(ShowPasswordIcon) });
}
public bool IsPolicyInEffect
{
get => _isPolicyInEffect;
set => SetProperty(ref _isPolicyInEffect, value);
}
public string PolicySummary
{
get => _policySummary;
set => SetProperty(ref _policySummary, value);
}
public MasterPasswordPolicyOptions Policy
{
get => _policy;
set => SetProperty(ref _policy, value);
}
public Command SubmitCommand { get; }
public Command TogglePasswordCommand { get; }
public Command ToggleConfirmPasswordCommand { get; }
public string ShowPasswordIcon => ShowPassword ? "" : "";
public string MasterPassword { get; set; }
public string ConfirmMasterPassword { get; set; }
public string Hint { get; set; }
public Action SetPasswordSuccessAction { get; set; }
public Action CloseAction { get; set; }
public async Task InitAsync()
{
await CheckPasswordPolicy();
}
public async Task SubmitAsync()
{
if (Connectivity.NetworkAccess == NetworkAccess.None)
{
await _platformUtilsService.ShowDialogAsync(AppResources.InternetConnectionRequiredMessage,
AppResources.InternetConnectionRequiredTitle);
return;
}
if (string.IsNullOrWhiteSpace(MasterPassword))
{
await Page.DisplayAlert(AppResources.AnErrorHasOccurred,
string.Format(AppResources.ValidationFieldRequired, AppResources.MasterPassword),
AppResources.Ok);
return;
}
if (IsPolicyInEffect)
{
var userInput = await GetPasswordStrengthUserInput();
var passwordStrength = _passwordGenerationService.PasswordStrength(MasterPassword, userInput);
if (!await _policyService.EvaluateMasterPassword(passwordStrength.Score, MasterPassword, Policy))
{
await Page.DisplayAlert(AppResources.MasterPasswordPolicyValidationTitle,
AppResources.MasterPasswordPolicyValidationMessage, AppResources.Ok);
return;
}
}
else
{
if (MasterPassword.Length < 8)
{
await Page.DisplayAlert(AppResources.MasterPasswordPolicyValidationTitle,
AppResources.MasterPasswordLengthValMessage, AppResources.Ok);
return;
}
}
if (MasterPassword != ConfirmMasterPassword)
{
await Page.DisplayAlert(AppResources.AnErrorHasOccurred,
AppResources.MasterPasswordConfirmationValMessage, AppResources.Ok);
return;
}
var kdf = KdfType.PBKDF2_SHA256;
var kdfIterations = 100000;
var email = await _userService.GetEmailAsync();
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations);
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key);
Tuple<SymmetricCryptoKey, CipherString> encKey;
var existingEncKey = await _cryptoService.GetEncKeyAsync();
if (existingEncKey == null)
{
encKey = await _cryptoService.MakeEncKeyAsync(key);
}
else
{
encKey = await _cryptoService.RemakeEncKeyAsync(key);
}
var keys = await _cryptoService.MakeKeyPairAsync(encKey.Item1);
var request = new SetPasswordRequest
{
MasterPasswordHash = masterPasswordHash,
Key = encKey.Item2.EncryptedString,
MasterPasswordHint = Hint,
Kdf = kdf,
KdfIterations = kdfIterations,
Keys = new KeysRequest
{
PublicKey = keys.Item1,
EncryptedPrivateKey = keys.Item2.EncryptedString
}
};
try
{
await _deviceActionService.ShowLoadingAsync(AppResources.CreatingAccount);
await _apiService.SetPasswordAsync(request);
await _userService.SetInformationAsync(await _userService.GetUserIdAsync(),
await _userService.GetEmailAsync(), kdf, kdfIterations);
await _cryptoService.SetKeyAsync(key);
await _cryptoService.SetKeyHashAsync(masterPasswordHash);
await _cryptoService.SetEncKeyAsync(encKey.Item2.EncryptedString);
await _cryptoService.SetEncPrivateKeyAsync(keys.Item2.EncryptedString);
await _deviceActionService.HideLoadingAsync();
SetPasswordSuccessAction?.Invoke();
}
catch (ApiException e)
{
await _deviceActionService.HideLoadingAsync();
if (e?.Error != null)
{
await _platformUtilsService.ShowDialogAsync(e.Error.GetSingleMessage(),
AppResources.AnErrorHasOccurred);
}
}
}
public void TogglePassword()
{
ShowPassword = !ShowPassword;
(Page as SetPasswordPage).MasterPasswordEntry.Focus();
}
public void ToggleConfirmPassword()
{
ShowPassword = !ShowPassword;
(Page as SetPasswordPage).ConfirmMasterPasswordEntry.Focus();
}
private async Task CheckPasswordPolicy()
{
Policy = await _policyService.GetMasterPasswordPolicyOptions();
IsPolicyInEffect = Policy?.InEffect() ?? false;
if (!IsPolicyInEffect)
{
return;
}
var bullet = "\n" + "".PadLeft(4) + "\u2022 ";
var sb = new StringBuilder();
sb.Append(_i18nService.T("MasterPasswordPolicyInEffect"));
if (Policy.MinComplexity > 0)
{
sb.Append(bullet)
.Append(string.Format(_i18nService.T("PolicyInEffectMinComplexity"), Policy.MinComplexity));
}
if (Policy.MinLength > 0)
{
sb.Append(bullet).Append(string.Format(_i18nService.T("PolicyInEffectMinLength"), Policy.MinLength));
}
if (Policy.RequireUpper)
{
sb.Append(bullet).Append(_i18nService.T("PolicyInEffectUppercase"));
}
if (Policy.RequireLower)
{
sb.Append(bullet).Append(_i18nService.T("PolicyInEffectLowercase"));
}
if (Policy.RequireNumbers)
{
sb.Append(bullet).Append(_i18nService.T("PolicyInEffectNumbers"));
}
if (Policy.RequireSpecial)
{
sb.Append(bullet).Append(string.Format(_i18nService.T("PolicyInEffectSpecial"), "!@#$%^&*"));
}
PolicySummary = sb.ToString();
}
private async Task<List<string>> GetPasswordStrengthUserInput()
{
var email = await _userService.GetEmailAsync();
List<string> userInput = null;
var atPosition = email.IndexOf('@');
if (atPosition > -1)
{
var rx = new Regex("/[^A-Za-z0-9]/", RegexOptions.Compiled);
var data = rx.Split(email.Substring(0, atPosition).Trim().ToLower());
userInput = new List<string>(data);
}
return userInput;
}
}
}

View File

@@ -1,10 +1,10 @@
using Bit.App.Controls;
using Bit.App.Models;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Utilities;
using System;
using System.Threading.Tasks;
using Bit.App.Utilities;
using Xamarin.Forms;
namespace Bit.App.Pages
@@ -14,22 +14,29 @@ namespace Bit.App.Pages
private readonly IBroadcasterService _broadcasterService;
private readonly IMessagingService _messagingService;
private readonly IStorageService _storageService;
private readonly IVaultTimeoutService _vaultTimeoutService;
private readonly AppOptions _appOptions;
private TwoFactorPageViewModel _vm;
private bool _inited;
private bool _authingWithSso;
public TwoFactorPage(AppOptions appOptions = null)
public TwoFactorPage(bool? authingWithSso = false, AppOptions appOptions = null)
{
InitializeComponent();
SetActivityIndicator();
_authingWithSso = authingWithSso ?? false;
_appOptions = appOptions;
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
_vm = BindingContext as TwoFactorPageViewModel;
_vm.Page = this;
_vm.TwoFactorAction = () => Device.BeginInvokeOnMainThread(async () => await TwoFactorAuthAsync());
_vm.StartSetPasswordAction = () =>
Device.BeginInvokeOnMainThread(async () => await StartSetPasswordAsync());
_vm.TwoFactorAuthSuccessAction = () =>
Device.BeginInvokeOnMainThread(async () => await TwoFactorAuthSuccessAsync());
_vm.CloseAction = async () => await Navigation.PopModalAsync();
DuoWebView = _duoWebView;
if (Device.RuntimePlatform == Device.Android)
@@ -141,7 +148,7 @@ namespace Bit.App.Pages
}
}
private async void Close_Clicked(object sender, System.EventArgs e)
private void Close_Clicked(object sender, System.EventArgs e)
{
if (DoOnce())
{
@@ -159,28 +166,29 @@ namespace Bit.App.Pages
}
}
}
private async Task TwoFactorAuthAsync()
private async Task StartSetPasswordAsync()
{
if (_appOptions != null)
_vm.CloseAction();
var page = new SetPasswordPage(_appOptions);
await Navigation.PushModalAsync(new NavigationPage(page));
}
private async Task TwoFactorAuthSuccessAsync()
{
if (_authingWithSso)
{
if (_appOptions.FromAutofillFramework && _appOptions.SaveType.HasValue)
Application.Current.MainPage = new NavigationPage(new LockPage(_appOptions));
}
else
{
if (AppHelpers.SetAlternateMainPage(_appOptions))
{
Application.Current.MainPage = new NavigationPage(new AddEditPage(appOptions: _appOptions));
return;
}
if (_appOptions.Uri != null)
{
Application.Current.MainPage = new NavigationPage(new AutofillCiphersPage(_appOptions));
return;
}
var previousPage = await AppHelpers.ClearPreviousPage();
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
}
var previousPage = await _storageService.GetAsync<PreviousPageInfo>(Constants.PreviousPageKey);
if (previousPage != null)
{
await _storageService.RemoveAsync(Constants.PreviousPageKey);
}
Application.Current.MainPage = new TabsPage(_appOptions, previousPage);
}
}
}

View File

@@ -31,6 +31,7 @@ namespace Bit.App.Pages
private TwoFactorProviderType? _selectedProviderType;
private string _totpInstruction;
private string _webVaultUrl = "https://vault.bitwarden.com";
private bool _authingWithSso = false;
public TwoFactorPageViewModel()
{
@@ -89,19 +90,21 @@ namespace Bit.App.Pages
});
}
public Command SubmitCommand { get; }
public Action TwoFactorAction { get; set; }
public Action TwoFactorAuthSuccessAction { get; set; }
public Action StartSetPasswordAction { get; set; }
public Action CloseAction { get; set; }
public void Init()
{
if (string.IsNullOrWhiteSpace(_authService.Email) ||
string.IsNullOrWhiteSpace(_authService.MasterPasswordHash) ||
if ((!_authService.AuthingWithSso() && !_authService.AuthingWithPassword()) ||
_authService.TwoFactorProvidersData == null)
{
// TODO: dismiss modal?
return;
}
_authingWithSso = _authService.AuthingWithSso();
if (!string.IsNullOrWhiteSpace(_environmentService.BaseUrl))
{
_webVaultUrl = _environmentService.BaseUrl;
@@ -204,14 +207,21 @@ namespace Bit.App.Pages
try
{
await _deviceActionService.ShowLoadingAsync(AppResources.Validating);
await _authService.LogInTwoFactorAsync(SelectedProviderType.Value, Token, Remember);
await _deviceActionService.HideLoadingAsync();
var result = await _authService.LogInTwoFactorAsync(SelectedProviderType.Value, Token, Remember);
var task = Task.Run(() => _syncService.FullSyncAsync(true));
await _deviceActionService.HideLoadingAsync();
_messagingService.Send("listenYubiKeyOTP", false);
_broadcasterService.Unsubscribe(nameof(TwoFactorPage));
var disableFavicon = await _storageService.GetAsync<bool?>(Constants.DisableFaviconKey);
await _stateService.SaveAsync(Constants.DisableFaviconKey, disableFavicon.GetValueOrDefault());
TwoFactorAction?.Invoke();
if (_authingWithSso && result.ResetMasterPassword)
{
StartSetPasswordAction?.Invoke();
}
else
{
var disableFavicon = await _storageService.GetAsync<bool?>(Constants.DisableFaviconKey);
await _stateService.SaveAsync(Constants.DisableFaviconKey, disableFavicon.GetValueOrDefault());
TwoFactorAuthSuccessAction?.Invoke();
}
}
catch (ApiException e)
{

View File

@@ -81,7 +81,7 @@
Text="{Binding Date, Mode=OneWay, Converter={StaticResource dateTime}}" />
<controls:FaButton
StyleClass="list-row-button, list-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding BindingContext.CopyCommand, Source={x:Reference _page}}"
CommandParameter="{Binding .}"
Grid.Row="0"

View File

@@ -286,6 +286,10 @@ namespace Bit.App.Pages
public async Task SliderInputAsync()
{
if (!_doneIniting)
{
return;
}
SetOptions();
_passwordGenerationService.NormalizeOptions(_options, _enforcedPolicyOptions);
Password = await _passwordGenerationService.GeneratePasswordAsync(_options);

View File

@@ -22,6 +22,7 @@ namespace Bit.App.Pages
private readonly IVaultTimeoutService _vaultTimeoutService;
private readonly IStorageService _storageService;
private readonly ISyncService _syncService;
private readonly IBiometricService _biometricService;
private bool _supportsBiometric;
private bool _pin;
@@ -60,6 +61,7 @@ namespace Bit.App.Pages
_vaultTimeoutService = ServiceContainer.Resolve<IVaultTimeoutService>("vaultTimeoutService");
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
_biometricService = ServiceContainer.Resolve<IBiometricService>("biometricService");
GroupedItems = new ExtendedObservableCollection<SettingsPageListGroup>();
PageTitle = AppResources.Settings;
@@ -306,6 +308,7 @@ namespace Bit.App.Pages
}
if (_biometric)
{
await _biometricService.SetupBiometricAsync();
await _storageService.SaveAsync(Constants.BiometricUnlockKey, true);
}
else

View File

@@ -16,23 +16,36 @@
<ToolbarItem Text="{u:I18n Close}" Clicked="Close_Clicked" Order="Primary" Priority="-1" />
</ContentPage.ToolbarItems>
<ScrollView>
<StackLayout Spacing="10"
Padding="10, 5"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand">
<Button Text="{u:I18n SyncVaultNow}"
Clicked="Sync_Clicked"></Button>
<Label StyleClass="text-muted, text-sm" HorizontalTextAlignment="Center">
<Label.FormattedText>
<FormattedString>
<Span Text="{u:I18n LastSync}" />
<Span Text=" " />
<Span Text="{Binding LastSync}" />
</FormattedString>
</Label.FormattedText>
</Label>
<ScrollView Padding="0, 0, 0, 20">
<StackLayout Padding="0" Spacing="20">
<StackLayout StyleClass="box">
<StackLayout StyleClass="box-row, box-row-switch">
<Label
Text="{u:I18n EnableSyncOnRefresh}"
StyleClass="box-label, box-label-regular"
HorizontalOptions="StartAndExpand" />
<Switch
IsToggled="{Binding EnableSyncOnRefresh}"
StyleClass="box-value"
HorizontalOptions="End" />
</StackLayout>
<Label
Text="{u:I18n EnableSyncOnRefreshDescription}"
StyleClass="box-footer-label, box-footer-label-switch" />
</StackLayout>
<StackLayout StyleClass="box">
<Button Text="{u:I18n SyncVaultNow}" Clicked="Sync_Clicked"></Button>
<Label StyleClass="text-muted, text-sm" HorizontalTextAlignment="Center">
<Label.FormattedText>
<FormattedString>
<Span Text="{u:I18n LastSync}" />
<Span Text=" " />
<Span Text="{Binding LastSync}" />
</FormattedString>
</Label.FormattedText>
</Label>
</StackLayout>
</StackLayout>
</ScrollView>
</pages:BaseContentPage>
</pages:BaseContentPage>

View File

@@ -21,7 +21,7 @@ namespace Bit.App.Pages
protected async override void OnAppearing()
{
base.OnAppearing();
await _vm.SetLastSyncAsync();
await _vm.InitAsync();
}
private async void Sync_Clicked(object sender, EventArgs e)

View File

@@ -1,5 +1,6 @@
using Bit.App.Abstractions;
using Bit.App.Resources;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Exceptions;
using Bit.Core.Utilities;
@@ -11,25 +12,56 @@ namespace Bit.App.Pages
{
private readonly IDeviceActionService _deviceActionService;
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IStorageService _storageService;
private readonly ISyncService _syncService;
private string _lastSync = "--";
private bool _inited;
private bool _syncOnRefresh;
public SyncPageViewModel()
{
_deviceActionService = ServiceContainer.Resolve<IDeviceActionService>("deviceActionService");
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
_syncService = ServiceContainer.Resolve<ISyncService>("syncService");
PageTitle = AppResources.Sync;
}
public bool EnableSyncOnRefresh
{
get => _syncOnRefresh;
set
{
if (SetProperty(ref _syncOnRefresh, value))
{
var task = UpdateSyncOnRefreshAsync();
}
}
}
public string LastSync
{
get => _lastSync;
set => SetProperty(ref _lastSync, value);
}
public async Task InitAsync()
{
await SetLastSyncAsync();
EnableSyncOnRefresh = await _storageService.GetAsync<bool>(Constants.SyncOnRefreshKey);
_inited = true;
}
public async Task UpdateSyncOnRefreshAsync()
{
if (_inited)
{
await _storageService.SaveAsync(Constants.SyncOnRefreshKey, _syncOnRefresh);
}
}
public async Task SetLastSyncAsync()
{
var last = await _syncService.GetLastSyncAsync();

View File

@@ -1,12 +1,14 @@
using Bit.App.Abstractions;
using Bit.App.Models;
using Bit.App.Resources;
using Bit.App.Utilities;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.PlatformConfiguration;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
@@ -243,6 +245,12 @@ namespace Bit.App.Pages
{
if (DoOnce())
{
var cameraPermission = await PermissionManager.CheckAndRequestPermissionAsync(new Permissions.Camera());
if (cameraPermission != PermissionStatus.Granted)
{
return;
}
var page = new ScanPage(key =>
{
Device.BeginInvokeOnMainThread(async () =>

View File

@@ -194,6 +194,7 @@ namespace Bit.App.Pages
base.OnDisappearing();
IsBusy = false;
_broadcasterService.Unsubscribe(_pageName);
_vm.DisableRefreshing();
}
private async void RowSelected(object sender, SelectedItemChangedEventArgs e)

View File

@@ -27,6 +27,7 @@ namespace Bit.App.Pages
private bool _showNoData;
private bool _showList;
private bool _websiteIconsEnabled;
private bool _syncRefreshing;
private string _noDataText;
private List<CipherView> _allCiphers;
private Dictionary<string, int> _folderCounts = new Dictionary<string, int>();
@@ -44,6 +45,7 @@ namespace Bit.App.Pages
private readonly IPlatformUtilsService _platformUtilsService;
private readonly IMessagingService _messagingService;
private readonly IStateService _stateService;
private readonly IStorageService _storageService;
public GroupingsPageViewModel()
{
@@ -57,6 +59,7 @@ namespace Bit.App.Pages
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
_messagingService = ServiceContainer.Resolve<IMessagingService>("messagingService");
_stateService = ServiceContainer.Resolve<IStateService>("stateService");
_storageService = ServiceContainer.Resolve<IStorageService>("storageService");
Loading = true;
PageTitle = AppResources.MyVault;
@@ -94,6 +97,11 @@ namespace Bit.App.Pages
get => _refreshing;
set => SetProperty(ref _refreshing, value);
}
public bool SyncRefreshing
{
get => _syncRefreshing;
set => SetProperty(ref _syncRefreshing, value);
}
public bool Loading
{
get => _loading;
@@ -149,6 +157,13 @@ namespace Bit.App.Pages
{
return;
}
if (await _storageService.GetAsync<bool>(Constants.SyncOnRefreshKey) && Refreshing && !SyncRefreshing)
{
SyncRefreshing = true;
await _syncService.FullSyncAsync(false);
return;
}
_doingLoad = true;
LoadedOnce = true;
ShowNoData = false;
@@ -266,12 +281,18 @@ namespace Bit.App.Pages
_doingLoad = false;
Loaded = true;
Loading = false;
Refreshing = false;
ShowNoData = (MainPage && !HasCiphers) || !groupedItems.Any();
ShowList = !ShowNoData;
DisableRefreshing();
}
}
public void DisableRefreshing()
{
Refreshing = false;
SyncRefreshing = false;
}
public async Task SelectCipherAsync(CipherView cipher)
{
var page = new ViewPage(cipher.Id);

View File

@@ -72,7 +72,7 @@
Text="{Binding LastUsedDate, Mode=OneWay, Converter={StaticResource dateTime}}" />
<controls:FaButton
StyleClass="list-row-button, list-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding BindingContext.CopyCommand, Source={x:Reference _page}}"
CommandParameter="{Binding .}"
Grid.Row="0"

View File

@@ -84,7 +84,7 @@
Grid.Column="0" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding CopyCommand}"
CommandParameter="LoginUsername"
Grid.Row="0"
@@ -148,7 +148,7 @@
IsVisible="{Binding Cipher.ViewPassword}" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding CopyCommand}"
CommandParameter="LoginPassword"
Grid.Row="0"
@@ -192,7 +192,7 @@
VerticalOptions="CenterAndExpand" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding CopyCommand}"
CommandParameter="LoginTotp"
Grid.Row="0"
@@ -237,7 +237,7 @@
Grid.Column="0" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding CopyCommand}"
CommandParameter="CardNumber"
Grid.Row="0"
@@ -309,7 +309,7 @@
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding CopyCommand}"
CommandParameter="CardCode"
Grid.Row="0"
@@ -470,7 +470,7 @@
Grid.Column="0"
IsVisible="{Binding IsWebsite, Mode=OneWay}" />
<Label
Text="{Binding HostnameOrUri, Mode=OneWay}"
Text="{Binding HostOrUri, Mode=OneWay}"
StyleClass="box-value"
Grid.Row="1"
Grid.Column="0" />
@@ -487,7 +487,7 @@
AutomationProperties.Name="{u:I18n Launch}" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding BindingContext.CopyUriCommand, Source={x:Reference _page}}"
CommandParameter="{Binding .}"
Grid.Row="0"
@@ -581,7 +581,7 @@
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
<controls:FaButton
StyleClass="box-row-button, box-row-button-platform"
Text="&#xf0ea;"
Text="&#xf24d;"
Command="{Binding BindingContext.CopyFieldCommand, Source={x:Reference _page}}"
CommandParameter="{Binding Field}"
IsVisible="{Binding ShowCopyButton}"
@@ -681,4 +681,4 @@
</Button>
</AbsoluteLayout>
</pages:BaseContentPage>
</pages:BaseContentPage>

View File

@@ -2936,5 +2936,119 @@ namespace Bit.App.Resources {
return ResourceManager.GetString("DoYouReallyWantToSoftDeleteCipher", resourceCulture);
}
}
public static string BiometricInvalidated {
get {
return ResourceManager.GetString("BiometricInvalidated", resourceCulture);
}
}
public static string EnableSyncOnRefresh {
get {
return ResourceManager.GetString("EnableSyncOnRefresh", resourceCulture);
}
}
public static string EnableSyncOnRefreshDescription {
get {
return ResourceManager.GetString("EnableSyncOnRefreshDescription", resourceCulture);
}
}
public static string LogInSso {
get {
return ResourceManager.GetString("LogInSso", resourceCulture);
}
}
public static string LogInSsoSummary {
get {
return ResourceManager.GetString("LogInSsoSummary", resourceCulture);
}
}
public static string OrgIdentifier {
get {
return ResourceManager.GetString("OrgIdentifier", resourceCulture);
}
}
public static string LoginSsoError {
get {
return ResourceManager.GetString("LoginSsoError", resourceCulture);
}
}
public static string SetMasterPassword {
get {
return ResourceManager.GetString("SetMasterPassword", resourceCulture);
}
}
public static string SetMasterPasswordSummary {
get {
return ResourceManager.GetString("SetMasterPasswordSummary", resourceCulture);
}
}
public static string MasterPasswordPolicyInEffect {
get {
return ResourceManager.GetString("MasterPasswordPolicyInEffect", resourceCulture);
}
}
public static string PolicyInEffectMinComplexity {
get {
return ResourceManager.GetString("PolicyInEffectMinComplexity", resourceCulture);
}
}
public static string PolicyInEffectMinLength {
get {
return ResourceManager.GetString("PolicyInEffectMinLength", resourceCulture);
}
}
public static string PolicyInEffectUppercase {
get {
return ResourceManager.GetString("PolicyInEffectUppercase", resourceCulture);
}
}
public static string PolicyInEffectLowercase {
get {
return ResourceManager.GetString("PolicyInEffectLowercase", resourceCulture);
}
}
public static string PolicyInEffectNumbers {
get {
return ResourceManager.GetString("PolicyInEffectNumbers", resourceCulture);
}
}
public static string PolicyInEffectSpecial {
get {
return ResourceManager.GetString("PolicyInEffectSpecial", resourceCulture);
}
}
public static string MasterPasswordPolicyValidationTitle {
get {
return ResourceManager.GetString("MasterPasswordPolicyValidationTitle", resourceCulture);
}
}
public static string MasterPasswordPolicyValidationMessage {
get {
return ResourceManager.GetString("MasterPasswordPolicyValidationMessage", resourceCulture);
}
}
public static string Loading {
get {
return ResourceManager.GetString("Loading", resourceCulture);
}
}
}
}

View File

@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Вы сапраўды хочаце адправіць элемент у сметніцу?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Сигурни ли сте, че искате да преместите записа в кошчето?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Засечена е промяна в биометричните данни. Впишете се с главната парола, за да я включите отново биометричната идентификация.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Синхронизация при опресняване</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Синхронизиране на трезора с жест — провлачване надолу.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Еднократна идентификация (SSO)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Вписване чрез портала на организацията ви за еднократна идентификация. За да продължите, въведете идентификатора на организацията.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Идентификатор на организация</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>В момента не може да се впишете с еднократна идентификация</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Задаване на главна парола</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>За да завършите настройките за еднократна идентификация, трябва да зададете главна парола за трезора.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Поне една политика на организация има следните изисквания към главната ви парола:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Минимална сложност от {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Минимална дължина от {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Поне една главна буква</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Поне една малка буква</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Поне една цифра</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Поне един от следните специални знаци: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Грешна парола</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Паролата не покрива изискванията на организацията. Проверете политиките и пробвайте отново.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Зареждане</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Esteu segur que voleu enviar-ho a la paperera?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>S'ha detectat un canvi biomètric. Inicieu la sessió mitjançant la contrasenya principal per tornar a activar-la.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Activa la sincronització en actualitzar-se</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronització de la caixa forta amb un gest cap avall.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Inici de sessió únic d'empresa</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Inicieu la sessió ràpidament mitjançant el portal d'inici de sessió únic de la vostra organització. Introduïu l'identificador de la vostra organització per començar.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identificador dorganització</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Actualment no es pot iniciar sessió amb SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Estableix la contrasenya mestra</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Per completar la sessió amb SSO, configureu una contrasenya mestra per accedir i protegir la vostra caixa forta.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Una o més polítiques dorganització requereixen que la vostra contrasenya mestra complisca els requisits següents:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Puntuació mínima de complexitat de {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Longitud mínima de {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Conté un o més caràcters en majúscula</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Conté un o més caràcters en minúscula</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Conté un o més números</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Conté un o més dels següents caràcters especials: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Contrasenya no vàlida</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>La contrasenya no compleix els requisits de l'organització. Comproveu la informació de la política i torneu-ho a provar.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>S'està carregant</value>
</data>
</root>

View File

@@ -519,28 +519,28 @@
<value>Zamknout</value>
</data>
<data name="FifteenMinutes" xml:space="preserve">
<value>15 minutes</value>
<value>15 minut</value>
</data>
<data name="OneHour" xml:space="preserve">
<value>1 hour</value>
<value>1 hodina</value>
</data>
<data name="OneMinute" xml:space="preserve">
<value>1 minuta</value>
</data>
<data name="FourHours" xml:space="preserve">
<value>4 hours</value>
<value>4 hodiny</value>
</data>
<data name="Immediately" xml:space="preserve">
<value>Immediately</value>
<value>Okamžitě</value>
</data>
<data name="VaultTimeout" xml:space="preserve">
<value>Vault Timeout</value>
<value>Časový limit trezoru</value>
</data>
<data name="VaultTimeoutAction" xml:space="preserve">
<value>Vault Timeout Action</value>
<value>Akce při vypršení časového limitu trezoru</value>
</data>
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
<value>Logging out will remove all access to your vault and requires online authentication after the timeout period. Are you sure you want to use this setting?</value>
<value>Po vypršení časového limitu dojde k odhlášení. Přístup k trezoru bude odebrán a pro opětovné přihlášení bude vyžadováno online ověření. Opravdu chcete použít toto nastavení?</value>
</data>
<data name="LoggingIn" xml:space="preserve">
<value>Přihlašování…</value>
@@ -1440,7 +1440,7 @@
<value>Odemknout</value>
</data>
<data name="ThirtyMinutes" xml:space="preserve">
<value>30 minutes</value>
<value>30 minut</value>
</data>
<data name="SetPINDescription" xml:space="preserve">
<value>Nastavte svůj PIN kód pro odemknutí trezoru. Pokud se zcela odhlásíte z aplikace bude váš současný PIN bude resetován.</value>
@@ -1536,7 +1536,7 @@
<value>„Výzva k uložení“ vás automaticky vyzve k uložení nových položek do trezoru, kdykoli je poprvé zadáte.</value>
</data>
<data name="OnRestart" xml:space="preserve">
<value>On App Restart</value>
<value>Při restartu aplikace</value>
</data>
<data name="AutofillServiceNotEnabled" xml:space="preserve">
<value>Automatické vyplňování usnadňuje bezpečný přístup k trezoru Bitwarden z jiných webových stránek a aplikací. Vypadá to, že jste službu Bitwarden nepovolili. Povolte automatické vyplnění pro Bitwarden z obrazovky „Nastavení“.</value>
@@ -1674,4 +1674,61 @@
<value>Opravdu chcete položku přesunout do koše?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Er du sikker på, at du sende til papirkurven?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometrisk ændring fundet. Log ind vha. hovedadgangskode for at aktivere igen.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Aktivér synk ved opfriskning</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Synkronisering af boks med træk nedad-gestus.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Virksomheds Single Sign On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Log hurtigt ind vha. din organisations single sign-on portal. Angiv din organisations identifikator for at begynde.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisationsidentifikator</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Kan pt. ikke logge ind vha. SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Indstil hovedadgangskode</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>For at fuldføre indlogning vha. SSO skal en hovedadgangskode opsættes for at tilgå og beskytte din boks.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Én eller flere organisationspolitikker kræver, at din hovedadgangskode opfylder flg. krav:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum kompleksitetsscore på {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimumslængde på {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Indeholder ét eller flere store bogstaver</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Indeholder ét eller flere små bogstaver</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Indeholder ét eller flere cifre</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Indeholder ét eller flere af flg. specialtegn: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Ugyldig adgangskode</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Adgangskoden opfylder ikke organisationskravene. Tjek politikinformationen og forsøg igen.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Indlæser</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Wirklich in den Papierkorb legen?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometrische Änderung erkannt, zum erneuten Aktivieren mit Master-Passwort anmelden.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Sync beim Aktualisieren aktivieren</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Tresor mit Pull-down-Geste synchronisieren.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Schnell über den Single Sign-on Ihrer Organisation anmelden. Bitte geben Sie Ihre Organisationskennung an, um zu beginnen.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisationskennung</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Anmeldung mit SSO derzeit nicht möglich</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Masterpasswort festlegen</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Bitte legen Sie ein Masterpasswort für den Schutz Ihres Tresors fest, um die Anmeldung über SSO abzuschließen.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Eine oder mehrere Organisationsrichtlinien erfordern, dass Ihr Master-Passwort die folgenden Anforderungen erfüllt:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Kleinste Komplexitätsstufe von {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Mindestlänge von {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Enthält einen oder mehrere Großbuchstaben</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Enthält einen oder mehrere Kleinbuchstaben</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Enthält eine oder mehrere Zahlen</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Enthält eines oder mehrere der folgenden Sonderzeichen: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Ungültiges Passwort</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Passwort entspricht nicht den Anforderungen der Organisation. Bitte überprüfen Sie die Richtlinien-Informationen und versuchen Sie es erneut.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Wird geladen</value>
</data>
</root>

View File

@@ -1675,4 +1675,61 @@
<value>Θέλετε πραγματικά να στείλετε στον κάδο απορριμμάτων;</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1564,7 +1564,7 @@
<value>Your login session has expired.</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>Use biometrics to verify.</value>
<value>Biometric verification</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Biometrics</value>
@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the bin?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using master password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise single sign-on</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organisation's single sign-on portal. Please enter your organisation's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisation identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set master password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organisation policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organisation requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>¿Seguro que quieres enviarlo a la papelera?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Se ha detectado un cambio biométrico, inicie sesión usando la contraseña maestra para volver a activarlo.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Habilitar sincronización al actualizar</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronizando caja fuerte con gesto desplegable.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Inicio de sesión único empresarial</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Inicie sesión rápidamente usando el portal de inicio de sesión único de su organización. Por favor, introduzca el identificador de su organización para comenzar.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identificador de la organización</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Actualmente no se puede iniciar sesión con SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Establecer contraseña maestra</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Para completar el inicio de sesión con SSO, por favor establezca una contraseña maestra para acceder y proteger su caja fuerte.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Una o más políticas de la organización requieren que su contraseña maestra cumpla con los siguientes requisitos:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Puntuación mínima de complejidad de $SCORE$</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Longitud mínima de {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contiene uno o más caracteres en mayúsculas</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contiene uno o más caracteres en minúsculas</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contiene uno o más números</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contiene uno o más de los siguientes caracteres especiales $CHARS$</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Contraseña no válida</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>La contraseña no cumple con los requisitos de la organización. Por favor, compruebe la información de la política e inténtelo de nuevo.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Cargando</value>
</data>
</root>

View File

@@ -1120,7 +1120,7 @@
<value>Ikoonide serveri URL</value>
</data>
<data name="AutofillWithBitwarden" xml:space="preserve">
<value>Täida automaatselt Bitwardeniga</value>
<value>Täida Bitwardeniga</value>
</data>
<data name="VaultIsLocked" xml:space="preserve">
<value>Hoidla on lukus</value>
@@ -1674,4 +1674,61 @@
<value>Oled kindel, et soovid kirje(d) prügikasti teisaldada?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Tuvastati biomeetriliste andmete muutus. Selle funktsiooni uuesti kasutamiseks on vajalik sisselogimine ülemparooliga. </value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Luba allatõmbel sünkrooniseerimine</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Hoidla sünkroonimine ekraanil allatõmbamisel.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Kiire sisselogimine läbi organisatsiooni ühekordne sisselogimise portaali. Jätkamiseks sisesta organisatsiooni identifikaator.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisatsiooni identifikaator</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Hetkel pole SSO-ga sisselogimine võimalik</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Määra ülemparool</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>SSO-ga sisselogimise kinnitamiseks tuleb määrata ülemparool. See kaitseb sinu hoidlat ning võimaldab sellele ligi pääseda.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Üks või enam organisatsiooni eeskirja nõuavad, et ülemparool vastaks nendele nõudmistele:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimaalne keerulisuse skoor {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimaalne pikkus {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Sisaldab üht või enamat suurtähte</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Sisaldab üht või enamat väiketähte</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Sisaldab üht või rohkem numbreid</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Sisaldab üht või enamat järgnevatest märkidest: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Parool on vale</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Parool ei vasta organisatsiooni nõuetele. Vaata see üle ning proovi uuesti.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Laadimine</value>
</data>
</root>

View File

@@ -334,7 +334,7 @@
<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>
@@ -1674,4 +1674,61 @@
<value>واقعا می خواهید این آیتم را به سطل زباله ارسال کنید؟</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>تغییر بیومتریک شناسایی شد، برای فعال کردن مجدد آن با استفاده از کلمه عبور اصلی وارد سیستم شوید.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>فعال کردن همگام سازی در نوسازی</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>همگام سازی گاوصندوق با کشیدن به پایین.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>ورود به سیستم پروژه</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>با استفاده از پورتال ورود به سیستم واحد سازمانی خود، سریع وارد سیستم شوید. لطفا برای شروع شناسه سازمانی خود را وارد کنید.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>شناسه سازمان</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>در حال حاضر نمی توانید با SSO وارد شوید</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>تنظیم کلمه عبور اصلی</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>برای تکمیل ورود به سیستم با SSO ، لطفاً یک کلمه عبور اصلی برای دسترسی و محافظت از گاوصندوق خود تنظیم کنید.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>یک یا چند سیاست سازمانی برای تأمین شرایط زیر به گذرواژه اصلی شما احتیاج دارد:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>حداقل نمره پیچیدگی $SCORE$</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>حداقل طول {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>حاوی یک یا چند کاراکتر بزرگ</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>حاوی یک یا چند کاراکتر کوچک</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>حاوی یک یا چند عدد بیشتر</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>حاوی یک یا چند کاراکتر خاص زیر است: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>کلمه عبور نامعتبر</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>کلمه عبور از شرایط سازمان پیروی نمیکند. لطفاً اطلاعات سیاست را بررسی کرده و دوباره امتحان کنید.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>در حال بارگذاری</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Haluatko varmasti siirtää roskakoriin?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometriikan muutos havaittiin, ota käyttöön uudestaan kirjautumalla sisään pääsalasanalla.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Ota synkronointi käyttöön päivityksen yhteydessä</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisaation tunniste</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Aseta pääsalasana</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Yksi tai useampi organisaatiokäytäntö edellyttää, että pääsalasanasi täyttää seuraavat vaatimukset:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Monimutkaisuuden vähimmäispistemäärä on $SCORE$</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Vähimmäispituus on %s</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Sisältää yhden tai useamman ison kirjaimen</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Sisältää yhden tai useamman pienen kirjaimen</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Sisältää yhden tai useamman numeron</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Sisältää yhden tai useamman seuraavista erikoismerkeistä $CHARS$</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Virheellinen salasana</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Ladataan</value>
</data>
</root>

View File

@@ -1564,7 +1564,7 @@
<value>Votre session a expiré.</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>Utiliser une empreinte biométrique pour vérifier.</value>
<value>Utilisez une empreinte biométrique pour vous authentifier.</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Empreintes biométriques</value>
@@ -1674,4 +1674,61 @@
<value>Voulez-vous vraiment envoyer à la corbeille ?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Changement biométrique détecté, connectez-vous à l'aide du mot de passe maître pour l'activer à nouveau.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Activer la synchronisation lors de l'actualisation</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Synchronisation du coffre avec un geste vers le bas</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Portail de connexion unique d'entreprise</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Connectez-vous rapidement en utilisant le portail de connexion unique de votre organisation. Veuillez entrer l'identifiant de votre organisation pour commencer.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identifiant de l'organisation</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Impossible de se connecter avec SSO pour le moment</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Définir le mot de passe maître</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Afin de terminer la connexion avec SSO, veuillez définir un mot de passe maître pour accéder à votre coffre et le protéger.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Une ou plusieurs politiques de l'organisation exigent que votre mot de passe maître réponde aux exigences suivantes :</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Score de complexité minimum de {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Longueur minimale de {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contenir une ou plusieurs majuscules</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contenir une ou plusieurs minuscules</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contenir un ou plusieurs chiffres</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contenir un ou plusieurs des caractères spéciaux suivants $CHARS$</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Mot de passe invalide</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Le mot de passe ne répond pas aux exigences de l'organisation. Veuillez vérifier les restrictions et réessayer.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Chargement</value>
</data>
</root>

View File

@@ -1675,4 +1675,61 @@ Bitwarden בעזרת פתיחת חלון "הגדרות".</value>
<value>האם אתה בטוח שברצונך לשלוח פריט זה לסל המחזור?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -538,7 +538,7 @@
<value>तिजोरी का समय समाप्त</value>
</data>
<data name="VaultTimeoutAction" xml:space="preserve">
<value>Vault Timeout Action</value>
<value>तिजोरी का समय समाप्त</value>
</data>
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
<value>लॉग आउट करने से तिजोरी में प्रवेश संभव नहीं होगा और समय समाप्त होने के बाद ऑनलाइन प्रमाणीकरण की आश्यकता होगी। आप इस सेटिंग्स को प्रयोग करने के लिए विश्वस्त हैं?</value>
@@ -687,39 +687,39 @@
<comment>What Apple calls their fingerprint reader.</comment>
</data>
<data name="TwoStepLogin" xml:space="preserve">
<value>Two-step Login</value>
<value>द्वि-चरणीय लॉगिन</value>
</data>
<data name="TwoStepLoginConfirmation" xml:space="preserve">
<value>Two-step login makes your account more secure by requiring you to enter a security code from an authenticator app whenever you log in. Two-step login can be enabled on the bitwarden.com web vault. Do you want to visit the website now?</value>
</data>
<data name="UnlockWith" xml:space="preserve">
<value>Unlock with {0}</value>
<value>{0} से अनलॉक करें</value>
</data>
<data name="UnlockWithPIN" xml:space="preserve">
<value>Unlock with PIN Code</value>
<value>पिन कोड के साथ अनलॉक करें</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>
<value>आइटम देखें</value>
</data>
<data name="WebVault" xml:space="preserve">
<value>bitwarden Web Vault</value>
</data>
<data name="Lost2FAApp" xml:space="preserve">
<value>Lost authenticator app?</value>
<value>प्रमाणिक एप खो गया?</value>
</data>
<data name="Items" xml:space="preserve">
<value>Items</value>
<value>आइटम</value>
<comment>Screen title</comment>
</data>
<data name="ExtensionActivated" xml:space="preserve">
<value>Extension Activated!</value>
<value>एक्सटेंशन सक्रिय!</value>
</data>
<data name="Icons" xml:space="preserve">
<value>आइकॉन</value>
@@ -728,15 +728,15 @@
<value>अनुवाद</value>
</data>
<data name="ItemsForUri" xml:space="preserve">
<value>Items for {0}</value>
<value>{0} के लिए आइटम</value>
<comment>This is used for the autofill service. ex. "Logins for twitter.com"</comment>
</data>
<data name="NoItemsForUri" xml:space="preserve">
<value>There are no items in your vault for {0}.</value>
<value>{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">
<value>When you select an input field and see a Bitwarden auto-fill overlay, you can tap it to launch the auto-fill service.</value>
<value>जब आप एक इनपुट फ़ील्ड का चयन करते हैं और एक बिटवर्डेन ऑटो-फिल ओवरले देखते हैं, तो आप इसे ऑटो-फिल सेवा लॉन्च करने के लिए टैप कर सकते हैं।</value>
</data>
<data name="BitwardenAutofillServiceNotificationContent" xml:space="preserve">
<value>Tap this notification to auto-fill a login from your vault.</value>
@@ -748,7 +748,7 @@
<value>1. On the Android Accessibility Settings screen, touch "bitwarden" under the Services heading.</value>
</data>
<data name="BitwardenAutofillServiceStep2" xml:space="preserve">
<value>2. Switch on the toggle and press OK to accept.</value>
<value>2. टॉगल स्विच करें और स्वीकार करने के लिए ठीक दबाएँ।</value>
</data>
<data name="Disabled" xml:space="preserve">
<value>अक्षम कर दिया गया</value>
@@ -760,10 +760,10 @@
<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>
<value>अपनी तिजोरी में नए लॉगिन जोड़ने का सबसे आसान तरीका बिटवर्डन ऑटो-फिल सर्विस है। "सेटिंग्स" स्क्रीन पर नेविगेट करके बिटवर्डेन ऑटो-फिल सेवा का उपयोग करने के बारे में अधिक जानें।</value>
</data>
<data name="Autofill" xml:space="preserve">
<value>Auto-fill</value>
<value>स्वत:भरण</value>
</data>
<data name="AutofillOrView" xml:space="preserve">
<value>Do you want to auto-fill or view this login?</value>
@@ -772,10 +772,10 @@
<value>Are you sure you want to auto-fill this login? It is not a complete match for "{0}".</value>
</data>
<data name="MatchingItems" xml:space="preserve">
<value>Matching Items</value>
<value>एक जैसे वस्तु</value>
</data>
<data name="PossibleMatchingItems" xml:space="preserve">
<value>Possible Matching Items</value>
<value>संभावित मिलान</value>
</data>
<data name="Search" xml:space="preserve">
<value>खोजें</value>
@@ -784,45 +784,45 @@
<value>You are searching for an auto-fill login for "{0}".</value>
</data>
<data name="ShareVault" xml:space="preserve">
<value>Share Your Vault</value>
<value>अपनी तिजोरी साझा करें</value>
</data>
<data name="CannotOpenApp" xml:space="preserve">
<value>Cannot open the app "{0}".</value>
<value>"{0}" ऐप नहीं खोल सकता।</value>
<comment>Message shown when trying to launch an app that does not exist on the user's device.</comment>
</data>
<data name="AuthenticatorAppTitle" xml:space="preserve">
<value>Authenticator App</value>
<value>प्रमाणक ऐप</value>
<comment>For 2FA</comment>
</data>
<data name="EnterVerificationCodeApp" xml:space="preserve">
<value>Enter the 6 digit verification code from your authenticator app.</value>
<value>अपने प्रमाणक ऐप से 6 अंकों का सत्यापन कोड डालें।</value>
<comment>For 2FA</comment>
</data>
<data name="EnterVerificationCodeEmail" xml:space="preserve">
<value>Enter the 6 digit verification code that was emailed to {0}.</value>
<value>6 अंकों का सत्यापन कोड दर्ज करें जिसे {0} पर ईमेल किया गया था।</value>
<comment>For 2FA</comment>
</data>
<data name="LoginUnavailable" xml:space="preserve">
<value>Login Unavailable</value>
<value>लॉग इन अनुपलब्ध</value>
<comment>For 2FA whenever there are no available providers on this device.</comment>
</data>
<data name="NoTwoStepAvailable" xml:space="preserve">
<value>This account has two-step login enabled, however, none of the configured two-step providers are supported on this device. Please use a supported device and/or add additional providers that are better supported across devices (such as an authenticator app).</value>
<value>इस खाते में दो-चरण लॉगिन सक्षम हैं, हालांकि, कॉन्फ़िगर किए गए दो-चरण प्रदाताओं में से कोई भी इस डिवाइस पर समर्थित नहीं है। कृपया एक समर्थित डिवाइस का उपयोग करें और / या अतिरिक्त प्रदाताओं को जोड़ें जो कि डिवाइसों में बेहतर समर्थित हैं (जैसे एक प्रमाणक ऐप)।</value>
</data>
<data name="RecoveryCodeTitle" xml:space="preserve">
<value>Recovery Code</value>
<value>पुनःप्राप्ति सांकेतिक अंक</value>
<comment>For 2FA</comment>
</data>
<data name="RememberMe" xml:space="preserve">
<value>Remember me</value>
<value>मुझे याद रखना</value>
<comment>Remember my two-step login</comment>
</data>
<data name="SendVerificationCodeAgain" xml:space="preserve">
<value>Send verification code email again</value>
<value>फिर से सत्यापन कोड ईमेल भेजें</value>
<comment>For 2FA</comment>
</data>
<data name="TwoStepLoginOptions" xml:space="preserve">
<value>Two-step Login Options</value>
<value>दो-चरण लॉगिन विकल्प</value>
</data>
<data name="UseAnotherTwoStepMethod" xml:space="preserve">
<value>Use another two-step login method</value>
@@ -995,25 +995,25 @@
<value>लॉग इन</value>
</data>
<data name="TypeSecureNote" xml:space="preserve">
<value>Secure Note</value>
<value>सुरक्षित नोट</value>
</data>
<data name="Address1" xml:space="preserve">
<value>Address 1</value>
<value>पता 1</value>
</data>
<data name="Address2" xml:space="preserve">
<value>Address 2</value>
<value>पता 2</value>
</data>
<data name="Address3" xml:space="preserve">
<value>Address 3</value>
<value>पता 3</value>
</data>
<data name="April" xml:space="preserve">
<value>April</value>
<value>अप्रैल</value>
</data>
<data name="August" xml:space="preserve">
<value>August</value>
<value>अगस्त</value>
</data>
<data name="Brand" xml:space="preserve">
<value>Brand</value>
<value>ब्रांड</value>
</data>
<data name="CardholderName" xml:space="preserve">
<value>कार्डधारक का नाम</value>
@@ -1182,7 +1182,7 @@
<value>Hidden</value>
</data>
<data name="FieldTypeText" xml:space="preserve">
<value>Text</value>
<value>वाक्य</value>
</data>
<data name="NewCustomField" xml:space="preserve">
<value>New Custom Field</value>
@@ -1300,7 +1300,7 @@
<value>Invalid email address.</value>
</data>
<data name="Cards" xml:space="preserve">
<value>Cards</value>
<value>पत्ते</value>
</data>
<data name="Identities" xml:space="preserve">
<value>पहचान</value>
@@ -1309,7 +1309,7 @@
<value>लॉग इन</value>
</data>
<data name="SecureNotes" xml:space="preserve">
<value>Secure Notes</value>
<value>सुरक्षित नोट</value>
</data>
<data name="AllItems" xml:space="preserve">
<value>सभी आइटम</value>
@@ -1386,7 +1386,7 @@
<value>You must select at least one collection.</value>
</data>
<data name="Share" xml:space="preserve">
<value>Share</value>
<value>शेयर करें</value>
</data>
<data name="ShareItem" xml:space="preserve">
<value>Share Item</value>
@@ -1407,7 +1407,7 @@
<value>Word Separator</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">
@@ -1465,22 +1465,22 @@
<comment>A light color</comment>
</data>
<data name="FiveMinutes" xml:space="preserve">
<value>5 minutes</value>
<value>5 मिनट</value>
</data>
<data name="TenSeconds" xml:space="preserve">
<value>10 seconds</value>
<value>10 सेकंड</value>
</data>
<data name="ThirtySeconds" xml:space="preserve">
<value>30 seconds</value>
<value>30 सेकंड</value>
</data>
<data name="TwentySeconds" xml:space="preserve">
<value>20 seconds</value>
<value>30 सेकंड</value>
</data>
<data name="TwoMinutes" xml:space="preserve">
<value>2 minutes</value>
<value>2 मिनट</value>
</data>
<data name="ClearClipboard" xml:space="preserve">
<value>Clear Clipboard</value>
<value>क्लिपबोर्ड साझा करें</value>
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
</data>
<data name="ClearClipboardDescription" xml:space="preserve">
@@ -1512,7 +1512,7 @@
<value>Copy Notes</value>
</data>
<data name="Exit" xml:space="preserve">
<value>Exit</value>
<value>निकास</value>
</data>
<data name="ExitConfirmation" xml:space="preserve">
<value>Are you sure you want to exit Bitwarden?</value>
@@ -1521,7 +1521,7 @@
<value>एप्लीकेशन पुनर्प्रारंभ करते समय मास्टर पासवर्ड पूछे?</value>
</data>
<data name="Black" xml:space="preserve">
<value>Black</value>
<value>काला</value>
<comment>The color black</comment>
</data>
<data name="BlacklistedUris" xml:space="preserve">
@@ -1620,7 +1620,7 @@
<value>One or more organization policies are affecting your generator settings</value>
</data>
<data name="Open" xml:space="preserve">
<value>Open</value>
<value>खुला</value>
<comment>Button text for an open operation (verb).</comment>
</data>
<data name="UnableToSaveAttachment" xml:space="preserve">
@@ -1644,7 +1644,7 @@
<comment>Confirmation message after successfully soft-deleting a login</comment>
</data>
<data name="Restore" xml:space="preserve">
<value>Restore</value>
<value>पुनः वापस लायें</value>
<comment>Restores an entity (verb).</comment>
</data>
<data name="Restoring" xml:space="preserve">
@@ -1656,7 +1656,7 @@
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
</data>
<data name="Trash" xml:space="preserve">
<value>Trash</value>
<value>ट्रैश</value>
<comment>(noun) Location of deleted items which have not yet been permanently deleted</comment>
</data>
<data name="SearchTrash" xml:space="preserve">
@@ -1675,4 +1675,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Biztosan a lomtárba kerüljön?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometrikus változás lett észlelve, bejelentkezés mesterjelszóval az ismételt engedélyezéshez.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Szinkronizálás engedélyezése frissítéskor</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>A széf szinkronizálása lehúzó művelettel.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Vállalati önálló bejelentkezés</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Gyors bejelentkezés a szervezeti önálló bejelentkező portálba. A kezdéshez meg kell adni a szervezeti azonosítót.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Szervezeti azonosító</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Jelenleg nem lehet bejelentkezni SSO segítségével.</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Mesterjelszó beállítása</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Az SSO-val történő bejelentkezés befejezéséhez mesterjelszót kell beállítani a széf eléréséhez és védelméhez.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Egy vagy több szervezeti rendszabályhoz mesterjelszó szükséges a következő követelmények megfeleléséhez:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>{0} minimális összetettségi pontszáma</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>{0} minimális hossza</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Egy vagy több nagybetűs karaktert tartalmaz</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Egy vagy több kisbetűs karaktert tartalmaz</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Egy vagy több számot tartalmaz</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>{0} speciális karakterekből egyet vagy többet tartalmaz</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Érvénytelen jelszó.</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>A jelszó nem egyezik a szervezeti követelményekhez. Ellenőrizzük a szabály információt és próbáljuk újra.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>A betöltés folyamatban van.</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Sei sicuro di voler spostare l'elemento nel cestino?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Dati biometrici modificati, accedi con la password principale per attivare nuovamente lo sblocco con dati biometrici.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Abilita la sincronizzazione durante l'aggiornamento</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronizza la cassaforte trascinando verso il basso.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Accesso con il portale dell'organizzazione (Single Sign-On)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Accedi usando il portale di accesso (Single Sign On) della tua organizzazione. Inserisci l'identificativo della tua organizzazione per iniziare.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identificativo dell'organizzazione</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Attualmente non sei in grado di effettuare il login con SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Impostare la password principale</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Per completare il login con SSO, si prega di impostare una password principale per accedere e proteggere la cassaforte.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>La password principale deve avere i seguenti requisiti, stabiliti da una o più regole dell'organizzazione:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Punteggio minimo di complessità {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>La lunghezza minima {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contiene almeno un carattere maiuscolo</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contiene almeno un carattere minuscolo</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contiene almeno una cifra</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contiene almeno uno dei seguenti caratteri speciali: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Password non valida</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>La password non soddisfa i requisiti dell'organizzazione. Si prega di controllare i criteri password dell'organizzazione e riprovare.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Caricamento</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>本当にごみ箱に入れますか?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>生体認証の変更が検出されました。マスターパスワードを使用してログインすると再度有効化できます。</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>更新時に同期を有効化</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>プルダウンジェスチャーで保管庫を同期します</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>組織のシングルサインオン</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>組織のシングルサインオンポータルを使用してログインします。開始するには組織の識別子を入力してください。</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>組織識別子</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>現在 SSO でログインできません</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>マスターパスワードを設定</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>SSO ログインを完了するには、保管庫にアクセス・保護するためのマスターパスワードを設定してください。</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>組織が求めるマスターパスワードの要件:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>複雑度スコアは最小 {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>長さは最小 {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>大文字が最低1つ必要</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>小文字が最低1つ必要</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>数字が最低1つ必要</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>次の特殊文字を含む: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>無効なパスワード</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>パスワードが組織の要件を満たしていません。ポリシー情報を確認して、もう一度やり直してください。</value>
</data>
<data name="Loading" xml:space="preserve">
<value>読み込み中</value>
</data>
</root>

View File

@@ -695,7 +695,7 @@
<value>{0}을 사용하여 잠금 해제</value>
</data>
<data name="UnlockWithPIN" xml:space="preserve">
<value>PIN 코드 잠금 해제</value>
<value>PIN 코드를 사용하여 잠금 해제</value>
</data>
<data name="Validating" xml:space="preserve">
<value>유효성 검증 중</value>
@@ -1517,7 +1517,7 @@
<value>정말로 Bitwarden에서 나가시려는 건가요?</value>
</data>
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
<value>You you want to require unlocking with your master password when the application is restarted?</value>
<value>애플리케이션을 다시 시작했을 때 마스터 비밀번호로 잠금 해제가 필요하도록 하시겠습니까?</value>
</data>
<data name="Black" xml:space="preserve">
<value>검은 테마</value>
@@ -1582,7 +1582,7 @@
<value>권한</value>
</data>
<data name="BitwardenAutofillServiceOpenOverlayPermissionSettings" xml:space="preserve">
<value>오버레이 권한 설정 열기</value>
<value>다른 앱 위에 그리기 권한 설정 열기</value>
</data>
<data name="BitwardenAutofillServiceStep3" xml:space="preserve">
<value>Bitwarden의 Android 앱 설정 화면에 있는 ("고급" 아래) "다른 앱 위에 표시"를 선택하고 오버레이를 허용해주세요.</value>
@@ -1647,11 +1647,11 @@
<comment>Restores an entity (verb).</comment>
</data>
<data name="Restoring" xml:space="preserve">
<value>복 중...</value>
<value>복 중...</value>
<comment>Message shown when interacting with the server</comment>
</data>
<data name="ItemRestored" xml:space="preserve">
<value>항목이 복되었습니다.</value>
<value>항목이 복되었습니다.</value>
<comment>Confirmation message after successfully restoring a soft-deleted item</comment>
</data>
<data name="Trash" xml:space="preserve">
@@ -1667,11 +1667,68 @@
<comment>Confirmation alert message when permanently deleteing a cipher.</comment>
</data>
<data name="DoYouReallyWantToRestoreCipher" xml:space="preserve">
<value>정말 이 항목을 복하시겠습니까?</value>
<value>정말 이 항목을 복하시겠습니까?</value>
<comment>Confirmation alert message when restoring a soft-deleted cipher.</comment>
</data>
<data name="DoYouReallyWantToSoftDeleteCipher" xml:space="preserve">
<value>정말로 휴지통으로 이동시킬까요?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1674,4 +1674,61 @@
<value>Vil du virkelig sende til papirkurven?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Weet je zeker dat je dit naar de prullenbak wilt verplaatsen?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometrische verandering geconstateerd, log in met hoofdwachtwoord om opnieuw in te schakelen.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Synchronisatie bij vernieuwen inschakelen</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Kluis synchroniseren met pull-down gebaar.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Snel inloggen met het single sign-on portaal van je organisatie. Voer de identificatie van je organisatie in om te beginnen.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisatie-identificatie</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Kan momenteel niet inloggen met SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Hoofdwachtwoord instellen</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Voor het inloggen met SSO moet je een hoofdwachtwoord instellen voor toegang tot en bescherming van je kluis.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Een of meer organisatiebeleidseisen stelt de volgende eisen aan je hoofdwachtwoord:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimale complexiteitsscore van {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimumlengte is {0} tekens</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Bevat een of meer hoofdletters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Bevat een of meer kleine letters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Bevat een of meer cijfers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Bevat een of meer van de volgende speciale tekens: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Ongeldig wachtwoord</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Het wachtwoord voldoet niet aan de organisatievereisten. Controleer het beleid en probeer het opnieuw.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Laden</value>
</data>
</root>

View File

@@ -372,7 +372,7 @@
<value>Wersja</value>
</data>
<data name="View" xml:space="preserve">
<value>Widok</value>
<value>Zobacz</value>
</data>
<data name="VisitOurWebsite" xml:space="preserve">
<value>Odwiedź naszą stronę</value>
@@ -1674,4 +1674,61 @@
<value>Czy na pewno chcesz to przenieść do kosza?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Dane biometryczne zostały zmienione. Zaloguj się hasłem głównym, aby włączyć je ponownie.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Włącz synchronizację podczas odświeżenia</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Synchronizuje sejf podczas gestu przeciągnięcia w dół</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Logowanie jednokrotne przedsiębiorstwa</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Zaloguj się szybko za pomocą logowania jednokrotnego SSO swojej organizacji. Aby rozpocząć, wpisz swój identyfikator organizacji.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identyfikator organizacji</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Obecnie nie możesz zalogować się za pomocą logowania jednokrotnego SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Ustaw hasło główne</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Aby zakończyć logowanie jednokrotne SSO, ustaw hasło główne, aby uzyskać dostęp do sejfu.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Co najmniej jedna zasada organizacji wymaga, aby hasło główne spełniało następujące wymagania:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimalny poziom złożoności wynosi {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimalna długość wynosi {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Zawiera co najmniej jedną wielką literę</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Zawiera co najmniej jedną małą literę</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Zawiera co najmniej jedną cyfrę</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Zawiera co najmniej jeden następujący znak specjalny: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Hasło jest nieprawidłowe</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Hasło nie spełnia wymogów organizacji. Sprawdź wymaganą zasadę i spróbuj ponownie.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Ładowanie</value>
</data>
</root>

View File

@@ -1564,7 +1564,7 @@
<value>A sua sessão expirou.</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>Use biometria para verificar.</value>
<value>Verificação Biométrica</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Biometria</value>
@@ -1674,4 +1674,61 @@
<value>Você realmente quer enviar para a lixeira?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Alteração biométrica detectada, faça o login usando a Senha Mestra para ativar novamente.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Ativar sincronização ao atualizar</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronizando o cofre com o gesto de deslizar para baixo.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Início de Sessão Único Empresarial</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Faça o login rapidamente usando o portal de login único da sua organização. Por favor, insira o identificador da sua organização para começar.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identificador da Organização</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Atualmente incapaz de acessar com SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Definir Senha Mestra</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Para concluir o login com o SSO, defina uma senha mestra para acessar e proteger o seu cofre.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Uma ou mais políticas da organização exigem que a sua senha mestra cumpra aos seguintes requisitos:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Pontuação mínima de complexidade de {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Tamanho mínimo de {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contém um ou mais caracteres em maiúsculo</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contém um ou mais caracteres em minúsculo</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contém um ou mais números</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contém um ou mais dos seguintes caracteres especiais: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Senha Inválida</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>A senha não atende aos requisitos da organização. Por favor, verifique as informações da política e tente novamente.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Carregando</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Pretende mesmo enviar para o lixo?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Alteração biométrica detetada, inicie sessão utilizando a palavra-passe mestra para ativar novamente.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Ativar sincronização ao atualizar</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronizar o cofre com o gesto de deslizar para baixo.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Início de Sessão Único da Empresa</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Inicie sessão rapidamente utilizando o portal de início de sessão único da sua organização. Por favor introduza o identificador da sua organização para começar.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identificador da organização</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Não foi possível iniciar sessão com SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Definir palavra-passe mestra</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Para concluir o início de sessão com SSO, por favor defina uma palavra-passe mestra para aceder e proteger o seu cofre.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Uma ou mais políticas da organização requerem que a sua palavra-passe mestra cumpra aos seguintes requisitos:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Pontuação mínima de complexidade de {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Comprimento mínimo de {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contém um ou mais caracteres em maiúsculas</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contém um ou mais caracteres em minúsculas</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contém um ou mais números</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contém um ou mais dos seguintes caracteres especiais: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Palavra-passe inválida</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Palavra-passe mestra não cumpre os requisitos da organização. Por favor verifique a informação da política e tente novamente.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>A carregar</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -412,7 +412,7 @@
<value>Extensia aplicaţiei Bitwarden</value>
</data>
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
<value>Cea mai ușoară modalitate de a adăuga noi autentificări în seif este din extensia aplicaţiei Bitwarden. Aflați mai multe despre utilizarea extensiei aplicaţiei Bitwarden accesând ecranul "Setări".</value>
<value>Cea mai ușoară modalitate de a adăuga noi autentificări în seif este din extensia aplicației Bitwarden. Aflați mai multe despre utilizarea extensiei aplicației Bitwarden accesând ecranul "Setări".</value>
</data>
<data name="BitwardenAppExtensionDescription" xml:space="preserve">
<value>Utilizați Bitwarden în Safari și în alte aplicații pentru a completa automat datele de autentificare.</value>
@@ -477,7 +477,7 @@
<value>Sunteţi gata să vă autentificaţi!</value>
</data>
<data name="ExtensionSetup" xml:space="preserve">
<value>Datele dvs. de conectare sunt acum uşor accesibile din Safari, Chrome şi alte aplicaţii suportate.</value>
<value>Datele dvs. de conectare sunt acum ușor accesibile din Safari, Chrome și alte aplicații suportate.</value>
</data>
<data name="ExtensionSetup2" xml:space="preserve">
<value>În Safari şi Chrome, găsiţi Bitwarden utilizând pictograma de partajare (indiciu: derulaţi la dreapta pe rândul de jos al meniului partajare).</value>
@@ -644,7 +644,7 @@
<value>Reintroduceţi parola principală</value>
</data>
<data name="SearchVault" xml:space="preserve">
<value>Căutaţi în seif</value>
<value>Căutați în Seif</value>
</data>
<data name="Security" xml:space="preserve">
<value>Securitate</value>
@@ -1227,7 +1227,7 @@
<comment>URI match detection for auto-fill.</comment>
</data>
<data name="YesAndSave" xml:space="preserve">
<value>Da, și salvează</value>
<value>Da, și Salvează</value>
</data>
<data name="AutofillAndSave" xml:space="preserve">
<value>Completează automat și salvează</value>
@@ -1240,10 +1240,10 @@
<value>Țineți YubiKey-ul dvs. deasupra aparatului.</value>
</data>
<data name="TryAgain" xml:space="preserve">
<value>Încercaţi din nou</value>
<value>Încercați din nou</value>
</data>
<data name="YubiKeyInstructionIos" xml:space="preserve">
<value>Pentru a continua, țineți-vă YubiKey NEO pe spatele aparatului.</value>
<value>Pentru a continua, țineți YubiKey-ul NEO dvs. pe spatele aparatului.</value>
</data>
<data name="BitwardenAutofillAccessibilityServiceDescription2" xml:space="preserve">
<value>Serviciul de accesibilitate poate fi de ajutor când aplicațiile nu acceptă serviciul standard de auto-completare.</value>
@@ -1293,7 +1293,7 @@
<value>Auto Completare Parolă</value>
</data>
<data name="BitwardenAutofillAlert2" xml:space="preserve">
<value>Cea mai ușoară modalitate de a adăuga noi autentificări în seif este din extensia aplicaţiei Bitwarden. Aflați mai multe despre utilizarea extensiei aplicaţiei Bitwarden accesând ecranul "Setări".</value>
<value>Cea mai ușoară modalitate de a adăuga noi autentificări în seif este din extensia aplicației Bitwarden. Aflați mai multe despre utilizarea extensiei aplicației Bitwarden accesând ecranul "Setări".</value>
</data>
<data name="InvalidEmail" xml:space="preserve">
<value>Adresă de e-mail greșită.</value>
@@ -1406,7 +1406,7 @@
<value>Separator cuvânt</value>
</data>
<data name="Clear" xml:space="preserve">
<value>Ştergere</value>
<value>Șterge</value>
<comment>To clear something out. example: To clear browser history.</comment>
</data>
<data name="Generator" xml:space="preserve">
@@ -1428,10 +1428,10 @@
<value>Bitwarden vă permite să vă împărtășiți seiful cu alte persoane utilizând un cont pentru organizații. Doriți să vizitați site-ul bitwarden.com pentru a afla mai multe?</value>
</data>
<data name="ExportVault" xml:space="preserve">
<value>Export seif</value>
<value>Export Seif</value>
</data>
<data name="LockNow" xml:space="preserve">
<value>Blocați acum</value>
<value>Blocați Acum</value>
</data>
<data name="PIN" xml:space="preserve">
<value>PIN</value>
@@ -1443,17 +1443,17 @@
<value>30 de minute</value>
</data>
<data name="SetPINDescription" xml:space="preserve">
<value>Setaţi codul PIN de deblocare Bitwarden. Setările codului PIN vor fi resetate dacă vă deconectaţi vreodată din aplicație.</value>
<value>Setați codul PIN de deblocare Bitwarden. Setările codului PIN vor fi resetate dacă vă deconectați vreodată din aplicație.</value>
</data>
<data name="LoggedInAsOn" xml:space="preserve">
<value>Autentificat ca {0} în {1}.</value>
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
</data>
<data name="VaultLockedMasterPassword" xml:space="preserve">
<value>Seiful dvs. este blocat. Verificaţi parola principală pentru a continua.</value>
<value>Seiful dvs. este blocat. Verificați parola principală pentru a continua.</value>
</data>
<data name="VaultLockedPIN" xml:space="preserve">
<value>Seiful dvs. este blocat. Verificaţi codul PIN pentru a continua.</value>
<value>Seiful dvs. este blocat. Verificați codul PIN pentru a continua.</value>
</data>
<data name="Dark" xml:space="preserve">
<value>Întunecată</value>
@@ -1479,19 +1479,19 @@
<value>2 minute</value>
</data>
<data name="ClearClipboard" xml:space="preserve">
<value>Goliţi Clipboardul</value>
<value>Goliți Clipboard-ul</value>
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
</data>
<data name="ClearClipboardDescription" xml:space="preserve">
<value>Şterge automat valorile copiate din clipboard.</value>
<value>Șterge automat valorile copiate din clipboard.</value>
<comment>Clipboard is the operating system thing where you copy/paste data to on your device.</comment>
</data>
<data name="DefaultUriMatchDetection" xml:space="preserve">
<value>Detectare de potrivire URI implicită</value>
<value>Detectare implicită a potrivirii URI</value>
<comment>Default URI match detection for auto-fill.</comment>
</data>
<data name="DefaultUriMatchDetectionDescription" xml:space="preserve">
<value>Alege modul în care se gestionează detectarea de potrivire de URI pentru autentificări la acțiuni precum cea de auto-completare.</value>
<value>Alege modul implicit în care este gestionată detectarea potrivirii URI pentru conectări la acțiuni precum cea de auto-completare.</value>
</data>
<data name="Theme" xml:space="preserve">
<value>Temă</value>
@@ -1501,20 +1501,20 @@
<value>Schimbă tema de culori a aplicației.</value>
</data>
<data name="RestartIsRequired" xml:space="preserve">
<value>Repornire necesară.</value>
<value>Repornirea este necesară.</value>
<comment>Referring to restarting the application.</comment>
</data>
<data name="Restarting" xml:space="preserve">
<value>Repornire...</value>
</data>
<data name="CopyNotes" xml:space="preserve">
<value>Copiere note</value>
<value>Copiere Note</value>
</data>
<data name="Exit" xml:space="preserve">
<value>Ieșire</value>
</data>
<data name="ExitConfirmation" xml:space="preserve">
<value>Sunteți sigur doriți să ieșiți?</value>
<value>Sigur doriți să ieșiți din Bitwarden?</value>
</data>
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
<value>Doriți să solicitați deblocarea cu parola principală atunci când aplicația este repornită?</value>
@@ -1524,7 +1524,7 @@
<comment>The color black</comment>
</data>
<data name="BlacklistedUris" xml:space="preserve">
<value>URI-uri în lista neagră</value>
<value>URI-uri pe Lista Neagră</value>
</data>
<data name="BlacklistedUrisDescription" xml:space="preserve">
<value>URI-urile de pe lista neagră nu vor oferi auto-completarea. Lista trebuie separată cu virgule. Ex: "https://twitter.com, androidapp: //com.twitter.android".</value>
@@ -1539,7 +1539,7 @@
<value>La repornirea aplicației</value>
</data>
<data name="AutofillServiceNotEnabled" xml:space="preserve">
<value>Auto-completarea ușurează accesul securizat al seifului Bitwarden de pe alte site-uri și aplicații. Se pare că nu ați activat serviciul de auto-completare pentru Bitwarden. Activați auto-completarea pentru Bitwarden din ecranul Setări.</value>
<value>Auto-completarea ușurează accesul securizat al seifului Bitwarden de pe alte site-uri și aplicații. Se pare că nu ați activat serviciul de auto-completare pentru Bitwarden. Activați auto-completarea pentru Bitwarden din ecranul "Setări".</value>
</data>
<data name="ThemeAppliedOnRestart" xml:space="preserve">
<value>Modificările temei se vor aplica după repornirea aplicației.</value>
@@ -1549,7 +1549,7 @@
<comment>ex. Uppercase the first character of a word.</comment>
</data>
<data name="IncludeNumber" xml:space="preserve">
<value>Include număr</value>
<value>Include Număr</value>
</data>
<data name="Download" xml:space="preserve">
<value>Descărcare</value>
@@ -1558,7 +1558,7 @@
<value>Partajate</value>
</data>
<data name="ToggleVisibility" xml:space="preserve">
<value>Comutare vizibilitate</value>
<value>Comutare Vizibilitate</value>
</data>
<data name="LoginExpired" xml:space="preserve">
<value>Sesiunea de autentificare a expirat.</value>
@@ -1567,16 +1567,16 @@
<value>Utilizați biometria la verificări</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Biometria</value>
<value>Biometrie</value>
</data>
<data name="UseBiometricsToUnlock" xml:space="preserve">
<value>Folosiți Biometria la Deblocare</value>
</data>
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
<value>Bitwarden are nevoie de atenție! Vedeți în Setările Bitwarden "Servicii Accesibilitate Auto-completare"</value>
<value>Bitwarden necesită atenție! Vedeți în Setările Bitwarden "Serviciul de accesibilitate Completare Automată"</value>
</data>
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
<value>3. În ecranul Android de Setări pentru Bitwarden accesați "Opțiuni", tapați comutatorul "Afișați pete alte aplicații" (sub Avansat) pentru a activa suportul de suprapunere.</value>
<value>3. În ecranul Android de Setări al aplicației Bitwarden, accesați opțiunile "Afișați peste alte aplicații" (sub Avansat) și atingeți comutatorul pentru a activa suportul pentru suprapunere.</value>
</data>
<data name="OverlayPermission" xml:space="preserve">
<value>Permisiune</value>
@@ -1594,7 +1594,7 @@
<value>Permis</value>
</data>
<data name="FileFormat" xml:space="preserve">
<value>Format fișier</value>
<value>Format Fișier</value>
</data>
<data name="ExportVaultMasterPasswordDescription" xml:space="preserve">
<value>Introdu parola principală pentru a exporta datele seifului.</value>
@@ -1612,7 +1612,7 @@
<value>Seiful exportat cu succes</value>
</data>
<data name="Clone" xml:space="preserve">
<value>Clon</value>
<value>Clonați</value>
<comment>Clone an entity (verb).</comment>
</data>
<data name="PasswordGeneratorPolicyInEffect" xml:space="preserve">
@@ -1629,10 +1629,10 @@
<value>Atașamente salvate cu succes</value>
</data>
<data name="AutofillTileAccessibilityRequired" xml:space="preserve">
<value>Activați "Serviciul Accesibilitate Auto-completare" în setările Bitwarden ca să utilizați placa de auto-completare.</value>
<value>Activați "Serviciul Accesibilitate Auto-completare" în setările Bitwarden ca să utilizați placa de Auto-Completare.</value>
</data>
<data name="AutofillTileUriNotFound" xml:space="preserve">
<value>Câmpul parolă nu a fost detectat</value>
<value>Nu s-au detectat câmpuri de parolă</value>
</data>
<data name="SoftDeleting" xml:space="preserve">
<value>Se trimite la gunoi...</value>
@@ -1671,7 +1671,64 @@
<comment>Confirmation alert message when restoring a soft-deleted cipher.</comment>
</data>
<data name="DoYouReallyWantToSoftDeleteCipher" xml:space="preserve">
<value>Chiar vreți să trimiteți la coșul de gunoi?</value>
<value>Sigur doriți să trimiteți la coșul de gunoi?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Modificare biometrică detectată, conectați-vă folosind Parola Principală pentru a activa din nou.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Activați sincronizarea la reîmprospătare</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Sincronizarea seifului cu un gest în jos</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value> Conectare Unică Centralizată Întreprinderi (SSO)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Conectați-vă rapid utilizând portalul de conectare unică al organizației dvs. Introduceți identificatorul organizației dvs. pentru a începe.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identificatorul Organizației</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>În prezent nu se poate conecta cu SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Setați Parola Principală</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Pentru a finaliza conectarea cu SSO, vă rugăm să setați o parolă principală pentru a accesa și a vă proteja seiful.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Una sau mai multe politici ale organizației necesită ca parola principală să îndeplinească următoarele cerințe:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Scor minim de complexitate de {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Lungimea minimă de {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Conține unul sau mai multe caractere majuscule</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Conține unul sau mai multe caractere minuscule</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Conține unul sau mai multe numere</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Conține unul sau mai multe din următoarele caractere: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Parolă invalidă</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Parola nu îndeplinește cerințele organizației. Verificați informațiile despre politică și încercați din nou.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Se încarcă</value>
</data>
</root>

View File

@@ -1517,7 +1517,7 @@
<value>Вы действительно хотите выйти из Bitwarden?</value>
</data>
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
<value>Вы хотите, чтобы при перезапуске приложения требовалась разблокировка с помощью мастер-пароля?</value>
<value>Хотите, чтобы при перезапуске приложения требовалась разблокировка с помощью мастер-пароля?</value>
</data>
<data name="Black" xml:space="preserve">
<value>Черная</value>
@@ -1564,13 +1564,13 @@
<value>Истек срок действия вашей сессии.</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>Использовать биометрию для верификации.</value>
<value>Биометрическая верификация.</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Биометрия</value>
<value>биометрией</value>
</data>
<data name="UseBiometricsToUnlock" xml:space="preserve">
<value>Использовать биометрию для разблокировки</value>
<value>Используйте биометрию для разблокировки</value>
</data>
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
<value>Bitwarden требует внимания - см. раздел 'Служба специальных возможностей автозаполнения' в настройках Bitwarden.</value>
@@ -1674,4 +1674,61 @@
<value>Вы действительно хотите отправить в корзину?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Обнаружено изменение параметров биометрии. Для повторной активации необходимо авторизоваться, используя мастер-пароль.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Включить синхронизацию при обновлении</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Синхронизация хранилища жестом смахивания вниз.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Единая корпоративная авторизация (SSO)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Авторизуйтесь при помощи единого корпоративного портала. Чтобы начать, введите идентификатор вашей организации.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Идентификатор организации</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>В настоящее время невозможно авторизоваться посредством SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Задать мастер-пароль</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Для завершения процесса авторизации при помощи SSO, установите мастер-пароль для доступа к вашему хранилищу и его защиты.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Согласно одной или нескольким политикам организации необходимо, чтобы ваш мастер-пароль отвечал следующим требованиям:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Минимальный уровень сложности {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Минимальная длина {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Содержать хотя бы одну заглавную букву</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Содержать хотя бы одну строчную букву</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Содержать хотя бы одну цифру</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Содержать хотя бы один из следующих специальных символов: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Некорректный пароль</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Пароль не соответствует требованиям организации. Пожалуйста, проверьте информацию о политике и попробуйте еще раз.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Загрузка</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Naozaj to chcete poslať do koša?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Bola zaznamenaná zmena biometrických údajov, prihláste za svojím hlavným heslom aby ste opäť povolili prihlásenie.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Povoliť synchronizáciu pri obnovení</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Synchronizácia trezora potiahnutím nadol</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Prihlásenie cez prihlasovací formulár spoločnosti (SSO)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Prihláste sa prostredníctvom prihlasovacieho portálu (SSO) vašej organizácie. Najskôr zadajte identifikátor vašej organizácie.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Identifikátor organizácie</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Momentálne nie je možné prihlásiť sa cez portál spoločnosti.</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Nastaviť hlavné heslo</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Aby ste dokončili nastavenie prihlasovacieho portálu (SSO), prosím nastavte hlavné heslo na prístup a ochranu vášho trezora.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Jedno alebo viac pravidiel organizácie požadujú aby vaše hlavné heslo spĺňalo nasledujúce požiadavky:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimálna úroveň zložitosti $SCORE$</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimálna dĺžka je %s</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Obsahuje aspoň jedno veľké písmeno</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Obsahuje aspoň jedno malé písmeno</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Obsahuje aspoň jednu číslicu</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Obsahuje aspoň jeden z následujúcich špeciálnych znakov $CHARS$</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Nesprávne heslo</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Vaše nové hlavné heslo nespĺňa pravidlá spoločnosti. Prosím pozrite si informácie o pravidlách a skúste to znova.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Načíta sa</value>
</data>
</root>

View File

@@ -689,7 +689,7 @@
<value>Tvåstegsverifiering</value>
</data>
<data name="TwoStepLoginConfirmation" xml:space="preserve">
<value>Tvåstegsverifiering gör ditt konto säkrare genom att kräva att du verifierar din inloggning med en annan enhet, t.ex. en säkerhetsnyckel, autentiseringsapp, SMS, telefonsamtal eller e-post. Tvåstegsverifiering kan aktiveras i Bitwarden.com webbvalv. Vill du besöka webbplatsen nu?</value>
<value>Tvåstegsverifiering gör ditt konto säkrare genom att kräva att du verifierar din inloggning med en annan enhet, t.ex. en säkerhetsnyckel, autentiseringsapp, SMS, telefonsamtal eller e-post. Tvåstegsverifiering kan aktiveras i Bitwardens webbvalv. Vill du besöka webbplatsen nu?</value>
</data>
<data name="UnlockWith" xml:space="preserve">
<value>Lås upp med {0}</value>
@@ -1674,4 +1674,61 @@
<value>Vill du verkligen skicka till papperskorgen?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Förändring av biometri upptäcktes, logga in med huvudlösenordet för att aktivera igen.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Aktivera synkronisering vid uppdatering</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Synkronisera valv genom att dra ned.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Single Sign-On för företag</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Logga in snabbt genom organisationens inloggningsportal. Ange organisationens identifierare för att börja.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organisationens Identifierare</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Det gick för närvarande inte att logga in med SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Ange huvudlösenord</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>För att slutföra inloggning med SSO, ange ett huvudlösenord för att komma åt och skydda ditt valv.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>En eller flera organisationspolicyer kräver att ditt huvudlösenord uppfyller följande krav:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minsta komplexitetspoäng på {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minsta längd på {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Innehålla en eller flera versaler</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Innehålla en eller flera gemener</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Innehålla en eller flera siffror</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Innehålla ett eller flera av följande specialtecken: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Ogiltigt lösenord</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Lösenordet uppfyller inte organisationens krav. Kontrollera policyn och försök igen.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Laddar</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Do you really want to send to the trash?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -1674,4 +1674,61 @@
<value>Bu ögeyi çöp kutusuna göndermeyi gerçekten istiyor musunuz?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biyometrik değişiklik algılandı, tekrar etkinleştirmek için Ana Parola kullanarak oturum açın.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Yenileme sırasında senkronizasyonu etkinleştir</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Kasayı aşağı çekme hareketiyle senkronize et.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Kurumsal Tek Oturum Açma (SSO)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Kuruluşunuzun tek oturum açma (SSO) portalını kullanarak hızlı bir şekilde oturum açın. Başlamak için lütfen kuruluşunuzun tanımlayıcısını girin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organizasyon Tanımlayıcı</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Şu anda SSO ile giriş yapılamıyor</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Ana Parola Belirleyin</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>SSO ile oturum açmayı tamamlamak için lütfen kasanıza erişmek ve onu korumak için bir ana parola ayarlayın.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Bir veya daha fazla kuruluş ilkesi, aşağıdaki gereksinimleri karşılamak için ana parolanızı gerektirir:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum karmaşıklık puanı {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum {0} uzunluk</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Bir veya daha fazla büyük harf karakter içermesi gerekir.</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Bir veya daha fazla küçük harfli karakter içermeli.</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Bir veya daha fazla sayı içermeli.</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Aşağıdaki özel karakterlerden birini veya daha fazlasını içermeli: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Şifre hatalı</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Parola organizasyon gereksinimlerini karşılamıyor. Lütfen politika bilgilerini kontrol edin ve tekrar deneyin.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Yükleniyor</value>
</data>
</root>

View File

@@ -1564,7 +1564,7 @@
<value>Тривалість вашого сеансу завершилась.</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>Використовувати біометрику для підтвердження.</value>
<value>Біометрична перевірка</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>Біометрика</value>
@@ -1674,4 +1674,61 @@
<value>Ви дійсно хочете перенести до смітника?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Виявлено біометричні зміни. Увійдіть за допомогою головного пароля, щоб увімкнути знову.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Увімкнути синхронізацію жестом</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Синхронізація сховища жестом Потягнути донизу.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Єдиний корпоративний вхід (SSO)</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Швидкий вхід з використанням порталу єдиного входу вашої організації. Для початку введіть ідентифікатор вашої організації.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Ідентифікатор організації</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Наразі неможливо увійти з SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Встановити головний пароль</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>Щоб завершити налаштування входу з SSO, встановіть головний пароль для доступу і захисту сховища.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>Одна або декілька політик організації зобов'язують дотримання таких вимог для головного пароля:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Мінімальний рівень складності {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Мінімальна довжина {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Наявність одного чи більше символів верхнього регістру</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Наявність одного чи більше символів нижнього регістру</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Наявність однієї чи більше цифр</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Наявність одного чи більше таких спеціальних символів: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Неправильний пароль</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Пароль не відповідає вимогам організації. Перевірте інформацію про політику і спробуйте знову.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Завантаження</value>
</data>
</root>

View File

@@ -1263,13 +1263,13 @@
<value>Bạn phải đăng nhập vào ứng dụng Bitwarden trước khi sử dụng Tự động điền.</value>
</data>
<data name="AutofillSetup" xml:space="preserve">
<value>Your logins are now easily accessable right from your keyboard while logging into apps and websites.</value>
<value>Tên và mật khẩu có quyền tự động điền từ bàn phím khi bạn sử dụng ứng dụng hay website.</value>
</data>
<data name="AutofillSetup2" xml:space="preserve">
<value>Chúng tôi khuyên nên vô hiệu hóa các ứng dụng tự động điền khác trong Cài đặt nếu bạn không có ý định sử dụng chúng.</value>
</data>
<data name="BitwardenAutofillDescription" xml:space="preserve">
<value>Truy cập kho của bạn trực tiếp từ bàn phím để có thể nhanh chóng tự động điền mật khẩu.</value>
<value>Thông tin tự động điền vào trên bàn phím bằng việc truy cập trực tiếp vào mục lưu trữ dữ liệu.</value>
</data>
<data name="AutofillTurnOn" xml:space="preserve">
<value>Để mở chức năng tự động điền mật khẩu trên thiết bị của bạn, xin làm theo hướng dẫn dưới đây:</value>
@@ -1674,4 +1674,61 @@
<value>Bạn có thực sự muốn đưa vào thùng rác?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -186,14 +186,14 @@
<comment>Short label for an email address.</comment>
</data>
<data name="EmailAddress" xml:space="preserve">
<value>Email 地址</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>请输入您的 PIN 码。</value>
@@ -222,7 +222,7 @@
<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">
@@ -243,11 +243,11 @@
<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">
@@ -403,7 +403,7 @@
<value>使用 Bitwarden 无障碍服务在应用和网站自动填写您的登录项目。</value>
</data>
<data name="AutofillService" xml:space="preserve">
<value>自动填服务</value>
<value>自动填服务</value>
</data>
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
<value>避免模棱两可</value>
@@ -418,10 +418,10 @@
<value>在 Safari 和其他应用中使用 Bitwarden 来自动填写登录信息。</value>
</data>
<data name="BitwardenAutofillService" xml:space="preserve">
<value>Bitwarden 自动填服务</value>
<value>Bitwarden 自动填服务</value>
</data>
<data name="BitwardenAutofillAccessibilityServiceDescription" xml:space="preserve">
<value>使用 Bitwarden 无障碍服务自动填写您的登录信息。</value>
<value>使用 bitwarden 无障碍服务自动填写您的登录信息。</value>
</data>
<data name="ChangeEmail" xml:space="preserve">
<value>修改 Email</value>
@@ -510,7 +510,7 @@
<value>从其他密码管理应用中快速批量导入您的项目。</value>
</data>
<data name="LastSync" xml:space="preserve">
<value>上次同步:</value>
<value>上次同步</value>
</data>
<data name="Length" xml:space="preserve">
<value>长度</value>
@@ -735,7 +735,7 @@
<comment>This is used for the autofill service. ex. "There are no items in your vault for twitter.com".</comment>
</data>
<data name="BitwardenAutofillServiceOverlay" xml:space="preserve">
<value>当您选择一个输入字段并看到一个 Bitwarden 自动填悬浮窗时,您可以点击它来启动自动填服务。</value>
<value>当您选择一个输入字段并看到一个 Bitwarden 自动填悬浮窗时,您可以点击它来启动自动填服务。</value>
</data>
<data name="BitwardenAutofillServiceNotificationContent" xml:space="preserve">
<value>点击此通知以自动填写密码库中的项目。</value>
@@ -750,25 +750,25 @@
<value>2. 切换开关,然后按确定以接受。</value>
</data>
<data name="Disabled" xml:space="preserve">
<value>禁用</value>
<value>禁用</value>
</data>
<data name="Enabled" xml:space="preserve">
<value>启用</value>
<value>启用</value>
</data>
<data name="Status" xml:space="preserve">
<value>状态</value>
</data>
<data name="BitwardenAutofillServiceAlert2" xml:space="preserve">
<value>向您的密码库中添加新登录项目的最简单方法,就是 Bitwarden 自动填服务。转到 “设置” 屏幕了解更多有关使用 Bitwarden 自动填服务的方法。</value>
<value>向您的密码库中添加新登录项目的最简单方法,就是 Bitwarden 自动填服务。转到 “设置” 屏幕了解更多有关使用 Bitwarden 自动填服务的方法。</value>
</data>
<data name="Autofill" xml:space="preserve">
<value>自动填写</value>
</data>
<data name="AutofillOrView" xml:space="preserve">
<value>您要自动填还是查看此项目?</value>
<value>您要自动填还是查看此项目?</value>
</data>
<data name="BitwardenAutofillServiceMatchConfirm" xml:space="preserve">
<value>您确定要自动填吗?并不完全匹配 "{0}" 。</value>
<value>您确定要自动填吗?并不完全匹配 "{0}" 。</value>
</data>
<data name="MatchingItems" xml:space="preserve">
<value>匹配项目</value>
@@ -780,10 +780,10 @@
<value>搜索</value>
</data>
<data name="BitwardenAutofillServiceSearch" xml:space="preserve">
<value>你正在为 "{0}" 寻找一个自动填项目。</value>
<value>你正在为 "{0}" 寻找一个自动填项目。</value>
</data>
<data name="ShareVault" xml:space="preserve">
<value>享你的密码库</value>
<value>享你的密码库</value>
</data>
<data name="CannotOpenApp" xml:space="preserve">
<value>无法打开应用 "{0}"。</value>
@@ -1144,13 +1144,13 @@
<value>自动填写无障碍服务</value>
</data>
<data name="AutofillServiceDescription" xml:space="preserve">
<value>Bitwarden 自动填服务使用 Android 自动填框架来帮助您将登录、信用卡和身份信息填写到你设备上的其他应用程序中。</value>
<value>Bitwarden 自动填服务使用 Android 自动填框架来帮助您将登录、信用卡和身份信息填写到你设备上的其他应用程序中。</value>
</data>
<data name="BitwardenAutofillServiceDescription" xml:space="preserve">
<value>使用 Bitwarden 自动填服务将登录、信用卡和身份信息填写到其他应用程序中。</value>
<value>使用 Bitwarden 自动填服务将登录、信用卡和身份信息填写到其他应用程序中。</value>
</data>
<data name="BitwardenAutofillServiceOpenAutofillSettings" xml:space="preserve">
<value>打开自动填设置</value>
<value>打开自动填设置</value>
</data>
<data name="FaceID" xml:space="preserve">
<value>面容 ID</value>
@@ -1230,7 +1230,7 @@
<value>是的,保存</value>
</data>
<data name="AutofillAndSave" xml:space="preserve">
<value>自动填并保存</value>
<value>自动填并保存</value>
</data>
<data name="Organization" xml:space="preserve">
<value>组织</value>
@@ -1246,7 +1246,7 @@
<value>要继续,请将您的 YubiKey NEO 设备放在设备背面。</value>
</data>
<data name="BitwardenAutofillAccessibilityServiceDescription2" xml:space="preserve">
<value>当应用程序不支持标准的自动填服务时,辅助功能服务可能会很有用。</value>
<value>当应用程序不支持标准的自动填服务时,无障碍服务可能会很有用。</value>
</data>
<data name="DatePasswordUpdated" xml:space="preserve">
<value>密码更新于</value>
@@ -1257,22 +1257,22 @@
<comment>ex. Date this item was updated</comment>
</data>
<data name="AutofillActivated" xml:space="preserve">
<value>自动填已激活!</value>
<value>自动填已激活!</value>
</data>
<data name="MustLogInMainAppAutofill" xml:space="preserve">
<value>您必须先登录 Bitwarden 应用,才可以使用自动填。</value>
<value>您必须先登录 Bitwarden 应用,才可以使用自动填。</value>
</data>
<data name="AutofillSetup" xml:space="preserve">
<value>现在您可以更轻松、快捷地登录应用和网站了!</value>
</data>
<data name="AutofillSetup2" xml:space="preserve">
<value>建议您在“设置”里关闭其它您不再使用的自动填应用程序。</value>
<value>建议您在“设置”里关闭其它您不再使用的自动填应用程序。</value>
</data>
<data name="BitwardenAutofillDescription" xml:space="preserve">
<value>从键盘直接访问密码库以快速自动填密码。</value>
<value>从键盘直接访问密码库以快速自动填密码。</value>
</data>
<data name="AutofillTurnOn" xml:space="preserve">
<value>请按照以下步骤在你的设备上开启密码自动填功能:</value>
<value>请按照以下步骤在你的设备上开启密码自动填功能:</value>
</data>
<data name="AutofillTurnOn1" xml:space="preserve">
<value>1. 前往 iOS 的 “设置” 应用</value>
@@ -1281,19 +1281,19 @@
<value>2. 点击 “密码与帐户”</value>
</data>
<data name="AutofillTurnOn3" xml:space="preserve">
<value>3. 点击 “自动填密码”</value>
<value>3. 点击 “自动填密码”</value>
</data>
<data name="AutofillTurnOn4" xml:space="preserve">
<value>4. 打开 “自动填充密码” 开关</value>
<value>4. 打开 “自动填” 开关</value>
</data>
<data name="AutofillTurnOn5" xml:space="preserve">
<value>5. 勾选 “Bitwarden”</value>
</data>
<data name="PasswordAutofill" xml:space="preserve">
<value>自动填密码</value>
<value>自动填密码</value>
</data>
<data name="BitwardenAutofillAlert2" xml:space="preserve">
<value>向您的密码库中添加新登录项目的最简单方法,就是 Bitwarden 密码自动填扩展。转到 “设置” 屏幕了解更多有关使用 Bitwarden 密码自动填扩展的方法。</value>
<value>向您的密码库中添加新登录项目的最简单方法,就是使用 Bitwarden 密码自动填扩展。转到 “设置” 屏幕了解更多有关使用 Bitwarden 密码自动填扩展的方法。</value>
</data>
<data name="InvalidEmail" xml:space="preserve">
<value>无效的电子邮件地址。</value>
@@ -1385,10 +1385,10 @@
<value>您必须至少选择一个集合。</value>
</data>
<data name="Share" xml:space="preserve">
<value>享</value>
<value>享</value>
</data>
<data name="ShareItem" xml:space="preserve">
<value>享项目</value>
<value>享项目</value>
</data>
<data name="NoOrgsToList" xml:space="preserve">
<value>没有可列出的组织。</value>
@@ -1491,7 +1491,7 @@
<comment>Default URI match detection for auto-fill.</comment>
</data>
<data name="DefaultUriMatchDetectionDescription" xml:space="preserve">
<value>选择在执行诸如自动填之类的操作时对登录进行URI匹配检测的默认方式。</value>
<value>选择在执行诸如自动填之类的操作时对登录进行 URI 匹配检测的默认方式。</value>
</data>
<data name="Theme" xml:space="preserve">
<value>主题</value>
@@ -1514,10 +1514,10 @@
<value>退出</value>
</data>
<data name="ExitConfirmation" xml:space="preserve">
<value>您确定要退出 Bitwarden吗</value>
<value>您确定要退出 Bitwarden 吗?</value>
</data>
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
<value>应用程序重启,要求使用主密码解锁吗?</value>
<value>应用程序重启,要求使用主密码解锁吗?</value>
</data>
<data name="Black" xml:space="preserve">
<value>黑色</value>
@@ -1527,7 +1527,7 @@
<value>黑名单 URI</value>
</data>
<data name="BlacklistedUrisDescription" xml:space="preserve">
<value>列入黑名单的URI将不提供自动填。列表应以逗号分隔。例如:"https://twitter.com, androidapp://com.twitter.android"。</value>
<value>列入黑名单的 URI 将不提供自动填。列表应以逗号分隔。例如:"https://twitter.com, androidapp://com.twitter.android"。</value>
</data>
<data name="DisableSavePrompt" xml:space="preserve">
<value>禁用保存提示</value>
@@ -1539,7 +1539,7 @@
<value>应用重启时</value>
</data>
<data name="AutofillServiceNotEnabled" xml:space="preserve">
<value>自动填可以简单安全地从其他网站和应用程序中访问您的 Bitwarden 密码库。看起来您还没有启用 Bitwarden 自动填服务。从“设置”屏幕启用 Bitwarden 自动填。</value>
<value>自动填可以简单安全地从其他网站和应用程序中访问您的 Bitwarden 密码库。看起来您还没有启用 Bitwarden 自动填服务。从“设置”屏幕启用 Bitwarden 自动填。</value>
</data>
<data name="ThemeAppliedOnRestart" xml:space="preserve">
<value>您的主题将在应用程序重启后生效。</value>
@@ -1555,7 +1555,7 @@
<value>下载</value>
</data>
<data name="Shared" xml:space="preserve">
<value>享</value>
<value>已共享</value>
</data>
<data name="ToggleVisibility" xml:space="preserve">
<value>切换可见性</value>
@@ -1564,7 +1564,7 @@
<value>您的登录会话已过期。</value>
</data>
<data name="BiometricsDirection" xml:space="preserve">
<value>使用生物识别进行验证。</value>
<value>使用生物识别技术验证。</value>
</data>
<data name="Biometrics" xml:space="preserve">
<value>生物识别</value>
@@ -1573,7 +1573,7 @@
<value>使用生物识别解锁</value>
</data>
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
<value>Bitwarden 需要相关权限 - 请在 Bitwarden 设置中查看“自动填充辅助功能服务”</value>
<value>Bitwarden 需要相关权限 - 请在 Bitwarden 设置中查看“自动填写无障碍服务”</value>
</data>
<data name="BitwardenAutofillServiceOverlayPermission" xml:space="preserve">
<value>3. 在 Android 应用设置界面找到 Bitwarden点击“高级”展开高级菜单后点击“显示在其他应用的上层”选项然后点击“允许显示在其它应用的上层”来启用。</value>
@@ -1591,7 +1591,7 @@
<value>拒绝</value>
</data>
<data name="Granted" xml:space="preserve">
<value>允许</value>
<value>已授权</value>
</data>
<data name="FileFormat" xml:space="preserve">
<value>文件格式</value>
@@ -1674,4 +1674,61 @@
<value>您确定要发送到回收站吗?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>检测到生物特征变化,使用主密码登录以重新启用。</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>启用刷新时同步</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>正在使用下拉手势同步密码库。</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>企业单点登录SSO</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>要使用您组织的单点登录SSO门户快速登录。请首先输入您组织的标识符。</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>组织标识符</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>当前无法使用 SSO 登陆</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>设置主密码</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>为使用单点登录SSO功能请设置一个主密码以访问和保护您的密码库。</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>一个或多个组织策略要求您的主密码满足下列要求:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>最小复杂度为 {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>最小长度为 {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>至少包含一个大写字符</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>至少包含一个小写字符</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>至少包含一个数字</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>包含至少一个下列的特殊字符: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>无效密码</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>密码不符合组织要求。请检查策略信息并重试。</value>
</data>
<data name="Loading" xml:space="preserve">
<value>载入中</value>
</data>
</root>

View File

@@ -534,13 +534,13 @@
<value>即時</value>
</data>
<data name="VaultTimeout" xml:space="preserve">
<value>密碼庫時</value>
<value>密碼庫時</value>
</data>
<data name="VaultTimeoutAction" xml:space="preserve">
<value>密碼庫時動作</value>
<value>密碼庫時動作</value>
</data>
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
<value>選擇登出將會在密碼庫時後移除所有密碼庫存取權,重新認證時需要連網路。決定選擇登出嗎?</value>
<value>選擇登出將會在密碼庫時後移除所有密碼庫存取權,重新認證時需要連網路。確定要登出嗎?</value>
</data>
<data name="LoggingIn" xml:space="preserve">
<value>正在登入...</value>
@@ -1674,4 +1674,61 @@
<value>您確定要丟到垃圾桶嗎?</value>
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
</data>
<data name="BiometricInvalidated" xml:space="preserve">
<value>Biometric change detected, login using Master Password to enable again.</value>
</data>
<data name="EnableSyncOnRefresh" xml:space="preserve">
<value>Enable sync on refresh</value>
</data>
<data name="EnableSyncOnRefreshDescription" xml:space="preserve">
<value>Syncing vault with pull down gesture.</value>
</data>
<data name="LogInSso" xml:space="preserve">
<value>Enterprise Single Sign-On</value>
</data>
<data name="LogInSsoSummary" xml:space="preserve">
<value>Quickly log in using your organization's single sign-on portal. Please enter your organization's identifier to begin.</value>
</data>
<data name="OrgIdentifier" xml:space="preserve">
<value>Organization Identifier</value>
</data>
<data name="LoginSsoError" xml:space="preserve">
<value>Currently unable to login with SSO</value>
</data>
<data name="SetMasterPassword" xml:space="preserve">
<value>Set Master Password</value>
</data>
<data name="SetMasterPasswordSummary" xml:space="preserve">
<value>In order to complete logging in with SSO, please set a master password to access and protect your vault.</value>
</data>
<data name="MasterPasswordPolicyInEffect" xml:space="preserve">
<value>One or more organization policies require your master password to meet the following requirements:</value>
</data>
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
<value>Minimum complexity score of {0}</value>
</data>
<data name="PolicyInEffectMinLength" xml:space="preserve">
<value>Minimum length of {0}</value>
</data>
<data name="PolicyInEffectUppercase" xml:space="preserve">
<value>Contain one or more uppercase characters</value>
</data>
<data name="PolicyInEffectLowercase" xml:space="preserve">
<value>Contain one or more lowercase characters</value>
</data>
<data name="PolicyInEffectNumbers" xml:space="preserve">
<value>Contain one or more numbers</value>
</data>
<data name="PolicyInEffectSpecial" xml:space="preserve">
<value>Contain one or more of the following special characters: {0}</value>
</data>
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
<value>Invalid Password</value>
</data>
<data name="MasterPasswordPolicyValidationMessage" xml:space="preserve">
<value>Password does not meet organization requirements. Please check the policy information and try again.</value>
</data>
<data name="Loading" xml:space="preserve">
<value>Loading</value>
</data>
</root>

View File

@@ -8,6 +8,7 @@ using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Bit.App.Models;
using Xamarin.Forms;
namespace Bit.App.Utilities
@@ -192,5 +193,34 @@ namespace Bit.App.Utilities
}
}
}
public static bool SetAlternateMainPage(AppOptions appOptions)
{
if (appOptions != null)
{
if (appOptions.FromAutofillFramework && appOptions.SaveType.HasValue)
{
Application.Current.MainPage = new NavigationPage(new AddEditPage(appOptions: appOptions));
return true;
}
if (appOptions.Uri != null)
{
Application.Current.MainPage = new NavigationPage(new AutofillCiphersPage(appOptions));
return true;
}
}
return false;
}
public static async Task<PreviousPageInfo> ClearPreviousPage()
{
var storageService = ServiceContainer.Resolve<IStorageService>("storageService");
var previousPage = await storageService.GetAsync<PreviousPageInfo>(Constants.PreviousPageKey);
if (previousPage != null)
{
await storageService.RemoveAsync(Constants.PreviousPageKey);
}
return previousPage;
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Threading.Tasks;
using Xamarin.Essentials;
using static Xamarin.Essentials.Permissions;
namespace Bit.App.Utilities
{
public static class PermissionManager
{
public static async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
where T : BasePermission
{
var status = await permission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
status = await permission.RequestAsync();
}
return status;
}
}
}

View File

@@ -26,11 +26,13 @@ namespace Bit.Core.Abstractions
Task<ProfileResponse> GetProfileAsync();
Task<SyncResponse> GetSyncAsync();
Task PostAccountKeysAsync(KeysRequest request);
Task PostAccountVerifyPasswordAsync(PasswordVerificationRequest request);
Task<CipherResponse> PostCipherAsync(CipherRequest request);
Task<CipherResponse> PostCipherCreateAsync(CipherCreateRequest request);
Task<FolderResponse> PostFolderAsync(FolderRequest request);
Task<Tuple<IdentityTokenResponse, IdentityTwoFactorResponse>> PostIdentityTokenAsync(TokenRequest request);
Task PostPasswordHintAsync(PasswordHintRequest request);
Task SetPasswordAsync(SetPasswordRequest request);
Task<PreloginResponse> PostPreloginAsync(PreloginRequest request);
Task PostRegisterAsync(RegisterRequest request);
Task<CipherResponse> PutCipherAsync(string id, CipherRequest request);
@@ -40,6 +42,7 @@ namespace Bit.Core.Abstractions
Task PutDeleteCipherAsync(string id);
Task PutRestoreCipherAsync(string id);
Task RefreshIdentityTokenAsync();
Task<object> PreValidateSso(string identifier);
Task<TResponse> SendAsync<TRequest, TResponse>(HttpMethod method, string path,
TRequest body, bool authed, bool hasResponse);
void SetUrls(EnvironmentUrls urls);

View File

@@ -10,16 +10,22 @@ namespace Bit.Core.Abstractions
{
string Email { get; set; }
string MasterPasswordHash { get; set; }
string Code { get; set; }
string CodeVerifier { get; set; }
string SsoRedirectUrl { get; set; }
TwoFactorProviderType? SelectedTwoFactorProviderType { get; set; }
Dictionary<TwoFactorProviderType, TwoFactorProvider> TwoFactorProviders { get; set; }
Dictionary<TwoFactorProviderType, Dictionary<string, object>> TwoFactorProvidersData { get; set; }
TwoFactorProviderType? GetDefaultTwoFactorProvider(bool u2fSupported);
bool AuthingWithSso();
bool AuthingWithPassword();
List<TwoFactorProvider> GetSupportedTwoFactorProviders();
Task<AuthResult> LogInAsync(string email, string masterPassword);
Task<AuthResult> LogInSsoAsync(string code, string codeVerifier, string redirectUrl);
Task<AuthResult> LogInCompleteAsync(string email, string masterPassword, TwoFactorProviderType twoFactorProvider, string twoFactorToken, bool? remember = null);
Task<AuthResult> LogInTwoFactorAsync(TwoFactorProviderType twoFactorProvider, string twoFactorToken, bool? remember = null);
void LogOut(Action callback);
void Init();
}
}
}

View File

@@ -0,0 +1,10 @@
using System.Threading.Tasks;
namespace Bit.Core.Abstractions
{
public interface IBiometricService
{
Task<bool> SetupBiometricAsync();
Task<bool> ValidateIntegrityAsync();
}
}

View File

@@ -15,7 +15,7 @@ namespace Bit.Core.Abstractions
Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)> GetOptionsAsync();
Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)>
EnforcePasswordGeneratorPoliciesOnOptionsAsync(PasswordGenerationOptions options);
Task<object> PasswordStrength(string password, List<string> userInputs = null);
Zxcvbn.Result PasswordStrength(string password, List<string> userInputs = null);
Task SaveOptionsAsync(PasswordGenerationOptions options);
void NormalizeOptions(PasswordGenerationOptions options, PasswordGeneratorPolicyOptions enforcedPolicyOptions);
}

View File

@@ -12,5 +12,8 @@ namespace Bit.Core.Abstractions
Task<IEnumerable<Policy>> GetAll(PolicyType? type);
Task Replace(Dictionary<string, PolicyData> policies);
Task Clear(string userId);
Task<MasterPasswordPolicyOptions> GetMasterPasswordPolicyOptions(IEnumerable<Policy> policies = null);
Task<bool> EvaluateMasterPassword(int passwordStrength, string newPassword,
MasterPasswordPolicyOptions enforcedPolicyOptions);
}
}

View File

@@ -7,7 +7,6 @@ namespace Bit.Core.Abstractions
public interface ISyncService
{
bool SyncInProgress { get; set; }
Task<bool> FullSyncAsync(bool forceSync, bool allowThrowOnError = false);
Task<DateTime?> GetLastSyncAsync();
Task SetLastSyncAsync(DateTime date);

View File

@@ -4,6 +4,7 @@
{
public const string AndroidAppProtocol = "androidapp://";
public const string iOSAppProtocol = "iosapp://";
public static string SyncOnRefreshKey = "syncOnRefresh";
public static string VaultTimeoutKey = "lockOption";
public static string VaultTimeoutActionKey = "vaultTimeoutAction";
public static string LastActiveKey = "lastActive";

View File

@@ -27,6 +27,7 @@
<PackageReference Include="LiteDB" Version="5.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="PCLCrypto" Version="2.0.147" />
<PackageReference Include="zxcvbn-core" Version="2.1.44" />
</ItemGroup>
</Project>

View File

@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Bit.Core.Models.Data
{
@@ -25,22 +26,35 @@ namespace Bit.Core.Models.Data
Notes = response.Notes;
CollectionIds = collectionIds?.ToList() ?? response.CollectionIds;
switch (Type)
try // Added to address Issue (https://github.com/bitwarden/mobile/issues/1006)
{
case Enums.CipherType.Login:
Login = new LoginData(response.Login);
break;
case Enums.CipherType.SecureNote:
SecureNote = new SecureNoteData(response.SecureNote);
break;
case Enums.CipherType.Card:
Card = new CardData(response.Card);
break;
case Enums.CipherType.Identity:
Identity = new IdentityData(response.Identity);
break;
default:
break;
switch (Type)
{
case Enums.CipherType.Login:
Login = new LoginData(response.Login);
break;
case Enums.CipherType.SecureNote:
SecureNote = new SecureNoteData(response.SecureNote);
break;
case Enums.CipherType.Card:
Card = new CardData(response.Card);
break;
case Enums.CipherType.Identity:
Identity = new IdentityData(response.Identity);
break;
default:
break;
}
}
catch
{
System.Diagnostics.Trace.WriteLine(new StringBuilder()
.Append("BitWarden CipherData constructor failed to initialize CyperType '")
.Append(Type)
.Append("'; id = {")
.Append(Id)
.AppendLine("}")
.ToString(), "BitWarden CipherData constructor");
}
Fields = response.Fields?.Select(f => new FieldData(f)).ToList();

View File

@@ -6,6 +6,7 @@ namespace Bit.Core.Models.Domain
public class AuthResult
{
public bool TwoFactor { get; set; }
public bool ResetMasterPassword { get; set; }
public Dictionary<TwoFactorProviderType, Dictionary<string, object>> TwoFactorProviders { get; set; }
}
}

View File

@@ -0,0 +1,22 @@
namespace Bit.Core.Models.Domain
{
public class MasterPasswordPolicyOptions
{
public int MinComplexity { get; set; }
public int MinLength { get; set; }
public bool RequireUpper { get; set; }
public bool RequireLower { get; set; }
public bool RequireNumbers { get; set; }
public bool RequireSpecial { get; set; }
public bool InEffect()
{
return MinComplexity > 0 ||
MinLength > 0 ||
RequireUpper ||
RequireLower ||
RequireNumbers ||
RequireSpecial;
}
}
}

View File

@@ -0,0 +1,7 @@
namespace Bit.Core.Models.Request
{
public class PasswordVerificationRequest
{
public string MasterPasswordHash { get; set; }
}
}

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