Compare commits
26 Commits
bug/PS-117
...
acostarj-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a1bc79eba | ||
|
|
dbfd15b819 | ||
|
|
acd0cb119d | ||
|
|
d61bc4b5c1 | ||
|
|
5aa1146657 | ||
|
|
f15fd246a8 | ||
|
|
2b8547878a | ||
|
|
942d5d29d2 | ||
|
|
fde63a836d | ||
|
|
6102a0c115 | ||
|
|
4f4953206e | ||
|
|
f772ee7068 | ||
|
|
8f93e6bf5f | ||
|
|
64fefac194 | ||
|
|
d784b1290b | ||
|
|
0f2bc2fa25 | ||
|
|
0e856d2add | ||
|
|
acc587ce45 | ||
|
|
66180397d9 | ||
|
|
571c4b8d22 | ||
|
|
660ba3d722 | ||
|
|
414cb9bd7e | ||
|
|
e588efd0a1 | ||
|
|
1cdba5f73d | ||
|
|
cbccd10271 | ||
|
|
6de6b19944 |
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,6 +1,6 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Report mobile autofill failure
|
||||
- name: Report mobile AUTOFILL failure
|
||||
url: https://docs.google.com/forms/d/e/1FAIpQLScMopHyN7KGJs8hW562VTzbIGL4KcFnx0wJcsW0GYE1BnPiGA/viewform
|
||||
about: We are aware of some situations where the Bitwarden mobile app will not autofill information correctly. This is something the Bitwarden team is actively working on but need your help as a community and active Bitwarden users!
|
||||
- name: Feature Requests
|
||||
|
||||
BIN
.github/secrets/GoogleService-Info.plist.gpg
vendored
Normal file
88
.github/workflows/build.yml
vendored
@@ -4,10 +4,10 @@ name: Build
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'l10n_master'
|
||||
- 'gh-pages'
|
||||
- "l10n_master"
|
||||
- "gh-pages"
|
||||
paths-ignore:
|
||||
- '.github/workflows/**'
|
||||
- ".github/workflows/**"
|
||||
workflow_dispatch:
|
||||
inputs: {}
|
||||
|
||||
@@ -62,16 +62,16 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
variant: ['prod', 'qa']
|
||||
variant: ["prod", "qa"]
|
||||
steps:
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
with:
|
||||
nuget-version: 5.9.0
|
||||
|
||||
- name: Set up MSBuild
|
||||
uses: microsoft/setup-msbuild@ab534842b4bdf384b8aaf93765dc6f721d9f5fab
|
||||
|
||||
|
||||
- name: Work Around for broken Windows 2022 Runner Image
|
||||
run: |
|
||||
Set-Location "C:\Program Files (x86)\Microsoft Visual Studio\Installer\"
|
||||
@@ -148,7 +148,17 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
- name: Run Core tests
|
||||
run: dotnet test test/Core.Test/Core.Test.csproj
|
||||
run: dotnet test test/Core.Test/Core.Test.csproj --logger "trx;LogFileName=test-results.trx" || true
|
||||
shell: pwsh
|
||||
|
||||
- name: Report test results
|
||||
uses: dorny/test-reporter@c9b3d0e2bd2a4e96aaf424dbaa31c46b42318226
|
||||
if: always()
|
||||
with:
|
||||
name: Test Results
|
||||
path: "**/test-results.trx"
|
||||
reporter: dotnet-trx
|
||||
fail-on-error: true
|
||||
|
||||
- name: Build Play Store publisher
|
||||
if: ${{ matrix.variant == 'prod' }}
|
||||
@@ -175,7 +185,7 @@ jobs:
|
||||
run: |
|
||||
$androidPath = $($env:GITHUB_WORKSPACE + "/src/Android/Android.csproj");
|
||||
$packageName = "com.x8bit.bitwarden";
|
||||
|
||||
|
||||
if ("${{ matrix.variant }}" -ne "prod")
|
||||
{
|
||||
$packageName = "com.x8bit.bitwarden.${{ matrix.variant }}";
|
||||
@@ -260,7 +270,7 @@ jobs:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
with:
|
||||
nuget-version: 5.9.0
|
||||
|
||||
@@ -440,11 +450,11 @@ jobs:
|
||||
|
||||
ios:
|
||||
name: Apple iOS
|
||||
runs-on: macos-11
|
||||
runs-on: macos-12
|
||||
needs: setup
|
||||
steps:
|
||||
- name: Setup NuGet
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
uses: nuget/setup-nuget@b2bc17b761a1d88cab755a776c7922eb26eefbfa # v1.0.6
|
||||
with:
|
||||
nuget-version: 5.9.0
|
||||
|
||||
@@ -503,6 +513,8 @@ jobs:
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output $HOME/secrets/dist_watch_app_extension.mobileprovision \
|
||||
./.github/secrets/dist_watch_app_extension.mobileprovision.gpg
|
||||
gpg --quiet --batch --yes --decrypt --passphrase="$DECRYPT_FILE_PASSWORD" \
|
||||
--output ./src/watchOS/bitwarden/GoogleService-Info.plist ./.github/secrets/GoogleService-Info.plist.gpg
|
||||
shell: bash
|
||||
|
||||
- name: Increment version
|
||||
@@ -584,15 +596,12 @@ jobs:
|
||||
echo "########################################"
|
||||
echo "##### Build WatchApp with Release Configuration"
|
||||
echo "########################################"
|
||||
|
||||
|
||||
xcodebuild archive -workspace ./src/watchOS/bitwarden/bitwarden.xcodeproj/project.xcworkspace -configuration Release -scheme bitwarden\ WatchKit\ App -archivePath ./src/watchOS/bitwarden
|
||||
|
||||
echo "########################################"
|
||||
echo "##### Done"
|
||||
echo "########################################"
|
||||
cd src/watchOS
|
||||
ls -R
|
||||
cd ../..
|
||||
shell: bash
|
||||
|
||||
- name: Restore packages
|
||||
@@ -630,7 +639,12 @@ jobs:
|
||||
ARCHIVE_DSYMS_PATH="$HOME/Library/Developer/Xcode/Archives/*/*.xcarchive/dSYMs"
|
||||
EXPORT_PATH="./bitwarden-export"
|
||||
|
||||
cp -r $ARCHIVE_DSYMS_PATH $EXPORT_PATH
|
||||
WATCH_ARCHIVE_DSYMS_PATH="./src/watchOS/bitwarden.xcarchive/dSYMs/"
|
||||
WATCH_DSYMS_EXPORT_PATH="$EXPORT_PATH/Watch_dSYMs"
|
||||
|
||||
cp -r -v $ARCHIVE_DSYMS_PATH $EXPORT_PATH
|
||||
mkdir $WATCH_DSYMS_EXPORT_PATH
|
||||
cp -r -v $WATCH_ARCHIVE_DSYMS_PATH $WATCH_DSYMS_EXPORT_PATH
|
||||
shell: bash
|
||||
|
||||
- name: Upload App Store .ipa & dSYMs artifacts
|
||||
@@ -653,23 +667,39 @@ jobs:
|
||||
|
||||
- name: Upload dSYMs to App Center
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
env:
|
||||
APPCENTER_IOS_TOKEN: ${{ steps.retrieve-secrets.outputs.appcenter-ios-token }}
|
||||
run: appcenter crashes upload-symbols -a bitwarden/bitwarden -s "./bitwarden-export/dSYMs" --token $APPCENTER_IOS_TOKEN
|
||||
shell: bash
|
||||
|
||||
- name: Upload Watch dSYMs to Firebase Crashlytics
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
run: |
|
||||
|
||||
echo "########################################"
|
||||
echo "##### Uploading Watch dSYMs to Firebase"
|
||||
echo "########################################"
|
||||
|
||||
find "$HOME/Library/Developer/XCode/DerivedData" -name "upload-symbols" -exec chmod +x {} \; -exec {} -gsp "./src/watchOS/bitwarden/GoogleService-Info.plist" -p ios "./bitwarden-export/Watch_dSYMs" \;
|
||||
shell: bash
|
||||
|
||||
- name: Deploy to App Store
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
(github.ref == 'refs/heads/master'
|
||||
&& needs.setup.outputs.rc_branch_exists == 0
|
||||
&& needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| (github.ref == 'refs/heads/rc' && needs.setup.outputs.hotfix_branch_exists == 0)
|
||||
|| github.ref == 'refs/heads/hotfix-rc'
|
||||
env:
|
||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||
@@ -737,9 +767,9 @@ jobs:
|
||||
steps:
|
||||
- name: Check if any job failed
|
||||
if: |
|
||||
(github.ref == 'refs/heads/master')
|
||||
|| (github.ref == 'refs/heads/rc')
|
||||
|| (github.ref == 'refs/heads/hotfix-rc')
|
||||
(github.ref == 'refs/heads/master')
|
||||
|| (github.ref == 'refs/heads/rc')
|
||||
|| (github.ref == 'refs/heads/hotfix-rc')
|
||||
env:
|
||||
CLOC_STATUS: ${{ needs.cloc.result }}
|
||||
ANDROID_STATUS: ${{ needs.android.result }}
|
||||
|
||||
4
.github/workflows/enforce-labels.yml
vendored
@@ -12,5 +12,5 @@ jobs:
|
||||
- name: Enforce Label
|
||||
uses: yogevbd/enforce-label-action@8d1e1709b1011e6d90400a0e6cf7c0b77aa5efeb
|
||||
with:
|
||||
BANNED_LABELS: "hold"
|
||||
BANNED_LABELS_DESCRIPTION: "PRs on hold cannot be merged"
|
||||
BANNED_LABELS: "hold,needs-qa"
|
||||
BANNED_LABELS_DESCRIPTION: "PRs with the hold or needs-qa labels cannot be merged"
|
||||
|
||||
4
.github/workflows/version-auto-bump.yml
vendored
@@ -21,8 +21,8 @@ jobs:
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.ref }}
|
||||
run: |
|
||||
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/')
|
||||
CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/')
|
||||
CURR_MAJOR=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\1/')
|
||||
CURR_PATCH=$(echo $RELEASE_TAG | sed -r 's/refs\/tags\/v([0-9]{4}\.[0-9]{1,2})\.([0-9]{1,2})/\2/')
|
||||
echo "Current Major: $CURR_MAJOR"
|
||||
echo "Current Patch: $CURR_PATCH"
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.mmbox.xbrowser", "search_box"),
|
||||
new Browser("com.mycompany.app.soulbrowser", "edit_text"),
|
||||
new Browser("com.naver.whale", "url_bar"),
|
||||
new Browser("com.neeva.app", "full_url_text_view"),
|
||||
new Browser("com.opera.browser", "url_field"),
|
||||
new Browser("com.opera.browser.beta", "url_field"),
|
||||
new Browser("com.opera.gx", "addressbarEdit"),
|
||||
@@ -75,6 +76,7 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.opera.touch", "addressbarEdit"),
|
||||
new Browser("com.qflair.browserq", "url"),
|
||||
new Browser("com.qwant.liberty", "mozac_browser_toolbar_url_view,url_bar_title"), // 2nd = Legacy (before v4)
|
||||
new Browser("com.rainsee.create", "search_box"),
|
||||
new Browser("com.sec.android.app.sbrowser", "location_bar_edit_text"),
|
||||
new Browser("com.sec.android.app.sbrowser.beta", "location_bar_edit_text"),
|
||||
new Browser("com.stoutner.privacybrowser.free", "url_edittext"),
|
||||
@@ -84,6 +86,9 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.vivaldi.browser.sopranos", "url_bar"),
|
||||
new Browser("com.yandex.browser", "bro_omnibar_address_title_text,bro_omnibox_collapsed_title",
|
||||
(s) => s.Split(new char[]{' ', ' '}).FirstOrDefault()), // 0 = Regular Space, 1 = No-break space (00A0)
|
||||
new Browser("com.yjllq.internet", "search_box"),
|
||||
new Browser("com.yjllq.kito", "search_box"),
|
||||
new Browser("com.yujian.ResideMenuDemo", "search_box"),
|
||||
new Browser("com.z28j.feel", "g2"),
|
||||
new Browser("idm.internet.download.manager", "search"),
|
||||
new Browser("idm.internet.download.manager.adm.lite", "search"),
|
||||
@@ -91,6 +96,7 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("io.github.forkmaintainers.iceraven", "mozac_browser_toolbar_url_view"),
|
||||
new Browser("mark.via", "am,an"),
|
||||
new Browser("mark.via.gp", "as"),
|
||||
new Browser("net.dezor.browser", "url_bar"),
|
||||
new Browser("net.slions.fulguris.full.download", "search"),
|
||||
new Browser("net.slions.fulguris.full.download.debug", "search"),
|
||||
new Browser("net.slions.fulguris.full.playstore", "search"),
|
||||
@@ -130,6 +136,7 @@ namespace Bit.Droid.Accessibility
|
||||
new Browser("com.htc.sense.browser", "title"),
|
||||
new Browser("com.jerky.browser2", "enterUrl"),
|
||||
new Browser("com.ksmobile.cb", "address_bar_edit_text"),
|
||||
new Browser("com.lemurbrowser.exts","url_bar"),
|
||||
new Browser("com.linkbubble.playstore", "url_text"),
|
||||
new Browser("com.mx.browser", "address_editor_with_progress"),
|
||||
new Browser("com.mx.browser.tablet", "address_editor_with_progress"),
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace Bit.Droid.Autofill
|
||||
"com.jamal2367.styx",
|
||||
"com.kiwibrowser.browser",
|
||||
"com.kiwibrowser.browser.dev",
|
||||
"com.lemurbrowser.exts",
|
||||
"com.microsoft.emmx",
|
||||
"com.microsoft.emmx.beta",
|
||||
"com.microsoft.emmx.canary",
|
||||
@@ -87,6 +88,7 @@ namespace Bit.Droid.Autofill
|
||||
"com.mmbox.xbrowser",
|
||||
"com.mycompany.app.soulbrowser",
|
||||
"com.naver.whale",
|
||||
"com.neeva.app",
|
||||
"com.opera.browser",
|
||||
"com.opera.browser.beta",
|
||||
"com.opera.gx",
|
||||
@@ -95,6 +97,7 @@ namespace Bit.Droid.Autofill
|
||||
"com.opera.touch",
|
||||
"com.qflair.browserq",
|
||||
"com.qwant.liberty",
|
||||
"com.rainsee.create",
|
||||
"com.sec.android.app.sbrowser",
|
||||
"com.sec.android.app.sbrowser.beta",
|
||||
"com.stoutner.privacybrowser.free",
|
||||
@@ -103,6 +106,9 @@ namespace Bit.Droid.Autofill
|
||||
"com.vivaldi.browser.snapshot",
|
||||
"com.vivaldi.browser.sopranos",
|
||||
"com.yandex.browser",
|
||||
"com.yjllq.internet",
|
||||
"com.yjllq.kito",
|
||||
"com.yujian.ResideMenuDemo",
|
||||
"com.z28j.feel",
|
||||
"idm.internet.download.manager",
|
||||
"idm.internet.download.manager.adm.lite",
|
||||
@@ -110,6 +116,7 @@ namespace Bit.Droid.Autofill
|
||||
"io.github.forkmaintainers.iceraven",
|
||||
"mark.via",
|
||||
"mark.via.gp",
|
||||
"net.dezor.browser",
|
||||
"net.slions.fulguris.full.download",
|
||||
"net.slions.fulguris.full.download.debug",
|
||||
"net.slions.fulguris.full.playstore",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2022.12.0" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:versionCode="1" android:versionName="2023.1.1" android:installLocation="internalOnly" package="com.x8bit.bitwarden">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
@@ -40,4 +40,16 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
<!-- Support for Xamarin.Essentials.Browser.OpenAsync (for Android > 11) -->
|
||||
<!-- Related docs: https://learn.microsoft.com/en-us/xamarin/essentials/open-browser?tabs=android -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="http"/>
|
||||
</intent>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<data android:scheme="https"/>
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
@@ -92,6 +92,9 @@
|
||||
<compatibility-package
|
||||
android:name="com.kiwibrowser.browser.dev"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.lemurbrowser.exts"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.microsoft.emmx"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
@@ -116,6 +119,9 @@
|
||||
<compatibility-package
|
||||
android:name="com.naver.whale"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.neeva.app"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.opera.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
@@ -140,6 +146,9 @@
|
||||
<compatibility-package
|
||||
android:name="com.qwant.liberty"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.rainsee.create"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.sec.android.app.sbrowser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
@@ -164,6 +173,15 @@
|
||||
<compatibility-package
|
||||
android:name="com.yandex.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.yjllq.internet"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.yjllq.kito"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.yujian.ResideMenuDemo"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="com.z28j.feel"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
@@ -185,6 +203,9 @@
|
||||
<compatibility-package
|
||||
android:name="mark.via.gp"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="net.dezor.browser"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
<compatibility-package
|
||||
android:name="net.slions.fulguris.full.download"
|
||||
android:maxLongVersionCode="10000000000"/>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
@@ -25,13 +26,13 @@ namespace Bit.Droid.Services
|
||||
try
|
||||
{
|
||||
var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
|
||||
Console.WriteLine(netLanguage + " failed, trying " + fallback + " (" + e1.Message + ")");
|
||||
Debug.WriteLine(netLanguage + " failed, trying " + fallback + " (" + e1.Message + ")");
|
||||
ci = new CultureInfo(fallback);
|
||||
}
|
||||
catch (CultureNotFoundException e2)
|
||||
{
|
||||
// iOS language not valid .NET culture, falling back to English
|
||||
Console.WriteLine(netLanguage + " couldn't be set, using 'en' (" + e2.Message + ")");
|
||||
Debug.WriteLine(netLanguage + " couldn't be set, using 'en' (" + e2.Message + ")");
|
||||
ci = new CultureInfo("en");
|
||||
}
|
||||
}
|
||||
@@ -40,7 +41,7 @@ namespace Bit.Droid.Services
|
||||
|
||||
private string AndroidToDotnetLanguage(string androidLanguage)
|
||||
{
|
||||
Console.WriteLine("Android Language:" + androidLanguage);
|
||||
Debug.WriteLine("Android Language:" + androidLanguage);
|
||||
var netLanguage = androidLanguage;
|
||||
if (androidLanguage.StartsWith("zh"))
|
||||
{
|
||||
@@ -79,13 +80,13 @@ namespace Bit.Droid.Services
|
||||
// ONLY use cultures that have been tested and known to work
|
||||
}
|
||||
}
|
||||
Console.WriteLine(".NET Language/Locale:" + netLanguage);
|
||||
Debug.WriteLine(".NET Language/Locale:" + netLanguage);
|
||||
return netLanguage;
|
||||
}
|
||||
|
||||
private string ToDotnetFallbackLanguage(PlatformCulture platCulture)
|
||||
{
|
||||
Console.WriteLine(".NET Fallback Language:" + platCulture.LanguageCode);
|
||||
Debug.WriteLine(".NET Fallback Language:" + platCulture.LanguageCode);
|
||||
var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
|
||||
switch (platCulture.LanguageCode)
|
||||
{
|
||||
@@ -95,7 +96,7 @@ namespace Bit.Droid.Services
|
||||
// add more application-specific cases here (if required)
|
||||
// ONLY use cultures that have been tested and known to work
|
||||
}
|
||||
Console.WriteLine(".NET Fallback Language/Locale:" + netLanguage + " (application-specific)");
|
||||
Debug.WriteLine(".NET Fallback Language/Locale:" + netLanguage + " (application-specific)");
|
||||
return netLanguage;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
<Folder Include="Utilities\AccountManagement\" />
|
||||
<Folder Include="Controls\DateTime\" />
|
||||
<Folder Include="Controls\IconLabelButton\" />
|
||||
<Folder Include="Controls\PasswordStrengthProgressBar\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -435,5 +436,6 @@
|
||||
<None Remove="Utilities\AccountManagement\" />
|
||||
<None Remove="Controls\DateTime\" />
|
||||
<None Remove="Controls\IconLabelButton\" />
|
||||
<None Remove="Controls\PasswordStrengthProgressBar\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
AccountView = accountView;
|
||||
AvatarImageSource = ServiceContainer.Resolve<IAvatarImageSourcePool>("avatarImageSourcePool")
|
||||
?.GetOrCreateAvatar(AccountView.UserId, AccountView.Name, AccountView.Email);
|
||||
?.GetOrCreateAvatar(AccountView.UserId, AccountView.Name, AccountView.Email, AccountView.AvatarColor);
|
||||
}
|
||||
|
||||
public AccountView AccountView
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
private readonly string _text;
|
||||
private readonly string _id;
|
||||
private readonly string _color;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
@@ -23,7 +24,7 @@ namespace Bit.App.Controls
|
||||
|
||||
if (obj is AvatarImageSource avatar)
|
||||
{
|
||||
return avatar._id == _id && avatar._text == _text;
|
||||
return avatar._id == _id && avatar._text == _text && avatar._color == _color;
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
@@ -31,7 +32,7 @@ namespace Bit.App.Controls
|
||||
|
||||
public override int GetHashCode() => _id?.GetHashCode() ?? _text?.GetHashCode() ?? -1;
|
||||
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null)
|
||||
public AvatarImageSource(string userId = null, string name = null, string email = null, string color = null)
|
||||
{
|
||||
_id = userId;
|
||||
_text = name;
|
||||
@@ -39,6 +40,7 @@ namespace Bit.App.Controls
|
||||
{
|
||||
_text = email;
|
||||
}
|
||||
_color = color;
|
||||
}
|
||||
|
||||
public override Func<CancellationToken, Task<Stream>> Stream => GetStreamAsync;
|
||||
@@ -71,7 +73,7 @@ namespace Bit.App.Controls
|
||||
chars = upperCaseText = _text.ToUpper();
|
||||
}
|
||||
|
||||
var bgColor = CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var bgColor = _color ?? CoreHelpers.StringToColor(_id ?? upperCaseText, "#33ffffff");
|
||||
var textColor = CoreHelpers.TextColorFromBgColor(bgColor);
|
||||
var size = 50;
|
||||
|
||||
|
||||
@@ -5,19 +5,19 @@ namespace Bit.App.Controls
|
||||
{
|
||||
public interface IAvatarImageSourcePool
|
||||
{
|
||||
AvatarImageSource GetOrCreateAvatar(string userId, string name, string email);
|
||||
AvatarImageSource GetOrCreateAvatar(string userId, string name, string email, string color);
|
||||
}
|
||||
|
||||
public class AvatarImageSourcePool : IAvatarImageSourcePool
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, AvatarImageSource> _cache = new ConcurrentDictionary<string, AvatarImageSource>();
|
||||
|
||||
public AvatarImageSource GetOrCreateAvatar(string userId, string name, string email)
|
||||
public AvatarImageSource GetOrCreateAvatar(string userId, string name, string email, string color)
|
||||
{
|
||||
var key = $"{userId}{name}{email}";
|
||||
var key = $"{userId}{name}{email}{color}";
|
||||
if (!_cache.TryGetValue(key, out var avatar))
|
||||
{
|
||||
avatar = new AvatarImageSource(userId, name, email);
|
||||
avatar = new AvatarImageSource(userId, name, email, color);
|
||||
if (!_cache.TryAdd(key, avatar)
|
||||
&&
|
||||
!_cache.TryGetValue(key, out avatar)) // If add fails another thread created the avatar in between the first try get and the try add.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public interface IPasswordStrengthable
|
||||
{
|
||||
string Password { get; }
|
||||
List<string> UserInputs { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using Bit.Core.Attributes;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public enum PasswordStrengthLevel
|
||||
{
|
||||
[LocalizableEnum("Weak")]
|
||||
VeryWeak,
|
||||
[LocalizableEnum("Weak")]
|
||||
Weak,
|
||||
[LocalizableEnum("Good")]
|
||||
Good,
|
||||
[LocalizableEnum("Strong")]
|
||||
Strong
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<StackLayout
|
||||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:controls="clr-namespace:Bit.App.Controls"
|
||||
xmlns:u="clr-namespace:Bit.App.Utilities"
|
||||
x:DataType="controls:PasswordStrengthViewModel"
|
||||
x:Class="Bit.App.Controls.PasswordStrengthProgressBar"
|
||||
StyleClass="box">
|
||||
|
||||
<StackLayout.Resources>
|
||||
<ResourceDictionary>
|
||||
<u:LocalizableEnumConverter x:Key="localizableEnum" />
|
||||
</ResourceDictionary>
|
||||
</StackLayout.Resources>
|
||||
|
||||
<ProgressBar
|
||||
x:Name="_progressBar"
|
||||
u:ProgressBarExtensions.AnimatedProgress="{Binding PasswordStrength}"
|
||||
ScaleY="2" />
|
||||
|
||||
<Label
|
||||
x:Name="_progressLabel"
|
||||
Text="{Binding PasswordStrengthLevel, Converter={StaticResource localizableEnum}, TargetNullValue=' ' }"
|
||||
StyleClass="box-footer-label" />
|
||||
|
||||
</StackLayout>
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public partial class PasswordStrengthProgressBar : StackLayout
|
||||
{
|
||||
public static readonly BindableProperty PasswordStrengthLevelProperty = BindableProperty.Create(
|
||||
nameof(PasswordStrengthLevel),
|
||||
typeof(PasswordStrengthLevel),
|
||||
typeof(PasswordStrengthProgressBar),
|
||||
propertyChanged: OnControlPropertyChanged);
|
||||
|
||||
public static readonly BindableProperty VeryWeakColorProperty = BindableProperty.Create(
|
||||
nameof(VeryWeakColor),
|
||||
typeof(Color),
|
||||
typeof(PasswordStrengthProgressBar),
|
||||
propertyChanged: OnControlPropertyChanged);
|
||||
|
||||
public static readonly BindableProperty WeakColorProperty = BindableProperty.Create(
|
||||
nameof(WeakColor),
|
||||
typeof(Color),
|
||||
typeof(PasswordStrengthProgressBar),
|
||||
propertyChanged: OnControlPropertyChanged);
|
||||
|
||||
public static readonly BindableProperty GoodColorProperty = BindableProperty.Create(
|
||||
nameof(GoodColor),
|
||||
typeof(Color),
|
||||
typeof(PasswordStrengthProgressBar),
|
||||
propertyChanged: OnControlPropertyChanged);
|
||||
|
||||
public static readonly BindableProperty StrongColorProperty = BindableProperty.Create(
|
||||
nameof(StrongColor),
|
||||
typeof(Color),
|
||||
typeof(PasswordStrengthProgressBar),
|
||||
propertyChanged: OnControlPropertyChanged);
|
||||
|
||||
public PasswordStrengthLevel? PasswordStrengthLevel
|
||||
{
|
||||
get { return (PasswordStrengthLevel?)GetValue(PasswordStrengthLevelProperty); }
|
||||
set { SetValue(PasswordStrengthLevelProperty, value); }
|
||||
}
|
||||
|
||||
public Color VeryWeakColor
|
||||
{
|
||||
get { return (Color)GetValue(VeryWeakColorProperty); }
|
||||
set { SetValue(VeryWeakColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color WeakColor
|
||||
{
|
||||
get { return (Color)GetValue(WeakColorProperty); }
|
||||
set { SetValue(WeakColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color GoodColor
|
||||
{
|
||||
get { return (Color)GetValue(GoodColorProperty); }
|
||||
set { SetValue(GoodColorProperty, value); }
|
||||
}
|
||||
|
||||
public Color StrongColor
|
||||
{
|
||||
get { return (Color)GetValue(StrongColorProperty); }
|
||||
set { SetValue(StrongColorProperty, value); }
|
||||
}
|
||||
|
||||
public PasswordStrengthProgressBar()
|
||||
{
|
||||
InitializeComponent();
|
||||
SetBinding(PasswordStrengthProgressBar.PasswordStrengthLevelProperty, new Binding() { Path = nameof(PasswordStrengthViewModel.PasswordStrengthLevel) });
|
||||
}
|
||||
|
||||
private static void OnControlPropertyChanged(BindableObject bindable, object oldValue, object newValue)
|
||||
{
|
||||
(bindable as PasswordStrengthProgressBar)?.UpdateColors();
|
||||
}
|
||||
|
||||
public void UpdateColors()
|
||||
{
|
||||
if (_progressBar == null || _progressLabel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
_progressBar.ProgressColor = GetColorForStrength();
|
||||
_progressLabel.TextColor = _progressBar.ProgressColor;
|
||||
}
|
||||
|
||||
private Color GetColorForStrength()
|
||||
{
|
||||
switch (PasswordStrengthLevel)
|
||||
{
|
||||
case Controls.PasswordStrengthLevel.VeryWeak:
|
||||
return VeryWeakColor;
|
||||
case Controls.PasswordStrengthLevel.Weak:
|
||||
return WeakColor;
|
||||
case Controls.PasswordStrengthLevel.Good:
|
||||
return GoodColor;
|
||||
case Controls.PasswordStrengthLevel.Strong:
|
||||
return StrongColor;
|
||||
default:
|
||||
return Color.Transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Controls
|
||||
{
|
||||
public class PasswordStrengthViewModel : ExtendedViewModel
|
||||
{
|
||||
private readonly IPasswordGenerationService _passwordGenerationService;
|
||||
private readonly IPasswordStrengthable _passwordStrengthable;
|
||||
private double _passwordStrength;
|
||||
private Color _passwordColor;
|
||||
private PasswordStrengthLevel? _passwordStrengthLevel;
|
||||
|
||||
public PasswordStrengthViewModel(IPasswordStrengthable passwordStrengthable)
|
||||
{
|
||||
_passwordGenerationService = ServiceContainer.Resolve<IPasswordGenerationService>();
|
||||
_passwordStrengthable = passwordStrengthable;
|
||||
}
|
||||
|
||||
public double PasswordStrength
|
||||
{
|
||||
get => _passwordStrength;
|
||||
set => SetProperty(ref _passwordStrength, value);
|
||||
}
|
||||
|
||||
public PasswordStrengthLevel? PasswordStrengthLevel
|
||||
{
|
||||
get => _passwordStrengthLevel;
|
||||
set => SetProperty(ref _passwordStrengthLevel, value);
|
||||
}
|
||||
|
||||
public List<string> GetPasswordStrengthUserInput(string email) => _passwordGenerationService.GetPasswordStrengthUserInput(email);
|
||||
|
||||
public void CalculatePasswordStrength()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_passwordStrengthable.Password))
|
||||
{
|
||||
PasswordStrength = 0;
|
||||
PasswordStrengthLevel = null;
|
||||
return;
|
||||
}
|
||||
|
||||
var passwordStrength = _passwordGenerationService.PasswordStrength(_passwordStrengthable.Password, _passwordStrengthable.UserInputs);
|
||||
// The passwordStrength.Score is 0..4, convertion was made to be used as a progress directly by the control 0..1
|
||||
PasswordStrength = (passwordStrength.Score + 1f) / 5f;
|
||||
if (PasswordStrength <= 0.4f)
|
||||
{
|
||||
PasswordStrengthLevel = Controls.PasswordStrengthLevel.VeryWeak;
|
||||
}
|
||||
else if (PasswordStrength <= 0.6f)
|
||||
{
|
||||
PasswordStrengthLevel = Controls.PasswordStrengthLevel.Weak;
|
||||
}
|
||||
else if (PasswordStrength <= 0.8f)
|
||||
{
|
||||
PasswordStrengthLevel = Controls.PasswordStrengthLevel.Good;
|
||||
}
|
||||
else
|
||||
{
|
||||
PasswordStrengthLevel = Controls.PasswordStrengthLevel.Strong;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Utilities;
|
||||
@@ -147,8 +149,8 @@ namespace Bit.App.Pages
|
||||
}
|
||||
if (IsPolicyInEffect)
|
||||
{
|
||||
var userInput = await GetPasswordStrengthUserInput();
|
||||
var passwordStrength = _passwordGenerationService.PasswordStrength(MasterPassword, userInput);
|
||||
var userInputs = _passwordGenerationService.GetPasswordStrengthUserInput(await _stateService.GetEmailAsync());
|
||||
var passwordStrength = _passwordGenerationService.PasswordStrength(MasterPassword, userInputs);
|
||||
if (!await _policyService.EvaluateMasterPassword(passwordStrength.Score, MasterPassword, Policy))
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.MasterPasswordPolicyValidationMessage,
|
||||
@@ -158,7 +160,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MasterPassword.Length < 8)
|
||||
if (MasterPassword.Length < Constants.MasterPasswordMinimumChars)
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.MasterPasswordLengthValMessage,
|
||||
AppResources.MasterPasswordPolicyValidationTitle, AppResources.Ok);
|
||||
@@ -174,19 +176,5 @@ namespace Bit.App.Pages
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<List<string>> GetPasswordStrengthUserInput()
|
||||
{
|
||||
var email = await _stateService.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,8 +149,7 @@ namespace Bit.App.Pages
|
||||
Email = await _stateService.GetRememberedEmailAsync();
|
||||
}
|
||||
var deviceIdentifier = await _appIdService.GetAppIdAsync();
|
||||
// TODO uncomment to enable login with device
|
||||
//IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier);
|
||||
IsKnownDevice = await _apiService.GetKnownDeviceAsync(Email, deviceIdentifier);
|
||||
CanRemoveAccount = await _stateService.GetActiveUserEmailAsync() != Email;
|
||||
await _deviceActionService.HideLoadingAsync();
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</ContentPage.ToolbarItems>
|
||||
|
||||
<ScrollView>
|
||||
<StackLayout Spacing="20">
|
||||
<StackLayout Spacing="10">
|
||||
<StackLayout StyleClass="box">
|
||||
<StackLayout StyleClass="box-row">
|
||||
<Label
|
||||
@@ -72,8 +72,19 @@
|
||||
AutomationProperties.HelpText="{Binding PasswordVisibilityAccessibilityText}"/>
|
||||
</Grid>
|
||||
<Label
|
||||
Text="{u:I18n MasterPasswordDescription}"
|
||||
StyleClass="box-footer-label" />
|
||||
StyleClass="box-sub-label"
|
||||
Margin="0,0,0,10">
|
||||
<Label.FormattedText>
|
||||
<FormattedString>
|
||||
<Span Text="{u:I18n Important}" TextColor="{DynamicResource InfoColor}"/>
|
||||
<Span Text=": " TextColor="{DynamicResource InfoColor}"/>
|
||||
<Span Text="{Binding MasterPasswordMininumCharactersDescription}" TextColor="{DynamicResource MutedColor}"/>
|
||||
</FormattedString>
|
||||
</Label.FormattedText>
|
||||
</Label>
|
||||
<controls:PasswordStrengthProgressBar
|
||||
BindingContext="{Binding PasswordStrengthViewModel}"
|
||||
Margin="0,0"/>
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box">
|
||||
<Grid StyleClass="box-row">
|
||||
@@ -126,6 +137,17 @@
|
||||
StyleClass="box-footer-label" />
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box">
|
||||
<StackLayout StyleClass="box-row, box-row-switch">
|
||||
<Switch
|
||||
IsToggled="{Binding CheckExposedMasterPassword}"
|
||||
StyleClass="box-value"
|
||||
HorizontalOptions="Start"
|
||||
Margin="0, 0, 10, 0"/>
|
||||
<Label
|
||||
Text="{u:I18n CheckKnownDataBreachesForThisPassword}"
|
||||
StyleClass="box-footer-label"
|
||||
VerticalOptions="Center"/>
|
||||
</StackLayout>
|
||||
<StackLayout StyleClass="box-row, box-row-switch"
|
||||
IsVisible="{Binding ShowTerms}">
|
||||
<Switch
|
||||
|
||||
@@ -1,28 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Request;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Pages
|
||||
{
|
||||
public class RegisterPageViewModel : CaptchaProtectedViewModel
|
||||
public class RegisterPageViewModel : CaptchaProtectedViewModel, IPasswordStrengthable
|
||||
{
|
||||
private readonly IDeviceActionService _deviceActionService;
|
||||
private readonly II18nService _i18nService;
|
||||
private readonly IEnvironmentService _environmentService;
|
||||
private readonly IAuditService _auditService;
|
||||
private readonly IApiService _apiService;
|
||||
private readonly ICryptoService _cryptoService;
|
||||
private readonly IPlatformUtilsService _platformUtilsService;
|
||||
private string _email;
|
||||
private string _masterPassword;
|
||||
private bool _showPassword;
|
||||
private bool _acceptPolicies;
|
||||
private bool _checkExposedMasterPassword;
|
||||
|
||||
public RegisterPageViewModel()
|
||||
{
|
||||
@@ -32,12 +40,14 @@ namespace Bit.App.Pages
|
||||
_platformUtilsService = ServiceContainer.Resolve<IPlatformUtilsService>("platformUtilsService");
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_environmentService = ServiceContainer.Resolve<IEnvironmentService>("environmentService");
|
||||
_auditService = ServiceContainer.Resolve<IAuditService>();
|
||||
|
||||
PageTitle = AppResources.CreateAccount;
|
||||
TogglePasswordCommand = new Command(TogglePassword);
|
||||
ToggleConfirmPasswordCommand = new Command(ToggleConfirmPassword);
|
||||
SubmitCommand = new Command(async () => await SubmitAsync());
|
||||
ShowTerms = !_platformUtilsService.IsSelfHost();
|
||||
PasswordStrengthViewModel = new PasswordStrengthViewModel(this);
|
||||
}
|
||||
|
||||
public ICommand PoliciesClickCommand => new Command<string>((url) =>
|
||||
@@ -61,6 +71,34 @@ namespace Bit.App.Pages
|
||||
get => _acceptPolicies;
|
||||
set => SetProperty(ref _acceptPolicies, value);
|
||||
}
|
||||
|
||||
public bool CheckExposedMasterPassword
|
||||
{
|
||||
get => _checkExposedMasterPassword;
|
||||
set => SetProperty(ref _checkExposedMasterPassword, value);
|
||||
}
|
||||
|
||||
public string MasterPassword
|
||||
{
|
||||
get => _masterPassword;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _masterPassword, value);
|
||||
PasswordStrengthViewModel.CalculatePasswordStrength();
|
||||
}
|
||||
}
|
||||
|
||||
public string Email
|
||||
{
|
||||
get => _email;
|
||||
set => SetProperty(ref _email, value);
|
||||
}
|
||||
|
||||
public string Password => MasterPassword;
|
||||
public List<string> UserInputs => PasswordStrengthViewModel.GetPasswordStrengthUserInput(Email);
|
||||
public string MasterPasswordMininumCharactersDescription => string.Format(AppResources.YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum,
|
||||
Constants.MasterPasswordMinimumChars);
|
||||
public PasswordStrengthViewModel PasswordStrengthViewModel { get; }
|
||||
public bool ShowTerms { get; set; }
|
||||
public Command SubmitCommand { get; }
|
||||
public Command TogglePasswordCommand { get; }
|
||||
@@ -68,13 +106,10 @@ namespace Bit.App.Pages
|
||||
public string ShowPasswordIcon => ShowPassword ? BitwardenIcons.EyeSlash : BitwardenIcons.Eye;
|
||||
public string PasswordVisibilityAccessibilityText => ShowPassword ? AppResources.PasswordIsVisibleTapToHide : AppResources.PasswordIsNotVisibleTapToShow;
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string MasterPassword { get; set; }
|
||||
public string ConfirmMasterPassword { get; set; }
|
||||
public string Hint { get; set; }
|
||||
public Action RegistrationSuccess { get; set; }
|
||||
public Action CloseAction { get; set; }
|
||||
|
||||
protected override II18nService i18nService => _i18nService;
|
||||
protected override IEnvironmentService environmentService => _environmentService;
|
||||
protected override IDeviceActionService deviceActionService => _deviceActionService;
|
||||
@@ -110,7 +145,7 @@ namespace Bit.App.Pages
|
||||
AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
if (MasterPassword.Length < 8)
|
||||
if (MasterPassword.Length < Constants.MasterPasswordMinimumChars)
|
||||
{
|
||||
await _platformUtilsService.ShowDialogAsync(AppResources.MasterPasswordLengthValMessage,
|
||||
AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
@@ -128,8 +163,10 @@ namespace Bit.App.Pages
|
||||
AppResources.AnErrorHasOccurred, AppResources.Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Password strength check?
|
||||
if (await IsPasswordWeakOrExposed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (showLoading)
|
||||
{
|
||||
@@ -139,8 +176,7 @@ namespace Bit.App.Pages
|
||||
Name = string.IsNullOrWhiteSpace(Name) ? null : Name;
|
||||
Email = Email.Trim().ToLower();
|
||||
var kdf = KdfType.PBKDF2_SHA256;
|
||||
var kdfIterations = 100_000;
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, Email, kdf, kdfIterations);
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, Email, kdf, Constants.KdfIterations);
|
||||
var encKey = await _cryptoService.MakeEncKeyAsync(key);
|
||||
var hashedPassword = await _cryptoService.HashPasswordAsync(MasterPassword, key);
|
||||
var keys = await _cryptoService.MakeKeyPairAsync(encKey.Item1);
|
||||
@@ -152,7 +188,7 @@ namespace Bit.App.Pages
|
||||
MasterPasswordHint = Hint,
|
||||
Key = encKey.Item2.EncryptedString,
|
||||
Kdf = kdf,
|
||||
KdfIterations = kdfIterations,
|
||||
KdfIterations = Constants.KdfIterations,
|
||||
Keys = new KeysRequest
|
||||
{
|
||||
PublicKey = keys.Item1,
|
||||
@@ -160,6 +196,7 @@ namespace Bit.App.Pages
|
||||
},
|
||||
CaptchaResponse = _captchaToken,
|
||||
};
|
||||
|
||||
// TODO: org invite?
|
||||
|
||||
try
|
||||
@@ -208,5 +245,43 @@ namespace Bit.App.Pages
|
||||
entry.Focus();
|
||||
entry.CursorPosition = String.IsNullOrEmpty(ConfirmMasterPassword) ? 0 : ConfirmMasterPassword.Length;
|
||||
}
|
||||
|
||||
private async Task<bool> IsPasswordWeakOrExposed()
|
||||
{
|
||||
try
|
||||
{
|
||||
var title = string.Empty;
|
||||
var message = string.Empty;
|
||||
var exposedPassword = CheckExposedMasterPassword ? await _auditService.PasswordLeakedAsync(MasterPassword) > 0 : false;
|
||||
var weakPassword = PasswordStrengthViewModel.PasswordStrengthLevel <= PasswordStrengthLevel.Weak;
|
||||
|
||||
if (exposedPassword && weakPassword)
|
||||
{
|
||||
title = AppResources.WeakAndExposedMasterPassword;
|
||||
message = AppResources.WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription;
|
||||
}
|
||||
else if (exposedPassword)
|
||||
{
|
||||
title = AppResources.ExposedMasterPassword;
|
||||
message = AppResources.PasswordFoundInADataBreachAlertDescription;
|
||||
}
|
||||
else if (weakPassword)
|
||||
{
|
||||
title = AppResources.WeakMasterPassword;
|
||||
message = AppResources.WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount;
|
||||
}
|
||||
|
||||
if (exposedPassword || weakPassword)
|
||||
{
|
||||
return !await _platformUtilsService.ShowDialogAsync(message, title, AppResources.Yes, AppResources.No);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
HandleException(ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Resources;
|
||||
using Bit.App.Utilities;
|
||||
using Bit.Core;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Enums;
|
||||
@@ -137,8 +138,8 @@ namespace Bit.App.Pages
|
||||
}
|
||||
if (IsPolicyInEffect)
|
||||
{
|
||||
var userInput = await GetPasswordStrengthUserInput();
|
||||
var passwordStrength = _passwordGenerationService.PasswordStrength(MasterPassword, userInput);
|
||||
var userInputs = _passwordGenerationService.GetPasswordStrengthUserInput(await _stateService.GetEmailAsync());
|
||||
var passwordStrength = _passwordGenerationService.PasswordStrength(MasterPassword, userInputs);
|
||||
if (!await _policyService.EvaluateMasterPassword(passwordStrength.Score, MasterPassword, Policy))
|
||||
{
|
||||
await Page.DisplayAlert(AppResources.MasterPasswordPolicyValidationTitle,
|
||||
@@ -148,7 +149,7 @@ namespace Bit.App.Pages
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MasterPassword.Length < 8)
|
||||
if (MasterPassword.Length < Constants.MasterPasswordMinimumChars)
|
||||
{
|
||||
await Page.DisplayAlert(AppResources.MasterPasswordPolicyValidationTitle,
|
||||
AppResources.MasterPasswordLengthValMessage, AppResources.Ok);
|
||||
@@ -163,9 +164,8 @@ namespace Bit.App.Pages
|
||||
}
|
||||
|
||||
var kdf = KdfType.PBKDF2_SHA256;
|
||||
var kdfIterations = 100000;
|
||||
var email = await _stateService.GetEmailAsync();
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, kdfIterations);
|
||||
var key = await _cryptoService.MakeKeyAsync(MasterPassword, email, kdf, Constants.KdfIterations);
|
||||
var masterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.ServerAuthorization);
|
||||
var localMasterPasswordHash = await _cryptoService.HashPasswordAsync(MasterPassword, key, HashPurpose.LocalAuthorization);
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace Bit.App.Pages
|
||||
Key = encKey.Item2.EncryptedString,
|
||||
MasterPasswordHint = Hint,
|
||||
Kdf = kdf,
|
||||
KdfIterations = kdfIterations,
|
||||
KdfIterations = Constants.KdfIterations,
|
||||
OrgIdentifier = OrgIdentifier,
|
||||
Keys = new KeysRequest
|
||||
{
|
||||
@@ -202,7 +202,7 @@ namespace Bit.App.Pages
|
||||
// Set Password and relevant information
|
||||
await _apiService.SetPasswordAsync(request);
|
||||
await _stateService.SetKdfTypeAsync(kdf);
|
||||
await _stateService.SetKdfIterationsAsync(kdfIterations);
|
||||
await _stateService.SetKdfIterationsAsync(Constants.KdfIterations);
|
||||
await _cryptoService.SetKeyAsync(key);
|
||||
await _cryptoService.SetKeyHashAsync(localMasterPasswordHash);
|
||||
await _cryptoService.SetEncKeyAsync(encKey.Item2.EncryptedString);
|
||||
|
||||
@@ -129,8 +129,8 @@ namespace Bit.App.Pages
|
||||
{
|
||||
if (useCurrentActiveAccount)
|
||||
{
|
||||
return new AvatarImageSource(await _stateService.GetActiveUserIdAsync(),
|
||||
await _stateService.GetNameAsync(), await _stateService.GetEmailAsync());
|
||||
var user = await _stateService.GetActiveUserCustomDataAsync(a => (a?.Profile?.UserId, a?.Profile?.Name, a?.Profile?.Email, a?.Profile?.AvatarColor));
|
||||
return new AvatarImageSource(user.UserId, user.Name, user.Email, user.AvatarColor);
|
||||
}
|
||||
return new AvatarImageSource();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Bit.App.Abstractions;
|
||||
using Bit.App.Controls;
|
||||
using Bit.App.Resources;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Services;
|
||||
using Bit.Core.Utilities;
|
||||
using Xamarin.Forms;
|
||||
@@ -33,6 +34,11 @@ namespace Bit.App.Pages
|
||||
|
||||
protected void HandleException(Exception ex, string message = null)
|
||||
{
|
||||
if (ex is ApiException apiException && apiException.Error != null)
|
||||
{
|
||||
message = apiException.Error.GetSingleMessage();
|
||||
}
|
||||
|
||||
Xamarin.Essentials.MainThread.InvokeOnMainThreadAsync(async () =>
|
||||
{
|
||||
await _deviceActionService.Value.HideLoadingAsync();
|
||||
|
||||
@@ -139,6 +139,7 @@ namespace Bit.App.Pages
|
||||
new KeyValuePair<string, string>(AppResources.Mr, AppResources.Mr),
|
||||
new KeyValuePair<string, string>(AppResources.Mrs, AppResources.Mrs),
|
||||
new KeyValuePair<string, string>(AppResources.Ms, AppResources.Ms),
|
||||
new KeyValuePair<string, string>(AppResources.Mx, AppResources.Mx),
|
||||
new KeyValuePair<string, string>(AppResources.Dr, AppResources.Dr),
|
||||
};
|
||||
FolderOptions = new List<KeyValuePair<string, string>>();
|
||||
|
||||
@@ -108,6 +108,10 @@ namespace Bit.App.Pages
|
||||
else if (message.Command == "syncCompleted")
|
||||
{
|
||||
await Task.Delay(500);
|
||||
if (_vm.MainPage)
|
||||
{
|
||||
_vm.AvatarImageSource = await GetAvatarImageSourceAsync();
|
||||
}
|
||||
Device.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
IsBusy = false;
|
||||
|
||||
121
src/App/Resources/AppResources.Designer.cs
generated
@@ -1372,6 +1372,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Check known data breaches for this password.
|
||||
/// </summary>
|
||||
public static string CheckKnownDataBreachesForThisPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("CheckKnownDataBreachesForThisPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Check if password has been exposed..
|
||||
/// </summary>
|
||||
@@ -2416,6 +2425,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Exposed Master Password.
|
||||
/// </summary>
|
||||
public static string ExposedMasterPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("ExposedMasterPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Extension activated!.
|
||||
/// </summary>
|
||||
@@ -2938,6 +2956,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Good.
|
||||
/// </summary>
|
||||
public static string Good {
|
||||
get {
|
||||
return ResourceManager.GetString("Good", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Go to my vault.
|
||||
/// </summary>
|
||||
@@ -3073,6 +3100,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Important.
|
||||
/// </summary>
|
||||
public static string Important {
|
||||
get {
|
||||
return ResourceManager.GetString("Important", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Import items.
|
||||
/// </summary>
|
||||
@@ -3947,7 +3983,18 @@ namespace Bit.App.Resources {
|
||||
return ResourceManager.GetString("Ms", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Mx.
|
||||
/// </summary>
|
||||
public static string Mx
|
||||
{
|
||||
get
|
||||
{
|
||||
return ResourceManager.GetString("Mx", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You must log into the main Bitwarden app before you can use the extension..
|
||||
/// </summary>
|
||||
@@ -4570,6 +4617,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?.
|
||||
/// </summary>
|
||||
public static string PasswordFoundInADataBreachAlertDescription {
|
||||
get {
|
||||
return ResourceManager.GetString("PasswordFoundInADataBreachAlertDescription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Password generated.
|
||||
/// </summary>
|
||||
@@ -5669,6 +5725,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Strong.
|
||||
/// </summary>
|
||||
public static string Strong {
|
||||
get {
|
||||
return ResourceManager.GetString("Strong", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Submit.
|
||||
/// </summary>
|
||||
@@ -6650,6 +6715,51 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Weak.
|
||||
/// </summary>
|
||||
public static string Weak {
|
||||
get {
|
||||
return ResourceManager.GetString("Weak", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Weak and Exposed Master Password.
|
||||
/// </summary>
|
||||
public static string WeakAndExposedMasterPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("WeakAndExposedMasterPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Weak Master Password.
|
||||
/// </summary>
|
||||
public static string WeakMasterPassword {
|
||||
get {
|
||||
return ResourceManager.GetString("WeakMasterPassword", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?.
|
||||
/// </summary>
|
||||
public static string WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription {
|
||||
get {
|
||||
return ResourceManager.GetString("WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Weak password identified. Use a strong password to protect your account. Are you sure you want to use a weak password?.
|
||||
/// </summary>
|
||||
public static string WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount {
|
||||
get {
|
||||
return ResourceManager.GetString("WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Website.
|
||||
/// </summary>
|
||||
@@ -6767,6 +6877,15 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Your master password cannot be recovered if you forget it! {0} characters minimum..
|
||||
/// </summary>
|
||||
public static string YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum {
|
||||
get {
|
||||
return ResourceManager.GetString("YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to To continue, hold your YubiKey NEO against the back of the device or insert your YubiKey into your device's USB port, then touch its button..
|
||||
/// </summary>
|
||||
|
||||
@@ -1576,7 +1576,7 @@ Skandering gebeur outomaties.</value>
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Solarized Dark</value>
|
||||
<value>'Solarized' Donker</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
@@ -2450,7 +2450,7 @@ kies u Voeg TOTP toe om die sleutel veilig te bewaar</value>
|
||||
<value>Lukraak</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Koppel aan horlosie</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Toeganklikheidsdiensopenbaarmaking</value>
|
||||
@@ -2468,50 +2468,50 @@ kies u Voeg TOTP toe om die sleutel veilig te bewaar</value>
|
||||
<value>Aantekenversoek het reeds verstryk.</value>
|
||||
</data>
|
||||
<data name="LoginAttemptFromXDoYouWantToSwitchToThisAccount" xml:space="preserve">
|
||||
<value>Login attempt from:
|
||||
<value>Teken Aan probeerslag van:
|
||||
{0}
|
||||
Do you want to switch to this account?</value>
|
||||
Wil u na die rekening omskakel?</value>
|
||||
</data>
|
||||
<data name="NewAroundHere" xml:space="preserve">
|
||||
<value>New around here?</value>
|
||||
<value>Nuut hier?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Get master password hint</value>
|
||||
<value>Kry hoofwagwoord wenk</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logging in as {0}</value>
|
||||
<value>Teken in as {0}</value>
|
||||
</data>
|
||||
<data name="NotYou" xml:space="preserve">
|
||||
<value>Not you?</value>
|
||||
<value>Nie jy nie?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Log in with master password</value>
|
||||
<value>Teken aan met hoofwagwoord</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Log In with another device</value>
|
||||
<value>Teken Aan met 'n ander toestel</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
<value>Aanmelding begin</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
<value>'n Kennisgewing was gestuur na u toestel.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
<value>Asseblief maak seker jou kluis is oopgesluit en die vingerafdruk frase stem ooreen op die ander toestel.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
<value>Stuur kennisgewing weer</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
<value>Is daar nog 'n opsie nodig?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
<value>Wys alle aanmeldings opsies</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
<value>Hierdie versoek is nie langer gelding nie</value>
|
||||
</data>
|
||||
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
|
||||
<value>Enable camera permission to use the scanner</value>
|
||||
<value>Laat die kamera versoek toe om die skandeerder te gebruik</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -118,17 +118,17 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="About" xml:space="preserve">
|
||||
<value>حول</value>
|
||||
<value>عن التطبيق</value>
|
||||
</data>
|
||||
<data name="Add" xml:space="preserve">
|
||||
<value>إضافة</value>
|
||||
<value>أضِف</value>
|
||||
<comment>Add/create a new entity (verb).</comment>
|
||||
</data>
|
||||
<data name="AddFolder" xml:space="preserve">
|
||||
<value>إضافة مجلد</value>
|
||||
<value>مجلد مضاف</value>
|
||||
</data>
|
||||
<data name="AddItem" xml:space="preserve">
|
||||
<value>إضافة عنصر</value>
|
||||
<value>تمت إضافة العنصر</value>
|
||||
<comment>The title for the add item page.</comment>
|
||||
</data>
|
||||
<data name="AnErrorHasOccurred" xml:space="preserve">
|
||||
@@ -2451,7 +2451,7 @@
|
||||
<value>عشوائي</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>متّصل بالسّاعة</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>كشف خدمة إمكانية الوصول</value>
|
||||
|
||||
@@ -2137,7 +2137,7 @@ Skan prosesi avtomatik baş tutacaq.</value>
|
||||
<value>Bu təşkilat, sizi "parol sıfırlama"da avtomatik olaraq qeydiyyata alan müəssisə siyasətinə sahibdir. Qeydiyyat, təşkilat administratorlarına ana parolunuzu dəyişdirmə icazəsi verəcək.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Təşkilatınızın siyasətləri, anbarınızın vaxt bitişinə təsir edir. Anbar vaxt bitişi üçün icazə verilən maksimum vaxt $HOURS$ saat $MINUTES$ dəqiqədir</value>
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Anbar vaxt bitişi, təşkilatınız tərəfindən tənzimlənən məhdudiyyətləri aşır.</value>
|
||||
|
||||
@@ -1575,7 +1575,7 @@
|
||||
<comment>'Nord' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SolarizedDark" xml:space="preserve">
|
||||
<value>Цёмная Solarized</value>
|
||||
<value>Solarized Dark</value>
|
||||
<comment>'Solarized Dark' is the name of a specific color scheme. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="AutofillBlockedUris" xml:space="preserve">
|
||||
|
||||
@@ -300,7 +300,7 @@
|
||||
<comment>The title for the vault page.</comment>
|
||||
</data>
|
||||
<data name="Authenticator" xml:space="preserve">
|
||||
<value>Authenticator</value>
|
||||
<value>Удостоверител</value>
|
||||
<comment>Authenticator TOTP feature</comment>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
@@ -2080,7 +2080,7 @@
|
||||
<value>Това действие е защитено. За да продължите, въведете отново главната си парола, за да потвърдите самоличността си.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Captcha required</value>
|
||||
<value>Адресът за hCaptcha е задължителен</value>
|
||||
</data>
|
||||
<data name="CaptchaFailed" xml:space="preserve">
|
||||
<value>
|
||||
@@ -2267,7 +2267,7 @@
|
||||
<value>Всички</value>
|
||||
</data>
|
||||
<data name="Totp" xml:space="preserve">
|
||||
<value>TOTP</value>
|
||||
<value>Кода за потвърждаване</value>
|
||||
</data>
|
||||
<data name="VerificationCodes" xml:space="preserve">
|
||||
<value>Кодове за потвърждаване</value>
|
||||
@@ -2291,10 +2291,10 @@
|
||||
<value>Ръчно въвеждане на кода</value>
|
||||
</data>
|
||||
<data name="AddTotp" xml:space="preserve">
|
||||
<value>Add TOTP</value>
|
||||
<value>Копиране на кода за потвърждаване</value>
|
||||
</data>
|
||||
<data name="SetupTotp" xml:space="preserve">
|
||||
<value>Set up TOTP</value>
|
||||
<value>Копиране на кода за потвърждаване</value>
|
||||
</data>
|
||||
<data name="OnceTheKeyIsSuccessfullyEntered" xml:space="preserve">
|
||||
<value>Once the key is successfully entered,
|
||||
@@ -2334,7 +2334,7 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Време</value>
|
||||
</data>
|
||||
<data name="Near" xml:space="preserve">
|
||||
<value>Near</value>
|
||||
<value>Близо</value>
|
||||
</data>
|
||||
<data name="ConfirmLogIn" xml:space="preserve">
|
||||
<value>Потвърждаване на вписването</value>
|
||||
@@ -2385,13 +2385,13 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Тип потребителско име</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Plus addressed email</value>
|
||||
<value>Адрес на е-поща с плюс</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Catch-all email</value>
|
||||
<value>Хващаща всичко е-поща</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Forwarded email alias</value>
|
||||
<value>Псевдоним на препратена е-поща</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Произволна дума</value>
|
||||
@@ -2430,7 +2430,7 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Генериране на потр. име</value>
|
||||
</data>
|
||||
<data name="EmailType" xml:space="preserve">
|
||||
<value>Email Type</value>
|
||||
<value>Вид е-поща</value>
|
||||
</data>
|
||||
<data name="WebsiteRequired" xml:space="preserve">
|
||||
<value>Уеб сайт (задължително)</value>
|
||||
@@ -2442,10 +2442,10 @@ select Add TOTP to store the key safely</value>
|
||||
<value>Използвайте възможностите за под-адресиране на е-поща на своя доставчик</value>
|
||||
</data>
|
||||
<data name="CatchAllEmailDescription" xml:space="preserve">
|
||||
<value>Use your domain's configured catch-all inbox.</value>
|
||||
<value>Използвайте конфигурираната входяща кутия за събиране на всичко.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Generate an email alias with an external forwarding service.</value>
|
||||
<value>Създайте псевдоним на е-поща с външна услуга за препращане.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Произволно</value>
|
||||
|
||||
@@ -1412,7 +1412,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Nema kolekcija za prikazati.</value>
|
||||
</data>
|
||||
<data name="MovedItemToOrg" xml:space="preserve">
|
||||
<value>premješteno u</value>
|
||||
<value>{0} moved to {1}.</value>
|
||||
<comment>ex: Item moved to Organization.</comment>
|
||||
</data>
|
||||
<data name="ItemShared" xml:space="preserve">
|
||||
|
||||
@@ -556,7 +556,7 @@
|
||||
<value>Temps d'espera de la caixa forta</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutAction" xml:space="preserve">
|
||||
<value>Acció del temps d'espera de la caixa forta</value>
|
||||
<value>Acció quan acabe el temps d'espera de la caixa forta</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
|
||||
<value>En tancar la sessió s'eliminarà tot l'accés a la vostra caixa forta i es requerirà una autenticació en línia després del període de temps d'espera. Esteu segur que voleu utilitzar aquesta configuració?</value>
|
||||
@@ -2450,7 +2450,7 @@ seleccioneu Afegeix TOTP per emmagatzemar la clau de manera segura</value>
|
||||
<value>Aleatori</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Connecta't a Watch</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Divulgació del servei d'accessibilitat</value>
|
||||
|
||||
@@ -2450,7 +2450,7 @@
|
||||
<value>Τυχαίο</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Σύνδεση με το ρολόι</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Γνωστοποίηση Υπηρεσίας Προσβασιμότητας</value>
|
||||
|
||||
@@ -1486,7 +1486,7 @@ El escaneo se realizará automáticamente.</value>
|
||||
<value>30 minutos</value>
|
||||
</data>
|
||||
<data name="SetPINDescription" xml:space="preserve">
|
||||
<value>Establece su código PIN para desbloquear Bitwarden. Sus ajustes de PIN se reiniciarán si alguna vez cierra su sesión completamente de la aplicación.</value>
|
||||
<value>Establezca su código PIN para desbloquear Bitwarden. Sus ajustes de PIN se reiniciarán si alguna vez cierra su sesión completamente de la aplicación.</value>
|
||||
</data>
|
||||
<data name="LoggedInAsOn" xml:space="preserve">
|
||||
<value>Iniciado como {0} en {1}.</value>
|
||||
@@ -1783,7 +1783,7 @@ El escaneo se realizará automáticamente.</value>
|
||||
<value>Una o más políticas de la organización requieren que su contraseña maestra cumpla con los siguientes requisitos:</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
|
||||
<value>Puntuación mínima de complejidad de $SCORE$</value>
|
||||
<value>Minimum complexity score of {0}</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectMinLength" xml:space="preserve">
|
||||
<value>Longitud mínima de {0}</value>
|
||||
@@ -1798,7 +1798,7 @@ El escaneo se realizará automáticamente.</value>
|
||||
<value>Contiene uno o más números</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectSpecial" xml:space="preserve">
|
||||
<value>Contiene uno o más de los siguientes caracteres especiales $CHARS$</value>
|
||||
<value>Contain one or more of the following special characters: {0}</value>
|
||||
</data>
|
||||
<data name="MasterPasswordPolicyValidationTitle" xml:space="preserve">
|
||||
<value>Contraseña no válida</value>
|
||||
@@ -2358,7 +2358,7 @@ seleccione Agregar TOTP para almacenar la clave de forma segura</value>
|
||||
<value>Aprobar solicitudes de inicio de sesión</value>
|
||||
</data>
|
||||
<data name="UseThisDeviceToApproveLoginRequestsMadeFromOtherDevices" xml:space="preserve">
|
||||
<value>Use este dispositivo para aprovar solicitudes de incio de sesión realizadas desde otros dispositivos.</value>
|
||||
<value>Use este dispositivo para aprobar solicitudes de inicio de sesión realizadas desde otros dispositivos.</value>
|
||||
</data>
|
||||
<data name="AllowNotifications" xml:space="preserve">
|
||||
<value>Permitir notificaciones</value>
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
<value>Modifier</value>
|
||||
</data>
|
||||
<data name="EditFolder" xml:space="preserve">
|
||||
<value>Modifier le dossier</value>
|
||||
<value>Éditer le dossier</value>
|
||||
</data>
|
||||
<data name="Email" xml:space="preserve">
|
||||
<value>E-mail</value>
|
||||
@@ -209,7 +209,7 @@
|
||||
<value>Ouvrir un ticket dans notre dépôt Github.</value>
|
||||
</data>
|
||||
<data name="FingerprintDirection" xml:space="preserve">
|
||||
<value>Utilisez votre empreinte pour vous authentifier.</value>
|
||||
<value>Utilisez votre empreinte pour vérifier.</value>
|
||||
</data>
|
||||
<data name="Folder" xml:space="preserve">
|
||||
<value>Dossier</value>
|
||||
@@ -229,7 +229,7 @@
|
||||
<value>Dossiers</value>
|
||||
</data>
|
||||
<data name="FolderUpdated" xml:space="preserve">
|
||||
<value>Dossier mis à jour.</value>
|
||||
<value>Dossier sauvegardé</value>
|
||||
</data>
|
||||
<data name="GoToWebsite" xml:space="preserve">
|
||||
<value>Accéder au site Web</value>
|
||||
@@ -243,7 +243,7 @@
|
||||
<comment>Hide a secret value that is currently shown (password).</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredMessage" xml:space="preserve">
|
||||
<value>Veuillez vous connecter à Internet avant de poursuivre.</value>
|
||||
<value>Veuillez vous connecter à internet avant de continuer.</value>
|
||||
<comment>Description message for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InternetConnectionRequiredTitle" xml:space="preserve">
|
||||
@@ -251,7 +251,7 @@
|
||||
<comment>Title for the alert when internet connection is required to continue.</comment>
|
||||
</data>
|
||||
<data name="InvalidMasterPassword" xml:space="preserve">
|
||||
<value>Mot de passe maître invalide. Veuillez réessayer.</value>
|
||||
<value>Mot de passe principal invalide. Essayez à nouveau.</value>
|
||||
</data>
|
||||
<data name="InvalidPIN" xml:space="preserve">
|
||||
<value>Code PIN invalide. Veuillez réessayer.</value>
|
||||
@@ -269,7 +269,7 @@
|
||||
<comment>Title for login page. (noun)</comment>
|
||||
</data>
|
||||
<data name="LogOut" xml:space="preserve">
|
||||
<value>Déconnexion</value>
|
||||
<value>Se déconnecter</value>
|
||||
<comment>The log out button text (verb).</comment>
|
||||
</data>
|
||||
<data name="LogoutConfirmation" xml:space="preserve">
|
||||
@@ -279,7 +279,7 @@
|
||||
<value>Supprimer le compte</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Êtes-vous sûr de vouloir retirer ce compte ?</value>
|
||||
<value>Êtes-vous sûr de vouloir supprimer ce compte ?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Le compte a déjà été ajouté</value>
|
||||
@@ -288,7 +288,7 @@
|
||||
<value>Souhaitez-vous y passer maintenant ?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Mot de passe maître</value>
|
||||
<value>Mot de passe principal</value>
|
||||
<comment>Label for a master password.</comment>
|
||||
</data>
|
||||
<data name="More" xml:space="preserve">
|
||||
@@ -342,7 +342,7 @@
|
||||
<comment>Reveal a hidden value (password).</comment>
|
||||
</data>
|
||||
<data name="ItemDeleted" xml:space="preserve">
|
||||
<value>L'élément a été supprimé.</value>
|
||||
<value>Élément supprimé</value>
|
||||
<comment>Confirmation message after successfully deleting a login.</comment>
|
||||
</data>
|
||||
<data name="Submit" xml:space="preserve">
|
||||
@@ -364,7 +364,7 @@
|
||||
<comment>Label for a uri/url.</comment>
|
||||
</data>
|
||||
<data name="UseFingerprintToUnlock" xml:space="preserve">
|
||||
<value>Utiliser votre empreinte pour déverrouiller</value>
|
||||
<value>Utiliser l'empreinte pour déverrouiller</value>
|
||||
</data>
|
||||
<data name="Username" xml:space="preserve">
|
||||
<value>Nom d'utilisateur</value>
|
||||
@@ -375,14 +375,14 @@
|
||||
<comment>Validation message for when a form field is left blank and is required to be entered.</comment>
|
||||
</data>
|
||||
<data name="ValueHasBeenCopied" xml:space="preserve">
|
||||
<value>{0} a été copié.</value>
|
||||
<value>{0} copié</value>
|
||||
<comment>Confirmation message after successfully copying a value to the clipboard.</comment>
|
||||
</data>
|
||||
<data name="VerifyFingerprint" xml:space="preserve">
|
||||
<value>S'authentifier avec l'empreinte</value>
|
||||
<value>Vérifier l'empreinte digitale</value>
|
||||
</data>
|
||||
<data name="VerifyMasterPassword" xml:space="preserve">
|
||||
<value>S'authentifier avec le mot de passe maître</value>
|
||||
<value>Vérifier le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="VerifyPIN" xml:space="preserve">
|
||||
<value>S'authentifier avec un code PIN</value>
|
||||
@@ -425,10 +425,10 @@
|
||||
<value>Service de remplissage automatique</value>
|
||||
</data>
|
||||
<data name="AvoidAmbiguousCharacters" xml:space="preserve">
|
||||
<value>Évitez les caractères ambigus</value>
|
||||
<value>Éviter les caractères ambigus</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtension" xml:space="preserve">
|
||||
<value>Extension de l'application bitwarden</value>
|
||||
<value>Extension de l'application Bitwarden</value>
|
||||
</data>
|
||||
<data name="BitwardenAppExtensionAlert2" xml:space="preserve">
|
||||
<value>Le meilleur moyen d'ajouter de nouveaux sites à votre coffre est d'utiliser l'extension de l'application Bitwarden. Parcourez le menu "Paramètres" pour en apprendre davantage.</value>
|
||||
@@ -449,10 +449,10 @@
|
||||
<value>Vous pouvez changer votre adresse e-mail depuis le coffre web sur bitwarden.com. Voulez-vous visiter le site web maintenant ?</value>
|
||||
</data>
|
||||
<data name="ChangeMasterPassword" xml:space="preserve">
|
||||
<value>Changer le mot de passe maître</value>
|
||||
<value>Changer le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="ChangePasswordConfirmation" xml:space="preserve">
|
||||
<value>Vous pouvez modifier votre mot de passe maître depuis le coffre web sur bitwarden.com. Souhaitez-vous visiter le site maintenant ?</value>
|
||||
<value>Vous pouvez changer votre mot de passe principal depuis le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?</value>
|
||||
</data>
|
||||
<data name="Close" xml:space="preserve">
|
||||
<value>Fermer</value>
|
||||
@@ -468,13 +468,13 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="EditItem" xml:space="preserve">
|
||||
<value>Modifier l'Élément</value>
|
||||
<value>Éditer l'élément</value>
|
||||
</data>
|
||||
<data name="EnableAutomaticSyncing" xml:space="preserve">
|
||||
<value>Activer la synchronisation automatique</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>Saisissez l'adresse e-mail de votre compte pour recevoir l'indice de votre mot de passe maître.</value>
|
||||
<value>Saisissez l'adresse électronique de votre compte pour recevoir l'indice de votre mot de passe principal.</value>
|
||||
</data>
|
||||
<data name="ExntesionReenable" xml:space="preserve">
|
||||
<value>Activez à nouveau l'extension de l'application</value>
|
||||
@@ -511,13 +511,13 @@
|
||||
<value>Favori</value>
|
||||
</data>
|
||||
<data name="Fingerprint" xml:space="preserve">
|
||||
<value>Empreinte</value>
|
||||
<value>Empreinte digitale</value>
|
||||
</data>
|
||||
<data name="GeneratePassword" xml:space="preserve">
|
||||
<value>Générer un mot de passe</value>
|
||||
</data>
|
||||
<data name="GetPasswordHint" xml:space="preserve">
|
||||
<value>Obtenir votre indice de mot de passe maître</value>
|
||||
<value>Obtenez votre indice de mot de passe principal</value>
|
||||
</data>
|
||||
<data name="ImportItems" xml:space="preserve">
|
||||
<value>Importer des éléments</value>
|
||||
@@ -556,10 +556,10 @@
|
||||
<value>Délai d'expiration du coffre</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutAction" xml:space="preserve">
|
||||
<value>Action lors de l'expiration du délai du coffre</value>
|
||||
<value>Après délai d'expiration du coffre</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutLogOutConfirmation" xml:space="preserve">
|
||||
<value>La déconnexion supprimera tous les accès à votre coffre et nécessite une authentification en ligne après la période d'expiration. Êtes-vous sûr de vouloir utiliser ce paramètre ?</value>
|
||||
<value>La déconnexion supprimera tout accès à votre coffre et nécessitera une authentification en ligne après la période d'expiration. Êtes-vous sûr de vouloir utiliser ce paramètre ?</value>
|
||||
</data>
|
||||
<data name="LoggingIn" xml:space="preserve">
|
||||
<value>Identification...</value>
|
||||
@@ -575,23 +575,23 @@
|
||||
<value>La confirmation du mot de passe est erronée.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordDescription" xml:space="preserve">
|
||||
<value>Le mot de passe maître correspond au mot de passe utilisé pour accéder à votre coffre. Il est très important de ne pas l'oublier. Il n'existe aucun moyen de le retrouver en cas d'oubli.</value>
|
||||
<value>Le mot de passe principal est le mot de passe que vous utilisez pour accéder à votre coffre. Il est très important de ne pas oublier votre mot de passe principal. Il n'existe aucun moyen de récupérer le mot de passe si vous l'oubliez.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHint" xml:space="preserve">
|
||||
<value>Indice de mot de passe maître (facultatif)</value>
|
||||
<value>Indice du mot de passe principal (facultatif)</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHintDescription" xml:space="preserve">
|
||||
<value>Un indice de mot de passe maître peut vous aider à vous rappeler de votre mot de passe en cas d'oubli.</value>
|
||||
<value>Un indice de mot de passe principal peut vous aider à vous souvenir de votre mot de passe si vous l'oubliez.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
|
||||
<value>Le mot de passe maître doit faire plus de 8 caractères.</value>
|
||||
<value>Le mot de passe principal doit comporter au moins 8 caractères.</value>
|
||||
</data>
|
||||
<data name="MinNumbers" xml:space="preserve">
|
||||
<value>Nombre minimum de chiffres</value>
|
||||
<value>Min. de chiffres</value>
|
||||
<comment>Minimum numeric characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MinSpecial" xml:space="preserve">
|
||||
<value>Nombre minimum de caractères spéciaux</value>
|
||||
<value>Min. de caractères spéciaux</value>
|
||||
<comment>Minimum special characters for password generator settings</comment>
|
||||
</data>
|
||||
<data name="MoreSettings" xml:space="preserve">
|
||||
@@ -613,7 +613,7 @@
|
||||
<value>Il n’y a aucun élément dans votre coffre.</value>
|
||||
</data>
|
||||
<data name="NoItemsTap" xml:space="preserve">
|
||||
<value>Il n’y a aucun élément dans votre coffre pour ce site. Appuyer pour en ajouter un.</value>
|
||||
<value>Il n’y a aucun élément dans votre coffre pour ce site web/app. Appuyer pour en ajouter un.</value>
|
||||
</data>
|
||||
<data name="NoUsernamePasswordConfigured" xml:space="preserve">
|
||||
<value>Cet identifiant n'a aucun nom d'utilisateur ou mot de passe associé.</value>
|
||||
@@ -660,7 +660,7 @@
|
||||
<value>Regénérer un mot de passe</value>
|
||||
</data>
|
||||
<data name="RetypeMasterPassword" xml:space="preserve">
|
||||
<value>Saisir à nouveau le mot de passe maître</value>
|
||||
<value>Ressaisir le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="SearchVault" xml:space="preserve">
|
||||
<value>Recherche dans le coffre</value>
|
||||
@@ -681,7 +681,7 @@
|
||||
<value>Informations sur l'élément</value>
|
||||
</data>
|
||||
<data name="ItemUpdated" xml:space="preserve">
|
||||
<value>Élément mis à jour.</value>
|
||||
<value>Élément sauvegardé</value>
|
||||
</data>
|
||||
<data name="Submitting" xml:space="preserve">
|
||||
<value>Soumission...</value>
|
||||
@@ -692,10 +692,10 @@
|
||||
<comment>Message shown when interacting with the server</comment>
|
||||
</data>
|
||||
<data name="SyncingComplete" xml:space="preserve">
|
||||
<value>Synchronisation terminée.</value>
|
||||
<value>Synchronisation terminée</value>
|
||||
</data>
|
||||
<data name="SyncingFailed" xml:space="preserve">
|
||||
<value>Échec de la synchronisation.</value>
|
||||
<value>Échec de la synchronisation</value>
|
||||
</data>
|
||||
<data name="SyncVaultNow" xml:space="preserve">
|
||||
<value>Synchroniser le coffre maintenant</value>
|
||||
@@ -705,10 +705,10 @@
|
||||
<comment>What Apple calls their fingerprint reader.</comment>
|
||||
</data>
|
||||
<data name="TwoStepLogin" xml:space="preserve">
|
||||
<value>Identification en deux étapes</value>
|
||||
<value>Authentification à deux facteurs</value>
|
||||
</data>
|
||||
<data name="TwoStepLoginConfirmation" xml:space="preserve">
|
||||
<value>L'authentification en deux étapes sécurise davantage votre compte en exigeant que chaque connexion soit confirmée par un autre dispositif tel qu'une clé de sécurité, une application d'authentification, un SMS, un appel téléphonique ou un courriel. Cette option peut être activée depuis le coffre web sur bitwarden.com. Voulez-vous y accéder maintenant ?</value>
|
||||
<value>L'authentification à deux facteurs rend votre compte plus sûr en vous demandant de vérifier votre connexion avec un autre dispositif tel qu'une clé de sécurité, une application d'authentification, un SMS, un appel téléphonique ou un courriel. L'authentification à deux facteurs peut être configurée sur le coffre web de bitwarden.com. Voulez-vous visiter le site web maintenant ?</value>
|
||||
</data>
|
||||
<data name="UnlockWith" xml:space="preserve">
|
||||
<value>Déverrouiller avec {0}</value>
|
||||
@@ -769,10 +769,10 @@
|
||||
<value>2. Activez l'option et appuyez sur OK pour accepter.</value>
|
||||
</data>
|
||||
<data name="Disabled" xml:space="preserve">
|
||||
<value>Désactivé</value>
|
||||
<value>Non</value>
|
||||
</data>
|
||||
<data name="Enabled" xml:space="preserve">
|
||||
<value>Activé</value>
|
||||
<value>Oui</value>
|
||||
</data>
|
||||
<data name="Off" xml:space="preserve">
|
||||
<value>Désactivé</value>
|
||||
@@ -831,14 +831,14 @@
|
||||
<comment>For 2FA whenever there are no available providers on this device.</comment>
|
||||
</data>
|
||||
<data name="NoTwoStepAvailable" xml:space="preserve">
|
||||
<value>Ce compte utilise l'authentification à double facteurs, mais aucun des services d'authentification à double facteurs n'est supporté sur cet appareil. Veuillez utiliser un appareil compatible et/ou ajouter des services supplémentaires qui sont mieux supportés sur les appareils (comme une application d'authentification).</value>
|
||||
<value>Ce compte a une authentification à deux facteurs configurée, mais aucun des fournisseurs d'authentification à deux facteurs configurés ne sont pris en charge sur cet appareil. Veuillez utiliser un appareil pris en charge et/ou ajouter des fournisseurs supplémentaires qui sont mieux pris en charge par les appareils (comme une application d'authentification).</value>
|
||||
</data>
|
||||
<data name="RecoveryCodeTitle" xml:space="preserve">
|
||||
<value>Code de récupération</value>
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="RememberMe" xml:space="preserve">
|
||||
<value>Rester connecté</value>
|
||||
<value>Se souvenir de moi</value>
|
||||
<comment>Remember my two-step login</comment>
|
||||
</data>
|
||||
<data name="SendVerificationCodeAgain" xml:space="preserve">
|
||||
@@ -846,10 +846,10 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="TwoStepLoginOptions" xml:space="preserve">
|
||||
<value>Options d'identification à double facteurs</value>
|
||||
<value>Options d'authentification à deux facteurs</value>
|
||||
</data>
|
||||
<data name="UseAnotherTwoStepMethod" xml:space="preserve">
|
||||
<value>Utiliser une autre méthode d'identification en deux étapes</value>
|
||||
<value>Utiliser une autre méthode d'authentification à deux facteurs</value>
|
||||
</data>
|
||||
<data name="VerificationEmailNotSent" xml:space="preserve">
|
||||
<value>Impossible d'envoyer l'e-mail de vérification. Essayez à nouveau.</value>
|
||||
@@ -922,7 +922,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Copier le code TOTP automatiquement</value>
|
||||
</data>
|
||||
<data name="PremiumRequired" xml:space="preserve">
|
||||
<value>Une adhésion premium est requise pour utiliser cette fonctionnalité.</value>
|
||||
<value>Une adhésion Premium est requise pour utiliser cette fonctionnalité.</value>
|
||||
</data>
|
||||
<data name="AttachementAdded" xml:space="preserve">
|
||||
<value>Pièce jointe ajoutée</value>
|
||||
@@ -1366,7 +1366,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Valeur</value>
|
||||
</data>
|
||||
<data name="PasswordHistory" xml:space="preserve">
|
||||
<value>Historique des mots de passe</value>
|
||||
<value>Historique du mot de passe</value>
|
||||
</data>
|
||||
<data name="Types" xml:space="preserve">
|
||||
<value>Types</value>
|
||||
@@ -1493,10 +1493,10 @@ La numérisation se fera automatiquement.</value>
|
||||
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="VaultLockedMasterPassword" xml:space="preserve">
|
||||
<value>Votre coffre est verrouillé. Saisissez votre mot de passe maître pour continuer.</value>
|
||||
<value>Votre coffre est verrouillé. Vérifiez votre mot de passe principal pour continuer.</value>
|
||||
</data>
|
||||
<data name="VaultLockedPIN" xml:space="preserve">
|
||||
<value>Votre coffre est verrouillé. Saisissez votre code PIN pour continuer.</value>
|
||||
<value>Votre coffre est verrouillé. Vérifiez votre code PIN pour continuer.</value>
|
||||
</data>
|
||||
<data name="VaultLockedIdentity" xml:space="preserve">
|
||||
<value>Votre coffre est verrouillé. Vérifiez votre identité pour continuer.</value>
|
||||
@@ -1565,7 +1565,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Êtes-vous sûr de vouloir quitter Bitwarden ?</value>
|
||||
</data>
|
||||
<data name="PINRequireMasterPasswordRestart" xml:space="preserve">
|
||||
<value>Voulez-vous avoir à déverrouiller avec votre mot de passe maître lorsque l'application est redémarrée ?</value>
|
||||
<value>Voulez-vous exiger le déverrouillage avec votre mot de passe principal lorsque l'application est redémarrée ?</value>
|
||||
</data>
|
||||
<data name="Black" xml:space="preserve">
|
||||
<value>Noir</value>
|
||||
@@ -1601,7 +1601,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Vos modifications de thème s'appliqueront lorsque l'application sera redémarrée.</value>
|
||||
</data>
|
||||
<data name="Capitalize" xml:space="preserve">
|
||||
<value>Mettre la première lettre de chaque mot en majuscule</value>
|
||||
<value>Mettre une majuscule</value>
|
||||
<comment>ex. Uppercase the first character of a word.</comment>
|
||||
</data>
|
||||
<data name="IncludeNumber" xml:space="preserve">
|
||||
@@ -1620,13 +1620,13 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Votre session a expiré.</value>
|
||||
</data>
|
||||
<data name="BiometricsDirection" xml:space="preserve">
|
||||
<value>Utiliser une empreinte biométrique pour vérifier.</value>
|
||||
<value>Vérification biométrique</value>
|
||||
</data>
|
||||
<data name="Biometrics" xml:space="preserve">
|
||||
<value>Empreintes biométriques</value>
|
||||
<value>Biométrie</value>
|
||||
</data>
|
||||
<data name="UseBiometricsToUnlock" xml:space="preserve">
|
||||
<value>Utiliser une empreinte biométrique pour déverrouiller</value>
|
||||
<value>Utiliser la biométrie pour déverrouiller</value>
|
||||
</data>
|
||||
<data name="AccessibilityOverlayPermissionAlert" xml:space="preserve">
|
||||
<value>Bitwarden requiert votre attention - Voir "Service d'accessibilité pour le remplissage automatique" dans les paramètres de Bitwarden</value>
|
||||
@@ -1653,7 +1653,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Format de fichier</value>
|
||||
</data>
|
||||
<data name="ExportVaultMasterPasswordDescription" xml:space="preserve">
|
||||
<value>Saisissez votre mot de passe maître pour exporter les données de votre coffre.</value>
|
||||
<value>Saisissez votre mot de passe principal pour exporter les données de votre coffre.</value>
|
||||
</data>
|
||||
<data name="SendVerificationCodeToEmail" xml:space="preserve">
|
||||
<value>Envoyer un code de vérification à votre adresse email</value>
|
||||
@@ -1750,10 +1750,10 @@ La numérisation se fera automatiquement.</value>
|
||||
<comment>Confirmation alert message when soft-deleting a cipher.</comment>
|
||||
</data>
|
||||
<data name="BiometricInvalidated" xml:space="preserve">
|
||||
<value>Le déverrouillage biométrique est désactivé en attendant la vérification du mot de passe maître.</value>
|
||||
<value>Déverrouillage biométrique désactivé dans l'attente de vérification du mot de passe principal.</value>
|
||||
</data>
|
||||
<data name="BiometricInvalidatedExtension" xml:space="preserve">
|
||||
<value>Le déverrouillage biométrique pour le remplissage automatique est désactivé en attendant la vérification du mot de passe maître.</value>
|
||||
<value>Déverrouillage biométrique pour la saisie automatique désactivé dans l'attente de vérification du mot de passe principal.</value>
|
||||
</data>
|
||||
<data name="EnableSyncOnRefresh" xml:space="preserve">
|
||||
<value>Activer la synchronisation lors de l'actualisation</value>
|
||||
@@ -1771,16 +1771,16 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Identifiant de l'organisation</value>
|
||||
</data>
|
||||
<data name="LoginSsoError" xml:space="preserve">
|
||||
<value>Impossible de se connecter avec SSO pour le moment</value>
|
||||
<value>Actuellement impossible de se connecter avec le SSO</value>
|
||||
</data>
|
||||
<data name="SetMasterPassword" xml:space="preserve">
|
||||
<value>Définir le mot de passe maître</value>
|
||||
<value>Définir le mot de passe principal</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>
|
||||
<value>Afin de finaliser la connexion avec SSO, veuillez définir un mot de passe principal pour accéder et protéger votre coffre.</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>
|
||||
<value>Une ou plusieurs politiques de l'organisation exigent que votre mot de passe principal réponde aux exigences suivantes :</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
|
||||
<value>Score de complexité minimum de {0}</value>
|
||||
@@ -2018,7 +2018,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendUpdated" xml:space="preserve">
|
||||
<value>Send mis à jour.</value>
|
||||
<value>Send sauvegardé</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NewSendCreated" xml:space="preserve">
|
||||
@@ -2063,7 +2063,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendFilePremiumRequired" xml:space="preserve">
|
||||
<value>Les comptes gratuits sont limités au partage de texte. Un abonnement premium est requis pour utiliser les fichiers avec Send.</value>
|
||||
<value>Les comptes gratuits sont limités au partage de texte uniquement. Une adhésion Premium est requise pour utiliser les fichiers avec Send.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendFileEmailVerificationRequired" xml:space="preserve">
|
||||
@@ -2071,13 +2071,13 @@ La numérisation se fera automatiquement.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="PasswordPrompt" xml:space="preserve">
|
||||
<value>Ressaisie du mot de passe maître</value>
|
||||
<value>Ressaisir le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="PasswordConfirmation" xml:space="preserve">
|
||||
<value>Confirmation du mot de passe maître</value>
|
||||
<value>Confirmation du mot de passe principal</value>
|
||||
</data>
|
||||
<data name="PasswordConfirmationDesc" xml:space="preserve">
|
||||
<value>Cette action est protégée. Pour continuer, veuillez ressaisir votre mot de passe maître pour vérifier votre identité.</value>
|
||||
<value>Cette action est protégée, pour continuer veuillez entrer à nouveau votre mot de passe principal pour vérifier votre identité.</value>
|
||||
</data>
|
||||
<data name="CaptchaRequired" xml:space="preserve">
|
||||
<value>Captcha obligatoire</value>
|
||||
@@ -2086,13 +2086,13 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Le captcha a échoué. Veuillez réessayer.</value>
|
||||
</data>
|
||||
<data name="UpdatedMasterPassword" xml:space="preserve">
|
||||
<value>Mot de passe maître mis à jour</value>
|
||||
<value>Mot de passe principal mis à jour</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPassword" xml:space="preserve">
|
||||
<value>Mettre à jour le mot de passe maître</value>
|
||||
<value>Mettre à jour le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="UpdateMasterPasswordWarning" xml:space="preserve">
|
||||
<value>Votre mot de passe maître a récemment été modifié par un administrateur de votre organisation. Pour accéder au coffre, vous devez mettre à jour votre mot de passe maître dès maintenant. Cette action va vous déconnecter et vous obligera à vous reconnecter. Les sessions actives sur d'autres appareils peuvent rester actives jusqu'à une heure.</value>
|
||||
<value>Votre mot de passe principal a été récemment changé par un administrateur de votre organisation. Pour pouvoir accéder au coffre, vous devez mettre à jour votre mot de passe principal maintenant. En poursuivant, vous serez déconnecté de votre session actuelle et vous devrez vous reconnecter. Les sessions actives sur d'autres appareils peuvent rester actives pendant encore une heure.</value>
|
||||
</data>
|
||||
<data name="UpdatingPassword" xml:space="preserve">
|
||||
<value>Mise à jour du mot de passe</value>
|
||||
@@ -2101,13 +2101,13 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Impossible de mettre à jour le mot de passe pour le moment</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPassword" xml:space="preserve">
|
||||
<value>Supprimer le mot de passe maître</value>
|
||||
<value>Supprimer le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning" xml:space="preserve">
|
||||
<value>{0} utilise le SSO avec un chiffrement géré par le client. En continuant, votre mot de passe maître sera supprimé de votre compte et vous devrez utiliser le SSO pour vous connecter.</value>
|
||||
<value>{0} utilise le SSO avec un chiffrement géré par le client. En continuant cela supprimera votre mot de passe principal de votre compte et exigera le SSO pour la connexion.</value>
|
||||
</data>
|
||||
<data name="RemoveMasterPasswordWarning2" xml:space="preserve">
|
||||
<value>Si vous ne souhaitez pas supprimer votre mot de passe maître actuel, vous pouvez quitter cette organisation. </value>
|
||||
<value>Si vous ne voulez pas supprimer votre mot de passe principal, vous pouvez quitter cette organisation.</value>
|
||||
</data>
|
||||
<data name="LeaveOrganization" xml:space="preserve">
|
||||
<value>Quitter l’organisation</value>
|
||||
@@ -2134,7 +2134,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Assurez-vous que votre navigateur par défaut prend en charge WebAuthn et réessayez.</value>
|
||||
</data>
|
||||
<data name="ResetPasswordAutoEnrollInviteWarning" xml:space="preserve">
|
||||
<value>Cette organisation a une politique d'entreprise qui vous inscrira automatiquement à la réinitialisation du mot de passe. L'inscription permettra aux administrateurs de l'organisation de changer votre mot de passe maître.</value>
|
||||
<value>Cette organisation dispose d'une politique d'entreprise qui vous inscrira automatiquement à la réinitialisation du mot de passe. L'inscription permettra aux administrateurs de l'organisation de changer votre mot de passe principal.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Les politiques de votre organisation affectent le délai d'expiration de votre coffre-fort. Le délai d'expiration maximal autorisé est de {0} heure(s) et {1} minute(s)</value>
|
||||
@@ -2218,7 +2218,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Saisissez le code de vérification que nous avons envoyé votre adresse e-mail</value>
|
||||
</data>
|
||||
<data name="SubmitCrashLogs" xml:space="preserve">
|
||||
<value>Envoyer le journal d'erreurs</value>
|
||||
<value>Envoyer les journaux de plantage</value>
|
||||
</data>
|
||||
<data name="SubmitCrashLogsDescription" xml:space="preserve">
|
||||
<value>Aidez Bitwarden à améliorer la stabilité de l'application en autorisant les rapports d'erreurs.</value>
|
||||
@@ -2254,7 +2254,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Filtrer les éléments par coffre</value>
|
||||
</data>
|
||||
<data name="AllVaults" xml:space="preserve">
|
||||
<value>Tous les Coffres</value>
|
||||
<value>Tous les coffres</value>
|
||||
</data>
|
||||
<data name="Vaults" xml:space="preserve">
|
||||
<value>Coffres</value>
|
||||
@@ -2293,7 +2293,7 @@ La numérisation se fera automatiquement.</value>
|
||||
<value>Ajouter un TOTP</value>
|
||||
</data>
|
||||
<data name="SetupTotp" xml:space="preserve">
|
||||
<value>Configurer le TOTP</value>
|
||||
<value>Configurer TOTP</value>
|
||||
</data>
|
||||
<data name="OnceTheKeyIsSuccessfullyEntered" xml:space="preserve">
|
||||
<value>Une fois que la clé est entrée avec succès,
|
||||
@@ -2381,22 +2381,22 @@ sélectionnez Ajouter TOTP pour stocker la clé en toute sécurité</value>
|
||||
<value>Que souhaitez-vous générer ?</value>
|
||||
</data>
|
||||
<data name="UsernameType" xml:space="preserve">
|
||||
<value>Type de Nom d'Utilisateur</value>
|
||||
<value>Type de nom d'utilisateur</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmail" xml:space="preserve">
|
||||
<value>Email prenant en charge le "plus-addressing"</value>
|
||||
<value>Courriel sous-adressé</value>
|
||||
</data>
|
||||
<data name="CatchAllEmail" xml:space="preserve">
|
||||
<value>Collecteur d'e-mail</value>
|
||||
<value>Courriel "catch-all"</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Alias d'email transféré</value>
|
||||
<value>Alias de courriel transféré</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Mot aléatoire</value>
|
||||
</data>
|
||||
<data name="EmailRequiredParenthesis" xml:space="preserve">
|
||||
<value>E-mail (requis)</value>
|
||||
<value>Courriel (requis)</value>
|
||||
</data>
|
||||
<data name="DomainNameRequiredParenthesis" xml:space="preserve">
|
||||
<value>Nom de domaine (requis)</value>
|
||||
@@ -2438,13 +2438,13 @@ sélectionnez Ajouter TOTP pour stocker la clé en toute sécurité</value>
|
||||
<value>L'erreur {0} inconnue est survenue.</value>
|
||||
</data>
|
||||
<data name="PlusAddressedEmailDescription" xml:space="preserve">
|
||||
<value>Utilisez les capacités de sous-adressage de votre fournisseur de messagerie</value>
|
||||
<value>Utilisez les capacités de sous-adresse de votre fournisseur de messagerie électronique</value>
|
||||
</data>
|
||||
<data name="CatchAllEmailDescription" xml:space="preserve">
|
||||
<value>Utilisez la boîte de réception de votre email collecteur/attrape-tout (catch-all).</value>
|
||||
<value>Utilisez la boîte de réception "catch-all" configurée sur votre domaine.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Générer un alias d'email avec un service de transfert externe.</value>
|
||||
<value>Générer un alias de courriel avec un service de transfert externe.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Aléatoire</value>
|
||||
@@ -2476,7 +2476,7 @@ Voulez-vous basculer vers ce compte ?</value>
|
||||
<value>Vous êtes nouveau ici ?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Obtenir l'indice du mot de passe maître</value>
|
||||
<value>Obtenir l'indice du mot de passe principal</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Connecté en tant que {0}</value>
|
||||
@@ -2485,7 +2485,7 @@ Voulez-vous basculer vers ce compte ?</value>
|
||||
<value>Ce n'est pas vous ?</value>
|
||||
</data>
|
||||
<data name="LogInWithMasterPassword" xml:space="preserve">
|
||||
<value>Connectez-vous avec le mot de passe maître</value>
|
||||
<value>Se connecter avec le mot de passe principal</value>
|
||||
</data>
|
||||
<data name="LogInWithAnotherDevice" xml:space="preserve">
|
||||
<value>Connectez-vous avec un autre appareil</value>
|
||||
@@ -2497,7 +2497,7 @@ Voulez-vous basculer vers ce compte ?</value>
|
||||
<value>Une notification a été envoyée à votre appareil.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Veuillez vous assurer que votre coffre est déverrouillé et que l'empreinte digitale est identique sur l'autre appareil.</value>
|
||||
<value>Veuillez vous assurer que votre coffre est déverrouillé et que la phrase d'empreinte correspond à celle de l'autre appareil.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Renvoyer la notification</value>
|
||||
|
||||
@@ -296,7 +296,7 @@
|
||||
<comment>Text to define that there are more options things to see.</comment>
|
||||
</data>
|
||||
<data name="MyVault" xml:space="preserve">
|
||||
<value>Berangkas Saya</value>
|
||||
<value>Brankas Saya</value>
|
||||
<comment>The title for the vault page.</comment>
|
||||
</data>
|
||||
<data name="Authenticator" xml:space="preserve">
|
||||
|
||||
@@ -2137,7 +2137,7 @@
|
||||
<value>Questa organizzazione ha una politica aziendale che ti iscriverà automaticamente al ripristino della password. Ciò permetterà agli amministratori dell'organizzazione di cambiare la tua password principale.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Le policy dell'organizzazione controllano il timeout della tua cassaforte. Il tempo massimo consentito è di $HOURS$ ore e $MINUTES$ minuti</value>
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Il timeout della tua cassaforte supera i limiti impostati dalla tua organizzazione.</value>
|
||||
@@ -2450,7 +2450,7 @@ seleziona Aggiungi TOTP per salvare la chiave in modo sicuro</value>
|
||||
<value>Casuale</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Connetti a Watch</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Maggiori informazioni sul servizio di accessibilità</value>
|
||||
@@ -2512,6 +2512,6 @@ Vuoi passare a questo account?</value>
|
||||
<value>La richiesta non è più valida</value>
|
||||
</data>
|
||||
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
|
||||
<value>Enable camera permission to use the scanner</value>
|
||||
<value>Abilita i permessi della fotocamera per usare lo scanner</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -477,13 +477,13 @@
|
||||
<value>マスターパスワードのヒントを受信するため、アカウントのメールアドレスを入力してください。</value>
|
||||
</data>
|
||||
<data name="ExntesionReenable" xml:space="preserve">
|
||||
<value>アプリの拡張機能を再度有効化</value>
|
||||
<value>App Extension を再度有効化</value>
|
||||
</data>
|
||||
<data name="ExtensionAlmostDone" xml:space="preserve">
|
||||
<value>ほぼ完了!</value>
|
||||
</data>
|
||||
<data name="ExtensionEnable" xml:space="preserve">
|
||||
<value>アプリの拡張機能を有効化</value>
|
||||
<value>App Extension を有効化</value>
|
||||
</data>
|
||||
<data name="ExtensionInSafari" xml:space="preserve">
|
||||
<value>Safari では、共有アイコンを使って Bitwarden を見つけてください(ヒント:メニューの一番下の行を右側にスクロール)</value>
|
||||
@@ -1457,7 +1457,7 @@
|
||||
<value>表示するフォルダーがありません。</value>
|
||||
</data>
|
||||
<data name="FingerprintPhrase" xml:space="preserve">
|
||||
<value>指紋句</value>
|
||||
<value>パスフレーズ</value>
|
||||
<comment>A 'fingerprint phrase' is a unique word phrase (similar to a passphrase) that a user can use to authenticate their public key with another user, for the purposes of sharing.</comment>
|
||||
</data>
|
||||
<data name="YourAccountsFingerprint" xml:space="preserve">
|
||||
|
||||
@@ -1783,7 +1783,7 @@ Nolasīšana notiks automātiski.</value>
|
||||
<value>Vienā vai vairākos apvienības nosacījumos ir norādīts, ka galvenajai parolei ir jāatbilst šādām prasībām:</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectMinComplexity" xml:space="preserve">
|
||||
<value>Mazākais pieļaujamais sarežģītības novērtējums ir $SCORE$</value>
|
||||
<value>Minimum complexity score of {0}</value>
|
||||
</data>
|
||||
<data name="PolicyInEffectMinLength" xml:space="preserve">
|
||||
<value>Mazākais pieļaujamais garums ir {0}</value>
|
||||
|
||||
@@ -452,7 +452,7 @@
|
||||
<value>Endre hovedpassord</value>
|
||||
</data>
|
||||
<data name="ChangePasswordConfirmation" xml:space="preserve">
|
||||
<value>Du kan endre superpassordet ditt på bitwarden.net-netthvelvet. Vil du besøke det nettstedet nå?</value>
|
||||
<value>Du kan endre hovedpassordet ditt på bitwarden.com-netthvelvet. Vil du besøke nettstedet nå?</value>
|
||||
</data>
|
||||
<data name="Close" xml:space="preserve">
|
||||
<value>Lukk</value>
|
||||
@@ -474,7 +474,7 @@
|
||||
<value>Aktiver automatisk synkronisering</value>
|
||||
</data>
|
||||
<data name="EnterEmailForHint" xml:space="preserve">
|
||||
<value>Skriv inn din kontos E-postadresse for å motta hintet til ditt superpassord.</value>
|
||||
<value>Skriv inn kontoens e-postadresse for å motta hint om hovedpassordet ditt.</value>
|
||||
</data>
|
||||
<data name="ExntesionReenable" xml:space="preserve">
|
||||
<value>Aktiver apputvidelsen på nytt</value>
|
||||
@@ -517,7 +517,7 @@
|
||||
<value>Lag passord</value>
|
||||
</data>
|
||||
<data name="GetPasswordHint" xml:space="preserve">
|
||||
<value>Få et hint om superpassordet</value>
|
||||
<value>Få et hint om hovedpassordet</value>
|
||||
</data>
|
||||
<data name="ImportItems" xml:space="preserve">
|
||||
<value>Importer elementer</value>
|
||||
@@ -575,16 +575,16 @@
|
||||
<value>Passordbekreftelsen er ikke riktig.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordDescription" xml:space="preserve">
|
||||
<value>Superpassordet er passordet du bruker for å få tilgang til hvelvet ditt. Det er veldig viktig at du aldri glemmer ditt superpassord. Det er ingen måter å få tilbake passordet på dersom du noensinne skulle klare å glemme det.</value>
|
||||
<value>Hovedpassordet er passordet du bruker for å få tilgang til hvelvet ditt. Det er svært viktig at du aldri glemmer hovedpassordet. Det er ikke mulig å gjenopprette passordet dersom du glemmer det.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHint" xml:space="preserve">
|
||||
<value>Et hint for hovedpassordet (valgfritt)</value>
|
||||
</data>
|
||||
<data name="MasterPasswordHintDescription" xml:space="preserve">
|
||||
<value>Et hint for superpassordet, kan hjelpe deg å huske på passordet hvis du skulle glemme det.</value>
|
||||
<value>Et hint om hovedpassordet kan hjelpe deg å huske passordet om du skulle glemme det.</value>
|
||||
</data>
|
||||
<data name="MasterPasswordLengthValMessage" xml:space="preserve">
|
||||
<value>Superpassordet må være ≥8 tegn lang.</value>
|
||||
<value>Hovedpassordet må være minst 8 tegn.</value>
|
||||
</data>
|
||||
<data name="MinNumbers" xml:space="preserve">
|
||||
<value>Minst antall siffer</value>
|
||||
@@ -641,7 +641,7 @@
|
||||
<value>Passordhint</value>
|
||||
</data>
|
||||
<data name="PasswordHintAlert" xml:space="preserve">
|
||||
<value>Vi har sendt deg en E-post med hintet til superpassordet.</value>
|
||||
<value>Vi har sendt deg en e-post med hint om hovedpassord.</value>
|
||||
</data>
|
||||
<data name="PasswordOverrideAlert" xml:space="preserve">
|
||||
<value>Er du sikker på at du vil overskrive det nåværende passordet?</value>
|
||||
@@ -1493,7 +1493,7 @@ Skanning skjer automatisk.</value>
|
||||
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="VaultLockedMasterPassword" xml:space="preserve">
|
||||
<value>Hvelvet ditt er låst. Kontroller superpassordet ditt for å fortsette.</value>
|
||||
<value>Hvelvet ditt er låst. Kontroller hovedpassordet ditt for å fortsette.</value>
|
||||
</data>
|
||||
<data name="VaultLockedPIN" xml:space="preserve">
|
||||
<value>Hvelvet ditt er låst. Kontroller PIN-koden din for å fortsette.</value>
|
||||
@@ -2477,7 +2477,7 @@ Vil du bytte til denne kontoen?</value>
|
||||
<value>Nytt rundt her?</value>
|
||||
</data>
|
||||
<data name="GetMasterPasswordwordHint" xml:space="preserve">
|
||||
<value>Få et hint om superpassordet</value>
|
||||
<value>Få et hint om hovedpassordet</value>
|
||||
</data>
|
||||
<data name="LoggingInAsX" xml:space="preserve">
|
||||
<value>Logger inn som {0}</value>
|
||||
|
||||
2518
src/App/Resources/AppResources.ne.resx
Normal file
@@ -1976,7 +1976,7 @@ Het scannen gebeurt automatisch.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="DisableSend" xml:space="preserve">
|
||||
<value>Schakel deze Send uit zodat niemand hem kan benaderen.</value>
|
||||
<value>Schakel deze Send uit zodat niemand hem kan benaderen</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="NoSends" xml:space="preserve">
|
||||
@@ -2044,7 +2044,7 @@ Het scannen gebeurt automatisch.</value>
|
||||
<value>Aangepast</value>
|
||||
</data>
|
||||
<data name="ShareOnSave" xml:space="preserve">
|
||||
<value>Deze Send bij het opslaan delen.</value>
|
||||
<value>Deze Send bij het opslaan delen</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="SendDisabledWarning" xml:space="preserve">
|
||||
@@ -2056,7 +2056,7 @@ Het scannen gebeurt automatisch.</value>
|
||||
<comment>'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.</comment>
|
||||
</data>
|
||||
<data name="HideEmail" xml:space="preserve">
|
||||
<value>Verberg mijn e-mailadres voor ontvangers.</value>
|
||||
<value>Verberg mijn e-mailadres voor ontvangers</value>
|
||||
</data>
|
||||
<data name="SendOptionsPolicyInEffect" xml:space="preserve">
|
||||
<value>Een of meer organisatiebeleidseisen heeft invloed op de mogelijkheden van je Send.</value>
|
||||
@@ -2137,7 +2137,7 @@ Het scannen gebeurt automatisch.</value>
|
||||
<value>Deze organisatie heeft een ondernemingsbeleid dat je automatisch inschrijft bij het resetten van je wachtwoord. Inschrijving stelt organisatiebeheerders in staat om je hoofdwachtwoord te wijzigen.</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutPolicyInEffect" xml:space="preserve">
|
||||
<value>Het beleid van je organisatie heeft invloed op de time-out van je kluis. De maximaal toegestane Kluis Time-out is $HOURS$ uur en $MINUTES$ minuten</value>
|
||||
<value>Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is {0} hour(s) and {1} minute(s)</value>
|
||||
</data>
|
||||
<data name="VaultTimeoutToLarge" xml:space="preserve">
|
||||
<value>Je kluis time-out is hoger dan het maximum van jouw organisatie.</value>
|
||||
@@ -2450,7 +2450,7 @@ kies je TOTP toevoegen om de sleutel veilig op te slaan</value>
|
||||
<value>Willekeurig</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Verbinding maken met horloge</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Toegankelijksheidsservice-melding</value>
|
||||
@@ -2491,22 +2491,22 @@ Wilt u naar dit account wisselen?</value>
|
||||
<value>Inloggen met een ander apparaat</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
<value>Inloggen gestart</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
<value>Er is een bericht naar je apparaat verstuurd.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
<value>Zorg ervoor dat je kluis is ontgrendeld en dat de Vingerafdrukzin overeenkomt met het andere apparaat.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
<value>Bericht opnieuw verzenden</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
<value>Nog een optie nodig?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
<value>Alle loginopties bekijken</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>Dit verzoek is niet langer geldig</value>
|
||||
|
||||
@@ -1489,7 +1489,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if you ever fully log out of the application.</value>
|
||||
</data>
|
||||
<data name="LoggedInAsOn" xml:space="preserve">
|
||||
<value>Skriven inn som {0} gjennom {0}.</value>
|
||||
<value>Logged in as {0} on {1}.</value>
|
||||
<comment>ex: Logged in as user@example.com on bitwarden.com.</comment>
|
||||
</data>
|
||||
<data name="VaultLockedMasterPassword" xml:space="preserve">
|
||||
|
||||
@@ -2390,7 +2390,7 @@ wybierz Dodaj TOTP, aby bezpiecznie przechowywać klucz</value>
|
||||
<value>Adres catch-all</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailAlias" xml:space="preserve">
|
||||
<value>Alias przekazywanego adresu</value>
|
||||
<value>Alias przekierowania</value>
|
||||
</data>
|
||||
<data name="RandomWord" xml:space="preserve">
|
||||
<value>Losowe słowo</value>
|
||||
@@ -2444,7 +2444,7 @@ wybierz Dodaj TOTP, aby bezpiecznie przechowywać klucz</value>
|
||||
<value>Użyj skonfigurowanej skrzynki catch-all w swojej domenie.</value>
|
||||
</data>
|
||||
<data name="ForwardedEmailDescription" xml:space="preserve">
|
||||
<value>Wygeneruj alias adresu e-mail z zewnętrznej usługi przekazywania.</value>
|
||||
<value>Wygeneruj alias adresu e-mail z zewnętrznej usługi przekierowania.</value>
|
||||
</data>
|
||||
<data name="Random" xml:space="preserve">
|
||||
<value>Losowy</value>
|
||||
|
||||
@@ -1103,6 +1103,9 @@ Scanning will happen automatically.</value>
|
||||
<data name="Ms" xml:space="preserve">
|
||||
<value>Ms</value>
|
||||
</data>
|
||||
<data name="Mx" xml:space="preserve">
|
||||
<value>Mx</value>
|
||||
</data>
|
||||
<data name="November" xml:space="preserve">
|
||||
<value>November</value>
|
||||
</data>
|
||||
@@ -2515,4 +2518,40 @@ Do you want to switch to this account?</value>
|
||||
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
|
||||
<value>Enable camera permission to use the scanner</value>
|
||||
</data>
|
||||
<data name="Important" xml:space="preserve">
|
||||
<value>Important</value>
|
||||
</data>
|
||||
<data name="YourMasterPasswordCannotBeRecoveredIfYouForgetItXCharactersMinimum" xml:space="preserve">
|
||||
<value>Your master password cannot be recovered if you forget it! {0} characters minimum.</value>
|
||||
</data>
|
||||
<data name="WeakMasterPassword" xml:space="preserve">
|
||||
<value>Weak Master Password</value>
|
||||
</data>
|
||||
<data name="WeakPasswordIdentifiedUseAStrongPasswordToProtectYourAccount" xml:space="preserve">
|
||||
<value>Weak password identified. Use a strong password to protect your account. Are you sure you want to use a weak password?</value>
|
||||
</data>
|
||||
<data name="Weak" xml:space="preserve">
|
||||
<value>Weak</value>
|
||||
</data>
|
||||
<data name="Good" xml:space="preserve">
|
||||
<value>Good</value>
|
||||
</data>
|
||||
<data name="Strong" xml:space="preserve">
|
||||
<value>Strong</value>
|
||||
</data>
|
||||
<data name="CheckKnownDataBreachesForThisPassword" xml:space="preserve">
|
||||
<value>Check known data breaches for this password</value>
|
||||
</data>
|
||||
<data name="ExposedMasterPassword" xml:space="preserve">
|
||||
<value>Exposed Master Password</value>
|
||||
</data>
|
||||
<data name="PasswordFoundInADataBreachAlertDescription" xml:space="preserve">
|
||||
<value>Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?</value>
|
||||
</data>
|
||||
<data name="WeakAndExposedMasterPassword" xml:space="preserve">
|
||||
<value>Weak and Exposed Master Password</value>
|
||||
</data>
|
||||
<data name="WeakPasswordIdentifiedAndFoundInADataBreachAlertDescription" xml:space="preserve">
|
||||
<value>Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2450,7 +2450,7 @@ selectați „Adăugare TOTP” pentru a stoca cheia în siguranță</value>
|
||||
<value>Aleatoriu</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Conectează-te pentru a urmări</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Dezvăluirea serviciilor de accesibilitate</value>
|
||||
@@ -2491,27 +2491,27 @@ Doriți să comutați la acest cont?</value>
|
||||
<value>Autentificați-vă cu un alt dispozitiv</value>
|
||||
</data>
|
||||
<data name="LogInInitiated" xml:space="preserve">
|
||||
<value>Log in initiated</value>
|
||||
<value>Autentificare inițiată</value>
|
||||
</data>
|
||||
<data name="ANotificationHasBeenSentToYourDevice" xml:space="preserve">
|
||||
<value>A notification has been sent to your device.</value>
|
||||
<value>O notificare a fost trimisă pe dispozitivul dvs.</value>
|
||||
</data>
|
||||
<data name="PleaseMakeSureYourVaultIsUnlockedAndTheFingerprintPhraseMatchesOnTheOtherDevice" xml:space="preserve">
|
||||
<value>Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device.</value>
|
||||
<value>Asigurați-vă că seiful dvs. este deblocat și că fraza amprentă corespunde cu cea a celuilalt dispozitiv.</value>
|
||||
</data>
|
||||
<data name="ResendNotification" xml:space="preserve">
|
||||
<value>Resend notification</value>
|
||||
<value>Retrimitere notificare</value>
|
||||
</data>
|
||||
<data name="NeedAnotherOption" xml:space="preserve">
|
||||
<value>Need another option?</value>
|
||||
<value>Selectezi o altă opțiune?</value>
|
||||
</data>
|
||||
<data name="ViewAllLoginOptions" xml:space="preserve">
|
||||
<value>View all log in options</value>
|
||||
<value>Vedeți toate opțiunile de autentificare</value>
|
||||
</data>
|
||||
<data name="ThisRequestIsNoLongerValid" xml:space="preserve">
|
||||
<value>This request is no longer valid</value>
|
||||
<value>Această cerere nu mai este valabilă</value>
|
||||
</data>
|
||||
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
|
||||
<value>Enable camera permission to use the scanner</value>
|
||||
<value>Permite accesul camerei foto pentru a utiliza scanerul</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
<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">
|
||||
@@ -279,20 +279,20 @@
|
||||
<value>Удалить аккаунт</value>
|
||||
</data>
|
||||
<data name="RemoveAccountConfirmation" xml:space="preserve">
|
||||
<value>Вы действительно хотите удалить эту учетную запись?</value>
|
||||
<value>Вы действительно хотите удалить этот аккаунт?</value>
|
||||
</data>
|
||||
<data name="AccountAlreadyAdded" xml:space="preserve">
|
||||
<value>Аккаунт уже добавлен</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Хотите переключиться на нее?</value>
|
||||
<value>Хотите переключиться на него?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Мастер-пароль</value>
|
||||
<comment>Label for a master password.</comment>
|
||||
</data>
|
||||
<data name="More" xml:space="preserve">
|
||||
<value>Больше</value>
|
||||
<value>Еще</value>
|
||||
<comment>Text to define that there are more options things to see.</comment>
|
||||
</data>
|
||||
<data name="MyVault" xml:space="preserve">
|
||||
@@ -315,7 +315,7 @@
|
||||
<comment>Label for notes.</comment>
|
||||
</data>
|
||||
<data name="Ok" xml:space="preserve">
|
||||
<value>Ok</value>
|
||||
<value>OK</value>
|
||||
<comment>Acknowledgement.</comment>
|
||||
</data>
|
||||
<data name="Password" xml:space="preserve">
|
||||
@@ -440,7 +440,7 @@
|
||||
<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>
|
||||
@@ -511,7 +511,7 @@
|
||||
<value>Избранный</value>
|
||||
</data>
|
||||
<data name="Fingerprint" xml:space="preserve">
|
||||
<value>отпечатком</value>
|
||||
<value>Отпечаток</value>
|
||||
</data>
|
||||
<data name="GeneratePassword" xml:space="preserve">
|
||||
<value>Сгенерировать пароль</value>
|
||||
@@ -523,10 +523,10 @@
|
||||
<value>Импорт элементов</value>
|
||||
</data>
|
||||
<data name="ImportItemsConfirmation" xml:space="preserve">
|
||||
<value>Вы можете импортировать элементы в свое веб-хранилище на bitwarden.com. Перейти на сайт сейчас?</value>
|
||||
<value>Вы можете массово импортировать свои элементы из веб-хранилища на bitwarden.com. Перейти на сайт сейчас?</value>
|
||||
</data>
|
||||
<data name="ImportItemsDescription" xml:space="preserve">
|
||||
<value>Быстрый импорт ваших элементов из других менеджеров паролей.</value>
|
||||
<value>Быстрый массовый импорт записей из других менеджеров паролей.</value>
|
||||
</data>
|
||||
<data name="LastSync" xml:space="preserve">
|
||||
<value>Последняя синхронизация:</value>
|
||||
@@ -860,7 +860,7 @@
|
||||
<comment>For 2FA</comment>
|
||||
</data>
|
||||
<data name="YubiKeyInstruction" xml:space="preserve">
|
||||
<value>Для продолжения приложите ваш YubiKey NEO к задней панели устройства или вставьте его в USB-порт и нажмите его кнопку.</value>
|
||||
<value>Для продолжения приложите ваш YubiKey NEO к задней панели устройства или вставьте в USB-порт и нажмите его кнопку.</value>
|
||||
</data>
|
||||
<data name="YubiKeyTitle" xml:space="preserve">
|
||||
<value>Ключ безопасности YubiKey</value>
|
||||
@@ -876,14 +876,14 @@
|
||||
<value>Не удается загрузить файл.</value>
|
||||
</data>
|
||||
<data name="UnableToOpenFile" xml:space="preserve">
|
||||
<value>Устройство не может открыть этот тип файла.</value>
|
||||
<value>Устройство не может открыть файл этого типа.</value>
|
||||
</data>
|
||||
<data name="Downloading" xml:space="preserve">
|
||||
<value>Загрузка...</value>
|
||||
<comment>Message shown when downloading a file</comment>
|
||||
</data>
|
||||
<data name="AttachmentLargeWarning" xml:space="preserve">
|
||||
<value>Это вложение имеет размер {0}. Вы действительно хотите загрузить его на устройство?</value>
|
||||
<value>Размер этого вложения - {0}. Вы действительно хотите загрузить его на устройство?</value>
|
||||
<comment>The placeholder will show the file size of the attachment. Ex "25 MB"</comment>
|
||||
</data>
|
||||
<data name="AuthenticatorKey" xml:space="preserve">
|
||||
|
||||
@@ -285,7 +285,7 @@
|
||||
<value>Račun je že bil dodan</value>
|
||||
</data>
|
||||
<data name="SwitchToAlreadyAddedAccountConfirmation" xml:space="preserve">
|
||||
<value>Would you like to switch to it now?</value>
|
||||
<value>Želite zdaj preklopiti na ta račun?</value>
|
||||
</data>
|
||||
<data name="MasterPassword" xml:space="preserve">
|
||||
<value>Glavno geslo</value>
|
||||
@@ -300,7 +300,7 @@
|
||||
<comment>The title for the vault page.</comment>
|
||||
</data>
|
||||
<data name="Authenticator" xml:space="preserve">
|
||||
<value>Authenticator</value>
|
||||
<value>Avtentikator</value>
|
||||
<comment>Authenticator TOTP feature</comment>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
@@ -775,10 +775,10 @@
|
||||
<value>Omogočeno</value>
|
||||
</data>
|
||||
<data name="Off" xml:space="preserve">
|
||||
<value>Off</value>
|
||||
<value>Ne</value>
|
||||
</data>
|
||||
<data name="On" xml:space="preserve">
|
||||
<value>On</value>
|
||||
<value>Da</value>
|
||||
</data>
|
||||
<data name="Status" xml:space="preserve">
|
||||
<value>Stanje</value>
|
||||
@@ -1354,7 +1354,7 @@ Scanning will happen automatically.</value>
|
||||
<value>Preveri ali je bilo geslo izpostavljeno.</value>
|
||||
</data>
|
||||
<data name="PasswordExposed" xml:space="preserve">
|
||||
<value>To geslo je bilo med ukradenimi podatki izpostavljeno $VALUE$ krat. Morali bi ga zamenjati.</value>
|
||||
<value>This password has been exposed {0} time(s) in data breaches. You should change it.</value>
|
||||
</data>
|
||||
<data name="PasswordSafe" xml:space="preserve">
|
||||
<value>To geslo ni bilo najdeno med do sedaj znanimi krajami podatkov. Njegova uporaba bi morala biti varna.</value>
|
||||
|
||||
@@ -2452,7 +2452,7 @@ välj Lägg till TOTP för att lagra nyckeln på ett säkert sätt</value>
|
||||
<value>Slumpmässig</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>Connect to Watch</value>
|
||||
<value>Anslut till Watch</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>Delgivning av tillgänglighetstjänst</value>
|
||||
@@ -2514,6 +2514,6 @@ Vill du byta till detta konto?</value>
|
||||
<value>Denna förfrågan är inte längre giltig</value>
|
||||
</data>
|
||||
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
|
||||
<value>Enable camera permission to use the scanner</value>
|
||||
<value>Bevilja kamerabehörighet för att använda skannern</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -2450,7 +2450,7 @@
|
||||
<value>隨機</value>
|
||||
</data>
|
||||
<data name="ConnectToWatch" xml:space="preserve">
|
||||
<value>連線至手錶</value>
|
||||
<value>連線至 Apple Watch</value>
|
||||
</data>
|
||||
<data name="AccessibilityServiceDisclosure" xml:space="preserve">
|
||||
<value>無障礙服務聲明</value>
|
||||
@@ -2512,6 +2512,6 @@
|
||||
<value>此請求已失效</value>
|
||||
</data>
|
||||
<data name="EnableCamerPermissionToUseTheScanner" xml:space="preserve">
|
||||
<value>啟用相機權限以使用掃描儀</value>
|
||||
<value>允許相機權限以使用掃描功能</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -562,4 +562,15 @@
|
||||
</VisualStateGroupList>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style TargetType="controls:PasswordStrengthProgressBar">
|
||||
<Setter Property="VeryWeakColor"
|
||||
Value="{DynamicResource DangerColor}" />
|
||||
<Setter Property="WeakColor"
|
||||
Value="{DynamicResource WarningColor}" />
|
||||
<Setter Property="GoodColor"
|
||||
Value="{DynamicResource PrimaryColor}" />
|
||||
<Setter Property="StrongColor"
|
||||
Value="{DynamicResource SuccessColor}" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
||||
25
src/App/Utilities/ProgressBarExtensions.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace Bit.App.Utilities
|
||||
{
|
||||
public static class ProgressBarExtensions
|
||||
{
|
||||
public static BindableProperty AnimatedProgressProperty =
|
||||
BindableProperty.CreateAttached("AnimatedProgress",
|
||||
typeof(double),
|
||||
typeof(ProgressBar),
|
||||
0.0d,
|
||||
BindingMode.OneWay,
|
||||
propertyChanged: (b, o, n) => ProgressBarProgressChanged((ProgressBar)b, (double)n));
|
||||
|
||||
public static double GetAnimatedProgress(BindableObject target) => (double)target.GetValue(AnimatedProgressProperty);
|
||||
public static void SetAnimatedProgress(BindableObject target, double value) => target.SetValue(AnimatedProgressProperty, value);
|
||||
|
||||
private static void ProgressBarProgressChanged(ProgressBar progressBar, double progress)
|
||||
{
|
||||
ViewExtensions.CancelAnimations(progressBar);
|
||||
progressBar.ProgressTo(progress, 500, Easing.SinIn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Models.Domain;
|
||||
using Zxcvbn;
|
||||
|
||||
namespace Bit.Core.Abstractions
|
||||
{
|
||||
@@ -16,8 +17,9 @@ namespace Bit.Core.Abstractions
|
||||
Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)> GetOptionsAsync();
|
||||
Task<(PasswordGenerationOptions, PasswordGeneratorPolicyOptions)>
|
||||
EnforcePasswordGeneratorPoliciesOnOptionsAsync(PasswordGenerationOptions options);
|
||||
Zxcvbn.Result PasswordStrength(string password, List<string> userInputs = null);
|
||||
Result PasswordStrength(string password, List<string> userInputs = null);
|
||||
Task SaveOptionsAsync(PasswordGenerationOptions options);
|
||||
void NormalizeOptions(PasswordGenerationOptions options, PasswordGeneratorPolicyOptions enforcedPolicyOptions);
|
||||
List<string> GetPasswordStrengthUserInput(string email);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,5 +163,9 @@ namespace Bit.Core.Abstractions
|
||||
Task<bool> GetShouldConnectToWatchAsync(string userId = null);
|
||||
Task SetShouldConnectToWatchAsync(bool shouldConnect, string userId = null);
|
||||
Task<bool> GetLastUserShouldConnectToWatchAsync();
|
||||
Task SetAvatarColorAsync(string value, string userId = null);
|
||||
Task<string> GetAvatarColorAsync(string userId = null);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
public const int SaveFileRequestCode = 44;
|
||||
public const int TotpDefaultTimer = 30;
|
||||
public const int PasswordlessNotificationTimeoutInMinutes = 15;
|
||||
public const int KdfIterations = 600000;
|
||||
public const int MasterPasswordMinimumChars = 8;
|
||||
|
||||
public static readonly string[] AndroidAllClearCipherCacheKeys =
|
||||
{
|
||||
|
||||
@@ -16,5 +16,7 @@ namespace Bit.Core.Exceptions
|
||||
}
|
||||
|
||||
public ErrorResponse Error { get; set; }
|
||||
|
||||
public override string Message => Error?.GetFullMessage() ?? base.Message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Bit.Core.Models.Domain
|
||||
KdfIterations = copy.KdfIterations;
|
||||
EmailVerified = copy.EmailVerified;
|
||||
HasPremiumPersonally = copy.HasPremiumPersonally;
|
||||
AvatarColor = copy.AvatarColor;
|
||||
}
|
||||
|
||||
public string UserId;
|
||||
@@ -55,6 +56,7 @@ namespace Bit.Core.Models.Domain
|
||||
public string Name;
|
||||
public string Stamp;
|
||||
public string OrgIdentifier;
|
||||
public string AvatarColor;
|
||||
public KdfType? KdfType;
|
||||
public int? KdfIterations;
|
||||
public bool? EmailVerified;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Bit.Core.Models.Response
|
||||
@@ -67,6 +68,32 @@ namespace Bit.Core.Models.Response
|
||||
return Message;
|
||||
}
|
||||
|
||||
public string GetFullMessage()
|
||||
{
|
||||
string GetDefaultMessage() => $"{(int)StatusCode} {StatusCode}. {Message}";
|
||||
|
||||
if (ValidationErrors is null)
|
||||
{
|
||||
return GetDefaultMessage();
|
||||
}
|
||||
|
||||
var valErrors = ValidationErrors.Where(e => e.Value != null && e.Value.Any()).ToList();
|
||||
if (!valErrors.Any())
|
||||
{
|
||||
return GetDefaultMessage();
|
||||
}
|
||||
|
||||
string GetFullError(string key, List<string> errors)
|
||||
{
|
||||
return new StringBuilder()
|
||||
.Append($"[{key}]: ")
|
||||
.Append(string.Join("; ", errors))
|
||||
.ToString();
|
||||
};
|
||||
|
||||
return $"{(int)StatusCode} {StatusCode}. {string.Join(Environment.NewLine, valErrors.Select(ve => GetFullError(ve.Key, ve.Value)))}";
|
||||
}
|
||||
|
||||
private class ErrorModel
|
||||
{
|
||||
public string Message { get; set; }
|
||||
|
||||
@@ -19,5 +19,6 @@ namespace Bit.Core.Models.Response
|
||||
public bool ForcePasswordReset { get; set; }
|
||||
public List<ProfileOrganizationResponse> Organizations { get; set; }
|
||||
public bool UsesKeyConnector { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Bit.Core.Models.View
|
||||
UserId = a.Profile?.UserId;
|
||||
Email = a.Profile?.Email;
|
||||
Name = a.Profile?.Name;
|
||||
AvatarColor = a.Profile?.AvatarColor;
|
||||
if (!string.IsNullOrWhiteSpace(a.Settings?.EnvironmentUrls?.WebVault))
|
||||
{
|
||||
Hostname = CoreHelpers.GetHostname(a.Settings?.EnvironmentUrls?.WebVault);
|
||||
@@ -37,5 +38,6 @@ namespace Bit.Core.Models.View
|
||||
public string Email { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Hostname { get; set; }
|
||||
public string AvatarColor { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace Bit.Core.Services
|
||||
public string CaptchaToken { get; set; }
|
||||
public string MasterPasswordHash { get; set; }
|
||||
public string LocalMasterPasswordHash { get; set; }
|
||||
public string AuthRequestId { get; set; }
|
||||
public string Code { get; set; }
|
||||
public string CodeVerifier { get; set; }
|
||||
public string SsoRedirectUrl { get; set; }
|
||||
@@ -163,7 +164,7 @@ namespace Bit.Core.Services
|
||||
CaptchaToken = captchaToken;
|
||||
}
|
||||
return LogInHelperAsync(Email, MasterPasswordHash, LocalMasterPasswordHash, Code, CodeVerifier, SsoRedirectUrl, _key,
|
||||
twoFactorProvider, twoFactorToken, remember, CaptchaToken);
|
||||
twoFactorProvider, twoFactorToken, remember, CaptchaToken, authRequestId: AuthRequestId);
|
||||
}
|
||||
|
||||
public async Task<AuthResult> LogInCompleteAsync(string email, string masterPassword,
|
||||
@@ -328,12 +329,12 @@ namespace Bit.Core.Services
|
||||
if (twoFactorToken != null && twoFactorProvider != null)
|
||||
{
|
||||
request = new TokenRequest(emailPassword, codeCodeVerifier, twoFactorProvider, twoFactorToken, remember,
|
||||
captchaToken, deviceRequest);
|
||||
captchaToken, deviceRequest, authRequestId);
|
||||
}
|
||||
else if (storedTwoFactorToken != null)
|
||||
{
|
||||
request = new TokenRequest(emailPassword, codeCodeVerifier, TwoFactorProviderType.Remember,
|
||||
storedTwoFactorToken, false, captchaToken, deviceRequest);
|
||||
storedTwoFactorToken, false, captchaToken, deviceRequest, authRequestId);
|
||||
}
|
||||
else if (authRequestId != null)
|
||||
{
|
||||
@@ -359,6 +360,7 @@ namespace Bit.Core.Services
|
||||
Email = email;
|
||||
MasterPasswordHash = hashedPassword;
|
||||
LocalMasterPasswordHash = localHashedPassword;
|
||||
AuthRequestId = authRequestId;
|
||||
Code = code;
|
||||
CodeVerifier = codeVerifier;
|
||||
SsoRedirectUrl = redirectUrl;
|
||||
@@ -481,6 +483,7 @@ namespace Bit.Core.Services
|
||||
Email = null;
|
||||
CaptchaToken = null;
|
||||
MasterPasswordHash = null;
|
||||
AuthRequestId = null;
|
||||
Code = null;
|
||||
CodeVerifier = null;
|
||||
SsoRedirectUrl = null;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
@@ -395,6 +396,19 @@ namespace Bit.Core.Services
|
||||
return enforcedOptions;
|
||||
}
|
||||
|
||||
public List<string> GetPasswordStrengthUserInput(string email)
|
||||
{
|
||||
var atPosition = email?.IndexOf('@');
|
||||
if (atPosition is null || atPosition < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var rx = new Regex("/[^A-Za-z0-9]/", RegexOptions.Compiled);
|
||||
var data = rx.Split(email.Substring(0, atPosition.Value).Trim().ToLower());
|
||||
|
||||
return new List<string>(data);
|
||||
}
|
||||
|
||||
private int? GetPolicyInt(Policy policy, string key)
|
||||
{
|
||||
if (policy.Data.ContainsKey(key))
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Models.View;
|
||||
using Bit.Core.Utilities;
|
||||
|
||||
namespace Bit.Core.Services
|
||||
{
|
||||
@@ -76,12 +77,12 @@ namespace Bit.Core.Services
|
||||
ct.ThrowIfCancellationRequested();
|
||||
var matchedCiphers = new List<CipherView>();
|
||||
var lowPriorityMatchedCiphers = new List<CipherView>();
|
||||
query = query.Trim().ToLower();
|
||||
query = query.Trim().ToLower().RemoveDiacritics();
|
||||
|
||||
foreach (var c in ciphers)
|
||||
{
|
||||
ct.ThrowIfCancellationRequested();
|
||||
if (c.Name?.ToLower().Contains(query) ?? false)
|
||||
if (c.Name?.ToLower().RemoveDiacritics().Contains(query) ?? false)
|
||||
{
|
||||
matchedCiphers.Add(c);
|
||||
}
|
||||
@@ -89,7 +90,7 @@ namespace Bit.Core.Services
|
||||
{
|
||||
lowPriorityMatchedCiphers.Add(c);
|
||||
}
|
||||
else if (c.SubTitle?.ToLower().Contains(query) ?? false)
|
||||
else if (c.SubTitle?.ToLower().RemoveDiacritics().Contains(query) ?? false)
|
||||
{
|
||||
lowPriorityMatchedCiphers.Add(c);
|
||||
}
|
||||
|
||||
@@ -1305,6 +1305,23 @@ namespace Bit.Core.Services
|
||||
var key = Constants.PasswordlessLoginNotificationKey;
|
||||
await SetValueAsync(key, value, options);
|
||||
}
|
||||
|
||||
public async Task SetAvatarColorAsync(string value, string userId = null)
|
||||
{
|
||||
var reconciledOptions = ReconcileOptions(new StorageOptions { UserId = userId },
|
||||
await GetDefaultStorageOptionsAsync());
|
||||
var account = await GetAccountAsync(reconciledOptions);
|
||||
account.Profile.AvatarColor = value;
|
||||
await SaveAccountAsync(account, reconciledOptions);
|
||||
}
|
||||
|
||||
public async Task<string> GetAvatarColorAsync(string userId = null)
|
||||
{
|
||||
return (await GetAccountAsync(
|
||||
ReconcileOptions(new StorageOptions { UserId = userId }, await GetDefaultStorageOptionsAsync())
|
||||
))?.Profile?.AvatarColor;
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
private async Task<T> GetValueAsync<T>(string key, StorageOptions options)
|
||||
|
||||
@@ -335,6 +335,7 @@ namespace Bit.Core.Services
|
||||
await _organizationService.ReplaceAsync(organizations);
|
||||
await _stateService.SetEmailVerifiedAsync(response.EmailVerified);
|
||||
await _stateService.SetNameAsync(response.Name);
|
||||
await _stateService.SetAvatarColorAsync(response.AvatarColor);
|
||||
await _keyConnectorService.SetUsesKeyConnector(response.UsesKeyConnector);
|
||||
}
|
||||
|
||||
|
||||
34
src/Core/Utilities/StringExtensions.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace Bit.Core.Utilities
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string RemoveDiacritics(this string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
var normalizedString = text.Normalize(NormalizationForm.FormD);
|
||||
var stringBuilder = new StringBuilder(capacity: normalizedString.Length);
|
||||
|
||||
for (int i = 0; i < normalizedString.Length; i++)
|
||||
{
|
||||
char c = normalizedString[i];
|
||||
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
if (unicodeCategory != UnicodeCategory.NonSpacingMark)
|
||||
{
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder
|
||||
.ToString()
|
||||
.Normalize(NormalizationForm.FormC);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.8bit.bitwarden.autofill</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2022.12.0</string>
|
||||
<string>2023.1.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using Bit.App.Abstractions;
|
||||
using Bit.App.Models;
|
||||
@@ -31,13 +32,13 @@ namespace Bit.iOS.Core.Services
|
||||
try
|
||||
{
|
||||
var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
|
||||
Console.WriteLine(netLanguage + " failed, trying " + fallback + " (" + e1.Message + ")");
|
||||
Debug.WriteLine(netLanguage + " failed, trying " + fallback + " (" + e1.Message + ")");
|
||||
ci = new CultureInfo(fallback);
|
||||
}
|
||||
catch (CultureNotFoundException e2)
|
||||
{
|
||||
// iOS language not valid .NET culture, falling back to English
|
||||
Console.WriteLine(netLanguage + " couldn't be set, using 'en' (" + e2.Message + ")");
|
||||
Debug.WriteLine(netLanguage + " couldn't be set, using 'en' (" + e2.Message + ")");
|
||||
ci = new CultureInfo("en");
|
||||
}
|
||||
}
|
||||
@@ -47,7 +48,7 @@ namespace Bit.iOS.Core.Services
|
||||
|
||||
private string iOSToDotnetLanguage(string iOSLanguage)
|
||||
{
|
||||
Console.WriteLine("iOS Language:" + iOSLanguage);
|
||||
Debug.WriteLine("iOS Language:" + iOSLanguage);
|
||||
var netLanguage = iOSLanguage;
|
||||
if (iOSLanguage.StartsWith("zh-Hant") || iOSLanguage.StartsWith("zh-HK"))
|
||||
{
|
||||
@@ -77,13 +78,13 @@ namespace Bit.iOS.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine(".NET Language/Locale:" + netLanguage);
|
||||
Debug.WriteLine(".NET Language/Locale:" + netLanguage);
|
||||
return netLanguage;
|
||||
}
|
||||
|
||||
private string ToDotnetFallbackLanguage(PlatformCulture platCulture)
|
||||
{
|
||||
Console.WriteLine(".NET Fallback Language:" + platCulture.LanguageCode);
|
||||
Debug.WriteLine(".NET Fallback Language:" + platCulture.LanguageCode);
|
||||
// Use the first part of the identifier (two chars, usually);
|
||||
var netLanguage = platCulture.LanguageCode;
|
||||
switch (platCulture.LanguageCode)
|
||||
@@ -97,7 +98,7 @@ namespace Bit.iOS.Core.Services
|
||||
// add more application-specific cases here (if required)
|
||||
// ONLY use cultures that have been tested and known to work
|
||||
}
|
||||
Console.WriteLine(".NET Fallback Language/Locale:" + netLanguage + " (application-specific)");
|
||||
Debug.WriteLine(".NET Fallback Language/Locale:" + netLanguage + " (application-specific)");
|
||||
return netLanguage;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Bit.App.Utilities;
|
||||
using Foundation;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using UIKit;
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Platform.iOS;
|
||||
@@ -110,7 +111,7 @@ namespace Bit.iOS.Core.Views
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Toast needs a keyWindows to display.");
|
||||
Debug.WriteLine("Toast needs a keyWindows to display.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.8bit.bitwarden.find-login-action-extension</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2022.12.0</string>
|
||||
<string>2023.1.1</string>
|
||||
<key>CFBundleLocalizations</key>
|
||||
<array>
|
||||
<string>en</string>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2022.12.0</string>
|
||||
<string>2023.1.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.8bit.bitwarden</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2022.12.0</string>
|
||||
<string>2023.1.1</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CFBundleIconName</key>
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 473 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 691 B After Width: | Height: | Size: 899 B |
|
Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.0 KiB |
34
src/watchOS/bitwarden/GoogleService-Info.plist
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CLIENT_ID</key>
|
||||
<string>___________</string>
|
||||
<key>REVERSED_CLIENT_ID</key>
|
||||
<string>___________</string>
|
||||
<key>API_KEY</key>
|
||||
<string>___________</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>___________</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>com.8bit.bitwarden.watchkitapp.watchkitextension</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>___________</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>___________</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false/>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false/>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<true/>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true/>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true/>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>___________</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,11 @@
|
||||
import WatchKit
|
||||
import FirebaseCore
|
||||
|
||||
class ExtensionDelegate: NSObject, WKExtensionDelegate {
|
||||
|
||||
func applicationDidFinishLaunching() {
|
||||
#if !DEBUG
|
||||
FirebaseApp.configure()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class CryptoService{
|
||||
let item = try JSONDecoder().decode(type, from: decryptedData)
|
||||
return item
|
||||
} catch {
|
||||
assertionFailure("Fail to decode item for keychain: \(error)")
|
||||
Log.e("Fail to decode item for keychain: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct bitwardenApp: App {
|
||||
struct bitwardenApp: App {
|
||||
@WKExtensionDelegateAdaptor(ExtensionDelegate.self) var delegate
|
||||
|
||||
@SceneBuilder var body: some Scene {
|
||||
WindowGroup {
|
||||
NavigationView {
|
||||
|
||||
@@ -35,6 +35,11 @@
|
||||
1B59EC632901B1C100A8718D /* LoggerHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B59EC622901B1C100A8718D /* LoggerHelper.swift */; };
|
||||
1B5AFF0329196C81004478F9 /* ColorUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B5AFF0229196C81004478F9 /* ColorUtils.swift */; };
|
||||
1B5AFF0729197822004478F9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 1B5AFF0929197822004478F9 /* Localizable.strings */; };
|
||||
1B5BE451295A08A900E0C323 /* FirebaseCrashlytics in Frameworks */ = {isa = PBXBuildFile; productRef = 1B5BE450295A08A900E0C323 /* FirebaseCrashlytics */; };
|
||||
1B5BE453295A08C600E0C323 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B5BE452295A08C600E0C323 /* ExtensionDelegate.swift */; };
|
||||
1B5BE45E295B472C00E0C323 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1B5BE45D295B472C00E0C323 /* GoogleService-Info.plist */; };
|
||||
1B5BE45F295B472C00E0C323 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1B5BE45D295B472C00E0C323 /* GoogleService-Info.plist */; };
|
||||
1B5BE460295B472C00E0C323 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1B5BE45D295B472C00E0C323 /* GoogleService-Info.plist */; };
|
||||
1B5F5E38293F9CF8009B5FCC /* TrackableWithHeaderListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B5F5E37293F9CF8009B5FCC /* TrackableWithHeaderListView.swift */; };
|
||||
1B5F5E3A293F9D6F009B5FCC /* ViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B5F5E39293F9D6F009B5FCC /* ViewExtensions.swift */; };
|
||||
1B5F5E3E293FBB17009B5FCC /* CipherItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B5F5E3D293FBB17009B5FCC /* CipherItemView.swift */; };
|
||||
@@ -144,6 +149,8 @@
|
||||
1B59EC622901B1C100A8718D /* LoggerHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerHelper.swift; sourceTree = "<group>"; };
|
||||
1B5AFF0229196C81004478F9 /* ColorUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorUtils.swift; sourceTree = "<group>"; };
|
||||
1B5AFF0829197822004478F9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
1B5BE452295A08C600E0C323 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = "<group>"; };
|
||||
1B5BE45D295B472C00E0C323 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||
1B5F5E37293F9CF8009B5FCC /* TrackableWithHeaderListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackableWithHeaderListView.swift; sourceTree = "<group>"; };
|
||||
1B5F5E39293F9D6F009B5FCC /* ViewExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewExtensions.swift; sourceTree = "<group>"; };
|
||||
1B5F5E3D293FBB17009B5FCC /* CipherItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CipherItemView.swift; sourceTree = "<group>"; };
|
||||
@@ -190,6 +197,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1B5BE451295A08A900E0C323 /* FirebaseCrashlytics in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -230,6 +238,7 @@
|
||||
1B15612628B7F3D400610B9B = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1B5BE45D295B472C00E0C323 /* GoogleService-Info.plist */,
|
||||
1B15613128B7F3D400610B9B /* bitwarden */,
|
||||
1B15614128B7F3D700610B9B /* bitwarden WatchKit App */,
|
||||
1B15614C28B7F3D800610B9B /* bitwarden WatchKit Extension */,
|
||||
@@ -298,6 +307,7 @@
|
||||
1B15615D28B7F3D900610B9B /* PushNotificationPayload.apns */,
|
||||
1B15615928B7F3D900610B9B /* Preview Content */,
|
||||
1B15616D28B81A4300610B9B /* WatchConnectivityManager.swift */,
|
||||
1B5BE452295A08C600E0C323 /* ExtensionDelegate.swift */,
|
||||
);
|
||||
path = "bitwarden WatchKit Extension";
|
||||
sourceTree = "<group>";
|
||||
@@ -470,6 +480,9 @@
|
||||
dependencies = (
|
||||
);
|
||||
name = "bitwarden WatchKit Extension";
|
||||
packageProductDependencies = (
|
||||
1B5BE450295A08A900E0C323 /* FirebaseCrashlytics */,
|
||||
);
|
||||
productName = "bitwarden WatchKit Extension";
|
||||
productReference = 1B15614828B7F3D800610B9B /* bitwarden WatchKit Extension.appex */;
|
||||
productType = "com.apple.product-type.watchkit2-extension";
|
||||
@@ -504,6 +517,9 @@
|
||||
Base,
|
||||
);
|
||||
mainGroup = 1B15612628B7F3D400610B9B;
|
||||
packageReferences = (
|
||||
1B5BE44F295A08A900E0C323 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
|
||||
);
|
||||
productRefGroup = 1B15613028B7F3D400610B9B /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
@@ -522,6 +538,7 @@
|
||||
files = (
|
||||
1B15613A28B7F3D700610B9B /* Preview Assets.xcassets in Resources */,
|
||||
1B15613728B7F3D700610B9B /* Assets.xcassets in Resources */,
|
||||
1B5BE45E295B472C00E0C323 /* GoogleService-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -530,6 +547,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1B15614328B7F3D800610B9B /* Assets.xcassets in Resources */,
|
||||
1B5BE45F295B472C00E0C323 /* GoogleService-Info.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -538,6 +556,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1B15615B28B7F3D900610B9B /* Preview Assets.xcassets in Resources */,
|
||||
1B5BE460295B472C00E0C323 /* GoogleService-Info.plist in Resources */,
|
||||
1B5AFF0729197822004478F9 /* Localizable.strings in Resources */,
|
||||
1B15615828B7F3D900610B9B /* Assets.xcassets in Resources */,
|
||||
);
|
||||
@@ -600,6 +619,7 @@
|
||||
1B15616E28B81A4300610B9B /* WatchConnectivityManager.swift in Sources */,
|
||||
1B5AFF0329196C81004478F9 /* ColorUtils.swift in Sources */,
|
||||
1B59EC612900C48E00A8718D /* KeychainHelper.swift in Sources */,
|
||||
1B5BE453295A08C600E0C323 /* ExtensionDelegate.swift in Sources */,
|
||||
1B59EC5729007DEE00A8718D /* BitwardenDB.xcdatamodeld in Sources */,
|
||||
1B8BF90D2919BED9006F069E /* Base32.swift in Sources */,
|
||||
1B8453EC290C672E00F921E1 /* CipherEntity+CoreDataClass.swift in Sources */,
|
||||
@@ -827,6 +847,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = LTZ2PFU5D6;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IBSC_MODULE = bitwarden_WatchKit_Extension;
|
||||
@@ -984,6 +1005,25 @@
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
1B5BE44F295A08A900E0C323 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 9.6.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
1B5BE450295A08A900E0C323 /* FirebaseCrashlytics */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 1B5BE44F295A08A900E0C323 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
|
||||
productName = FirebaseCrashlytics;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
1B59EC5529007DEE00A8718D /* BitwardenDB.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "abseil-cpp-swiftpm",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/abseil-cpp-SwiftPM.git",
|
||||
"state" : {
|
||||
"revision" : "583de9bd60f66b40e78d08599cc92036c2e7e4e1",
|
||||
"version" : "0.20220203.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "boringssl-swiftpm",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/boringssl-SwiftPM.git",
|
||||
"state" : {
|
||||
"revision" : "dd3eda2b05a3f459fc3073695ad1b28659066eab",
|
||||
"version" : "0.9.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "firebase-ios-sdk",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/firebase-ios-sdk",
|
||||
"state" : {
|
||||
"revision" : "7e80c25b51c2ffa238879b07fbfc5baa54bb3050",
|
||||
"version" : "9.6.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "googleappmeasurement",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/GoogleAppMeasurement.git",
|
||||
"state" : {
|
||||
"revision" : "c1cfde8067668027b23a42c29d11c246152fe046",
|
||||
"version" : "9.6.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "googledatatransport",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/GoogleDataTransport.git",
|
||||
"state" : {
|
||||
"revision" : "5056b15c5acbb90cd214fe4d6138bdf5a740e5a8",
|
||||
"version" : "9.2.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "googleutilities",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/GoogleUtilities.git",
|
||||
"state" : {
|
||||
"revision" : "6db6edb48bdd9943426562c7f042a5492de5ba3d",
|
||||
"version" : "7.10.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "grpc-ios",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/grpc/grpc-ios.git",
|
||||
"state" : {
|
||||
"revision" : "8440b914756e0d26d4f4d054a1c1581daedfc5b6",
|
||||
"version" : "1.44.3-grpc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "gtm-session-fetcher",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/gtm-session-fetcher.git",
|
||||
"state" : {
|
||||
"revision" : "5ccda3981422a84186387dbb763ba739178b529c",
|
||||
"version" : "2.3.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "leveldb",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/leveldb.git",
|
||||
"state" : {
|
||||
"revision" : "0706abcc6b0bd9cedfbb015ba840e4a780b5159b",
|
||||
"version" : "1.22.2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "nanopb",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/firebase/nanopb.git",
|
||||
"state" : {
|
||||
"revision" : "819d0a2173aff699fb8c364b6fb906f7cdb1a692",
|
||||
"version" : "2.30909.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "promises",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/google/promises.git",
|
||||
"state" : {
|
||||
"revision" : "3e4e743631e86c8c70dbc6efdc7beaa6e90fd3bb",
|
||||
"version" : "2.1.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-protobuf",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-protobuf.git",
|
||||
"state" : {
|
||||
"revision" : "ab3a58b7209a17d781c0d1dbb3e1ff3da306bae8",
|
||||
"version" : "1.20.3"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
}
|
||||
@@ -122,31 +122,31 @@
|
||||
<comment>Max 30 characters</comment>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>Bitwarden, Inc. is the parent company of 8bit Solutions LLC.
|
||||
<value>„Bitwarden, Inc.“ е компанията-майка на „8bit Solutions LLC“.
|
||||
|
||||
NAMED BEST PASSWORD MANAGER BY THE VERGE, U.S. NEWS & WORLD REPORT, CNET, AND MORE.
|
||||
ОПРЕДЕЛЕН КАТО НАЙ-ДОБРИЯТ УПРАВИТЕЛ НА ПАРОЛИ ОТ „THE VERGE“, „U.S. NEWS & WORLD REPORT“, „CNET“ И ОЩЕ.
|
||||
|
||||
Manage, store, secure, and share unlimited passwords across unlimited devices from anywhere. Bitwarden delivers open source password management solutions to everyone, whether at home, at work, or on the go.
|
||||
Управлявайте, съхранявайте, защитавайте и споделяйте неограничен брой пароли на неограничен брой устройства от всяка точка на света. Битуорден предоставя решение за управление на паролите с отворен код, от което може да се възползва всеки, било то у дома, на работа или на път.
|
||||
|
||||
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
|
||||
Създавайте сигурни, уникални и случайни пароли според изискванията за сигурност на всеки уеб сайт, който посещавате.
|
||||
|
||||
Bitwarden Send quickly transmits encrypted information --- files and plaintext -- directly to anyone.
|
||||
С Изпращанията на Битуорден можете незабавно да предавате шифрована информация под формата на файлове и обикновен текст – директно и с всекиго.
|
||||
|
||||
Bitwarden offers Teams and Enterprise plans for companies so you can securely share passwords with colleagues.
|
||||
Битуорден предлага планове за екипи и големи фирми, така че служителите в компаниите да могат безопасно да споделят пароли помежду си.
|
||||
|
||||
Why Choose Bitwarden:
|
||||
Защо да изберете Битуорден:
|
||||
|
||||
World-Class Encryption
|
||||
Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private.
|
||||
Шифроване от най-висока класа
|
||||
Паролите са защитени със сложен шифър „от край до край“ (AES-256 bit, salted hashtag и PBKDF2 SHA-256), така че данните Ви остават да са защитени и неприкосновени.
|
||||
|
||||
Built-in Password Generator
|
||||
Generate strong, unique, and random passwords based on security requirements for every website you frequent.
|
||||
Вграден генератор на пароли
|
||||
Създавайте сигурни, уникални и случайни пароли според изискванията за сигурност на всеки уеб сайт, който посещавате.
|
||||
|
||||
Global Translations
|
||||
Bitwarden translations exist in 40 languages and are growing, thanks to our global community.
|
||||
Глобални преводи
|
||||
Битуорден е преведен на 40 езика и този брой не спира да расте, благодарение на нашата глобална общност.
|
||||
|
||||
Cross-Platform Applications
|
||||
Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more.
|
||||
Приложения за всяка система
|
||||
Защитете и споделяйте поверителните данни от своя трезор в Битуорден от всеки браузър, мобилно устройство или компютър.
|
||||
</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
|
||||
@@ -124,40 +124,40 @@
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>Bitwarden، Inc. شرکت مادر 8bit Solutions LLC است.
|
||||
|
||||
به عنوان بهترین مدیر رمز عبور توسط VERGE، US News & WORLD REPORT، CNET و دیگران انتخاب شد.
|
||||
به عنوان بهترین مدیر کلمه عبور توسط VERGE، US News & WORLD REPORT، CNET و دیگران انتخاب شد.
|
||||
|
||||
گذرواژههای با تعداد نامحدود را در دستگاههای نامحدود از هر کجا مدیریت کنید، ذخیره کنید، ایمن کنید و به اشتراک بگذارید. Bitwarden راه حل های مدیریت رمز عبور منبع باز را به همه ارائه می دهد، چه در خانه، چه در محل کار یا در حال حرکت.
|
||||
کلمه های هبور با تعداد نامحدود را در دستگاههای نامحدود از هر کجا مدیریت کنید، ذخیره کنید، ایمن کنید و به اشتراک بگذارید. Bitwarden راه حل های مدیریت کلمه عبور منبع باز را به همه ارائه می دهد، چه در خانه، چه در محل کار یا در حال حرکت.
|
||||
|
||||
بر اساس الزامات امنیتی برای هر وب سایتی که بازدید می کنید، رمزهای عبور قوی، منحصر به فرد و تصادفی ایجاد کنید.
|
||||
بر اساس الزامات امنیتی برای هر وب سایتی که بازدید می کنید، کلمههای عبور قوی، منحصر به فرد و تصادفی ایجاد کنید.
|
||||
|
||||
Bitwarden Send به سرعت اطلاعات رمزگذاری شده --- فایل ها و متن ساده - را مستقیماً به هر کسی منتقل می کند.
|
||||
Bitwarden Send به سرعت اطلاعات رمزگذاری شده --- فایل ها و متن ساده - را مستقیماً به هر کسی منتقل میکند.
|
||||
|
||||
Bitwarden برنامههای Teams و Enterprise را برای شرکتها ارائه میدهد تا بتوانید بهطور ایمن گذرواژهها را با همکاران خود به اشتراک بگذارید.
|
||||
|
||||
چرا Bitwarden را انتخاب کنید:
|
||||
|
||||
رمزگذاری در کلاس جهانی
|
||||
گذرواژهها با رمزگذاری پیشرفته (AES-256 بیت، هشتگ سالت و PBKDF2 SHA-256) محافظت میشوند تا دادههای شما امن و خصوصی بمانند.
|
||||
کلمههای عبور با رمزگذاری پیشرفته (AES-256 بیت، هشتگ سالت و PBKDF2 SHA-256) محافظت میشوند تا دادههای شما امن و خصوصی بمانند.
|
||||
|
||||
تولیدکننده رمز عبور داخلی
|
||||
بر اساس الزامات امنیتی برای هر وب سایتی که بازدید می کنید، رمزهای عبور قوی، منحصر به فرد و تصادفی ایجاد کنید.
|
||||
تولیدکننده کلمه عبور داخلی
|
||||
بر اساس الزامات امنیتی برای هر وب سایتی که بازدید می کنید، کلمههای عبور قوی، منحصر به فرد و تصادفی ایجاد کنید.
|
||||
|
||||
ترجمه های جهانی
|
||||
ترجمه Bitwarden به 40 زبان وجود دارد و به لطف جامعه جهانی ما در حال رشد است.
|
||||
|
||||
برنامه های کاربردی چند پلتفرمی
|
||||
داده های حساس را در Bitwarden Vault خود از هر مرورگر، دستگاه تلفن همراه یا سیستم عامل دسکتاپ و غیره ایمن کنید و به اشتراک بگذارید.</value>
|
||||
دادههای حساس را در Bitwarden Vault خود از هر مرورگر، دستگاه تلفن همراه یا سیستم عامل دسکتاپ و غیره ایمن کنید و به اشتراک بگذارید.</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
<data name="Keywords" xml:space="preserve">
|
||||
<value>بیت واردن، 8bit، رمز عبور، مدیر رمز عبور رایگان، مدیر رمز عبور، مدیر ورود به سیستم</value>
|
||||
<value>بیت واردن، 8bit، رمز عبور، مدیر کلمه عبور رایگان، مدیر کلمه عبور، مدیر ورود به سیستم</value>
|
||||
<comment>Max 100 characters</comment>
|
||||
</data>
|
||||
<data name="Screenshot1" xml:space="preserve">
|
||||
<value>مدیریت تمام اطلاعات ورود و رمزهای عبورتان از یک گاوصندوق امن</value>
|
||||
<value>مدیریت تمام اطلاعات ورود و کلمههای عبورتان از یک گاوصندوق امن</value>
|
||||
</data>
|
||||
<data name="Screenshot2" xml:space="preserve">
|
||||
<value>به صورت خودکار کلمات عبور قوی، تصادفی و امن ایجاد کنید</value>
|
||||
<value>به صورت خودکار کلمههای عبور قوی، تصادفی و امن ایجاد کنید</value>
|
||||
</data>
|
||||
<data name="Screenshot3" xml:space="preserve">
|
||||
<value>گاوصندوق خود را با اثر انگشت، کد پین یا رمز عبور اصلی محافظت کنید</value>
|
||||
@@ -166,6 +166,6 @@ Bitwarden برنامههای Teams و Enterprise را برای شرکته
|
||||
<value>ورود خودکار از سافاری، کروم، و صدها برنامه دیگر</value>
|
||||
</data>
|
||||
<data name="Screenshot5" xml:space="preserve">
|
||||
<value>همگام سازی و دسترسی به گاوصندوق خود را از دستگاه های مختلف</value>
|
||||
<value>همگام سازی و دسترسی به گاوصندوق خود از دستگاه های مختلف</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Bitwarden</value>
|
||||
<value>Bitwarden - Gestionnaire de mots de passe</value>
|
||||
<comment>Max 30 characters</comment>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
@@ -126,27 +126,28 @@
|
||||
|
||||
NOMMÉ MEILLEUR GESTIONNAIRE DE MOTS DE PASSE PAR THE VERGE, U.S. NEWS & WORLD REPORT, CNET, ET PLUS ENCORE.
|
||||
|
||||
Gérez, stockez, sécurisez et partagez un nombre illimité de mots de passe sur un nombre illimité d'appareils, où que vous soyez. Bitwarden fournit des solutions de gestion de mots de passe open source à tout le monde, que ce soit à la maison, au travail ou en déplacement.
|
||||
Gérez, stockez, sécurisez et partagez un nombre illimité de mots de passe sur un nombre illimité d'appareils, où que vous soyez. Bitwarden fournit des solutions de gestion de mots de passe open source à tout le monde, que ce soit chez soi, au travail ou en déplacement.
|
||||
|
||||
Générez des mots de passe forts, uniques et aléatoires basés sur des exigences de sécurité pour chaque site web que vous fréquentez.
|
||||
Générez des mots de passe robustes, uniques et aléatoires basés sur des exigences de sécurité pour chaque site web que vous fréquentez.
|
||||
|
||||
Bitwarden Send transmet rapidement des informations chiffrées --- fichiers et texte --- directement à quiconque.
|
||||
|
||||
Bitwarden propose les plans Teams et Enterprise pour les entreprises afin que vous puissiez partager des mots de passe en toute sécurité avec vos collègues.
|
||||
Bitwarden propose des plans Teams et Enterprise pour les sociétés afin que vous puissiez partager des mots de passe en toute sécurité avec vos collègues.
|
||||
|
||||
Pourquoi choisir Bitwarden :
|
||||
|
||||
Un chiffrement de classe internationale
|
||||
Les mots de passe sont protégés par un chiffrement avancé de bout en bout (AES-256 bit, salted hashtag, et PBKDF2 SHA-256) afin que vos données restent sécurisées et privées.
|
||||
Les mots de passe sont protégés par un cryptage avancé de bout en bout (AES-256 bit, hachage salé et PBKDF2 SHA-256) afin que vos données restent sécurisées et privées.
|
||||
|
||||
Générateur de mots de passe intégré
|
||||
Générez des mots de passe forts, uniques et aléatoires en fonction des exigences de sécurité pour chaque site web que vous fréquentez.
|
||||
|
||||
Traductions mondiales
|
||||
Les traductions de Bitwarden existent dans 40 langues et ne cessent de croître, grâce à notre communauté mondiale.
|
||||
Traductions internationales
|
||||
Les traductions de Bitwarden existent dans 40 langues et ne cessent de croître, grâce à notre communauté globale.
|
||||
|
||||
Applications multiplateformes
|
||||
Sécurisez et partagez des données sensibles dans votre coffre-fort Bitwarden à partir de n'importe quel navigateur, appareil mobile ou système d'exploitation de bureau, et plus encore.</value>
|
||||
Applications multiplateformes
|
||||
Sécurisez et partagez des données sensibles dans votre coffre Bitwarden à partir de n'importe quel navigateur, appareil mobile ou système d'exploitation de bureau, et plus encore.
|
||||
</value>
|
||||
<comment>Max 4000 characters</comment>
|
||||
</data>
|
||||
<data name="Keywords" xml:space="preserve">
|
||||
@@ -157,13 +158,13 @@ Sécurisez et partagez des données sensibles dans votre coffre-fort Bitwarden
|
||||
<value>Gérer tous vos identifiants et mots de passe depuis un coffre sécurisé</value>
|
||||
</data>
|
||||
<data name="Screenshot2" xml:space="preserve">
|
||||
<value>Générer automatiquement des mots de passe forts, aléatoires et sécurisés</value>
|
||||
<value>Générer automatiquement des mots de passe robustes, aléatoires et sécurisés</value>
|
||||
</data>
|
||||
<data name="Screenshot3" xml:space="preserve">
|
||||
<value>Protéger votre coffre avec Touch ID, un code PIN, ou un mot de passe maître</value>
|
||||
<value>Protéger votre coffre avec Touch ID, un code PIN ou un mot de passe principal</value>
|
||||
</data>
|
||||
<data name="Screenshot4" xml:space="preserve">
|
||||
<value>Remplissage automatique des identifiants depuis Safari, Chrome et des centaines d'autres applications</value>
|
||||
<value>Saisie automatique des identifiants depuis Safari, Chrome et des centaines d'autres applications</value>
|
||||
</data>
|
||||
<data name="Screenshot5" xml:space="preserve">
|
||||
<value>Synchroniser et accéder à votre coffre depuis plusieurs appareils</value>
|
||||
|
||||