From 39e4b5775a511f5b1533f919819e762342f1ae44 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:50:46 +0200 Subject: [PATCH 01/93] Autosync the updated translations (#14117) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 30 +- apps/desktop/src/locales/ar/messages.json | 40 +-- apps/desktop/src/locales/az/messages.json | 36 +-- apps/desktop/src/locales/be/messages.json | 30 +- apps/desktop/src/locales/bg/messages.json | 30 +- apps/desktop/src/locales/bn/messages.json | 30 +- apps/desktop/src/locales/bs/messages.json | 30 +- apps/desktop/src/locales/ca/messages.json | 30 +- apps/desktop/src/locales/cs/messages.json | 30 +- apps/desktop/src/locales/cy/messages.json | 30 +- apps/desktop/src/locales/da/messages.json | 30 +- apps/desktop/src/locales/de/messages.json | 30 +- apps/desktop/src/locales/el/messages.json | 30 +- apps/desktop/src/locales/en_GB/messages.json | 30 +- apps/desktop/src/locales/en_IN/messages.json | 30 +- apps/desktop/src/locales/eo/messages.json | 322 +++++++++---------- apps/desktop/src/locales/es/messages.json | 30 +- apps/desktop/src/locales/et/messages.json | 30 +- apps/desktop/src/locales/eu/messages.json | 30 +- apps/desktop/src/locales/fa/messages.json | 30 +- apps/desktop/src/locales/fi/messages.json | 30 +- apps/desktop/src/locales/fil/messages.json | 30 +- apps/desktop/src/locales/fr/messages.json | 30 +- apps/desktop/src/locales/gl/messages.json | 30 +- apps/desktop/src/locales/he/messages.json | 30 +- apps/desktop/src/locales/hi/messages.json | 30 +- apps/desktop/src/locales/hr/messages.json | 30 +- apps/desktop/src/locales/hu/messages.json | 30 +- apps/desktop/src/locales/id/messages.json | 30 +- apps/desktop/src/locales/it/messages.json | 30 +- apps/desktop/src/locales/ja/messages.json | 30 +- apps/desktop/src/locales/ka/messages.json | 30 +- apps/desktop/src/locales/km/messages.json | 30 +- apps/desktop/src/locales/kn/messages.json | 30 +- apps/desktop/src/locales/ko/messages.json | 30 +- apps/desktop/src/locales/lt/messages.json | 30 +- apps/desktop/src/locales/lv/messages.json | 30 +- apps/desktop/src/locales/me/messages.json | 30 +- apps/desktop/src/locales/ml/messages.json | 30 +- apps/desktop/src/locales/mr/messages.json | 30 +- apps/desktop/src/locales/my/messages.json | 30 +- apps/desktop/src/locales/nb/messages.json | 30 +- apps/desktop/src/locales/ne/messages.json | 30 +- apps/desktop/src/locales/nl/messages.json | 30 +- apps/desktop/src/locales/nn/messages.json | 30 +- apps/desktop/src/locales/or/messages.json | 30 +- apps/desktop/src/locales/pl/messages.json | 30 +- apps/desktop/src/locales/pt_BR/messages.json | 146 ++++----- apps/desktop/src/locales/pt_PT/messages.json | 30 +- apps/desktop/src/locales/ro/messages.json | 30 +- apps/desktop/src/locales/ru/messages.json | 30 +- apps/desktop/src/locales/si/messages.json | 30 +- apps/desktop/src/locales/sk/messages.json | 30 +- apps/desktop/src/locales/sl/messages.json | 30 +- apps/desktop/src/locales/sr/messages.json | 32 +- apps/desktop/src/locales/sv/messages.json | 30 +- apps/desktop/src/locales/te/messages.json | 30 +- apps/desktop/src/locales/th/messages.json | 30 +- apps/desktop/src/locales/tr/messages.json | 30 +- apps/desktop/src/locales/uk/messages.json | 30 +- apps/desktop/src/locales/vi/messages.json | 30 +- apps/desktop/src/locales/zh_CN/messages.json | 38 +-- apps/desktop/src/locales/zh_TW/messages.json | 30 +- 63 files changed, 406 insertions(+), 1918 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index e288e9e70cc..c204a8e3d00 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Gaan Voort" }, - "enterVerificationCodeApp": { - "message": "Voer die 6-syferbevestigingskode van u waarmerktoep in." - }, - "enterVerificationCodeEmail": { - "message": "Voer die 8-syferbevestigingskode in wat aan $EMAIL$ gestuur is.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pos met bevestigingskode is na $EMAIL$ gestuur.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Onthou my" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Stuur weer e-pos met bevestigingskode" - }, - "useAnotherTwoStepMethod": { - "message": "Gebruik ’n ander tweestapaantekenmetode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Plaas u YubiKey in u rekenaar se USB-poort en druk dan op sy knop." - }, "insertU2f": { "message": "Plaas u beveilingsleutel in u rekenaar se USB-poort. Indien dit ’n knop het, druk dit dan." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index 7de8ecb50f5..dca2856b74d 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -250,17 +250,17 @@ "message": "خطأ" }, "decryptionError": { - "message": "Decryption error" + "message": "خطأ في فك التشفير" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "تعذّر على Bitwarden فك تشفير عنصر(العناصر) المخزنة في الخزنة والمذكورة أدناه" }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "فريق نجاح العملاء", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "لتجنب فقدان بيانات إضافية.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "january": { @@ -649,7 +649,7 @@ "message": "تسجيل الدخول إلى Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "أدخل الرمز الذي تم إرساله إلى بريدك الإلكتروني." }, "enterTheCodeFromYourAuthenticatorApp": { "message": "Enter the code from your authenticator app" @@ -833,18 +833,6 @@ "continue": { "message": "متابعة" }, - "enterVerificationCodeApp": { - "message": "أدخل رمز التحقق من 6 أرقام من تطبيق المصادقة الخاص بك." - }, - "enterVerificationCodeEmail": { - "message": "أدخل رمز التحقق المكون من 6 أرقام الذي تم إرساله إلى $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "تم إرسال رسالة التحقق إلى $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "تذكرني" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "إرسال رمز التحقق إلى البريد الإلكتروني مرة أخرى" - }, - "useAnotherTwoStepMethod": { - "message": "استخدام طريقة أخرى لتسجيل الدخول بخطوتين" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "أدخل YubiKey الخاص بك في منفذ USB في كمبيوترك، ثم لمس الزر." - }, "insertU2f": { "message": "أدخل مفتاح الأمان الخاص بك في منفذ USB كمبيوترك، إذا كان يحتوي على زر، إلمسه." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "خطأ في الاتصال بخدمة Duo. استخدم طريقة تسجيل الدخول بخطوتين مختلفة أو اتصل بـ Duo للمساعدة." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "قم بتشغيل دوو واتبع الخطوات لإنهاء تسجيل الدخول." - }, "duoRequiredByOrgForAccount": { "message": "تسجيل الدخول لـ Duo من خطوتين مطلوب لحسابك." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 738944f1791..eb347605fa4 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -801,7 +801,7 @@ "message": "Element məlumatları" }, "noItemsInList": { - "message": "Siyahılanacaq heç bir element yoxdur." + "message": "Sadalanacaq heç bir element yoxdur." }, "sendVerificationCode": { "message": "Doğrulama kodunu e-poçtunuza göndərin" @@ -833,18 +833,6 @@ "continue": { "message": "Davam" }, - "enterVerificationCodeApp": { - "message": "Kimlik doğrulayıcı tətbiqindən 6 rəqəmli doğrulama kodunu daxil edin." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ ünvanına göndərilən e-poçtdakı 6 rəqəmli doğrulama kodunu daxil edin.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Doğrulama poçtu $EMAIL$ ünvanına göndərildi.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Məni xatırla" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Bu cihazda 30 gün ərzində soruşulmasın" }, - "sendVerificationCodeEmailAgain": { - "message": "Doğrulama kodu olan e-poçtu yenidən göndər" - }, - "useAnotherTwoStepMethod": { - "message": "Başqa bir iki mərhələli giriş metodu istifadə edin" - }, "selectAnotherMethod": { "message": "Başqa üsul seçin", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Geri qaytarma kodunuzu istifadə edin" }, - "insertYubiKey": { - "message": "\"YubiKey\"i kompüterinizin USB portuna taxın, daha sonra düyməsinə toxunun." - }, "insertU2f": { "message": "Güvənlik açarını kompüterinizin USB portuna taxın. Düyməsi varsa toxunun." }, @@ -1447,7 +1423,7 @@ "description": "To clear something out. example: To clear browser history." }, "noPasswordsInList": { - "message": "Siyahılanacaq heç bir parol yoxdur." + "message": "Sadalanacaq heç bir parol yoxdur." }, "clearHistory": { "message": "Tarixçəni təmizlə" @@ -1718,7 +1694,7 @@ "message": "Heç bir təşkilata aid deyilsiniz. Təşkilatlar, elementlərinizi digər istifadəçilərlə güvənli şəkildə paylaşmağınızı təmin edir." }, "noCollectionsInList": { - "message": "Siyahılanacaq heç bir kolleksiya yoxdur." + "message": "Sadalanacaq heç bir kolleksiya yoxdur." }, "ownership": { "message": "Sahiblik" @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo xidmətinə bağlanarkən xəta baş verdi. Fərqli iki addımlı giriş üsulu istifadə edin və ya kömək üçün Duo ilə əlaqə saxlayın." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Duo-nu başladın və giriş prosesini tamamlamaq üçün addımları izləyin." - }, "duoRequiredByOrgForAccount": { "message": "Hesabınız üçün Duo iki addımlı giriş tələb olunur." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Riskli parolları dəyişdir" + }, + "move": { + "message": "Daşı" } } diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index ef73dcb3ed3..3f3cc67d3cf 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Працягнуць" }, - "enterVerificationCodeApp": { - "message": "Увядзіце 6 лічбаў праверачнага кода з вашай праграмы аўтэнтыфікацыі." - }, - "enterVerificationCodeEmail": { - "message": "Увядзіце 6 лічбаў праверачнага кода, які быў адпраўлены на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Праверачны ліст адпраўлены на $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Запомніць мяне" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Адправіць праверачны код яшчэ раз" - }, - "useAnotherTwoStepMethod": { - "message": "Выкарыстоўваць іншы метад двухэтапнага ўваходу" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Устаўце свой YubiKey у порт USB камп'ютара, а потым націсніце на кнопку." - }, "insertU2f": { "message": "Устаўце ваш ключ бяспекі ў порт USB камп'ютара. Калі на ім ёсць кнопка, націсніце на яе." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index c9bae830eff..c565f67df59 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Продължаване" }, - "enterVerificationCodeApp": { - "message": "Въведете шестцифрения код за потвърждение от приложението за удостоверяване." - }, - "enterVerificationCodeEmail": { - "message": "Въведете шестцифрения код за потвърждение, който е бил изпратен на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Писмото за потвърждение е изпратено на $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Запомняне" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не ме питайте отново на това устройство за 30 дни" }, - "sendVerificationCodeEmailAgain": { - "message": "Повторно изпращане на писмото за потвърждение" - }, - "useAnotherTwoStepMethod": { - "message": "Използвайте друг начин на двустепенно удостоверяване" - }, "selectAnotherMethod": { "message": "Изберете друг метод", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Използване на код за възстановяване" }, - "insertYubiKey": { - "message": "Поставете устройството на YubiKey в USB порт на компютъра и натиснете бутона на устройството." - }, "insertU2f": { "message": "Поставете устройството за удостоверяване в USB порт на компютъра. Ако на устройството има бутон, натиснете го." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Грешка при свързването с услугата на Duo. Използвайте друг метод за двустепенно удостоверяване или се свържете с Duo за съдействие." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Стартирайте Duo и следвайте инструкциите, за да завършите вписването." - }, "duoRequiredByOrgForAccount": { "message": "Вашата регистрация изисква двустепенно удостоверяване чрез Duo." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Промяна на парола в риск" + }, + "move": { + "message": "Преместване" } } diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 440462cf5d3..9343f95a5ef 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "অবিরত" }, - "enterVerificationCodeApp": { - "message": "আপনার প্রমাণীকরণকারী অ্যাপ থেকে ৬ সংখ্যার যাচাইকরণ কোডটি প্রবেশ করুন।" - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ এ ইমেইল করা ৬ সংখ্যার যাচাই কোডটি প্রবেশ করুন।", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ এ যাচাইকরণ ইমেইল প্রেরণ করা হয়েছে।", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "আমাকে মনে রাখবেন" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "আবার যাচাইকরণ কোড ইমেইলে প্রেরণ করুন" - }, - "useAnotherTwoStepMethod": { - "message": "অন্য দ্বি-পদক্ষেপ প্রবেশ পদ্ধতি ব্যবহার করুন" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "আপনার কম্পিউটারের ইউএসবি পোর্টে আপনার YubiKey ঢোকান, তারপরে তার বোতামটি স্পর্শ করুন।" - }, "insertU2f": { "message": "আপনার কম্পিউটারের ইউএসবি পোর্টে আপনার সুরক্ষা কী ঢোকান। এটিতে যদি একটি বোতাম থাকে তবে তা স্পর্শ করুন।" }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 4fb9697a2c9..a3e915a4bfe 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Nastavi" }, - "enterVerificationCodeApp": { - "message": "Unesite 6-ocifreni verifikacioni kod iz Vaše aplikacije za potvrdu autentičnosti." - }, - "enterVerificationCodeEmail": { - "message": "Unesite 6-ocifreni verifikacioni kod koji je E-Mailom poslan na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifikacijski E-Mail poslan je na $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovo pošaljite E-Mail sa verifikacionim kodom" - }, - "useAnotherTwoStepMethod": { - "message": "Koristite drugi način prijavljivanja u dva koraka" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Ubaci svoj YubiKey u USB slot računara, a zatim dodirni njegovu tipku." - }, "insertU2f": { "message": "Ubaci svoj sigurnosni ključ u USB slot kompjutera. Ako ima tipku, dodirni je." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index dbba24a9050..a368009b1d2 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continua" }, - "enterVerificationCodeApp": { - "message": "Introduïu el codi de verificació de 6 dígits de l'aplicació autenticadora." - }, - "enterVerificationCodeEmail": { - "message": "Introduïu el codi de verificació de 6 dígits que s'ha enviat per correu electrònic a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Correu electrònic de verificació enviat a $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Recorda'm" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Envia el codi de verificació altra vegada" - }, - "useAnotherTwoStepMethod": { - "message": "Utilitzeu un altre mètode d'inici de sessió en dues passes" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Introduïu la vostra YubiKey al port USB de l'ordinador i, a continuació, premeu el seu botó." - }, "insertU2f": { "message": "Introduïu la vostra clau de seguretat al port USB de l'ordinador. Si té un botó, premeu-lo." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "S'ha produït un error en connectar amb el servei Duo. Utilitzeu un mètode d'inici de sessió en dos passos diferent o poseu-vos en contacte amb Duo per obtenir ajuda." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicieu DUO i seguiu els passos per finalitzar la sessió." - }, "duoRequiredByOrgForAccount": { "message": "Es requereix l'inici de sessió en dos passos de DUO al vostre compte." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index c4d61da936b..236278b3c5a 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Pokračovat" }, - "enterVerificationCodeApp": { - "message": "Zadejte 6místný kód z ověřovací aplikace." - }, - "enterVerificationCodeEmail": { - "message": "Zadejte 6místný kód z e-mailu, který byl zaslán na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Ověřovací e-mail byl zaslán na $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapamatovat mě" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Neptat se na tomto zařízení 30 dnů" }, - "sendVerificationCodeEmailAgain": { - "message": "Znovu zaslat ověřovací kód na e-mail" - }, - "useAnotherTwoStepMethod": { - "message": "Použít jinou metodu dvoufázového přihlášení" - }, "selectAnotherMethod": { "message": "Vybrat jinou metodu", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Použít obnovovací kód" }, - "insertYubiKey": { - "message": "Vložte YubiKey do USB portu Vašeho počítače a stiskněte jeho tlačítko." - }, "insertU2f": { "message": "Vložte svůj bezpečnostní klíč do USB portu Vašeho počítače a pokud má tlačítko, tak jej stiskněte." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Chyba při připojování ke službě Duo. Použijte jinou dvoufázovou metodu přihlášení nebo kontaktujte Duo o pomoc." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Spusťte DUO a pro dokončení přihlášení postupujte podle kroků." - }, "duoRequiredByOrgForAccount": { "message": "Pro Váš účet je vyžadováno dvoufázové přihlášení DUO." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Změnit ohrožené heslo" + }, + "move": { + "message": "Přesunout" } } diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index 5f06fd762f4..2657e0cb942 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index e11aef18e14..8e5fbd90b68 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Fortsæt" }, - "enterVerificationCodeApp": { - "message": "Angiv den 6-cifrede bekræftelseskode fra godkendelses-appen." - }, - "enterVerificationCodeEmail": { - "message": "Angiv den 6-cifrede bekræftelseskode, der blev sendt til $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Bekræftelsese-mail sendt til $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Husk mig" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send bekræftelseskodee-mail igen" - }, - "useAnotherTwoStepMethod": { - "message": "Brug en anden totrins-loginmetode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Indsæt din YubiKey i din computers USB-port og tryk derefter på dens knap." - }, "insertU2f": { "message": "Indsæt din sikkerhedsnøgle i din computers USB-port. Hvis den har en knap, tryk på den." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fejl under forbindelsesoprettelsen til Duo-tjenesten. Brug en anden totrins-indlogningsmetode eller kontakt Duo for hjælp." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Start Duo og følg trinnene for at fuldføre indlogningen." - }, "duoRequiredByOrgForAccount": { "message": "Duo totrinsindlogning kræves for kontoen." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index b28c2fced1d..0433e68d761 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Weiter" }, - "enterVerificationCodeApp": { - "message": "Gib den 6-stelligen Verifizierungscode aus deiner Authentifizierungs-App ein." - }, - "enterVerificationCodeEmail": { - "message": "Gib den 6-stelligen Verifizierungscode ein, der an $EMAIL$ gesendet wurde.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifizierungsmail wurde an $EMAIL$ gesendet.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Angemeldet bleiben" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Für 30 Tage auf diesem Gerät nicht mehr fragen" }, - "sendVerificationCodeEmailAgain": { - "message": "E-Mail mit Bestätigungscode erneut versenden" - }, - "useAnotherTwoStepMethod": { - "message": "Eine andere Zwei-Faktor-Anmeldemethode verwenden" - }, "selectAnotherMethod": { "message": "Wähle eine andere Methode", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Verwende deinen Wiederherstellungscode" }, - "insertYubiKey": { - "message": "Stecke deinen YubiKey in einen USB-Anschluss deines Computers, dann berühre den Button." - }, "insertU2f": { "message": "Stecke deinen Sicherheitsschlüssel in einen USB-Anschluss deines Computers. Falls er einen Knopf hat, drücke diesen." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fehler beim Verbinden mit dem Duo-Dienst. Verwende eine andere Zwei-Faktor-Authentifizierungsmethode oder kontaktiere Duo für Hilfe." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Starte DUO und folge den Schritten, um die Anmeldung abzuschließen." - }, "duoRequiredByOrgForAccount": { "message": "Für dein Konto ist die DUO Zwei-Faktor-Authentifizierung erforderlich." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Gefährdetes Passwort ändern" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 9c59be2e0a7..168618ca6f3 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Συνέχεια" }, - "enterVerificationCodeApp": { - "message": "Εισάγετε τον 6ψήφιο κωδικό από την εφαρμογή επαλήθευσης." - }, - "enterVerificationCodeEmail": { - "message": "Εισάγετε τον 6ψήφιο κωδικό επαλήθευσης τον οποίο λάβατε στο $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Εστάλη email επαλήθευσης στο $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Να με θυμάσαι" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Επανάληψη αποστολής κωδικού επαλήθευσης μέσω ηλ. ταχυδρομείου" - }, - "useAnotherTwoStepMethod": { - "message": "Χρήση άλλης μεθόδου σύνδεσης δύο βημάτων" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Τοποθετήστε το YubiKey στη θύρα USB του υπολογιστή σας και έπειτα αγγίξτε το κουμπί του." - }, "insertU2f": { "message": "Εισάγετε το κλειδί ασφαλείας στη θύρα USB του υπολογιστή σας. Αν έχει κουμπί, πατήστε το." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Σφάλμα κατά τη σύνδεση με την υπηρεσία Duo. Χρησιμοποιήστε μια διαφορετική μέθοδο σύνδεσης δύο βημάτων ή επικοινωνήστε με την Duo για βοήθεια." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Εκκινήστε το Duo και ακολουθήστε τα βήματα για να ολοκληρώσετε τη σύνδεση." - }, "duoRequiredByOrgForAccount": { "message": "Η σύνδεση δύο βημάτων Duo απαιτείται για τον λογαριασμό σας." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 74e43b24076..81eba8202d1 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index 3ec9e17769b..6d75ce10763 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 2dfdcdd9484..48b0600724d 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -154,7 +154,7 @@ "message": "Eksvalidiĝo" }, "securityCode": { - "message": "Kodo de sekureco" + "message": "Kodo por sekureco" }, "identityName": { "message": "Identecnomo" @@ -169,7 +169,7 @@ "message": "Numero de pasporto" }, "licenseNumber": { - "message": "License number" + "message": "Numero de permesilo" }, "email": { "message": "Retpoŝtadreso" @@ -334,22 +334,22 @@ "message": "Alia" }, "generatePassword": { - "message": "Generate password" + "message": "Generi pasvorton" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Generi pasfrazon" }, "type": { "message": "Tipo" }, "firstName": { - "message": "First name" + "message": "Persona nomo" }, "middleName": { "message": "Middle name" }, "lastName": { - "message": "Last name" + "message": "Familia nomo" }, "fullName": { "message": "Plena nomo" @@ -364,7 +364,7 @@ "message": "Adreso 3" }, "cityTown": { - "message": "City / Town" + "message": "Urbo / Urbeto" }, "stateProvince": { "message": "State / Province" @@ -394,10 +394,10 @@ "message": "Authenticator key (TOTP)" }, "folder": { - "message": "Folder" + "message": "Dosierujo" }, "newCustomField": { - "message": "New custom field" + "message": "Nova propra kampo" }, "value": { "message": "Valoro" @@ -419,38 +419,38 @@ "description": "This describes a field that is 'linked' (related) to another field." }, "linkedValue": { - "message": "Linked value", + "message": "Ligita valoro", "description": "This describes a value that is 'linked' (related) to another value." }, "remove": { "message": "Forigi" }, "nameRequired": { - "message": "Name is required." + "message": "Necesas la nomo." }, "addedItem": { - "message": "Item added" + "message": "La ero aldoniĝis" }, "editedItem": { - "message": "Item saved" + "message": "La ero konserviĝis" }, "deleteItem": { - "message": "Delete item" + "message": "Forigi la eron" }, "deleteFolder": { - "message": "Delete folder" + "message": "Forigi la dosierujon" }, "deleteAttachment": { - "message": "Delete attachment" + "message": "Forigi la aldonaĵon" }, "deleteItemConfirmation": { - "message": "Do you really want to send to the trash?" + "message": "Ĉu vi vere volas sendi al la rubujo?" }, "deletedItem": { - "message": "Item sent to trash" + "message": "La ero sendiĝis al la rubujo" }, "overwritePasswordConfirmation": { - "message": "Are you sure you want to overwrite the current password?" + "message": "Ĉu vi certas, ke vi volas superskribi la nunan pasvorton?" }, "overwriteUsername": { "message": "Overwrite username" @@ -488,24 +488,24 @@ "message": "Copy URI" }, "copyVerificationCodeTotp": { - "message": "Copy verification code (TOTP)" + "message": "Kopii la kontrolan kodon (TOTP)" }, "length": { - "message": "Length" + "message": "Longo" }, "passwordMinLength": { - "message": "Minimum password length" + "message": "Minimuma longo de pasvorto" }, "uppercase": { - "message": "Uppercase (A-Z)", + "message": "Majuskla (A-Z)", "description": "deprecated. Use uppercaseLabel instead." }, "lowercase": { - "message": "Lowercase (a-z)", + "message": "Minisukla (a-z)", "description": "deprecated. Use lowercaseLabel instead." }, "numbers": { - "message": "Numbers (0-9)", + "message": "Numeroj (0-9)", "description": "deprecated. Use numbersLabel instead." }, "specialCharacters": { @@ -544,10 +544,10 @@ "description": "Full description for the password generator special characters checkbox" }, "numWords": { - "message": "Number of words" + "message": "La nombro de la vortoj" }, "wordSeparator": { - "message": "Word separator" + "message": "Disigilo de la vortoj" }, "capitalize": { "message": "Capitalize", @@ -579,74 +579,74 @@ "description": "Indicates that a policy limits the credential generator screen." }, "searchCollection": { - "message": "Search collection" + "message": "Kolekto por serĉi" }, "searchFolder": { - "message": "Search folder" + "message": "Dosierujo por serĉi" }, "searchFavorites": { "message": "Search favorites" }, "searchType": { - "message": "Search type", + "message": "Tipo por serĉi", "description": "Search item type" }, "newAttachment": { - "message": "Add new attachment" + "message": "Aldoni novan aldonaĵon" }, "deletedAttachment": { - "message": "Attachment deleted" + "message": "Aldonaĵo foriĝis" }, "deleteAttachmentConfirmation": { - "message": "Are you sure you want to delete this attachment?" + "message": "Ĉu vi certas, ke vi volas forigi ĉi tiun aldonaĵon?" }, "attachmentSaved": { - "message": "Attachment saved" + "message": "Aldonaĵo konserviĝis" }, "file": { "message": "Dosiero" }, "selectFile": { - "message": "Select a file" + "message": "Elekti dosieron" }, "maxFileSize": { - "message": "Maximum file size is 500 MB." + "message": "La minimuma dosiergrando estas 500 MB" }, "encryptionKeyMigrationRequired": { "message": "Encryption key migration required. Please login through the web vault to update your encryption key." }, "editedFolder": { - "message": "Folder saved" + "message": "La dosierujo konserviĝis" }, "addedFolder": { - "message": "Folder added" + "message": "La dosierujo aldoniĝis" }, "deleteFolderConfirmation": { - "message": "Are you sure you want to delete this folder?" + "message": "Ĉu vi certas, ke vi volas forigi ĉi tiun dosierujon?" }, "deletedFolder": { - "message": "Folder deleted" + "message": "La dosierujo foriĝis" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, "createAccount": { - "message": "Create account" + "message": "Krei konton" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Novulo por Bitwarden?" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Ŝargi fortan pasvorton" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Finu krei vian konton per ŝargado de pasvorto" }, "logIn": { - "message": "Ensaluti" + "message": "Saluti" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Saluti en Bitwarden'on" }, "enterTheCodeSentToYourEmail": { "message": "Enter the code sent to your email" @@ -658,10 +658,10 @@ "message": "Press your YubiKey to authenticate" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Saluti per pasŝlosilo" }, "loginWithDevice": { - "message": "Log in with device" + "message": "Saluti per aparato" }, "useSingleSignOn": { "message": "Use single sign-on" @@ -670,7 +670,7 @@ "message": "Submit" }, "masterPass": { - "message": "Master password" + "message": "Ĉefa pasvorto" }, "masterPassDesc": { "message": "The master password is the password you use to access your vault. It is very important that you do not forget your master password. There is no way to recover the password in the event that you forget it." @@ -679,7 +679,7 @@ "message": "A master password hint can help you remember your password if you forget it." }, "reTypeMasterPass": { - "message": "Re-type master password" + "message": "Re-entajpu la ĉefan pasvorton" }, "masterPassHint": { "message": "Master password hint (optional)" @@ -698,13 +698,13 @@ } }, "masterPassword": { - "message": "Master password" + "message": "Ĉefa pasvorto" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "Via ĉefa pasvorto ne povas esti restarigita, se vi forgesas ĝin!" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Konfirmi la ĉefan pasvorton" }, "masterPassHintLabel": { "message": "Master password hint" @@ -737,7 +737,7 @@ "message": "Agordoj" }, "accountEmail": { - "message": "Account email" + "message": "La konta retpoŝto" }, "requestHint": { "message": "Request hint" @@ -783,13 +783,13 @@ "message": "Master password confirmation does not match." }, "newAccountCreated": { - "message": "Your new account has been created! You may now log in." + "message": "Via nova konto estas kreita! Vi eble ĵus salutis," }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "Via nova konto estas kreita!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "Vi estas en salutaĵo!" }, "masterPassSent": { "message": "We've sent you an email with your master password hint." @@ -804,22 +804,22 @@ "message": "There are no items to list." }, "sendVerificationCode": { - "message": "Send a verification code to your email" + "message": "Sendi kontrolan kodon al via retpoŝto" }, "sendCode": { - "message": "Send code" + "message": "Sendi kodon" }, "codeSent": { - "message": "Code sent" + "message": "Kodo sendiĝis" }, "verificationCode": { - "message": "Verification code" + "message": "La kontrola kodo" }, "confirmIdentity": { - "message": "Confirm your identity to continue." + "message": "Konfirmi vian identecon por daŭrigi" }, "verificationCodeRequired": { - "message": "Verification code is required." + "message": "Postulata estas la kontrola kodo." }, "webauthnCancelOrTimeout": { "message": "The authentication was cancelled or took too long. Please try again." @@ -833,18 +833,6 @@ "continue": { "message": "Daŭrigi" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,27 +842,15 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Elekti alian metodon", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" - }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." + "message": "Uzi vian restarigan kodon" }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." @@ -883,7 +859,7 @@ "message": "Lost access to all of your two-factor providers? Use your recovery code to turn off all two-factor providers on your account." }, "recoveryCodeTitle": { - "message": "Recovery code" + "message": "Restariga kodo" }, "authenticatorAppTitle": { "message": "Authenticator app" @@ -913,7 +889,7 @@ "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Daŭrigi salutadon" }, "webAuthnTitle": { "message": "FIDO2 WebAuthn" @@ -937,13 +913,13 @@ "message": "Please add additional providers that are better supported across devices (such as an authenticator app)." }, "twoStepOptions": { - "message": "Two-step login options" + "message": "Elektebloj pri la dupaŝa salutado" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "Elekti metodon de dupaŝa salutado" }, "selfHostedEnvironment": { - "message": "Self-hosted environment" + "message": "Singastigata medio" }, "selfHostedBaseUrlHint": { "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" @@ -955,10 +931,10 @@ "message": "You must add either the base Server URL or at least one custom environment." }, "customEnvironment": { - "message": "Custom environment" + "message": "Proprigita medio" }, "baseUrl": { - "message": "Server URL" + "message": "La retadreso de servilo" }, "authenticationTimeout": { "message": "Authentication timeout" @@ -967,7 +943,7 @@ "message": "The authentication session timed out. Please restart the login process." }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "La retadreso de singastigata servilo", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -989,7 +965,7 @@ "message": "Environment URLs saved" }, "ok": { - "message": "Bone" + "message": "En ordo" }, "yes": { "message": "Jes" @@ -998,46 +974,46 @@ "message": "Ne" }, "location": { - "message": "Location" + "message": "Loko" }, "overwritePassword": { "message": "Overwrite password" }, "learnMore": { - "message": "Learn more" + "message": "Lerni pli" }, "featureUnavailable": { "message": "Feature unavailable" }, "loggedOut": { - "message": "Elsalutinta" + "message": "Adiaŭinta" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Vi estas adiaŭinta el via konto." }, "loginExpired": { - "message": "Your login session has expired." + "message": "Via salutaĵo eksvalidiĝis." }, "restartRegistration": { - "message": "Restart registration" + "message": "Restartigi registradon" }, "expiredLink": { "message": "Expired link" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Bonvole relanĉu registradon aŭ provu salutadon." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Vi eble jam havas konton" }, "logOutConfirmation": { - "message": "Are you sure you want to log out?" + "message": "Ĉu vi certas, ke vi volas adiaŭi?" }, "logOut": { "message": "Elsaluti" }, "addNewLogin": { - "message": "Nova ensaluto" + "message": "Nova salutado" }, "addNewItem": { "message": "Nova ero" @@ -1058,10 +1034,10 @@ "message": "Ŝlosi la trezorejon" }, "passwordGenerator": { - "message": "Password generator" + "message": "Generilo de pasvorto" }, "contactUs": { - "message": "Contact us" + "message": "Kontakti nin" }, "helpAndFeedback": { "message": "Help and feedback" @@ -1079,16 +1055,16 @@ "message": "Sekvi nin" }, "syncVault": { - "message": "Sync vault" + "message": "Samhavigi la trezorujon" }, "changeMasterPass": { "message": "Change master password" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Daŭrigu en la retumilan apon?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Vi povas ŝanĝi vian ĉefan pasvorton en la retumila apo de Bitwarden" }, "fingerprintPhrase": { "message": "Fingerprint phrase", @@ -1099,7 +1075,7 @@ "description": "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." }, "goToWebVault": { - "message": "Go to web vault" + "message": "Iri al la retumila trezorejo" }, "getMobileApp": { "message": "Get mobile app" @@ -1214,15 +1190,15 @@ "message": "Sekureco" }, "clearClipboard": { - "message": "Clear clipboard", + "message": "Forviŝi la tondujon", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "clearClipboardDesc": { - "message": "Automatically clear copied values from your clipboard.", + "message": "Aŭtomate forviŝi la kopiitajn valorojn el via tondujo.", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "enableFavicon": { - "message": "Show website icons" + "message": "Montri la bildosimbolojn de la retejoj" }, "faviconDesc": { "message": "Show a recognizable image next to each login." @@ -1291,7 +1267,7 @@ "message": "Lingvo" }, "languageDesc": { - "message": "Change the language used by the application. Restart is required." + "message": "Ŝanĝi la lingvon uzatan de la aplikaĵo. Postulata estas relanĉo." }, "theme": { "message": "Etoso" @@ -1327,7 +1303,7 @@ "message": "Restart to update" }, "restartToUpdateDesc": { - "message": "Version $VERSION_NUM$ is ready to install. You must restart the application to complete the installation. Do you want to restart and update now?", + "message": "La versio $VERSION_NUM$ estas preta por instali. Vi devas relanĉi la aplikaĵon por plenumi la instalon. Ĉu vi volas nun relanĉi kaj ĝisdatigi?", "placeholders": { "version_num": { "content": "$1", @@ -1342,32 +1318,32 @@ "message": "An update was found. Do you want to download it now?" }, "restart": { - "message": "Restart" + "message": "Relanĉi" }, "later": { "message": "Poste" }, "noUpdatesAvailable": { - "message": "No updates are currently available. You are using the latest version." + "message": "Neniu ĝisdatiĝo nun disponeblas. Vi nun uzas la plej novan version." }, "updateError": { - "message": "Update error" + "message": "Eraro en ĝisdatigo" }, "unknown": { "message": "Nekonata" }, "copyUsername": { - "message": "Copy username" + "message": "Kopii la uzantonomon" }, "copyNumber": { - "message": "Copy number", + "message": "Kopii la numeron", "description": "Copy credit card number" }, "copyEmail": { - "message": "Copy email" + "message": "Kopii la retpoŝton" }, "copySecurityCode": { - "message": "Copy security code", + "message": "Kopii sekurigan kodon", "description": "Copy credit card security code (CVV)" }, "premiumMembership": { @@ -1434,29 +1410,29 @@ "message": "Pasvorta historio" }, "generatorHistory": { - "message": "Generator history" + "message": "La ĵurnalo de la generilo" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Forviŝi la ĵurnalon de la generilo" }, "cleargGeneratorHistoryDescription": { "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" }, "clear": { - "message": "Clear", + "message": "Forviŝi", "description": "To clear something out. example: To clear browser history." }, "noPasswordsInList": { "message": "There are no passwords to list." }, "clearHistory": { - "message": "Clear history" + "message": "Forviŝi la historion" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Neniu por montri" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Vi ne generis ion ajn lastatempe" }, "undo": { "message": "Malfari" @@ -1517,7 +1493,7 @@ "message": "Hide others" }, "showAll": { - "message": "Show all" + "message": "Montri ĉiujn" }, "quitBitwarden": { "message": "Quit Bitwarden" @@ -1533,10 +1509,10 @@ } }, "copySuccessful": { - "message": "Copy Successful" + "message": "Sukcesis la kopiado" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Eraro en la Refreŝigo de Alilo" }, "errorRefreshingAccessTokenDesc": { "message": "No refresh token or API keys found. Please try logging out and logging back in." @@ -1600,7 +1576,7 @@ "description": "An entity of multiple related people (ex. a team or business organization)." }, "default": { - "message": "Defaŭlta" + "message": "Implicita" }, "exit": { "message": "Forlasi" @@ -1749,13 +1725,13 @@ "description": "PIN code. Ex. The short code (often numeric) that you use to unlock a device." }, "unlockWithPin": { - "message": "Unlock with PIN" + "message": "Malŝlosi per PIN" }, "setYourPinCode": { "message": "Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if you ever fully log out of the application." }, "pinRequired": { - "message": "PIN code is required." + "message": "Postulata estas PIN-kodo" }, "invalidPin": { "message": "Invalid PIN code." @@ -1803,7 +1779,7 @@ "message": "Recommended for security." }, "lockWithMasterPassOnRestart1": { - "message": "Lock with master password on restart" + "message": "Ŝlosi per la ĉefa pasvorto ĉe relanĉo" }, "deleteAccount": { "message": "Forigi la konton" @@ -1821,41 +1797,41 @@ "message": "This action cannot be completed because your account is owned by an organization. Contact your organization administrator for additional details." }, "accountDeleted": { - "message": "Konto forigita" + "message": "La konto forigita" }, "accountDeletedDesc": { - "message": "Via konto estis fermita kaj ĉiuj rilataj datumoj estis forigitaj." + "message": "Via konto estas fermita kaj ĉiuj rilataj datumoj estas forigitaj." }, "preferences": { - "message": "Preferences" + "message": "Agordoj" }, "enableMenuBar": { "message": "Show menu bar icon" }, "enableMenuBarDesc": { - "message": "Always show an icon in the menu bar." + "message": "Ĉiam montri bildsimbolon en la menustrio." }, "hideToMenuBar": { - "message": "Hide to menu bar" + "message": "Kaŝi al la menustrio" }, "selectOneCollection": { - "message": "You must select at least one collection." + "message": "Vi devas elekti apenaŭ unu kolekton." }, "premiumUpdated": { "message": "You've upgraded to Premium." }, "restore": { - "message": "Restore" + "message": "Reakiri" }, "premiumManageAlertAppStore": { - "message": "You can manage your subscription from the App Store. Do you want to visit the App Store now?" + "message": "Vi povas administri vian abonon pere de App Store. Ĉu vi volas nun viziti la App Store?" }, "legal": { "message": "Jura", "description": "Noun. As in 'legal documents', like our terms of service and privacy policy." }, "termsOfService": { - "message": "Terms of Service" + "message": "La regularo de la servo" }, "privacyPolicy": { "message": "Privacy Policy" @@ -1879,7 +1855,7 @@ "message": "Master password or other unlock method is required to access your vault again." }, "vaultTimeoutActionLogOutDesc": { - "message": "Re-authentication is required to access your vault again." + "message": "Reaŭtentigo estas postulata por aliri vian trezorejon denove." }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "Set up an unlock method to change your vault timeout action." @@ -1893,19 +1869,19 @@ "description": "Noun: a special folder to hold deleted items" }, "searchTrash": { - "message": "Search trash" + "message": "Serĉi la rubujon" }, "permanentlyDeleteItem": { - "message": "Permanently delete item" + "message": "Poreterne forviŝi eron" }, "permanentlyDeleteItemConfirmation": { - "message": "Are you sure you want to permanently delete this item?" + "message": "Se vi certas, ke vi volas poreterne forviŝi ĉi tiun eron?" }, "permanentlyDeletedItem": { - "message": "Item permanently deleted" + "message": "La ero poreterne forviŝiĝis" }, "restoredItem": { - "message": "Item restored" + "message": "La ero restariĝis" }, "permanentlyDelete": { "message": "Permanently delete" @@ -2055,13 +2031,13 @@ "message": "Use hardware acceleration" }, "enableHardwareAccelerationDesc": { - "message": "By default this setting is ON. Turn OFF only if you experience graphical issues. Restart is required." + "message": "Implicite tiu ĉi agordo estas ŝaltita. Malŝaltu nur se vi spertas grafikajn problemojn. Postulata estas relanĉo." }, "approve": { "message": "Aprobi" }, "verifyBrowserTitle": { - "message": "Verify browser connection" + "message": "Konfirmi la konekton de la retumilo" }, "verifyBrowserDesc": { "message": "Please ensure the shown fingerprint is identical to the fingerprint showed in the browser extension." @@ -2305,7 +2281,7 @@ "message": "Update master password" }, "updateMasterPasswordWarning": { - "message": "Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "Via ĉefa pasvorto estis lastatempe ŝanĝita de administranto en via organizo. Por aliri al la trezorejo vi nun devas ĝin ĝisdatigi. La traktado adiaŭigos vin el via nuna salutaĵo, postulante de vi resaluti. La aktivaj salutaĵoj en la aliaj aparatoj eble daŭros esti aktivaj ĝis unu horon." }, "updateWeakMasterPasswordWarning": { "message": "Your master password does not meet one or more of your organization policies. In order to access the vault, you must update your master password now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." @@ -2332,13 +2308,13 @@ "message": "Could not complete biometrics." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Bezonas diferencan metodon?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Uzi la ĉefan pasvorton" }, "usePin": { - "message": "Use PIN" + "message": "Uzi PIN-on." }, "useBiometrics": { "message": "Use biometrics" @@ -2449,7 +2425,7 @@ "message": "No more than 5 accounts may be logged in at the same time." }, "accountPreferences": { - "message": "Preferences" + "message": "Agordoj" }, "appPreferences": { "message": "App settings (all accounts)" @@ -2473,13 +2449,13 @@ "message": "Already have an account?" }, "options": { - "message": "Options" + "message": "Elektebloj" }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "Via salutaĵo eksvalidiĝis. Bonvole reiru kaj provu saluti denove." }, "exportingPersonalVaultTitle": { - "message": "Exporting individual vault" + "message": "Elportadas la individuan trezorejon" }, "exportingIndividualVaultDescription": { "message": "Only the individual vault items associated with $EMAIL$ will be exported. Organization vault items will not be included. Only vault item information will be exported and will not include associated attachments.", @@ -2515,7 +2491,7 @@ "message": "Ŝlosita" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Via trezorejo estas ŝlosita" }, "unlocked": { "message": "Malŝlosita" @@ -2525,7 +2501,7 @@ "description": "Short for 'credential generator'." }, "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" + "message": "Kion vi ŝatus generi?" }, "passwordType": { "message": "Password type" @@ -2590,7 +2566,7 @@ "message": "Use your domain's configured catch-all inbox." }, "useThisEmail": { - "message": "Use this email" + "message": "Uzi ĉi tiun retpoŝton" }, "random": { "message": "Hazarda" @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3391,16 +3364,16 @@ "description": "Label indicating the most common import formats" }, "success": { - "message": "Success" + "message": "Sukcesis" }, "troubleshooting": { "message": "Troubleshooting" }, "disableHardwareAccelerationRestart": { - "message": "Disable hardware acceleration and restart" + "message": "Neebligi aparatan akcelon kaj relanĉi" }, "enableHardwareAccelerationRestart": { - "message": "Enable hardware acceleration and restart" + "message": "Ebligi aparatan akcelon kaj relanĉi" }, "removePasskey": { "message": "Remove passkey" @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 6936753ebb2..ff9d805a9af 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continuar" }, - "enterVerificationCodeApp": { - "message": "Introduce el código de verificación de 6 dígitos de tu aplicación autenticadora." - }, - "enterVerificationCodeEmail": { - "message": "Introduce el código de verificación de 6 dígitos que fue enviado a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Correo de verificación enviado a $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Recordarme" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Reenviar código de verificación por correo electrónico" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar otro método de autenticación en dos pasos" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Inserta tu YubiKey en el puerto USB de tu equipo y posteriormente pulsa su botón." - }, "insertU2f": { "message": "Inserta tu llave de seguridad en el puerto USB de tu equipo. Si tiene un botón, púlsalo." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicia Duo y sigue los pasos para terminar de iniciar sesión." - }, "duoRequiredByOrgForAccount": { "message": "Se requiere el inicio de sesión en dos pasos de Duo para tu cuenta." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 20650145478..2f2925cf212 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Jätka" }, - "enterVerificationCodeApp": { - "message": "Sisesta autentimise rakendusest 6 kohaline number." - }, - "enterVerificationCodeEmail": { - "message": "Sisesta 6 kohaline number, mis saadeti e-posti aadressile $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kinnituskood saadeti e-posti aadressile $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Jäta mind meelde" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Saada kinnituskood uuesti e-postile" - }, - "useAnotherTwoStepMethod": { - "message": "Kasuta teist kaheastmelist sisselogimise meetodit" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sisesta oma YubiKey arvuti USB porti ja kliki sellele nupule." - }, "insertU2f": { "message": "Sisesta oma turvaline võti arvuti USB porti. Kui sellel on nupp, siis vajuta seda." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo teenustega ühendamine ebaõnnestus. Kasuta teist kahe-astmelise sisselogimise meetodit või kontakteeru Duoga." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Käivita Duo ja järgi juhiseid, et lõpetada sisselogimine." - }, "duoRequiredByOrgForAccount": { "message": "Duo kahe-astmeline sisselogimine on sinu kontol nõutud." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 57763cc62c1..e14618f4bc3 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Jarraitu" }, - "enterVerificationCodeApp": { - "message": "Sartu zure autentifikazio aplikazioaren 6 digituko egiaztatze kodea." - }, - "enterVerificationCodeEmail": { - "message": "Sartu $EMAIL$-era bidalitako 6 digituko egiaztatze-kodea.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Egiaztatze emaila $EMAIL$-era bidalia.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Gogora nazazu" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Berbidali email bidezko egiaztatze-kodea" - }, - "useAnotherTwoStepMethod": { - "message": "Erabili bi urratseko saio hasierarako beste modu bat" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sartu zure YubiKey-a ordenagailuko USB atakan, ondoren, sakatu bere botoia." - }, "insertU2f": { "message": "Sartu zure segurtasun-gakoa ordenagailuaren USB atakan. Botoia badu, sakatu ezazu." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index eecbd6dcb85..80836f6a50f 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "ادامه" }, - "enterVerificationCodeApp": { - "message": "کد ۶ رقمی تأیید را از برنامه احراز هویت وارد کنید." - }, - "enterVerificationCodeEmail": { - "message": "کد ۶ رقمی تأیید را که به $EMAIL$ ایمیل شده را وارد کنید.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ایمیل تأیید به $EMAIL$ ارسال شد.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "مرا به خاطر بسپار" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ارسال دوباره ایمیل کد تأیید" - }, - "useAnotherTwoStepMethod": { - "message": "استفاده از روش ورود دو مرحله‌ای دیگر" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey خود را وارد پورت USB رایانه کنید، بعد دکمه آن را بفشارید." - }, "insertU2f": { "message": "کلید امنیتی خود را وارد پورت USB رایانه کنید، اگر دکمه‌ای دارد آن را بفشارید." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 8964e7cf982..0c2f22dd209 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Jatka" }, - "enterVerificationCodeApp": { - "message": "Syötä todennussovelluksesi näyttämä kuusinumeroinen todennuskoodi." - }, - "enterVerificationCodeEmail": { - "message": "Syötä osoitteeseen $EMAIL$ lähetetty kuusinumeroinen todennuskoodi.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Todennussähköposti lähetettiin osoitteeseen $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Muista minut" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Älä kysy uudelleen tällä laitteella 30 päivään" }, - "sendVerificationCodeEmailAgain": { - "message": "Lähetä todennuskoodi sähköpostitse uudelleen" - }, - "useAnotherTwoStepMethod": { - "message": "Käytä vaihtoehtoista todennustapaa" - }, "selectAnotherMethod": { "message": "Valitse vaihtoehtoinen tapa", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Käytä palautuskoodiasi" }, - "insertYubiKey": { - "message": "Kytke YubiKey-suojausavaimesi tietokoneen USB-porttiin ja kosketa sen painiketta." - }, "insertU2f": { "message": "Kytke suojausavaimesi tietokoneen USB-porttiin ja jos laitteessa on painike, paina sitä." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Virhe yhdistettäessä Duo-palveluun. Käytä vaihtoehtoista todennustapaa tai ole yhteydessä Duon asiakaspalveluun saadaksesi apua." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." - }, "duoRequiredByOrgForAccount": { "message": "Tilillesi kirjautuminen vaatii Duo-vahvistuksen." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Vaihda vaarantunut salasana" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index ec1a2d0e281..0e7b15a7f62 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Magpatuloy" }, - "enterVerificationCodeApp": { - "message": "Ipasok ang 6 na digit na code ng pagpapatunay mula sa iyong authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Ipasok ang 6 digit verification code na ipinadala sa $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email ng pagpapatunay na ipinadala sa $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Tandaan mo ako" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ipadala muli ang email ng verification code" - }, - "useAnotherTwoStepMethod": { - "message": "Gamitin ang isa pang two-step na paraan ng pag-login" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Ipasok ang iyong YubiKey sa USB port ng iyong computer, pagkatapos ay hawakan ang pindutan nito." - }, "insertU2f": { "message": "Ipasok ang iyong key ng seguridad sa USB port ng iyong computer. Kung may butones ito, hawakan ito." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 750b91adf57..4143cc34d22 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continuer" }, - "enterVerificationCodeApp": { - "message": "Saisissez le code de vérification à 6 chiffres depuis votre application d'authentification." - }, - "enterVerificationCodeEmail": { - "message": "Saisissez le code de vérification à 6 chiffres qui a été envoyé par courriel à $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Courriel de vérification envoyé à $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Rester connecté" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne plus demander sur cet appareil pendant 30 jours" }, - "sendVerificationCodeEmailAgain": { - "message": "Envoyer à nouveau le courriel de code de vérification" - }, - "useAnotherTwoStepMethod": { - "message": "Utiliser une autre méthode de connexion en deux étapes" - }, "selectAnotherMethod": { "message": "Sélectionner une autre méthode", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Utilisez votre code de récupération" }, - "insertYubiKey": { - "message": "Insérez votre YubiKey dans le port USB de votre ordinateur puis appuyez sur son bouton." - }, "insertU2f": { "message": "Insérez votre clé de sécurité dans le port USB de votre ordinateur. S'il dispose d'un bouton, appuyez dessus." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erreur de connexion avec le service Duo. Utilisez une autre méthode d'authentification à deux facteurs ou contactez Duo pour obtenir de l'aide." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Lancez Duo et suivez les étapes pour terminer la connexion." - }, "duoRequiredByOrgForAccount": { "message": "L'authentification à double facteur Duo est requise pour votre compte." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Changer le mot de passe à risque" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 07404b37fcd..f1c63780793 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 34db4dd53ba..42d5e8a74cc 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "המשך" }, - "enterVerificationCodeApp": { - "message": "הכנס את קוד האימות בן 6 הספרות מאפליקציית האימות שלך." - }, - "enterVerificationCodeEmail": { - "message": "הכנס את קוד האימות בן 6 הספרות שנשלח ל-$EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "מייל אימות נשלח לכתובת $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "זכור אותי" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "אל תשאל אותי שוב במכשיר זה למשך 30 יום" }, - "sendVerificationCodeEmailAgain": { - "message": "שלח שוב קוד אימות לאימייל" - }, - "useAnotherTwoStepMethod": { - "message": "השתמש בשיטה אחרת עבור כניסה דו שלבית" - }, "selectAnotherMethod": { "message": "בחר שיטה אחרת", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "השתמש בקוד השחזור שלך" }, - "insertYubiKey": { - "message": "הכנס את ה-YubiKey אל כניסת ה-USB במחשבך, ואז גע בכפתור שלו." - }, "insertU2f": { "message": "הכנס את מפתח האבטחה שלך אל כניסת ה-USB במחשבך. אם יש לו כפתור, גע בו." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "שגיאה בהתחברות עם השירות Duo. השתמש בשיטת כניסה דו־שלבית אחרת או פנה אל Duo לסיוע." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "פתח את Duo ועקוב אחר השלבים כדי לסיים להיכנס." - }, "duoRequiredByOrgForAccount": { "message": "נדרשת כניסה דו־שלבית של Duo עבור החשבון שלך." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "שנה סיסמה בסיכון" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 7cfbb08a7d4..4ac5136a684 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 989faae1759..5b1098328e4 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Nastavi" }, - "enterVerificationCodeApp": { - "message": "Unesi 6-znamenkasti kôd za provjeru iz autentifikatorske aplikacije." - }, - "enterVerificationCodeEmail": { - "message": "Unesi 6-znamenkasti kôd za provjeru poslan e-poštom na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pošta za potvrdu poslana je na $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne pitaj na ovom uređaju idućih 30 dana" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno slanje kontrolnog koda e-poštom" - }, - "useAnotherTwoStepMethod": { - "message": "Koristiti drugi način prijave dvostrukom autentifikacijom" - }, "selectAnotherMethod": { "message": "Odaberi drugi način", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Koristi kôd za oporavak" }, - "insertYubiKey": { - "message": "Umetni svoj YubiKey u USB priključak računala, a zatim dodirni njegovu tipku." - }, "insertU2f": { "message": "Umetni svoj sigurnosni ključ u USB priključak računala. Ako ima tipku, dodirni ju." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Greška pri povezivanju s uslugom Duo. Koristi drugu metodu prijave s dvostrukom autentifikacijom ili kontaktiraj Duo za pomoć." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Pokreni Duo i slijedi korake za dovršetak prijave." - }, "duoRequiredByOrgForAccount": { "message": "Za tvoj račun je potrebna Duo dvostruka autentifikacija." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Promijeni rizičnu lozinku" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 775ce2dd80c..894dac4402f 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Folytatás" }, - "enterVerificationCodeApp": { - "message": "A 6 számjegyű ellenőrző kód megadása a hitelesítő alkalmazásból." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ email címre elküldött 6 számjegyű ellenőrző kód megadása.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Az ellenőrző kód elküldésre került $EMAIL$ email címre.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Adatok megjegyzése" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne kérdezzen újra ezen az eszközön 30 napig" }, - "sendVerificationCodeEmailAgain": { - "message": "Megerősítő kód ismételt elküldése emailben" - }, - "useAnotherTwoStepMethod": { - "message": "Másik kétlépcsős bejelentkezési mód használata" - }, "selectAnotherMethod": { "message": "Másik módszer választás", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Helyreállító kód használata" }, - "insertYubiKey": { - "message": "A YubiKey beillesztése a számítógép USB portjába és a rajta levő gomb megnyomása." - }, "insertU2f": { "message": "A biztonsági kulcs beillesztése a számítógép USB portjába. Ha van rajta gomb, nyomjuk meg." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Hiba történt a Duo szolgáltatáshoz csatlakozáskor. Használjunk másik kétlépcsős bejelentkezési módot vagy kérjünk segítséget a Duotól." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Indítsuk el a DUO-t és kövessük a lépéseket a bejelentkezés befejezéséhez." - }, "duoRequiredByOrgForAccount": { "message": "A fiókhoz kétlépcsős DUO bejelentkezés szükséges." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Kockázatos jelszó megváltoztatása" + }, + "move": { + "message": "Áthelyezés" } } diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 0c46ff5e5ea..1ea5c94e861 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Lanjutkan" }, - "enterVerificationCodeApp": { - "message": "Masukkan 6 digit kode verifikasi dari aplikasi autentikasi Anda." - }, - "enterVerificationCodeEmail": { - "message": "Masukkan 6 digit kode verifikasi yang dikirim melalui email ke $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email verifikasi dikirim ke $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Ingat saya" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Kirim ulang email kode verifikasi" - }, - "useAnotherTwoStepMethod": { - "message": "Gunakan metode masuk dua langkah lainnya" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Masukkan YubiKey Anda ke port USB komputer Anda, lalu sentuh tombol nya." - }, "insertU2f": { "message": "Masukkan kunci keamanan ke port USB komputer Anda. Jika ada tombolnya, tekanlah." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index f97b3135c9f..2bb11cee1d2 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continua" }, - "enterVerificationCodeApp": { - "message": "Inserisci il codice di verifica a 6 cifre dalla tua app di autenticazione." - }, - "enterVerificationCodeEmail": { - "message": "Inserisci il codice di verifica a 6 cifre inviato a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email di verifica inviata a $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Ricordami" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Non chiedere più su questo dispositivo per 30 giorni" }, - "sendVerificationCodeEmailAgain": { - "message": "Invia email con codice di verifica di nuovo" - }, - "useAnotherTwoStepMethod": { - "message": "Usa un altro metodo di verifica in due passaggi" - }, "selectAnotherMethod": { "message": "Seleziona un altro metodo", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Usa il tuo codice di recupero" }, - "insertYubiKey": { - "message": "Inserisci la tua YubiKey nella porta USB del computer e premi il suo pulsante." - }, "insertU2f": { "message": "Inserisci la tua chiave di sicurezza nella porta USB del tuo computer. Se dispone di un pulsante, premilo." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Errore di connessione con il servizio Duo. Utilizza un metodo di login in due passaggi diverso o contatta Duo per assistenza." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avvia Duo e segui i passaggi per finire di accedere." - }, "duoRequiredByOrgForAccount": { "message": "Per il tuo account è richiesta la verifica in due passaggi Duo." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Modifica la password non sicura o esposta" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 58c4d866e42..eaa80931539 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "続行" }, - "enterVerificationCodeApp": { - "message": "認証アプリに表示された6桁の認証コードを入力してください。" - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ に送信された6桁の認証コードを入力してください。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ に認証コードを送信しました。", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "情報を保存する" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "このデバイスで30日間再表示しない" }, - "sendVerificationCodeEmailAgain": { - "message": "確認コードをメールで再送" - }, - "useAnotherTwoStepMethod": { - "message": "他の2段階認証方法を使用" - }, "selectAnotherMethod": { "message": "別の方法を選択", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "リカバリーコードを使用する" }, - "insertYubiKey": { - "message": "YubiKey を USB ポートに挿入し、ボタンをタッチしてください。" - }, "insertU2f": { "message": "セキュリティキーを USB ポートに挿入し、ボタンがある場合はボタンをタッチしてください。" }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo サービスへの接続中にエラーが発生しました。異なる二段階ログイン方法を使用するか、Duo に連絡してください。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "ログインを完了するには Duo を起動し手順に従ってください。" - }, "duoRequiredByOrgForAccount": { "message": "アカウントには Duo 二段階認証が必要です。" }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "危険なパスワードの変更" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 3eb666c7d44..2e7214e5170 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "გაგრძელება" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "დამიმახსოვრე" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 07404b37fcd..f1c63780793 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index c530ab799f7..2869cffeed2 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "ಮುಂದುವರಿಸಿ" }, - "enterVerificationCodeApp": { - "message": "ನಿಮ್ಮ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ಗೆ ಇಮೇಲ್ ಮಾಡಲಾದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ಪರಿಶೀಲನೆ ಇಮೇಲ್ $EMAIL$ ಗೆ ಕಳುಹಿಸಲಾಗಿದೆ.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "ನನ್ನನ್ನು ನೆನಪಿನಲ್ಲಿ ಇಡು" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ಪರಿಶೀಲನೆ ಕೋಡ್ ಇಮೇಲ್ ಅನ್ನು ಮತ್ತೆ ಕಳುಹಿಸಿ" - }, - "useAnotherTwoStepMethod": { - "message": "ಮತ್ತೊಂದು ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ವಿಧಾನವನ್ನು ಬಳಸಿ" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "ನಿಮ್ಮ ಯುಬಿಕಿಯನ್ನು ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಯುಎಸ್‌ಬಿ ಪೋರ್ಟ್ಗೆ ಸೇರಿಸಿ, ನಂತರ ಅದರ ಗುಂಡಿಯನ್ನು ಸ್ಪರ್ಶಿಸಿ." - }, "insertU2f": { "message": "ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಯುಎಸ್‌ಬಿ ಪೋರ್ಟ್ಗೆ ನಿಮ್ಮ ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಸೇರಿಸಿ. ಅದು ಬಟನ್ ಹೊಂದಿದ್ದರೆ, ಅದನ್ನು ಸ್ಪರ್ಶಿಸಿ." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index e5df2555531..ed69ad34fdf 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "계속" }, - "enterVerificationCodeApp": { - "message": "인증 앱에서 6자리 인증 코드를 입력하세요." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ 주소로 전송된 6자리 인증 코드를 입력하세요.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ 주소로 인증 이메일을 보냈습니다.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "기억하기" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "인증 코드 이메일 다시 보내기" - }, - "useAnotherTwoStepMethod": { - "message": "다른 2단계 인증 사용" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey를 컴퓨터의 USB 포트에 삽입하고 버튼을 누르세요." - }, "insertU2f": { "message": "보안 키를 컴퓨터의 USB 포트에 삽입하고 버튼이 있는 경우 누르세요." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index 7cf1bc463b3..1d20b814539 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Tęsti" }, - "enterVerificationCodeApp": { - "message": "Įveskite 6 skaitmenų patvirtinimo kodą iš autentifikavimo programos." - }, - "enterVerificationCodeEmail": { - "message": "Įveskite 6 skaitmenų patvirtinimo kodą, kuris buvo išsiųstas $EMAIL$ el. paštu.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Patvirtinimo laiškas išsiųstas į $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Prisiminti mane" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Pakartotinai atsiųsti patvirtinimo kodą el. paštu" - }, - "useAnotherTwoStepMethod": { - "message": "Naudoti kitą dviejų žingsnių prisijungimo metodą" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Įkiškite YubiKey į savo kompiuterio USB prievadą, tada palieskite jo mygtuką." - }, "insertU2f": { "message": "Įkiškite savo saugos raktą į kompiuterio USB prievadą. Jei jame yra mygtukas, palieskite jį." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index b3fa396d811..7a4c7343272 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Turpināt" }, - "enterVerificationCodeApp": { - "message": "Jāievada 6 ciparu apstiprinājuma kods no autentificētāja lietotnes." - }, - "enterVerificationCodeEmail": { - "message": "Jāievada 6 ciparu apstiprinājuma kods, kas tika nosūtīts uz $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pasts apstiprināšanai nosūtīts uz $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Atcerēties mani" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Šajā ierīcē 30 dienas vairs nevaicāt" }, - "sendVerificationCodeEmailAgain": { - "message": "Sūtīt apstiprinājuma koda e-pastu vēlreiz" - }, - "useAnotherTwoStepMethod": { - "message": "Izmantot citu divpakāpju pieteikšanās veidu" - }, "selectAnotherMethod": { "message": "Atlasīt citu veidu", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Izmantot savu atkopes kodu" }, - "insertYubiKey": { - "message": "Ievieto savu YubiKey datora USB ligzdā un pieskaries tā pogai!" - }, "insertU2f": { "message": "Ievieto savu drošības atslēgu datora USB ligzdā! Ja tai ir poga, pieskaries tai!" }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Kļūda savienojuma izveidošanā ar Duo pakalpojumu. Jāizmanto cits divpakāpju pieteikšanās veids vai jāvēršas pie Duo pēc palīdzības." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Jāpalaiž Duo un jāseko soļiem, lai pabeigtu pieteikšanos." - }, "duoRequiredByOrgForAccount": { "message": "Kontam ir nepieciešama Duo divpakāpju pieteikšanās." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Mainīt riskam pakļautu paroli" + }, + "move": { + "message": "Pārvietot" } } diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index 99944c6e10c..c3c761f1ffb 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Nastavi" }, - "enterVerificationCodeApp": { - "message": "Unesi kod sa 6 cifri iz vaše aplikacije za autentifikaciju." - }, - "enterVerificationCodeEmail": { - "message": "Unesi kod sa 6 cifri koji vam je poslat na email $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifikacioni email poslat na $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Pošalji ponovo verifikacioni kod na email" - }, - "useAnotherTwoStepMethod": { - "message": "Koristi drugi metod prijave u dva koraka" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Priključi svoj YubiKey u USB port na kompjuteru i onda takni njegovo dugme." - }, "insertU2f": { "message": "Priključi svoj sigurnonosni ključ u USB port na kompjuteru. Ako ima dugme, takni ga." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index 79d36b99526..3b22d0369ab 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "തുടരുക" }, - "enterVerificationCodeApp": { - "message": "നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷനിൽ നിന്ന് 6 അക്ക സ്ഥിരീകരണ കോഡ് നൽകുക." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$-ൽ ഇമെയിൽ ചെയ്ത 6 അക്ക സ്ഥിരീകരണ കോഡ് നൽകുക.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "സ്ഥിരീകരണ ഇമെയിൽ $EMAIL$-ലേക്ക് അയച്ചു.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "എന്നെ ഓർക്കണം" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "സ്ഥിരീകരണ കോഡ് ഇമെയിൽ വഴി വീണ്ടും അയയ്ക്കുക" - }, - "useAnotherTwoStepMethod": { - "message": "മറ്റൊരു രണ്ട് ഘട്ട പ്രവേശന രീതി ഉപയോഗിക്കുക" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ യു‌എസ്‌ബി പോർട്ടിലേക്ക് YubiKey ഇടുക, തുടർന്ന് അതിന്റെ ബട്ടൺ അമർത്തുക." - }, "insertU2f": { "message": "നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ യുഎസ്ബി പോർട്ടിൽ സുരക്ഷാ കീ ഇടുക. അതിന് ഒരു ബട്ടൺ ഉണ്ടെങ്കിൽ അത് അമർത്തുക." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index 07404b37fcd..f1c63780793 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index 8aa0327203b..d79065b8cde 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index d96eb92efb2..2873e2a931a 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Fortsett" }, - "enterVerificationCodeApp": { - "message": "Skriv inn den 6-sifrede verifiseringskoden som står på din autentiseringsapp." - }, - "enterVerificationCodeEmail": { - "message": "Skriv inn den 6-sifrede verifiseringskoden som ble sendt til $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "En verifiserings-E-post har blitt sendt til $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Husk på meg" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send E-posten med verifiseringskoden på nytt" - }, - "useAnotherTwoStepMethod": { - "message": "Bruk en annen 2-trinnsinnloggingsmetode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sett inn din YubiKey i din datamaskins USB-uttak, og så trykk på dens knapp." - }, "insertU2f": { "message": "Sett din sikkerhetsnøkkel inn i din datamaskins USB-uttak. Dersom den har en knapp, trykk på den." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 79aa89aed90..5fdbfe2bf02 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 29dddbf0f08..782decad1ef 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Doorgaan" }, - "enterVerificationCodeApp": { - "message": "Voer de 6-cijferige verificatiecode uit je authenticatie-app in." - }, - "enterVerificationCodeEmail": { - "message": "Voer de 6-cijferige verificatiecode in die via e-mail is verstuurd naar $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail met verificatiecode is verzonden naar $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Mijn gegevens onthouden" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "30 dagen niet meer vragen op dit apparaat" }, - "sendVerificationCodeEmailAgain": { - "message": "E-mail met verificatiecode opnieuw versturen" - }, - "useAnotherTwoStepMethod": { - "message": "Gebruik een andere methode voor tweestapsaanmelding" - }, "selectAnotherMethod": { "message": "Kies een andere methode", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Gebruik je herstelcode" }, - "insertYubiKey": { - "message": "Plaats je YubiKey in de USB-poort van je computer en druk op de knop." - }, "insertU2f": { "message": "Plaats je beveilingssleutel in de USB-poort van je computer. Als het een knop heeft, druk deze dan in." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fout bij het verbinden met de Duo-service. Gebruik een andere tweestapsaanmeldingsmethode of neem contact op met Duo voor hulp." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Start Duo en volg de stappen om in te loggen." - }, "duoRequiredByOrgForAccount": { "message": "Jouw account vereist Duo-tweestapsaanmelding." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Risicovol wachtwoord wijzigen" + }, + "move": { + "message": "Verplaatsen" } } diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 753b3ba5524..2b8acdf0a93 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Fortsett" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Ein stadfestingskode har blitt sendt til $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Husk meg" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send e-post om stadfestingskode på nytt" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index b5c3d4eab46..075ad16dd2d 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index a8b5205a9d9..78d3da851fa 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Kontynuuj" }, - "enterVerificationCodeApp": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny z aplikacji uwierzytelniającej." - }, - "enterVerificationCodeEmail": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny, który został przesłany na adres $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kod weryfikacyjny został wysłany na adres $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapamiętaj mnie" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Nie pytaj ponownie na tym urządzeniu przez 30 dni" }, - "sendVerificationCodeEmailAgain": { - "message": "Wyślij ponownie wiadomość z kodem weryfikacyjnym" - }, - "useAnotherTwoStepMethod": { - "message": "Użyj innej metody logowania dwustopniowego" - }, "selectAnotherMethod": { "message": "Wybierz inną metodę", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Użyj kodu odzyskiwania" }, - "insertYubiKey": { - "message": "Włóż klucz YubiKey do portu USB komputera, a następnie dotknij jego przycisku." - }, "insertU2f": { "message": "Włóż klucz bezpieczeństwa do portu USB komputera. Jeśli klucz posiada przycisk, dotknij go." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Wystąpił błąd podczas połączenia z usługą Duo. Aby uzyskać pomoc, użyj innej metody dwustopniowego logowania lub skontaktuj się z Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Uruchom Duo i wykonaj kroki, aby zakończyć logowanie." - }, "duoRequiredByOrgForAccount": { "message": "Dwustopniowe logowanie Duo jest wymagane dla Twojego konta." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Zmień zagrożone hasło" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index 539d254344d..d5cedf8fc33 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -250,17 +250,17 @@ "message": "Erro" }, "decryptionError": { - "message": "Decryption error" + "message": "Erro ao descriptografar" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "O Bitwarden não pode descriptografar o(s) item(ns) do cofre listado abaixo." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Contato com o cliente feito com sucesso", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "para evitar a perca adicional dos dados.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "january": { @@ -649,13 +649,13 @@ "message": "Inicie a sessão no Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Digite o código enviado por e-mail" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "Insira o código do seu aplicativo autenticador" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Pressione seu YubiKey para autenticar" }, "logInWithPasskey": { "message": "Iniciar sessão com a chave de acesso" @@ -710,7 +710,7 @@ "message": "Dica da senha mestra" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Pontuação de força da senha $SCORE$", "placeholders": { "score": { "content": "$1", @@ -825,7 +825,7 @@ "message": "A autenticação foi cancelada ou demorou muito. Por favor tente novamente." }, "openInNewTab": { - "message": "Open in new tab" + "message": "Abrir numa nova aba" }, "invalidVerificationCode": { "message": "Código de verificação inválido" @@ -833,18 +833,6 @@ "continue": { "message": "Continuar" }, - "enterVerificationCodeApp": { - "message": "Insira o código de verificação de 6 dígitos do seu aplicativo de autenticação." - }, - "enterVerificationCodeEmail": { - "message": "Insira o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail de verificação enviado para $EMAIL$.", "placeholders": { @@ -854,27 +842,15 @@ } } }, - "rememberMe": { - "message": "Lembrar de mim" - }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" - }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar código de verificação para o e-mail novamente" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de verificação em duas etapas" + "message": "Não perguntar novamente neste dispositivo por 30 dias" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Escolher outro método", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" - }, - "insertYubiKey": { - "message": "Introduza a sua YubiKey na porta USB do seu computador, e depois toque no botão da mesma." + "message": "Use seu código de recuperação" }, "insertU2f": { "message": "Insira a sua chave de segurança na porta USB do seu computador. Se ele tiver um botão, toque nele." @@ -907,13 +883,13 @@ "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "verifyYourIdentity": { - "message": "Verify your Identity" + "message": "Verifique sua identidade" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Não reconhecemos este dispositivo. Digite o código enviado por e-mail para verificar a sua identidade." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Continue acessando" }, "webAuthnTitle": { "message": "WebAuthn FIDO2" @@ -940,7 +916,7 @@ "message": "Opções de Login em Duas Etapas" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "Selecionar método de login em duas etapas" }, "selfHostedEnvironment": { "message": "Ambiente auto-hospedado" @@ -998,7 +974,7 @@ "message": "Não" }, "location": { - "message": "Location" + "message": "Localização" }, "overwritePassword": { "message": "Substituir Senha" @@ -1797,7 +1773,7 @@ "message": "Exigir senha ou PIN ao iniciar o app" }, "requirePasswordWithoutPinOnStart": { - "message": "Require password on app start" + "message": "Exigir senha ao iniciar o app" }, "recommendedForSecurity": { "message": "Recomendado para segurança." @@ -2269,10 +2245,10 @@ "message": "Autenticar WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "Ler chave de segurança" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "Aguardando interação com a chave de segurança..." }, "hideEmail": { "message": "Ocultar meu endereço de e-mail dos destinatários." @@ -2491,7 +2467,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Apenas os itens individuais do cofre, incluindo anexos associados ao $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos", "placeholders": { "email": { "content": "$1", @@ -2590,7 +2566,7 @@ "message": "Use o catch-all configurado no seu domínio." }, "useThisEmail": { - "message": "Use this email" + "message": "Usar este e-mail" }, "random": { "message": "Aleatório" @@ -2680,7 +2656,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ recusou sua solicitação. Contate seu provedor de serviços para receber assistência.", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -2690,7 +2666,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ recusou sua solicitação: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2803,7 +2779,7 @@ "message": "Login iniciado" }, "logInRequestSent": { - "message": "Request sent" + "message": "Pedido enviado" }, "notificationSentDevice": { "message": "Uma notificação foi enviada para seu dispositivo." @@ -2812,13 +2788,13 @@ "message": "Uma notificação foi enviada para seu dispositivo" }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the " + "message": "Desbloqueie o Bitwarden no seu dispositivo ou na " }, "notificationSentDeviceAnchor": { - "message": "web app" + "message": "aplicativo web" }, "notificationSentDevicePart2": { - "message": "Make sure the Fingerprint phrase matches the one below before approving." + "message": "Certifique-se de que a frase de biometria corresponde à frase abaixo antes de aprovar." }, "needAnotherOptionV1": { "message": "Precisa de outra opção?" @@ -2849,10 +2825,10 @@ "description": "'Character count' describes a feature that displays a number next to each character of the password." }, "areYouTryingToAccessYourAccount": { - "message": "Are you trying to access your account?" + "message": "Você está tentando acessar sua conta?" }, "accessAttemptBy": { - "message": "Access attempt by $EMAIL$", + "message": "Tentativa de acesso por $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -2870,10 +2846,10 @@ "message": "Horário" }, "confirmAccess": { - "message": "Confirm access" + "message": "Confirmar acesso" }, "denyAccess": { - "message": "Deny access" + "message": "Negar acesso" }, "logInConfirmedForEmailOnDevice": { "message": "Acesso confirmado para $EMAIL$ em $DEVICE$", @@ -2910,7 +2886,7 @@ "message": "Este pedido não é mais válido." }, "confirmAccessAttempt": { - "message": "Confirm access attempt for $EMAIL$", + "message": "Confirmar tentativa de acesso para $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -2922,7 +2898,7 @@ "message": "Acesso solicitado" }, "accountAccessRequested": { - "message": "Account access requested" + "message": "Acesso à conta solicitado" }, "creatingAccountOn": { "message": "Criando conta em" @@ -2958,10 +2934,10 @@ "message": "Senha fraca identificada e encontrada em um vazamento de dados. Use uma senha forte e única para proteger a sua conta. Tem certeza de que deseja usar essa senha?" }, "useThisPassword": { - "message": "Use this password" + "message": "Use esta senha" }, "useThisUsername": { - "message": "Use this username" + "message": "Use este nome de usuário" }, "checkForBreaches": { "message": "Verificar vazamentos de dados conhecidos para esta senha" @@ -3224,17 +3200,14 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro ao se conectar com o serviço Duo. Use um método de verificação de duas etapas diferente ou contate o Duo para assistência." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o Duo e siga os passos para finalizar o login." - }, "duoRequiredByOrgForAccount": { "message": "A autenticação em duas etapas do Duo é necessária para sua conta." }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "A autenticação de dois fatores é necessária para sua conta. Siga os passos abaixo para conseguir entrar." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Siga os passos abaixo para finalizar o login." }, "launchDuo": { "message": "Iniciar o Duo no navegador" @@ -3461,19 +3434,19 @@ "message": "Nenhuma porta livre foi encontrada para o cliente final." }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "O desbloqueio por biometria está indisponível, pois é necessário informar o PIN ou a senha primeiro." }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "O desbloqueio por biometria está indisponível no momento." }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "O desbloqueio por biometria está indisponível devido a algum erro na configuração dos arquivos de sistema." }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "O desbloqueio por biometria está indisponível devido a algum erro na configuração dos arquivos de sistema." }, "biometricsStatusHelptextNotEnabledLocally": { - "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", + "message": "O desbloqueio por biometria está indisponível, pois a opção não foi ativada no aplicativo de desktop de $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -3482,7 +3455,7 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "message": "O desbloqueio por biometria está indisponível por razões desconhecidas." }, "authorize": { "message": "Autorizar" @@ -3494,25 +3467,25 @@ "message": "Confirmar uso da chave SSH" }, "agentForwardingWarningTitle": { - "message": "Warning: Agent Forwarding" + "message": "Aviso: Encaminhamento de Agente" }, "agentForwardingWarningText": { - "message": "This request comes from a remote device that you are logged into" + "message": "Este pedido vem de um dispositivo remoto em que você está logado" }, "sshkeyApprovalMessageInfix": { "message": "está solicitando acesso para" }, "sshkeyApprovalMessageSuffix": { - "message": "in order to" + "message": "a fim de" }, "sshActionLogin": { - "message": "authenticate to a server" + "message": "autenticar em um servidor" }, "sshActionSign": { - "message": "sign a message" + "message": "assine uma mensagem" }, "sshActionGitSign": { - "message": "sign a git commit" + "message": "assine um commit no git" }, "unknownApplication": { "message": "Uma aplicação" @@ -3527,7 +3500,7 @@ "message": "Importar chave da área de transferência" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "Chave SSH importada com sucesso" }, "fileSavedToDevice": { "message": "Arquivo salvo no dispositivo. Gerencie a partir das transferências do seu dispositivo." @@ -3569,24 +3542,27 @@ "message": "Alterar e-mail" }, "allowScreenshots": { - "message": "Allow screen capture" + "message": "Permitir captura de tela" }, "allowScreenshotsDesc": { - "message": "Allow the Bitwarden desktop application to be captured in screenshots and viewed in remote desktop sessions. Disabling this will prevent access on some external displays." + "message": "Permitir que a aplicação do Bitwarden seja capturada em capturas de tela e visualizada em sessões remotas no computador. Desabilitar isso impedirá acesso em algumas telas externas." }, "confirmWindowStillVisibleTitle": { - "message": "Confirm window still visible" + "message": "Confirmar janela ainda visível" }, "confirmWindowStillVisibleContent": { - "message": "Please confirm that the window is still visible." + "message": "Por favor, confirme que a janela ainda está visível." }, "updateBrowserOrDisableFingerprintDialogTitle": { - "message": "Extension update required" + "message": "Atualização de extensão necessária" }, "updateBrowserOrDisableFingerprintDialogMessage": { - "message": "The browser extension you are using is out of date. Please update it or disable browser integration fingerprint validation in the desktop app settings." + "message": "A extensão de navegador que você está usando está desatualizada. Atualize-a ou desabilite a validação de integração de impressão digital do navegador nas configurações do aplicativo da área de trabalho." }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "Alterar senhas vulneráveis" + }, + "move": { + "message": "Mover" } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index 28ac0c82486..265df8b7566 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continuar" }, - "enterVerificationCodeApp": { - "message": "Introduza o código de verificação de 6 dígitos da sua aplicação de autenticação." - }, - "enterVerificationCodeEmail": { - "message": "Introduza o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail de verificação enviado para $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Memorizar" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Não voltar a perguntar neste dispositivo durante 30 dias" }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar e-mail com o código de verificação novamente" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de verificação de dois passos" - }, "selectAnotherMethod": { "message": "Selecionar outro método", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Utilize o seu código de recuperação" }, - "insertYubiKey": { - "message": "Introduza a sua YubiKey na porta USB do seu computador, depois toque no botão da mesma." - }, "insertU2f": { "message": "Introduza a sua chave de segurança na porta USB do seu computador. Se tiver um botão, toque no mesmo." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro ao ligar ao serviço Duo. Utilize um método de verificação de dois passos diferente ou contacte o Duo para obter assistência." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o Duo e siga os passos para concluir o início de sessão." - }, "duoRequiredByOrgForAccount": { "message": "A verificação de dois passos Duo é necessária para a sua conta." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Alterar palavra-passe em risco" + }, + "move": { + "message": "Mover" } } diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index b160bfc14e3..002a0a9398b 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continuare" }, - "enterVerificationCodeApp": { - "message": "Introducere cod de verificare din 6 cifre din aplicația de autentificare." - }, - "enterVerificationCodeEmail": { - "message": "Introducere cod de verificare din 6 cifre care a fost trimis prin e-mail la $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mailul de verificare a fost trimis la $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Memorare autentificare" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Retrimitere e-mail cu codul de verificare" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizare de metodă diferită de autentificare în două etape" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Introduceți YubiKey în portul USB al calculatorului apoi atingeți butonul acestuia." - }, "insertU2f": { "message": "Introduceți cheia de securitate în portul USB al computerului. Dacă are un buton, apăsați-l." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index 73f52200e04..c86747af746 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Продолжить" }, - "enterVerificationCodeApp": { - "message": "Введите 6-значный код подтверждения из вашего приложения-аутентификатора." - }, - "enterVerificationCodeEmail": { - "message": "Введите 6-значный код подтверждения, который был отправлен на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Отправлено письмо подтверждения на $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Запомнить меня" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не спрашивать на этом устройстве в течение 30 дней" }, - "sendVerificationCodeEmailAgain": { - "message": "Отправить код подтверждения еще раз" - }, - "useAnotherTwoStepMethod": { - "message": "Использовать другой метод двухэтапной аутентификации" - }, "selectAnotherMethod": { "message": "Выбрать другой способ", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Использовать код восстановления" }, - "insertYubiKey": { - "message": "Вставьте свой YubiKey в USB-порт компьютера и нажмите его кнопку." - }, "insertU2f": { "message": "Вставьте ключ безопасности в USB-порт компьютера. Если у ключа есть кнопка, нажмите ее." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Ошибка при подключении к сервису Duo. Используйте другой метод двухэтапной аутентификации или обратитесь за помощью в Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустите Duo и следуйте шагам для завершения авторизации." - }, "duoRequiredByOrgForAccount": { "message": "Для вашего аккаунта требуется двухэтапная аутентификация Duo." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Изменить пароль, подверженный риску" + }, + "move": { + "message": "Переместить" } } diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index e2f23c7bc56..ecc5a8f29bc 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "ඉදිරියට" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 0f32c9945ce..e059566ddd7 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Pokračovať" }, - "enterVerificationCodeApp": { - "message": "Zadajte 6-miestny overovací kód z vašej overovacej aplikácie." - }, - "enterVerificationCodeEmail": { - "message": "Zadajte 6-miestny overovací kód, ktorý bol zaslaný e-mailom na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Overovací e-mail odoslaný na $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapamätaj si ma" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Nepýtať sa znova na tomto zariadení 30 dní" }, - "sendVerificationCodeEmailAgain": { - "message": "Znovu zaslať overovací kód e-mailom" - }, - "useAnotherTwoStepMethod": { - "message": "Použiť inú dvojstupňovú metódu prihlásenia" - }, "selectAnotherMethod": { "message": "Vyberte iný spôsob", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Použiť obnovovací kód" }, - "insertYubiKey": { - "message": "Vložte váš YubiKey do USB portu počítača a stlačte jeho tlačidlo." - }, "insertU2f": { "message": "Vložte váš bezpečnostný kľúč do USB portu počítača. Ak má tlačidlo, stlačte ho." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Chyba pri pripájaní k službe Duo. Použite inú metódu dvojstupňového prihlásenia alebo kontaktujte Duo a požiadajte o pomoc." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Spustite DuO a postupujte podľa pokynov na dokončenie prihlásenia." - }, "duoRequiredByOrgForAccount": { "message": "Pre váš účet je potrebné dvojstupňové prihlásenie Duo." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Zmeniť rizikové heslá" + }, + "move": { + "message": "Presunúť" } } diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 4d50b4d9def..0a911f69546 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Nadaljuj" }, - "enterVerificationCodeApp": { - "message": "Vnesite 6-mestno verifikacijsko kodo iz vaše avtentikacijske aplikacije." - }, - "enterVerificationCodeEmail": { - "message": "Vnesite 6-mestno verifikacijsko kodo, ki vam je bila poslana na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Potrditveno sporočilo poslano na $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Zapomni si me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno pošlji verifikacijsko kodo" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 561e3d35ec2..806c2115a04 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Настави" }, - "enterVerificationCodeApp": { - "message": "Унесите шестоцифрени верификациони код из апликације за утврђивање аутентичности." - }, - "enterVerificationCodeEmail": { - "message": "Унесите шестоцифрени верификациони код који је послан на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Провера имејла послата на $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Запамти ме" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не питајте поново на овом уређају 30 дана" }, - "sendVerificationCodeEmailAgain": { - "message": "Поново послати верификациони код на имејл" - }, - "useAnotherTwoStepMethod": { - "message": "Користите другу методу пријављивања у два корака" - }, "selectAnotherMethod": { "message": "Изаберите другу методу", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Употребите шифру за опоравак" }, - "insertYubiKey": { - "message": "Убаците свој YubiKey у УСБ порт рачунара, а затим додирните његово дугме." - }, "insertU2f": { "message": "Убаците свој сигурносни кључ у УСБ порт рачунара, и ако има дугме , додирните га." }, @@ -2491,7 +2467,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Извешће се само појединачни сеф, укључујући прилоге повезане са $EMAIL$. Организациони сефски предмети неће бити укључени", "placeholders": { "email": { "content": "$1", @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Грешка при повезивању са услугом Duo. Користите други метод пријаве у два корака или контактирајте Duo за помоћ." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Покренути Duo и пратите кораке да бисте завршили пријављивање." - }, "duoRequiredByOrgForAccount": { "message": "Duo пријава у два корака је потребна за ваш налог." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Променити ризичну лозинку" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index f33339ea80d..f257b51e1c5 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Fortsätt" }, - "enterVerificationCodeApp": { - "message": "Ange den 6-siffriga verifieringskoden från din autentiseringsapp." - }, - "enterVerificationCodeEmail": { - "message": "Ange den 6-siffriga verifieringskoden som har skickats till $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifieringsmeddelande har skickats till $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Kom ihåg mig" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Skicka e-postmeddelandet med verifieringskoden igen" - }, - "useAnotherTwoStepMethod": { - "message": "Använd en annan metod för tvåstegsverifiering" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Anslut din YubiKey till datorns USB-port och tryck sedan på dess knapp." - }, "insertU2f": { "message": "Anslut din säkerhetsnyckel till datorns USB-port. Om den har en knapp, tryck på den." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Starta Duo och följ stegen för att slutföra inloggningen." - }, "duoRequiredByOrgForAccount": { "message": "Duo tvåstegsverifiering krävs för ditt konto." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 07404b37fcd..f1c63780793 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 2bec157ec15..c0e8a91476a 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "ดำเนินการต่อไป" }, - "enterVerificationCodeApp": { - "message": "ป้อนรหัสยืนยัน 6 หลักจากคุณแอป authenticator" - }, - "enterVerificationCodeEmail": { - "message": "ป้อนรหัสยืนยัน 6 หลักที่ส่งทางอีเมล $EMAIL$", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ส่งอีเมลยืนยันไปที่ $EMAIL$ แล้ว", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "จดจำการเข้าระบบของฉัน" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ส่งอีเมล์ยืนยันรหัสอีกครั้ง" - }, - "useAnotherTwoStepMethod": { - "message": "ใช้วิธีลงชื่อเข้าใช้แบบสองขั้นตอนวิธีอื่น" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "เสียบ YubiKey ของคุณเข้ากับพอร์ต USB ของคอมพิวเตอร์ จากนั้นแตะปุ่ม" - }, "insertU2f": { "message": "เสียบคีย์ความปลอดภัยเข้ากับพอร์ต USB ของคอมพิวเตอร์ หากมีปุ่ม ให้แตะปุ่มนั้น" }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 974d27f4735..53c556b0383 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Devam Et" }, - "enterVerificationCodeApp": { - "message": "Kimlik doğrulayıcı uygulamanızdaki 6 haneli doğrulama kodunu girin." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ adresine e-postalanan 6 haneli doğrulama kodunu girin.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Doğrulama e-postası $EMAIL$ 'e gönderildi.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Beni hatırla" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Doğrulama kodunu yeniden e-postala" - }, - "useAnotherTwoStepMethod": { - "message": "Başka bir iki aşamalı giriş yöntemini kullan" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey'i bilgisayarınızın USB portuna takın, ardından düğmesine dokunun." - }, "insertU2f": { "message": "Güvenlik anahtarınızı bilgisayarınızın USB portuna takın. Bir düğmesi varsa dokunun." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Duo'yu açın ve girişi tamamlamak için adımları izleyin." - }, "duoRequiredByOrgForAccount": { "message": "Hesabınız için Duo iki adımlı giriş gereklidir." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Taşı" } } diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 6fb5c564f3a..07fccfc7d41 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Продовжити" }, - "enterVerificationCodeApp": { - "message": "Введіть 6-значний код підтвердження з програми автентифікації." - }, - "enterVerificationCodeEmail": { - "message": "Введіть 6-значний код підтвердження, надісланий на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Код підтвердження надіслано на $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Запам'ятати мене" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Більше не запитувати на цьому пристрої протягом 30 днів" }, - "sendVerificationCodeEmailAgain": { - "message": "Надіслати код підтвердження ще раз" - }, - "useAnotherTwoStepMethod": { - "message": "Інший спосіб двоетапної перевірки" - }, "selectAnotherMethod": { "message": "Обрати інший спосіб", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Скористайтеся своїм кодом відновлення" }, - "insertYubiKey": { - "message": "Вставте свій YubiKey в USB порт комп'ютера, потім торкніться цієї кнопки." - }, "insertU2f": { "message": "Вставте свій ключ безпеки в USB порт комп'ютера. Якщо в нього є кнопка, натисніть її." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Помилка під'єднання до служби Duo. Скористайтеся іншим способом двоетапної перевірки або зверніться до служби підтримки Duo по допомогу." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустіть Duo і виконайте дії для завершення входу." - }, "duoRequiredByOrgForAccount": { "message": "Для вашого облікового запису необхідна двоетапна перевірка з Duo." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Змінити ризикований пароль" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index 8b5f3250b85..b0c6b08d6c7 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Tiếp tục" }, - "enterVerificationCodeApp": { - "message": "Nhập mã xác minh 6 chữ số từ ứng dụng xác thực của bạn." - }, - "enterVerificationCodeEmail": { - "message": "Nhập mã xác nhận 6 chữ số đã được gửi tới $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email xác minh được gửi tới $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Ghi nhớ đăng nhập" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Gửi lại email chứa mã xác minh" - }, - "useAnotherTwoStepMethod": { - "message": "Sử dụng phương pháp xác minh hai lớp khác" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Cắm YubiKey vào cổng USB trên máy tính bạn và bấm nút trên Yubikey." - }, "insertU2f": { "message": "Lắp khóa bảo mật vào cổng USB của máy tính. Nếu nó có một nút, nhấn vào nó." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Lỗi kết nối với dịch vụ Duo. Sử dụng phương thức đăng nhập hai bước khác hoặc liên hệ với Duo để được hỗ trợ." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Khởi chạy Duo và làm theo các bước để hoàn tất đăng nhập." - }, "duoRequiredByOrgForAccount": { "message": "Tài khoản của bạn yêu cầu xác minh hai bước với Duo." }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index e85b2606535..7a168fb4e05 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -459,7 +459,7 @@ "message": "确定要覆盖当前用户名吗?" }, "noneFolder": { - "message": "默认文件夹", + "message": "无文件夹", "description": "This is the folder for uncategorized items" }, "addFolder": { @@ -833,18 +833,6 @@ "continue": { "message": "继续" }, - "enterVerificationCodeApp": { - "message": "请输入您的验证器 App 中的 6 位数验证码。" - }, - "enterVerificationCodeEmail": { - "message": "请输入发送给 $EMAIL$ 的 6 位数验证码。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "验证邮件已发送到 $EMAIL$。", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "记住我" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "30 天内在此设备上不再询问" }, - "sendVerificationCodeEmailAgain": { - "message": "再次发送验证码电子邮件" - }, - "useAnotherTwoStepMethod": { - "message": "使用其他两步登录方式" - }, "selectAnotherMethod": { "message": "选择其他方式", "description": "Select another two-step login method" @@ -873,14 +852,11 @@ "useYourRecoveryCode": { "message": "使用您的恢复代码" }, - "insertYubiKey": { - "message": "将您的 YubiKey 插入计算机的 USB 端口,然后触摸其按钮。" - }, "insertU2f": { "message": "将您的安全密钥插入计算机的 USB 端口。如果它有按钮,请触摸它。" }, "recoveryCodeDesc": { - "message": "无法访问您所有的双重身份提供程序吗?请使用您的恢复代码来关闭您账户中所有的双重身份提供程序。" + "message": "无法访问您所有的双重身份提供程序吗?请使用您的恢复代码来停用您账户中所有的双重身份提供程序。" }, "recoveryCodeTitle": { "message": "恢复代码" @@ -998,7 +974,7 @@ "message": "否" }, "location": { - "message": "Location" + "message": "位置" }, "overwritePassword": { "message": "覆盖密码" @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "与 Duo 服务连接时出错。请使用其他两步登录方式或联系 Duo 寻求帮助。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "启动 Duo 然后按照步骤完成登录。" - }, "duoRequiredByOrgForAccount": { "message": "您的账户要求使用 Duo 两步登录。" }, @@ -3563,7 +3536,7 @@ "message": "是的,我可以正常访问我的电子邮箱" }, "turnOnTwoStepLogin": { - "message": "开启两步登录" + "message": "启用两步登录" }, "changeAcctEmail": { "message": "更改账户电子邮箱" @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "更改有风险的密码" + }, + "move": { + "message": "移动" } } diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index ab09790dcd0..43d3dc4d9a4 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "繼續" }, - "enterVerificationCodeApp": { - "message": "輸入驗證器應用程式提供的 6 位數驗證碼。" - }, - "enterVerificationCodeEmail": { - "message": "請輸入 6 位數驗證碼,我們已將其傳送至 $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "已傳送驗證電子郵件至 $EMAIL$。", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "記住我" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "再次傳送​​包含驗證碼的電子郵件" - }, - "useAnotherTwoStepMethod": { - "message": "使用另一種兩步驟登入方式" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "將您的 YubiKey 插入電腦的 USB 連接埠,然後按一下它的按鈕。" - }, "insertU2f": { "message": "將您的安全鑰匙插入電腦的 USB 連接埠,然後觸摸其按鈕(如有的話)。" }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "連接到 Duo 服務時發生錯誤。使用不同的兩階段認證或聯繫 Duo 來獲得支援。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "啟動 Duo 並依照步驟完成登入。" - }, "duoRequiredByOrgForAccount": { "message": "您的帳號要求使用 Duo 兩步驟驗證登入。" }, @@ -3588,5 +3561,8 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "move": { + "message": "Move" } } From abaeffea4b28fc88790e6b6e8a857fab339a299a Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:58:43 +0200 Subject: [PATCH 02/93] Autosync the updated translations (#14119) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 48 +---- apps/browser/src/_locales/az/messages.json | 52 +---- apps/browser/src/_locales/be/messages.json | 48 +---- apps/browser/src/_locales/bg/messages.json | 52 +---- apps/browser/src/_locales/bn/messages.json | 48 +---- apps/browser/src/_locales/bs/messages.json | 48 +---- apps/browser/src/_locales/ca/messages.json | 48 +---- apps/browser/src/_locales/cs/messages.json | 48 +---- apps/browser/src/_locales/cy/messages.json | 180 +++++++----------- apps/browser/src/_locales/da/messages.json | 48 +---- apps/browser/src/_locales/de/messages.json | 48 +---- apps/browser/src/_locales/el/messages.json | 48 +---- apps/browser/src/_locales/en_GB/messages.json | 48 +---- apps/browser/src/_locales/en_IN/messages.json | 48 +---- apps/browser/src/_locales/es/messages.json | 48 +---- apps/browser/src/_locales/et/messages.json | 48 +---- apps/browser/src/_locales/eu/messages.json | 48 +---- apps/browser/src/_locales/fa/messages.json | 48 +---- apps/browser/src/_locales/fi/messages.json | 48 +---- apps/browser/src/_locales/fil/messages.json | 48 +---- apps/browser/src/_locales/fr/messages.json | 48 +---- apps/browser/src/_locales/gl/messages.json | 48 +---- apps/browser/src/_locales/he/messages.json | 48 +---- apps/browser/src/_locales/hi/messages.json | 48 +---- apps/browser/src/_locales/hr/messages.json | 48 +---- apps/browser/src/_locales/hu/messages.json | 48 +---- apps/browser/src/_locales/id/messages.json | 48 +---- apps/browser/src/_locales/it/messages.json | 48 +---- apps/browser/src/_locales/ja/messages.json | 48 +---- apps/browser/src/_locales/ka/messages.json | 48 +---- apps/browser/src/_locales/km/messages.json | 48 +---- apps/browser/src/_locales/kn/messages.json | 48 +---- apps/browser/src/_locales/ko/messages.json | 48 +---- apps/browser/src/_locales/lt/messages.json | 48 +---- apps/browser/src/_locales/lv/messages.json | 48 +---- apps/browser/src/_locales/ml/messages.json | 48 +---- apps/browser/src/_locales/mr/messages.json | 48 +---- apps/browser/src/_locales/my/messages.json | 48 +---- apps/browser/src/_locales/nb/messages.json | 48 +---- apps/browser/src/_locales/ne/messages.json | 48 +---- apps/browser/src/_locales/nl/messages.json | 50 +---- apps/browser/src/_locales/nn/messages.json | 48 +---- apps/browser/src/_locales/or/messages.json | 48 +---- apps/browser/src/_locales/pl/messages.json | 48 +---- apps/browser/src/_locales/pt_BR/messages.json | 156 ++++++--------- apps/browser/src/_locales/pt_PT/messages.json | 48 +---- apps/browser/src/_locales/ro/messages.json | 48 +---- apps/browser/src/_locales/ru/messages.json | 52 +---- apps/browser/src/_locales/si/messages.json | 48 +---- apps/browser/src/_locales/sk/messages.json | 48 +---- apps/browser/src/_locales/sl/messages.json | 48 +---- apps/browser/src/_locales/sr/messages.json | 54 +----- apps/browser/src/_locales/sv/messages.json | 48 +---- apps/browser/src/_locales/te/messages.json | 48 +---- apps/browser/src/_locales/th/messages.json | 48 +---- apps/browser/src/_locales/tr/messages.json | 48 +---- apps/browser/src/_locales/uk/messages.json | 48 +---- apps/browser/src/_locales/vi/messages.json | 48 +---- apps/browser/src/_locales/zh_CN/messages.json | 80 +++----- apps/browser/src/_locales/zh_TW/messages.json | 48 +---- apps/browser/store/locales/cy/copy.resx | 6 +- 61 files changed, 509 insertions(+), 2669 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index bf22a38be08..55a9dbca20a 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "هذه المِيزة متاحة فقط للعضوية المميزة." }, - "enterVerificationCodeApp": { - "message": "أدخل رمز التحقق من 6 أرقام من تطبيق المصادقة الخاص بك." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "أدخل رمز التحقق المكون من 6 أرقام الذي تم إرساله إلى $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "تم إرسال رسالة التحقق إلى $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "تذكرني" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "إرسال رمز التحقق إلى البريد الإلكتروني مرة أخرى" - }, - "useAnotherTwoStepMethod": { - "message": "استخدام طريقة أخرى لتسجيل الدخول بخطوتين" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "أدخل YubiKey الخاص بك في منفذ USB في كمبيوترك، ثم المس الزر." - }, "insertU2f": { "message": "أدخل مفتاح الأمان الخاص بك في منفذ USB كمبيوترك، إذا كان يحتوي على زر، إلمسه." }, - "webAuthnNewTab": { - "message": "لبدء التحقق من WebAuthn 2FA. انقر على الزر أدناه لفتح علامة تبويب جديدة واتبع التعليمات المقدمة في علامة التبويب الجديدة." - }, - "webAuthnNewTabOpen": { - "message": "فتح علامة تبويب جديدة" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "قم بتشغيل Duo واتبع الخطوات لإنهاء تسجيل الدخول." - }, "duoRequiredForAccount": { "message": "تسجيل الدخول لـ Duo من خطوتين مطلوب لحسابك." }, - "popoutTheExtensionToCompleteLogin": { - "message": "انبثق الامتداد لإكمال تسجيل الدخول." - }, "popoutExtension": { "message": "تمديد منبثق" }, diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 1ca7642eb19..a6d885898a2 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Bu özəlliyi istifadə etmək üçün premium üzvlük lazımdır." }, - "enterVerificationCodeApp": { - "message": "Kimlik doğrulayıcı tətbiqindən 6 rəqəmli doğrulama kodunu daxil edin." - }, "authenticationTimeout": { "message": "Kimlik doğrulama vaxtı bitdi" }, "authenticationSessionTimedOut": { "message": "Kimlik doğrulama seansının vaxtı bitdi. Lütfən giriş prosesini yenidən başladın." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ ünvanına göndərilən e-poçtdakı 6 rəqəmli doğrulama kodunu daxil edin.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Doğrulama poçtu $EMAIL$ ünvanına göndərildi.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Məni xatırla" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Bu cihazda 30 gün ərzində soruşulmasın" }, - "sendVerificationCodeEmailAgain": { - "message": "Doğrulama kodu olan e-poçtu yenidən göndər" - }, - "useAnotherTwoStepMethod": { - "message": "Başqa bir iki addımlı giriş üsulu istifadə edin" - }, "selectAnotherMethod": { "message": "Başqa üsul seçin", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Geri qaytarma kodunuzu istifadə edin" }, - "insertYubiKey": { - "message": "\"YubiKey\"i kompüterinizin USB portuna taxın, daha sonra düyməsinə toxunun." - }, "insertU2f": { "message": "Güvənlik açarını kompüterinizin USB portuna taxın. Düyməsi varsa toxunun." }, - "webAuthnNewTab": { - "message": "WebAuthn 2FA doğrulamasını başladın. Yeni bir vərəq açmaq üçün aşağıdakı düyməyə klikləyin və yeni vərəqdəki təlimatları izləyin." - }, - "webAuthnNewTabOpen": { - "message": "Yeni vərəq aç" - }, "openInNewTab": { "message": "Yeni vərəqdə aç" }, @@ -2534,15 +2504,15 @@ "message": "Təşkilatınız parolları zəif, təkrar istifadə olunduğu və/və ya ifşa olunduğu üçün risk altındadır.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Risk altındakı girişlərin olduğu siyahının təsviri" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Risk altındakı girişlərin olduğu siyahının təsviri." }, "generatePasswordSlideDesc": { "message": "Risk altında olan saytda Bitwarden avto-doldurma menyusu ilə güclü, unikal parolları cəld yaradın.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Yaradılan parolları göstərən Bitwarden avto-doldurma menyusunun təsviri" + "generatePasswordSlideImgAltPeriod": { + "message": "Yaradılan parolları göstərən Bitwarden avto-doldurma menyusunun təsviri." }, "updateInBitwarden": { "message": "Bitwarden-də güncəllə" @@ -2551,8 +2521,8 @@ "message": "Bitwarden, daha sonra parol menecerində parolu güncəlləməyinizi istəyəcək.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "İstifadəçidən giriş məlumatlarını güncəlləməsini istəyən Bitwarden bildirişinin təsviri" + "updateInBitwardenSlideImgAltPeriod": { + "message": "İstifadəçidən giriş məlumatlarını güncəlləməsini istəyən Bitwarden bildirişinin təsviri." }, "turnOnAutofill": { "message": "Avto-doldurmanı işə sal" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo xidmətinə bağlanarkən xəta baş verdi. Fərqli iki addımlı giriş üsulu istifadə edin və ya kömək üçün Duo ilə əlaqə saxlayın." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Duo-nu başladın və giriş prosesini tamamlamaq üçün addımları izləyin." - }, "duoRequiredForAccount": { "message": "Hesabınız üçün Duo iki addımlı giriş tələb olunur." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Girişi tamamlamaq üçün uzantını aç." - }, "popoutExtension": { "message": "Popout uzantısı" }, @@ -4280,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Elementə bax - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Avto-doldurma - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index a9a237aeb99..fcf9786a210 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Для выкарыстання гэтай функцыі патрабуецца прэміяльны статус." }, - "enterVerificationCodeApp": { - "message": "Увядзіце 6 лічбаў праверачнага кода з вашай праграмы аўтэнтыфікацыі." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Увядзіце 6 лічбаў праверачнага кода, які быў адпраўлены на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Праверачны ліст адпраўлены на $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Запомніць мяне" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Адправіць праверачны код яшчэ раз" - }, - "useAnotherTwoStepMethod": { - "message": "Выкарыстоўваць іншы метад двухэтапнага ўваходу" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Устаўце свой YubiKey у порт USB камп'ютара, а потым націсніце на кнопку." - }, "insertU2f": { "message": "Устаўце ваш ключ бяспекі ў порт USB камп'ютара. Калі на ім ёсць кнопка, націсніце на яе." }, - "webAuthnNewTab": { - "message": "Каб пачаць праверку WebAuthn 2FA, націсніце кнопку знізу для адкрыцця новай укладкі і прытрымлівайцеся інструкцый, якія паказаны ў новай укладцы." - }, - "webAuthnNewTabOpen": { - "message": "Адкрыць новую ўкладку" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index c5dd0237a2c..bdba04b0f46 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "За да се възползвате от тази възможност, трябва да ползвате платен абонамент." }, - "enterVerificationCodeApp": { - "message": "Въведете шестцифрения код за потвърждение от приложението за удостоверяване." - }, "authenticationTimeout": { "message": "Време на давност за удостоверяването" }, "authenticationSessionTimedOut": { "message": "Сесията за удостоверяване е изтекла. Моля, започнете отначало процеса по вписване." }, - "enterVerificationCodeEmail": { - "message": "Въведете шестцифрения код за потвърждение, който е бил изпратен на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Писмото за потвърждение е изпратено на $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Запомняне" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не ме питайте отново на това устройство за 30 дни" }, - "sendVerificationCodeEmailAgain": { - "message": "Повторно изпращане на писмото за потвърждение" - }, - "useAnotherTwoStepMethod": { - "message": "Използвайте друг начин на двустепенно удостоверяване" - }, "selectAnotherMethod": { "message": "Изберете друг метод", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Използване на код за възстановяване" }, - "insertYubiKey": { - "message": "Поставете устройството на YubiKey в USB порт на компютъра и натиснете бутона на устройството." - }, "insertU2f": { "message": "Поставете устройството за удостоверяване в USB порт на компютъра. Ако на устройството има бутон, натиснете го." }, - "webAuthnNewTab": { - "message": "Продължаване на двустепенното удостоверяване чрез WebAuthn в новия раздел." - }, - "webAuthnNewTabOpen": { - "message": "Отваряне на нов раздел" - }, "openInNewTab": { "message": "Отваряне в нов раздел" }, @@ -2534,15 +2504,15 @@ "message": "Паролите в организацията Ви са в риск, защото са слаби, преизползвани и/или разкрити.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Илюстрация на списък с елементи за вписване, които са в риск" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Илюстрация на списък с елементи за вписване, които са в риск." }, "generatePasswordSlideDesc": { "message": "Генерирайте бързо сложна и уникална парола от менюто за автоматично попълване на Битуорден, на уеб сайта, който е в риск.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Илюстрация на автоматичното попълване на Битуорден, показващо генерирана парола" + "generatePasswordSlideImgAltPeriod": { + "message": "Илюстрация на автоматичното попълване на Битуорден, показващо генерирана парола." }, "updateInBitwarden": { "message": "Обновяване в Битуорден" @@ -2551,8 +2521,8 @@ "message": "След това Битуорден ще попита дали искате да обновите паролата в управителя на пароли.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Илюстрация на известието на Битуорден, чрез което пита потребителя дали да се обновят данните за вписване" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Илюстрация на известието на Битуорден, чрез което пита потребителя дали да се обновят данните за вписване." }, "turnOnAutofill": { "message": "Включване на автоматичното попълване" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Грешка при свързването с услугата на Duo. Използвайте друг метод за двустепенно удостоверяване или се свържете с Duo за съдействие." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Стартирайте DUO и следвайте инструкциите, за да завършите вписването." - }, "duoRequiredForAccount": { "message": "Вашата регистрация изисква двустепенно удостоверяване чрез Duo." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Отворете разширението в изскачащ прозорец, за да завършите вписването." - }, "popoutExtension": { "message": "Отваряне на разширението в нов прозорец" }, @@ -4280,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Преглед на елемента – $ITEMNAME$ – $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Авт. попълване – $ITEMNAME$ – $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 21a455265e4..e7ac4f6b729 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "এই বৈশিষ্ট্যটি ব্যবহার করতে একটি প্রিমিয়াম সদস্যতার প্রয়োজন।" }, - "enterVerificationCodeApp": { - "message": "আপনার প্রমাণীকরণকারী অ্যাপ থেকে ৬ সংখ্যার যাচাইকরণ কোডটি প্রবেশ করুন।" - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ এ ইমেইল করা ৬ সংখ্যার যাচাই কোডটি প্রবেশ করুন।", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ এ যাচাইকরণ ইমেইল প্রেরণ করা হয়েছে।", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "আমাকে মনে রাখবেন" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "আবার যাচাইকরণ কোড ইমেইলে প্রেরণ করুন" - }, - "useAnotherTwoStepMethod": { - "message": "অন্য দ্বি-পদক্ষেপ প্রবেশ পদ্ধতি ব্যবহার করুন" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "আপনার কম্পিউটারের ইউএসবি পোর্টে আপনার YubiKey ঢোকান, তারপরে তার বোতামটি স্পর্শ করুন।" - }, "insertU2f": { "message": "আপনার কম্পিউটারের ইউএসবি পোর্টে আপনার সুরক্ষা কী ঢোকান। এটিতে যদি একটি বোতাম থাকে তবে তা স্পর্শ করুন।" }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index a2457c94080..e277f2cee8f 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index d16a679824d..a6b3820971f 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Cal una subscripció premium per utilitzar aquesta característica." }, - "enterVerificationCodeApp": { - "message": "Introduïu el codi de verificació de 6 dígits de l'aplicació autenticadora." - }, "authenticationTimeout": { "message": "Temps d'espera d'autenticació" }, "authenticationSessionTimedOut": { "message": "La sessió d'autenticació s'ha esgotat. Reinicieu el procés d'inici de sessió." }, - "enterVerificationCodeEmail": { - "message": "Introduïu el codi de verificació de 6 dígits que s'ha enviat per correu electrònic a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Correu electrònic de verificació enviat a $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Recorda'm" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Envia el codi de verificació altra vegada" - }, - "useAnotherTwoStepMethod": { - "message": "Utilitzeu un altre mètode d'inici de sessió en dues passes" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Introduïu la vostra YubiKey al port USB de l'ordinador i, a continuació, premeu el seu botó." - }, "insertU2f": { "message": "Introduïu la vostra clau de seguretat al port USB de l'ordinador. Si té un botó, premeu-lo." }, - "webAuthnNewTab": { - "message": "\nPer iniciar la verificació de WebAuthn 2FA. Feu clic al botó següent per obrir una pestanya nova i seguiu les instruccions d'aquesta." - }, - "webAuthnNewTabOpen": { - "message": "Obri una pestanya nova" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "S'ha produït un error en connectar amb el servei Duo. Utilitzeu un mètode d'inici de sessió en dos passos diferent o poseu-vos en contacte amb Duo per obtenir ajuda." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicieu DUO i seguiu els passos per finalitzar la sessió." - }, "duoRequiredForAccount": { "message": "Es requereix l'inici de sessió en dos passos de DUO al vostre compte." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Desplega l'extensió per completar l'inici de sessió." - }, "popoutExtension": { "message": "Extensió emergent" }, diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index e6bf4a728e4..7f03e3f0598 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Pro použití této funkce je potřebné členství Premium." }, - "enterVerificationCodeApp": { - "message": "Zadejte 6místný kód z ověřovací aplikace." - }, "authenticationTimeout": { "message": "Časový limit ověření" }, "authenticationSessionTimedOut": { "message": "Vypršel časový limit relace ověřování. Restartujte proces přihlášení." }, - "enterVerificationCodeEmail": { - "message": "Zadejte 6místný kód z e-mailu, který byl zaslán na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Ověřovací e-mail byl zaslán na $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Zapamatovat mě" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Neptat se na tomto zařízení 30 dnů" }, - "sendVerificationCodeEmailAgain": { - "message": "Znovu zaslat ověřovací kód na e-mail" - }, - "useAnotherTwoStepMethod": { - "message": "Použít jinou metodu dvoufázového přihlášení" - }, "selectAnotherMethod": { "message": "Vybrat jinou metodu", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Použít obnovovací kód" }, - "insertYubiKey": { - "message": "Vložte YubiKey do USB portu Vašeho počítače a stiskněte jeho tlačítko." - }, "insertU2f": { "message": "Vložte svůj bezpečnostní klíč do USB portu Vašeho počítače a pokud má tlačítko, tak jej stiskněte." }, - "webAuthnNewTab": { - "message": "Pro spuštění ověření WebAuthn 2FA: Klepnutím na tlačítko níže otevřete novou kartu a postupujte podle pokynů uvedených v nové kartě." - }, - "webAuthnNewTabOpen": { - "message": "Otevřít novou kartu" - }, "openInNewTab": { "message": "Otevřít v nové kartě" }, @@ -2534,15 +2504,15 @@ "message": "Hesla Vaší organizace jsou ohrožena, protože jsou slabá, opakovaně používaná nebo odhalená.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Ilustrace seznamu přihlášení, která jsou riziková" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Ilustrace seznamu přihlášení, která jsou riziková." }, "generatePasswordSlideDesc": { "message": "Rychle vygeneruje silné, unikátní heslo s nabídkou automatického vyplňování Bitwarden na rizikových stránkách.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Ilustrace nabídky automatického vyplňování Bitwarden zobrazující vygenerované heslo" + "generatePasswordSlideImgAltPeriod": { + "message": "Ilustrace nabídky automatického vyplňování Bitwarden zobrazující vygenerované heslo." }, "updateInBitwarden": { "message": "Aktualizovat v Bitwardenu" @@ -2551,8 +2521,8 @@ "message": "Bitwarden Vás poté požádá o aktualizaci hesla ve správci hesel.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Ilustrace oznámení v Bitwardenu, která uživatele vyzývá k aktualizaci přihlášení" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Ilustrace oznámení v Bitwardenu, která uživatele vyzývá k aktualizaci přihlášení." }, "turnOnAutofill": { "message": "Zapnout automatické vyplňování" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Chyba při připojování ke službě Duo. Použijte jinou dvoufázovou metodu přihlášení nebo kontaktujte Duo o pomoc." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Spusťte DUO a pro dokončení přihlášení postupujte podle kroků." - }, "duoRequiredForAccount": { "message": "Pro Váš účet je vyžadováno dvoufázové přihlášení DUO." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Pro dokončení přihlášení použijte vyskakovací okno rozšíření." - }, "popoutExtension": { "message": "Zobrazit okno s doplňkem" }, diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 5ccff5a8332..3a59bca3f71 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -56,13 +56,13 @@ "message": "Prif gyfrinair" }, "masterPassDesc": { - "message": "The master password is the password you use to access your vault. It is very important that you do not forget your master password. There is no way to recover the password in the event that you forget it." + "message": "Y prif gyfrinair yw'r cyfrinair ddefnyddiwch chi i gael mynediad i'ch cell. Mae'n bwysig iawn nad ydych chi'n anghofio eich prif gyfrinair. Does dim modd adfer y cyfrinair pe baech yn ei anghofio." }, "masterPassHintDesc": { - "message": "A master password hint can help you remember your password if you forget it." + "message": "Gall awgrym o'ch prif gyfrinair eich helpu i'w gofio os ydych chi'n ei anghofio." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Os anghofiwch chi eich cyfrinair, gallwch anfon awgrym i'ch cyfeiriad ebost. $CURRENT$/$MAXIMUM$ nod.", "placeholders": { "current": { "content": "$1", @@ -380,7 +380,7 @@ "message": "Golygu ffolder" }, "editFolderWithName": { - "message": "Edit folder: $FOLDERNAME$", + "message": "Golygu ffolder: $FOLDERNAME$", "placeholders": { "foldername": { "content": "$1", @@ -392,10 +392,10 @@ "message": "Ffolder newydd" }, "folderName": { - "message": "Folder name" + "message": "Enw'r ffolder" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "Gallwch nythu ffolder drwy ychwanegu enw ffolder arall wedi'i olynu gan \"/\". Enghraifft: Cymdeithasol/Fforymau" }, "noFoldersAdded": { "message": "No folders added" @@ -459,19 +459,19 @@ "message": "Cynhyrchu cyfrinair" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Cynhyrchu cyfrinymadrodd" }, "passwordGenerated": { - "message": "Password generated" + "message": "Cyfrinair wedi'i gynhyrchu" }, "passphraseGenerated": { - "message": "Passphrase generated" + "message": "Cyfrinymadrodd wedi'i gynhyrchu" }, "usernameGenerated": { - "message": "Username generated" + "message": "Enw defnyddiwr wedi'i gynhyrchu" }, "emailGenerated": { - "message": "Email generated" + "message": "Cyfeiriad ebost wedi'i gynhyrchu" }, "regeneratePassword": { "message": "Ailgynhyrchu cyfrinair" @@ -483,11 +483,11 @@ "message": "Hyd" }, "include": { - "message": "Include", + "message": "Cynnwys", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "Cynnwys priflythrennau", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -495,7 +495,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "Cynnwys llythrennau bach", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -503,7 +503,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "Cynnwys rhifau", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -893,7 +893,7 @@ "message": "Please restart registration or try logging in." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Mae'n bosib fod gennych gyfrif eisoes" }, "logOutConfirmation": { "message": "Ydych chi'n siŵr eich bod am allgofnodi?" @@ -905,10 +905,10 @@ "message": "Na" }, "location": { - "message": "Location" + "message": "Lleoliad" }, "unexpectedError": { - "message": "An unexpected error has occurred." + "message": "Digwyddodd gwall annisgwyl." }, "nameRequired": { "message": "Mae angen enw." @@ -1007,10 +1007,10 @@ "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { - "message": "Ask to add login" + "message": "Gofyn i ychwanegu manylion mewngofnodi" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "Dewisiadau cadw i'r gell" }, "addLoginNotificationDesc": { "message": "Ask to add an item if one isn't found in your vault." @@ -1107,7 +1107,7 @@ "description": "Detailed error message shown when saving login details fails." }, "enableChangedPasswordNotification": { - "message": "Ask to update existing login" + "message": "Gofyn i ddiweddaru manylion mewngofnodi sy'n bodoli eisoes" }, "changedPasswordNotificationDesc": { "message": "Ask to update a login's password when a change is detected on a website." @@ -1207,7 +1207,7 @@ "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "Rhybudd", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Mae angen aelodaeth uwch i ddefnyddio'r nodwedd hon." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Anfonwyd ebost dilysu i $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Fy nghofio i" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Anfon ebost â chod dilysu eto" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Rhowch eich YubiKey i mewn i borth USB eich cyfrifiadur, yna gwasgwch y botwm." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Agor tab newydd" - }, "openInNewTab": { "message": "Agor mewn tab newydd" }, @@ -1674,7 +1644,7 @@ "message": "Testun" }, "cfTypeHidden": { - "message": "Hidden" + "message": "Cudd" }, "cfTypeBoolean": { "message": "Gwerth Boole" @@ -1877,7 +1847,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Golygu $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1886,7 +1856,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "Gweld $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1898,10 +1868,10 @@ "message": "Hanes cyfrineiriau" }, "generatorHistory": { - "message": "Generator history" + "message": "Hanes y cynhyrchydd" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Clirio hanes y cynhyrchydd" }, "cleargGeneratorHistoryDescription": { "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" @@ -1913,7 +1883,7 @@ "message": "Casgliadau" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ o gasgliadau", "placeholders": { "count": { "content": "$1", @@ -1969,11 +1939,11 @@ "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "Parth sylfaen (awgrymir)", "description": "Domain name. Ex. website.com" }, "domainName": { - "message": "Domain name", + "message": "Enw parth", "description": "Domain name. Ex. website.com" }, "host": { @@ -2023,13 +1993,13 @@ "message": "Does dim cyfrineiriau i'w rhestru." }, "clearHistory": { - "message": "Clear history" + "message": "Clirio'r hanes" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Dim byd i'w ddangos" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Dydych chi heb gynhyrchu unrhyw beth yn ddiweddar" }, "remove": { "message": "Tynnu" @@ -2056,7 +2026,7 @@ "message": "You do not belong to any organizations. Organizations allow you to securely share items with other users." }, "noCollectionsInList": { - "message": "There are no collections to list." + "message": "Does dim casgliadau i'w rhestru." }, "ownership": { "message": "Perchnogaeth" @@ -2090,10 +2060,10 @@ "message": "Datgloi â PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "Gosod PIN" }, "setYourPinButton": { - "message": "Set PIN" + "message": "Gosod PIN" }, "setYourPinCode": { "message": "Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if you ever fully log out of the application." @@ -2114,7 +2084,7 @@ "message": "Datgloi â biometreg" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "Datgloi gyda'r prif gyfrinair" }, "awaitDesktop": { "message": "Awaiting confirmation from desktop" @@ -2126,7 +2096,7 @@ "message": "Lock with master password on browser restart" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Gofyn am y prif gyfrinair wrth ailgychwyn y porwr" }, "selectOneCollection": { "message": "You must select at least one collection." @@ -2156,11 +2126,11 @@ "message": "Secure password generated! Don't forget to also update your password on the website." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Defnyddiwch y cynhyrchydd", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "useGeneratorHelpTextPartTwo": { - "message": "to create a strong unique password", + "message": "i greu cyfrinair cryf ac unigryw", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { @@ -2250,13 +2220,13 @@ "message": "Gosod prif gyfrinair" }, "currentMasterPass": { - "message": "Current master password" + "message": "Prif gyfrinair presennol" }, "newMasterPass": { "message": "Prif gyfrinair newydd" }, "confirmNewMasterPass": { - "message": "Confirm new master password" + "message": "Cadarnhau'r prif gyfrinair newydd" }, "masterPasswordPolicyInEffect": { "message": "One or more organization policies require your master password to meet the following requirements:" @@ -2331,7 +2301,7 @@ "message": "Your password hint cannot be the same as your password." }, "ok": { - "message": "Ok" + "message": "Iawn" }, "errorRefreshingAccessToken": { "message": "Access Token Refresh Error" @@ -2473,7 +2443,7 @@ } }, "atRiskPasswords": { - "message": "At-risk passwords" + "message": "Cyfrineiriau mewn perygl" }, "atRiskPasswordDescSingleOrg": { "message": "$ORGANIZATION$ is requesting you change one password because it is at-risk.", @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -2561,7 +2531,7 @@ "message": "Turned on autofill" }, "dismiss": { - "message": "Dismiss" + "message": "Diystyru" }, "websiteItemLabel": { "message": "Website $number$ (URI)", @@ -2662,7 +2632,7 @@ "message": "Disabled" }, "removePasswordConfirmation": { - "message": "Are you sure you want to remove the password?" + "message": "Ydych chi'n sicr yr hoffech chi dynnu'r cyfrinair?" }, "deleteSend": { "message": "Delete Send", @@ -3049,10 +3019,10 @@ "message": "Cynhyrchu enw defnyddiwr" }, "generateEmail": { - "message": "Generate email" + "message": "Cynhyrchu ebost" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Rhaid iddo fod rhwng $MIN$ a $MAX$ nod.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -3066,7 +3036,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Defnyddiwch $RECOMMENDED$ neu fwy o nodau i gynhyrchu cyfrinair cryf.", "description": "Appended to `spinboxBoundariesHint` to recommend a length to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3076,7 +3046,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Defnyddiwch $RECOMMENDED$ neu fwy o eiriau i gynhyrchu cyfrinymadrodd cryff.", "description": "Appended to `spinboxBoundariesHint` to recommend a number of words to the user. This must include any language-specific 'sentence' separator characters (e.g. a space in english).", "placeholders": { "recommended": { @@ -3139,7 +3109,7 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Cynhyrchwyd gan Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { @@ -3153,7 +3123,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Tocyn API $SERVICENAME$ annilys", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -3163,7 +3133,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Tocyn API $SERVICENAME$ annilys: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3420,7 +3390,7 @@ "message": "Change shortcut" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "Rheoli llwybrau byr" }, "autofillShortcut": { "message": "Autofill keyboard shortcut" @@ -3483,10 +3453,10 @@ "message": "Check your email" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Dilynwch y ddolen yn yr ebost anfonwyd i" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "a pharhau i greu eich cyfrif." }, "noEmail": { "message": "Dim ebost?" @@ -3546,7 +3516,7 @@ "message": "Input is required." }, "required": { - "message": "required" + "message": "gofynnol" }, "search": { "message": "Chwilio" @@ -3798,7 +3768,7 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Ceisio eto" }, "verificationRequiredForActionSetPinToContinue": { "message": "Verification required for this action. Set a PIN to continue." @@ -3831,7 +3801,7 @@ "message": "Enter the verification code that was sent to your email." }, "resendCode": { - "message": "Resend code" + "message": "Ailanfon cod" }, "total": { "message": "Cyfanswm" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, @@ -4013,13 +3977,13 @@ "message": "Enw defnyddiwr neu gyfrinair anghywir" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Cyfrinair anghywir" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Cod anghywir" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "PIN anghywir" }, "multifactorAuthenticationFailed": { "message": "Multifactor authentication failed" @@ -4365,7 +4329,7 @@ "message": "Error assigning target folder." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Gweld eitemau yn $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -4375,7 +4339,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Yn ôl i $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -4388,7 +4352,7 @@ "message": "Newydd" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Tynnu $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -5082,7 +5046,7 @@ "message": "Generated password" }, "compactMode": { - "message": "Compact mode" + "message": "Modd cryno" }, "beta": { "message": "Beta" diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index f66f8f34495..55e68031f03 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Premium-medlemskab kræves for at anvende denne funktion." }, - "enterVerificationCodeApp": { - "message": "Indtast den 6-cifrede verifikationskode fra din autentificerings-app." - }, "authenticationTimeout": { "message": "Godkendelsestimeout" }, "authenticationSessionTimedOut": { "message": "Godkendelsessessionen fik timeout. Genstart loginprocessen." }, - "enterVerificationCodeEmail": { - "message": "Indtast den 6-cifrede verifikationskode, der blev sendt til $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Bekræftelsesmail sendt til $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Husk mig" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verifikationskode-email igen" - }, - "useAnotherTwoStepMethod": { - "message": "Brug en anden to-trins login metode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Indsæt din YubiKey i din computers USB-port, og tryk derefter på dens knap." - }, "insertU2f": { "message": "Indsæt din sikkerhedsnøgle i din computers USB-port. Hvis den har en knap, tryk på den." }, - "webAuthnNewTab": { - "message": "For at starte WebAuthn 2FA-verifikationen. Klik på knappen nedenfor for at åbne en ny fane og følg instruktionerne i den nye fane." - }, - "webAuthnNewTabOpen": { - "message": "Åbn ny fane" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fejl under forbindelsesoprettelsen til Duo-tjenesten. Brug en anden totrins-indlogningsmetode eller kontakt Duo for hjælp." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Start Duo og følg trinnene for at fuldføre indlogningen." - }, "duoRequiredForAccount": { "message": "Duo-totrinsindlogning kræves for kontoen." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Pop udvidelsen ud for at fuldføre indlogning." - }, "popoutExtension": { "message": "Pop ud-udvidelse" }, diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 25e8b53cdb5..ba129609937 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Eine Premium-Mitgliedschaft ist für diese Funktion notwendig." }, - "enterVerificationCodeApp": { - "message": "Gib den 6-stelligen Verifizierungscode aus deiner Authenticator App ein." - }, "authenticationTimeout": { "message": "Authentifizierungs-Timeout" }, "authenticationSessionTimedOut": { "message": "Die Authentifizierungssitzung ist abgelaufen. Bitte starte den Anmeldeprozess neu." }, - "enterVerificationCodeEmail": { - "message": "Gib den 6-stelligen Bestätigungscode ein, der an $EMAIL$ gesendet wurde.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifizierungsmail wurde an $EMAIL$ gesendet.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Angemeldet bleiben" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Für 30 Tage auf diesem Gerät nicht mehr fragen" }, - "sendVerificationCodeEmailAgain": { - "message": "E-Mail mit Bestätigungscode erneut versenden" - }, - "useAnotherTwoStepMethod": { - "message": "Verwende eine andere zweistufige Login-Methode" - }, "selectAnotherMethod": { "message": "Wähle eine andere Methode", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Verwende deinen Wiederherstellungscode" }, - "insertYubiKey": { - "message": "Stecke deinen YubiKey in den USB-Port Ihres Computers, dann berühre den Button." - }, "insertU2f": { "message": "Stecke deinen Sicherheitsschlüssel in den USB-Port deines Computers. Falls ein Knopf vorhanden ist, berühre diesen." }, - "webAuthnNewTab": { - "message": "Um die WebAuthn 2FA Verifizierung zu starten, klicke auf die Schaltfläche unten, um einen neuen Tab zu öffnen und folge den Anweisungen, die im neuen Tab angezeigt werden." - }, - "webAuthnNewTabOpen": { - "message": "Neuen Tab öffnen" - }, "openInNewTab": { "message": "In neuem Tab öffnen" }, @@ -2534,15 +2504,15 @@ "message": "Die Passwörter deiner Organisationen sind gefährdet, weil sie schwach, wiederverwendet und/oder kompromittiert sind.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration einer Liste gefährdeter Zugangsdaten" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Generiere schnell ein starkes, einzigartiges Passwort mit dem Bitwarden Auto-Ausfüllen-Menü auf der gefährdeten Website.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration des Bitwarden Auto-Ausfüllen-Menüs, das ein generiertes Passwort anzeigt" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "In Bitwarden aktualisieren" @@ -2551,8 +2521,8 @@ "message": "Bitwarden wird dich dann auffordern, das Passwort im Passwort-Manager zu aktualisieren.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration einer Bitwarden-Benachrichtigung, die den Benutzer dazu auffordert, die Zugangsdaten zu aktualisieren" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Auto-Ausfüllen aktivieren" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fehler beim Verbinden mit dem Duo-Dienst. Verwende eine andere Zwei-Faktor-Authentifizierungsmethode oder kontaktiere Duo für Hilfe." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Starte DUO und folge den Schritten, um die Anmeldung zu abzuschließen." - }, "duoRequiredForAccount": { "message": "Für dein Konto ist die Duo Zwei-Faktor-Authentifizierung erforderlich." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Koppel die Erweiterung ab, um die Anmeldung abzuschließen." - }, "popoutExtension": { "message": "Popout-Erweiterung" }, diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 47dca3701ec..a4564b3705e 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Για να χρησιμοποιήσετε αυτή τη λειτουργία, απαιτείται συνδρομή Premium." }, - "enterVerificationCodeApp": { - "message": "Εισάγετε τον 6ψήφιο κωδικό από την εφαρμογή επαλήθευσης." - }, "authenticationTimeout": { "message": "Χρονικό όριο επαλήθευσης" }, "authenticationSessionTimedOut": { "message": "Λήξη χρονικού ορίου συνεδρίας επαλήθευσης. Παρακαλώ επανεκκινήστε τη διαδικασία σύνδεσης." }, - "enterVerificationCodeEmail": { - "message": "Εισάγετε τον 6ψήφιο κωδικό επαλήθευσης τον οποίο λάβατε στο $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Εστάλη email επαλήθευσης στο $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Να με θυμάσαι" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Αποστολή email κωδικού επαλήθευσης ξανά" - }, - "useAnotherTwoStepMethod": { - "message": "Χρήση άλλης μεθόδου σύνδεσης δύο παραγόντων" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Τοποθετήστε το YubiKey στη θύρα USB του υπολογιστή σας και έπειτα κάντε κλικ στο κουμπί του." - }, "insertU2f": { "message": "Εισάγετε το κλειδί ασφαλείας στη θύρα USB του υπολογιστή σας. Αν έχει κουμπί, πατήστε το." }, - "webAuthnNewTab": { - "message": "Συνεχίστε την επαλήθευση WebAuthn 2FA στη νέα καρτέλα." - }, - "webAuthnNewTabOpen": { - "message": "Άνοιγμα νέας καρτέλας" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Ενεργοποίηση αυτόματης συμπλήρωσης" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Σφάλμα κατά τη σύνδεση με την υπηρεσία Duo. Χρησιμοποιήστε μια διαφορετική μέθοδο σύνδεσης δύο βημάτων ή επικοινωνήστε με την Duo για βοήθεια." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Εκκινήστε το Duo και ακολουθήστε τα βήματα για να ολοκληρώσετε τη σύνδεση." - }, "duoRequiredForAccount": { "message": "Απαιτείται σύνδεση δύο βημάτων Duo για το λογαριασμό σας." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Ανοίξτε την επέκταση σε νέο παράθυρο για να ολοκληρώσετε τη σύνδεση." - }, "popoutExtension": { "message": "Άνοιγμα επέκτασης σε νέο παράθυρο" }, diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 9c6d212f8c9..f19382347b0 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organisation passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index aa7a234246f..eb86d90a74e 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organisation passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index d282011e628..11d21e74d0f 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Una membrasía Premium es requerida para utilizar esta característica." }, - "enterVerificationCodeApp": { - "message": "Introduce el código de verificación de 6 dígitos de tu aplicación autenticadora." - }, "authenticationTimeout": { "message": "Tiempo de autenticación agotado" }, "authenticationSessionTimedOut": { "message": "Se ha agotado el tiempo de la sesión de autenticación. Por favor, inicie nuevamente el proceso de inicio de sesión." }, - "enterVerificationCodeEmail": { - "message": "Introduce el código de verificación de 6 dígitos que te ha sido enviado por correo electrónico", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Correo electrónico de verificación enviado a $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Recordarme" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Reenviar código de verificación por correo electrónico" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar otro método de autenticación en dos pasos" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Inserta tu YubiKey en el puerto USB de tu equipo y posteriormente pulsa su botón." - }, "insertU2f": { "message": "Inserta tu llave de seguridad en el puerto USB de tu equipo. Si tiene un botón, púlsalo." }, - "webAuthnNewTab": { - "message": "Para iniciar la verificación de WebAuthn 2FA. Haga clic en el botón de abajo para abrir una nueva pestaña y siga las instrucciones proporcionadas en la nueva pestaña." - }, - "webAuthnNewTabOpen": { - "message": "Abrir nueva pestaña" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Activar autorrelleno" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error al conectarse con el servicio Duo. Utiliza un método de inicio de sesión en dos pasos diferente o ponte en contacto con Duo para obtener ayuda." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Abra Duo y siga los pasos para terminar de iniciar sesión." - }, "duoRequiredForAccount": { "message": "Se requiere el inicio de sesión en dos pasos Duo para su cuenta." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Abra la extensión para completar el inicio de sesión." - }, "popoutExtension": { "message": "Abrir extensión" }, diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index e2ad9a1e53a..8576ee1db7e 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Selle funktsiooni kasutamiseks on vajalik tasulist kontot omada." }, - "enterVerificationCodeApp": { - "message": "Sisesta autentimise rakendusest 6 kohaline number." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Sisesta 6 kohaline number, mis saadeti e-posti aadressile $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kinnituskood saadeti e-posti aadressile $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Jäta mind meelde" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Saada kinnituskood uuesti e-postile" - }, - "useAnotherTwoStepMethod": { - "message": "Kasuta teist kaheastmelist sisselogimise meetodit" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sisesta oma YubiKey arvuti USB porti ja kliki sellele nupule." - }, "insertU2f": { "message": "Sisesta oma turvaline võti arvuti USB porti. Kui sellel on nupp, siis vajuta seda." }, - "webAuthnNewTab": { - "message": "Jätka WebAuthn 2FA kinnitamisega uuel vahelehel." - }, - "webAuthnNewTabOpen": { - "message": "Ava uus vahekaart" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 95d843a3aa8..542c9a0d03f 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Premium bazkidetza beharrezkoa da ezaugarri hau erabiltzeko." }, - "enterVerificationCodeApp": { - "message": "Sartu zure autentifikazio aplikazioaren 6 digituko egiaztatze kodea." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Sartu $EMAIL$-era bidalitako 6 digituko egiaztatze-kodea.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Egiaztatze emaila $EMAIL$-era bidalia.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Gogora nazazu" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Berbidali email bidezko egiaztatze-kodea." - }, - "useAnotherTwoStepMethod": { - "message": "Erabili bi urratseko saio hasierarako beste modu bat" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sartu zure YubiKey-a ordenagailuko USB atakan, ondoren, sakatu bere botoia." - }, "insertU2f": { "message": "Sartu zure segurtasun-gakoa ordenagailuaren USB atakan. Botoia badu, sakatu ezazu." }, - "webAuthnNewTab": { - "message": "WebAuthn 2FA egiaztatzea hasteko. Egin klik beheko botoian fitxa berria irekitzeko eta jarraitu fitxa berriko jarraibideei." - }, - "webAuthnNewTabOpen": { - "message": "Ireki fitxa berria" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 0f5616cd001..91acd3c7081 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "برای استفاده از این ویژگی عضویت پرمیوم لازم است." }, - "enterVerificationCodeApp": { - "message": "کد ۶ رقمی تأیید را از برنامه احراز هویت وارد کنید." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "کد ۶ رقمی تأیید را که به $EMAIL$ ایمیل شده را وارد کنید.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ایمیل تأیید به $EMAIL$ ارسال شد.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "مرا به خاطر بسپار" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ارسال دوباره ایمیل کد تأیید" - }, - "useAnotherTwoStepMethod": { - "message": "استفاده از روش ورود دو مرحله‌ای دیگر" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey خود را وارد پورت USB رایانه کنید، بعد دکمه آن را بفشارید." - }, "insertU2f": { "message": "کلید امنیتی خود را وارد پورت USB رایانه کنید، اگر دکمه ای دارد آن را بفشارید." }, - "webAuthnNewTab": { - "message": "تأیید WebAuthn 2FA را در برگه جدید ادامه دهید." - }, - "webAuthnNewTabOpen": { - "message": "باز کردن زبانه جدید" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index ff71b93a62d..0875639868e 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Tämä ominaisuus edellyttää Premium-jäsenyyttä." }, - "enterVerificationCodeApp": { - "message": "Syötä todennussovelluksesi näyttämä kuusinumeroinen todennuskoodi." - }, "authenticationTimeout": { "message": "Todennuksen aikakatkaisu" }, "authenticationSessionTimedOut": { "message": "Todennusistunto aikakatkaistiin. Ole hyvä ja aloita kirjautumisprosessi uudelleen." }, - "enterVerificationCodeEmail": { - "message": "Syötä osoitteeseen $EMAIL$ lähetetty kuusinumeroinen todennuskoodi.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Todennussähköposti lähetettiin osoitteeseen $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Muista minut" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Älä kysy uudelleen tällä laitteella 30 päivään" }, - "sendVerificationCodeEmailAgain": { - "message": "Lähetä todennuskoodi sähköpostitse uudelleen" - }, - "useAnotherTwoStepMethod": { - "message": "Käytä vaihtoehtoista todennustapaa" - }, "selectAnotherMethod": { "message": "Valitse vaihtoehtoinen tapa", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Käytä palautuskoodiasi" }, - "insertYubiKey": { - "message": "Kytke YubiKey-suojausavaimesi tietokoneen USB-porttiin ja kosketa sen painiketta." - }, "insertU2f": { "message": "Kytke suojausavaimesi tietokoneen USB-porttiin. Jos laitteessa on painike, paina sitä." }, - "webAuthnNewTab": { - "message": "Aloittaaksesi kaksivaiheisen WebAuthn-tunnistautumisen, seuraa alla olevasta painikkeesta uuteen välilehteen avautuvia ohjeita." - }, - "webAuthnNewTabOpen": { - "message": "Avaa uusi välilehti" - }, "openInNewTab": { "message": "Avaa uudessa välilehdessä" }, @@ -2534,15 +2504,15 @@ "message": "Organisaatiosalasanasi ovat vaarantuneet, koska ne ovat heikkoja, toistuvasti käytettyjä ja/tai paljastuneita.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Kuvitus vaarantuneiden kirjautumistietojen luettelosta" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Luo vahva ja ainutlaatuinen salasana nopeasti Bitwardenin automaattitäytön valikosta vaarantuneella sivustolla.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Kuvitus Bitwardenin automaattitäytön valikosta, luodulla salasanalla" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Päivitä Bitwardenissa" @@ -2551,8 +2521,8 @@ "message": "Bitwarden pyytää sinua sitten päivittämään salasanan salasanahallinnassa.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Kuvitus ilmoituksesta, jossa Bitwarden tarjoaa kirjautumistiedon päivitystä" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Ota automaattitäyttö käyttöön" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Virhe yhdistettäessä Duo-palveluun. Käytä vaihtoehtoista todennustapaa tai ole yhteydessä Duon asiakaspalveluun saadaksesi apua." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." - }, "duoRequiredForAccount": { "message": "Tilillesi kirjautuminen vaatii Duo-vahvistuksen." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Viimeistele kirjautuminen avaamalla laajennus erilliseen ikkunaan." - }, "popoutExtension": { "message": "Irrota laajennus" }, diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 292c5fd0576..939137c36ce 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Ang Premium na membership ay kinakailangan upang gamitin ang tampok na ito." }, - "enterVerificationCodeApp": { - "message": "Ipasok ang 6 na digit na code ng pagpapatunay mula sa iyong authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Ipasok ang 6 na digit na code na na-email sa $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Veripikasyon na email na ipinadala sa $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Tandaan mo ako" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ipadala muli ang email ng verification code" - }, - "useAnotherTwoStepMethod": { - "message": "Gamitin ang isa pang two-step na paraan ng pag-login" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "I-insert ang iyong YubiKey sa USB port ng iyong computer, pagkatapos ay tindigin ang buton nito." - }, "insertU2f": { "message": "I-insert ang iyong security key sa USB port ng iyong computer. Kung mayroon itong buton, tindigin ito." }, - "webAuthnNewTab": { - "message": "Upang simulan ang WebAuthn 2FA verification. I-click ang buton sa ibaba upang buksan ang isang bagong tab at sundin ang mga tagubilin na ibinigay sa bagong tab." - }, - "webAuthnNewTabOpen": { - "message": "Buksan ang bagong tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 5ec06f52a76..488cec4066d 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Une adhésion Premium est requise pour utiliser cette fonctionnalité." }, - "enterVerificationCodeApp": { - "message": "Saisissez le code de vérification à 6 chiffres depuis votre application d'authentification." - }, "authenticationTimeout": { "message": "Délai d'authentification dépassé" }, "authenticationSessionTimedOut": { "message": "La session d'authentification a expiré. Veuillez redémarrer le processus de connexion." }, - "enterVerificationCodeEmail": { - "message": "Saisissez le code de vérification à 6 chiffres qui a été envoyé par courriel à $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Courriel de vérification envoyé à $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Rester connecté" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne plus demander sur cet appareil pendant 30 jours" }, - "sendVerificationCodeEmailAgain": { - "message": "Envoyer à nouveau le courriel de code de vérification" - }, - "useAnotherTwoStepMethod": { - "message": "Utiliser une autre méthode d'identification en deux étapes" - }, "selectAnotherMethod": { "message": "Sélectionnez une autre méthode", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Utilisez votre code de récupération" }, - "insertYubiKey": { - "message": "Insérez votre YubiKey dans le port USB de votre ordinateur puis appuyez sur son bouton." - }, "insertU2f": { "message": "Insérez votre clé de sécurité dans le port USB de votre ordinateur. S'il dispose d'un bouton, appuyez dessus." }, - "webAuthnNewTab": { - "message": "Pour démarrer la vérification 2FA WebAuthn, cliquez sur le bouton ci-dessous et suivez les instructions dans le nouvel onglet." - }, - "webAuthnNewTabOpen": { - "message": "Ouvrir un nouvel onglet" - }, "openInNewTab": { "message": "Ouvrir dans un nouvel onglet" }, @@ -2534,15 +2504,15 @@ "message": "Les mots de passe de votre organisation sont à risque, car ils sont faibles, réutilisés et/ou exposés.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration d'une liste d'identifiants à risque" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Générez rapidement un mot de passe fort et unique grâce au menu de saisie automatique de Bitwarden sur le site à risque.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration du menu de saisie automatique de Bitwarden affichant un mot de passe généré" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Mettre à jour dans Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden vous demandera alors de mettre à jour le mot de passe dans le gestionnaire de mots de passe.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration d’une notification de Bitwarden invitant l’utilisateur à mettre à jour l'identifiant" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Activer la saisie automatique" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erreur de connexion avec le service Duo. Utilisez une autre méthode de connexion en deux étapes ou contactez Duo pour obtenir de l'aide." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Lancez DUO et suivez les étapes pour terminer la connexion." - }, "duoRequiredForAccount": { "message": "L'authentification à deux facteurs Duo est requise pour votre compte." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Faire apparaître l'extension pour terminer la connexion." - }, "popoutExtension": { "message": "Détacher l'extension" }, diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index c76c60114c9..23a29400e25 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Requírese un plan Prémium para poder empregar esta función." }, - "enterVerificationCodeApp": { - "message": "Insire o código de 6 díxitos da túa aplicación de autenticación." - }, "authenticationTimeout": { "message": "Tempo límite de autenticación superado" }, "authenticationSessionTimedOut": { "message": "Superouse o tempo límite da sesión de autenticación. Recomeza o proceso." }, - "enterVerificationCodeEmail": { - "message": "Insire o código de verificación de 6 díxitos enviado a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Enviouse un correo de verificación a $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Lémbrame" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar un novo correo de verificación" - }, - "useAnotherTwoStepMethod": { - "message": "Empregar outro método de verificación en 2 pasos" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Conecta a túa YubiKey no porto USB, despois preme o seu botón." - }, "insertU2f": { "message": "Conecta a túa YubiKey no porto USB. Se ten un botón, prémeo." }, - "webAuthnNewTab": { - "message": "Para iniciar o proceso de verificación WebAuthn 2FA, clica no botón embaixo e segue as instrucións na pestana que se abrirá." - }, - "webAuthnNewTabOpen": { - "message": "Abrir nova pestana" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro conectando co servizo de Duo. Usa un método de verificación en 2 pasos alternativo ou contacta con Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Executa Duo e segue os pasos para finalizar o inicio de sesión." - }, "duoRequiredForAccount": { "message": "A túa conta require a verificación en 2 pasos de Duo." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Saca a extensión nunha ventá para continuar." - }, "popoutExtension": { "message": "Sacar a extensión" }, diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 0d15c90c3d1..bff75506ad0 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "נדרשת חברות פרימיום כדי להשתמש בתכונה זו." }, - "enterVerificationCodeApp": { - "message": "הכנס את קוד האימות בן 6 הספרות מאפליקציית האימות שלך." - }, "authenticationTimeout": { "message": "פסק זמן לאימות" }, "authenticationSessionTimedOut": { "message": "זמן אימות ההפעלה תם. נא להתחיל מחדש את תהליך הכניסה." }, - "enterVerificationCodeEmail": { - "message": "הכנס את קוד האימות בן 6 הספרות שנשלח ל-$EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "מייל אימות נשלח לכתובת $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "זכור אותי" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "אל תשאל אותי שוב במכשיר זה למשך 30 יום" }, - "sendVerificationCodeEmailAgain": { - "message": "שלח שוב קוד אימות לאימייל" - }, - "useAnotherTwoStepMethod": { - "message": "השתמש בשיטה אחרת עבור כניסה דו שלבית" - }, "selectAnotherMethod": { "message": "בחר שיטה אחרת", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "השתמש בקוד השחזור שלך" }, - "insertYubiKey": { - "message": "הכנס את ה-YubiKey אל כניסת ה-USB במחשבך, ואז גע בכפתור שלו." - }, "insertU2f": { "message": "הכנס את מפתח האבטחה שלך אל כניסת ה-USB במחשבך. אם יש לו כפתור, לחץ עליו." }, - "webAuthnNewTab": { - "message": "על מנת להתחיל אימות WebAuthn דו־שלבי. לחץ על הלחצן למטה כדי לפתוח כרטיסיה חדשה ועקוב אחר ההוראות המסופקת בכרטיסיה החדשה." - }, - "webAuthnNewTabOpen": { - "message": "פתח כרטיסיה חדשה" - }, "openInNewTab": { "message": "פתח בכרטיסיה חדשה" }, @@ -2534,15 +2504,15 @@ "message": "סיסמאות הארגון שלך הן בסכנה בגלל שהן חלשות, משומשות, ו/או חשופות.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "איור של רשימת כניסות בסיכון" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "צור במהירות סיסמה חזקה וייחודית עם תפריט המילוי האוטומטי של Bitwarden באתר שבסיכון.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "איור של תפריט המילוי האוטומטי של Bitwarden המציג סיסמה שנוצרה" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "עדכן ב־Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden אז ינחה אותך לעדכן את הסיסמה במנהל הסיסמאות.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "איור של התראת Bitwarden המנחה את המשתמש לעדכן את הכניסה" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "הפעל מילוי אוטומטי" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "שגיאה בהתחברות עם השירות Duo. השתמש בשיטת כניסה דו־שלבית אחרת או פנה אל Duo לסיוע." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "פתח את Duo ועקוב אחר השלבים כדי לסיים להיכנס." - }, "duoRequiredForAccount": { "message": "נדרשת כניסה דו־שלבית של Duo עבור החשבון שלך." }, - "popoutTheExtensionToCompleteLogin": { - "message": "הקפץ את ההרחבה כדי להשלים כניסה." - }, "popoutExtension": { "message": "הקפץ הרחבה" }, diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 6dc3dced829..215ea3e9cd4 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "इस सुविधा का उपयोग करने के लिए प्रीमियम सदस्यता की आवश्यकता होती है।" }, - "enterVerificationCodeApp": { - "message": "अपने ऑथेंटिकेटर ऐप से 6 डिजिट वेरिफिकेशन कोड डालें।" - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ईमेल $EMAIL$ को भेजा गया।", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "मुझे याद रखें" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "फिर से सत्यापन कोड ईमेल भेजें" - }, - "useAnotherTwoStepMethod": { - "message": "एक और दो-चरण लॉगिन विधि का उपयोग करें" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "अपने कंप्यूटर के यूएसबी पोर्ट में अपने YubiKey डालें, फिर इसके बटन को स्पर्श करें।" - }, "insertU2f": { "message": "अपने कंप्यूटर के यूएसबी पोर्ट में अपनी सुरक्षा कुंजी डालें। अगर इसमें कोई बटन है तो उसे टच करें।\n" }, - "webAuthnNewTab": { - "message": "वेबऑथन 2FA सत्यापन शुरू करने के लिए। एक नया टैब खोलने के लिए नीचे दिए गए बटन पर क्लिक करें और नए टैब में दिए गए निर्देशों का पालन करें।" - }, - "webAuthnNewTabOpen": { - "message": "नया टैब खोलें" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "जोखिमग्रस्त लॉगिन की सूची का चित्रण।" }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "उत्पन्न पासवर्ड प्रदर्शित करने वाले बिटवर्डन स्वतः भरण मेनू का चित्रण।" }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "उपयोगकर्ता को लॉगिन अपडेट करने के लिए प्रेरित करने वाली बिटवर्डन की अधिसूचना का चित्रण।" }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index eda6d7267a3..1549c5c793a 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Za korištenje ove značajke potrebno je Premium članstvo." }, - "enterVerificationCodeApp": { - "message": "Unesi 6-znamenkasti kôd za provjeru iz autentifikatorske aplikacije." - }, "authenticationTimeout": { "message": "Istek vremena za autentifikaciju" }, "authenticationSessionTimedOut": { "message": "Sesija za autentifikaciju je istekla. Ponovi proces prijave." }, - "enterVerificationCodeEmail": { - "message": "Unesi 6-znamenkasti kôd za provjeru poslan e-poštom na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pošta za potvrdu poslana je na $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne pitaj na ovom uređaju idućih 30 dana" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno slanje kontrolnog koda e-poštom" - }, - "useAnotherTwoStepMethod": { - "message": "Koristiti drugi način prijave dvostrukom autentifikacijom" - }, "selectAnotherMethod": { "message": "Odaberi drugi način", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Koristi kôd za oporavak" }, - "insertYubiKey": { - "message": "Umetni svoj YubiKey u USB priključak računala, a zatim dodirni njegovu tipku." - }, "insertU2f": { "message": "Umetni svoj sigurnosni ključ u USB priključak računala. Ako ima tipku, dodirni ju." }, - "webAuthnNewTab": { - "message": "Nastavi na WebAuthn 2FA verifikaciju u novoj kartici." - }, - "webAuthnNewTabOpen": { - "message": "Otvori novu karticu" - }, "openInNewTab": { "message": "Otvori u novoj kartici" }, @@ -2534,15 +2504,15 @@ "message": "Lozinke tvoje organizacije su rizične jer su slabe, nanovo korištene i/ili iscurile.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Ilustracija liste rizičnih prijava" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Brzo generiraj jake, jedinstvene lozinke koristeći Bitwarden dijalog auto-ispune direktno na stranici.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Ilustracija Bitwarden dijalog auto-ispune s prikazom generirane lozinke" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Ažuriraj u Bitwardenu" @@ -2551,8 +2521,8 @@ "message": "Bitwarden će te pitati treba li ažurirati lozinku u upravitelju lozinki.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Ilustracija Bitwarden upita za ažuriranje prijave" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Uključi auto-ispunu" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Greška pri povezivanju s uslugom Duo. Koristi drugu metodu prijave s dvostrukom autentifikacijom ili kontaktiraj Duo za pomoć." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Pokreni Duo i slijedi korake za dovršetak prijave." - }, "duoRequiredForAccount": { "message": "Za tvoj račun je potrebna Duo dvostruka autentifikacija." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Otvori proširenje za dovršetak prijave." - }, "popoutExtension": { "message": "Otvori proširenje" }, diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index ec313c2cd10..92745a09c3d 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Prémium tagság szükséges ennek a funkciónak eléréséhez a jövőben." }, - "enterVerificationCodeApp": { - "message": "Add meg a 6 számjegyű ellenőrző kódot a hitelesítő alkalmazásodból." - }, "authenticationTimeout": { "message": "Hitelesítési időkifutás" }, "authenticationSessionTimedOut": { "message": "A hitelesítési munkamenet időkifutással lejárt. Indítsuk újra a bejelentkezési folyamatot." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ email címre elküldött 6 számjegyű ellenőrző kód megadása.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Az ellenőrző kód elküldésre került $EMAIL$ email címre.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Emlékezz rám" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne kérdezzen újra ezen az eszközön 30 napig" }, - "sendVerificationCodeEmailAgain": { - "message": "Megerősítő kód e-mail újra küldése" - }, - "useAnotherTwoStepMethod": { - "message": "Más két lépcsős bejelentkezés használata" - }, "selectAnotherMethod": { "message": "Másik módszer választás", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Helyreállító kód használata" }, - "insertYubiKey": { - "message": "Illeszd be a YubiKey-t a számítógéped egyik USB portjába, majd nyomd meg a gombját." - }, "insertU2f": { "message": "Illesz be biztonsági kulcsod a számítógéped egyik USB portjába. Ha van rajta egy gomb, nyomd le." }, - "webAuthnNewTab": { - "message": "A WebAuthn 2FA ellenőrzés folytatása az új fülön." - }, - "webAuthnNewTabOpen": { - "message": "Új fül megnyitása" - }, "openInNewTab": { "message": "Megnyitás új fülön" }, @@ -2534,14 +2504,14 @@ "message": "A szervezeti jelszavak kockázatosak, mert gyengék, újra felhasználásra kerültek és/vagy nyilvánosságra kerültek.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "A kockázatos bejelentkezések listájának illusztrációja" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "A kockázatos bejelentkezések listájának illusztrációja." }, "generatePasswordSlideDesc": { "message": "Gyorsan generálhatunk erős, egyedi jelszót a Bitwarden automatikus kitöltési menüjével a kockázatos webhelyen.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { + "generatePasswordSlideImgAltPeriod": { "message": "A Bitwarden automatikus kitöltési menüjének illusztrációja, amely egy generált jelszót jelenít meg." }, "updateInBitwarden": { @@ -2551,7 +2521,7 @@ "message": "A Bitwarden ezután felkér a jelszó frissítésére a jelszókezelőben.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { + "updateInBitwardenSlideImgAltPeriod": { "message": "Illusztráció a Bitwarden értesítéséről, amely felszólítja a felhasználót a bejelentkezési adatok frissítésére." }, "turnOnAutofill": { @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Indítsuk el a DUO-t és kövessük a lépéseket a bejelentkezés befejezéséhez." - }, "duoRequiredForAccount": { "message": "A fiókhoz kétlépcsős DUO bejelentkezés szükséges." }, - "popoutTheExtensionToCompleteLogin": { - "message": "A bejelentkezés befejezéséhez nyissuk meg a kiterjesztést." - }, "popoutExtension": { "message": "Felugró bővítmény" }, @@ -4280,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Elem megtekintése - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Automatikus kitöltés - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index daccc3d8272..b9218126dbb 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Keanggotaan premium diperlukan untuk menggunakan fitur ini." }, - "enterVerificationCodeApp": { - "message": "Masukkan 6 digit kode verifikasi dari aplikasi autentikasi Anda." - }, "authenticationTimeout": { "message": "Batas waktu otentikasi" }, "authenticationSessionTimedOut": { "message": "Sesi otentikasi telah berakhir. Harap mulai ulang proses masuk." }, - "enterVerificationCodeEmail": { - "message": "Masukkan 6 digit kode verifikasi yang dikirim melalui email ke $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Surel verifikasi telah dikirim ke $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Ingat saya" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Jangan tanyakan lagi pada perangkat ini untuk 30 hari" }, - "sendVerificationCodeEmailAgain": { - "message": "Kirim ulang email kode verifikasi" - }, - "useAnotherTwoStepMethod": { - "message": "Gunakan metode masuk dua langkah lainnya" - }, "selectAnotherMethod": { "message": "Pilih metode lain", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Gunakan kode pemulihan Anda" }, - "insertYubiKey": { - "message": "Masukkan YubiKey Anda ke port USB komputer Anda, lalu sentuh tombolnya." - }, "insertU2f": { "message": "Masukkan kunci keamanan ke port USB komputer Anda. Jika ada tombolnya, tekanlah." }, - "webAuthnNewTab": { - "message": "Untuk memulai verifikasi 2FA WebAuthn. Klik tombol di bawah untuk membuka tab baru dan ikuti instruksi yang diberikan." - }, - "webAuthnNewTabOpen": { - "message": "Buka tab baru" - }, "openInNewTab": { "message": "Buka dalam tab baru" }, @@ -2534,15 +2504,15 @@ "message": "Kata sandi organisasi Anda berrisiko karena mereka lemah, dipakai ulang, dan/atau terpapar.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Ilustrasi dari daftar log masuk yang berrisiko" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Gagal menyambungkan dengan layanan Duo. Gunakan cara masuk dua-langkah lainnya atau hubungi Duo untuk mendapatkan panduan." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Luncurkan Duo dan ikuti langkah-langkah untuk menyelesaikan masuk." - }, "duoRequiredForAccount": { "message": "Login dua-langkah Duo diperlukan untuk akun Anda." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Sembulkan ekstensi untuk melengkapi login." - }, "popoutExtension": { "message": "Sembulkan ekstensi" }, diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index b18acbc79b8..cd7daff61f5 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Passa a Premium per utilizzare questa funzionalità." }, - "enterVerificationCodeApp": { - "message": "Inserisci il codice di verifica a 6 cifre dalla tua app di autenticazione." - }, "authenticationTimeout": { "message": "Timeout autenticazione" }, "authenticationSessionTimedOut": { "message": "La sessione di autenticazione è scaduta. Accedi di nuovo." }, - "enterVerificationCodeEmail": { - "message": "Inserisci il codice di verifica a 6 cifre inviato a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "L'email di verifica è stata inviata all'indirizzo $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Ricordami" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Non chiedere più su questo dispositivo per 30 giorni" }, - "sendVerificationCodeEmailAgain": { - "message": "Invia di nuovo l'email con codice di verifica" - }, - "useAnotherTwoStepMethod": { - "message": "Usa un altro metodo di verifica in due passaggi" - }, "selectAnotherMethod": { "message": "Seleziona un altro metodo", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Usa il tuo codice di recupero" }, - "insertYubiKey": { - "message": "Inserisci la tua YubiKey nella porta USB del computer, poi premi il suo pulsante." - }, "insertU2f": { "message": "Inserisci la tua chiave di sicurezza nella porta USB del tuo computer. Se dispone di un pulsante, premilo." }, - "webAuthnNewTab": { - "message": "Per avviare la verifica WebAuthn 2FA. Clicca il pulsante qui sotto per aprire una nuova scheda e segui le istruzioni fornite nella nuova scheda." - }, - "webAuthnNewTabOpen": { - "message": "Apri nuova scheda" - }, "openInNewTab": { "message": "Apri in una nuova scheda" }, @@ -2534,15 +2504,15 @@ "message": "Le parole d'accesso dell'organizzazione sono a rischio perché sono deboli, riutilizzate, e/o esposte.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustrazione di un elenco di accessi a rischio" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Genera rapidamente una parola d'accesso forte e unica con il menu' di riempimento automatico Bitwarden nel sito a rischio.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustrazione del menu' di riempimento automatico Bitwarden che mostra una parola d'accesso generata" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Aggiorna in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden ti chiederà quindi di aggiornare la parola d'accesso nel gestore di parole d'accesso.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustrazione di una notifica Bitwarden che richiede all'utente di aggiornare l'accesso" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Attiva riempimento automatico" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Errore di connessione con il servizio Duo. Utilizza un metodo di login in due passaggi diverso o contatta Duo per assistenza." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avvia DUO e segui i passaggi per finire di accedere." - }, "duoRequiredForAccount": { "message": "Per il tuo account è richiesta la verifica in due passaggi DUO." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Apri l'estensione in un popup per completare l'accesso." - }, "popoutExtension": { "message": "Estrai estensione" }, diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index a6dd0f709a2..c49688b9e7a 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "この機能を使うにはプレミアム会員になってください。" }, - "enterVerificationCodeApp": { - "message": "認証アプリに表示された6桁の認証コードを入力してください。" - }, "authenticationTimeout": { "message": "認証のタイムアウト" }, "authenticationSessionTimedOut": { "message": "認証セッションの有効期限が切れました。ログインプロセスを再開してください。" }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$に送信された6桁の認証コードを入力してください。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$に認証コードを送信しました。", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "情報を保存する" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "このデバイスで30日間再表示しない" }, - "sendVerificationCodeEmailAgain": { - "message": "確認コードをメールで再送" - }, - "useAnotherTwoStepMethod": { - "message": "他の2段階認証方法を使用" - }, "selectAnotherMethod": { "message": "別の方法を選択", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "リカバリーコードを使用する" }, - "insertYubiKey": { - "message": " YubiKey を USB ポートに挿入し、ボタンをタッチしてください。" - }, "insertU2f": { "message": "セキュリティキーを USB ポートに挿入し、ボタンがある場合はボタンをタッチしてください。" }, - "webAuthnNewTab": { - "message": "WebAuthn 2FA 認証を開始するには、下のボタンをクリックして新しいタブを開き、新しいタブの指示に従ってください。" - }, - "webAuthnNewTabOpen": { - "message": "新しいタブを開く" - }, "openInNewTab": { "message": "新しいタブで開く" }, @@ -2534,15 +2504,15 @@ "message": "組織で使用するパスワードが脆弱である、または再利用されているか流出しており、危険な状態です。", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "危険な状態にあるログイン情報の一覧表示の例" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Bitwarden の自動入力メニューで、強力で一意なパスワードをすぐに生成しましょう。", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Bitwarden の自動入力メニューで、生成されたパスワードが表示されている例" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Bitwarden 上のデータを更新" @@ -2551,8 +2521,8 @@ "message": "続いて、 Bitwarden がパスワードマネージャーに保存されたパスワードを更新するよう促します。", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "ユーザーにログイン情報を更新するよう促す Bitwarden の通知例" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "自動入力をオンにする" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo サービスへの接続中にエラーが発生しました。異なる二段階ログイン方法を使用するか、Duo に連絡してください。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "ログインを完了するには DUO を起動し手順に従ってください。" - }, "duoRequiredForAccount": { "message": "アカウントには Duo 二段階認証が必要です。" }, - "popoutTheExtensionToCompleteLogin": { - "message": "ログインを完了するために拡張機能を開きます。" - }, "popoutExtension": { "message": "拡張機能のポップアップ" }, diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 0e11594faac..71032cbedf9 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "დამიმახსოვრე" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "ახალი ჩანართის გახსნა" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 0c087ef7de9..19e11bd4579 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 31ea7daa668..dc82624e0df 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "ಈ ವೈಶಿಷ್ಟ್ಯವನ್ನು ಬಳಸಲು ಪ್ರೀಮಿಯಂ ಸದಸ್ಯತ್ವ ಅಗತ್ಯವಿದೆ." }, - "enterVerificationCodeApp": { - "message": "ನಿಮ್ಮ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ಗೆ ಇಮೇಲ್ ಮಾಡಲಾದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ಪರಿಶೀಲನೆ ಇಮೇಲ್ $EMAIL$ ಗೆ ಕಳುಹಿಸಲಾಗಿದೆ.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "ನನ್ನನ್ನು ನೆನಪಿನಲ್ಲಿ ಇಡು" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ಪರಿಶೀಲನೆ ಕೋಡ್ ಇಮೇಲ್ ಅನ್ನು ಮತ್ತೆ ಕಳುಹಿಸಿ" - }, - "useAnotherTwoStepMethod": { - "message": "ಮತ್ತೊಂದು ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ವಿಧಾನವನ್ನು ಬಳಸಿ" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "ನಿಮ್ಮ ಯುಬಿಕಿಯನ್ನು ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಯುಎಸ್‌ಬಿ ಪೋರ್ಟ್ಗೆ ಸೇರಿಸಿ, ನಂತರ ಅದರ ಗುಂಡಿಯನ್ನು ಸ್ಪರ್ಶಿಸಿ." - }, "insertU2f": { "message": "ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಯುಎಸ್‌ಬಿ ಪೋರ್ಟ್ಗೆ ನಿಮ್ಮ ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಸೇರಿಸಿ. ಅದು ಬಟನ್ ಹೊಂದಿದ್ದರೆ, ಅದನ್ನು ಸ್ಪರ್ಶಿಸಿ." }, - "webAuthnNewTab": { - "message": "WebAuthn 2FA ಪರಿಶೀಲನೆಯನ್ನು ಪ್ರಾರಂಭಿಸಲು. ಹೊಸ ಟ್ಯಾಬ್ ತೆರೆಯಲು ಕೆಳಗಿನ ಬಟನ್ ಕ್ಲಿಕ್ ಮಾಡಿ ಮತ್ತು ಹೊಸ ಟ್ಯಾಬ್‌ನಲ್ಲಿ ಒದಗಿಸಲಾದ ಸೂಚನೆಗಳನ್ನು ಅನುಸರಿಸಿ." - }, - "webAuthnNewTabOpen": { - "message": "ಹೊಸ ಟ್ಯಾಬ್ ತೆರೆಯಿರಿ" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 92654f84e31..990f43d5d7d 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "이 기능을 사용하려면 프리미엄 멤버십이 필요합니다." }, - "enterVerificationCodeApp": { - "message": "인증 앱에서 6자리 인증 코드를 입력하세요." - }, "authenticationTimeout": { "message": "인증 시간 초과" }, "authenticationSessionTimedOut": { "message": "인증 세션 시간이 초과 되었습니다. 다시 로그인을 시작해주세요." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ 주소로 전송된 6자리 인증 코드를 입력하세요.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ 주소로 인증 이메일을 보냈습니다.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "기억하기" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "인증 코드 이메일 다시 보내기" - }, - "useAnotherTwoStepMethod": { - "message": "다른 2단계 인증 사용" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey를 컴퓨터의 USB 포트에 삽입하고 이 버튼을 누르세요." - }, "insertU2f": { "message": "보안 키를 컴퓨터의 USB 포트에 삽입하고 버튼이 있는 경우 누르세요." }, - "webAuthnNewTab": { - "message": "새 탭에서 WebAuthn 2단계 인증을 계속하세요." - }, - "webAuthnNewTabOpen": { - "message": "새 탭 열기" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo 서비스 연결 중 오류가 발생했습니다. 다른 2단계 로그인 방법을 사용하거나 Duo에 문의하여 도움을 받으세요." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "듀오를 실행하고 단계를 따라 로그인을 완료하세요" - }, "duoRequiredForAccount": { "message": "계정에 Duo 2단계 로그인이 필요합니다." }, - "popoutTheExtensionToCompleteLogin": { - "message": "확장 프로그램을 실행하여 로그인을 완료합니다." - }, "popoutExtension": { "message": "확장 프로그램을 새 창에서 열기" }, diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index e1536abdf83..fb010417cee 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Premium narystė reikalinga šiai funkcijai naudoti." }, - "enterVerificationCodeApp": { - "message": "Įvesk 6 skaitmenų patvirtinimo kodą iš tavo autentifikavimo aplikacijos." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Įvesk 6 skaitmenų prisijungimo kodą, kuris buvo išsiųstas $EMAIL$ el. paštu.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Patvirtinimo elektroninis paštas išsiųstas į $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Prisiminti mane" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Pakartotinai atsiųsti patvirtinimo koda el. paštu" - }, - "useAnotherTwoStepMethod": { - "message": "Naudoti dar vieną dviejų žingsnių prisijungimo metodą" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Įkišk YubiKey į savo kompiuterio USB prievadą, tada paliesk jo mygtuką." - }, "insertU2f": { "message": "Įkišk savo saugos raktą į kompiuterio USB prievadą. Jei jame yra mygtukas, paliesk jį." }, - "webAuthnNewTab": { - "message": "Norint pradėti WebAuthn 2FA patikrinimą. Spustelėk toliau esantį mygtuką, kad atsidarytų naujas skirtukas, ir sek naujame skirtuke pateiktas instrukcijas." - }, - "webAuthnNewTabOpen": { - "message": "Atidaryti naują skirtuką" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Klaida prijungiant su „Duo“ paslauga. Naudokite kitą dvigubo prisijungimo būdą arba susisiekite su „Duo“ dėl pagalbos." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Paleisk DUO ir sek veiksmus, kad baigtum prisijungti." - }, "duoRequiredForAccount": { "message": "Tavo paskyrai reikalingas Duo dviejų veiksmų prisijungimas." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Išskleisk plėtinį, kad užbaigtum prisijungimą." - }, "popoutExtension": { "message": "Iššokantis plėtinys" }, diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 789666ef2c1..85e08f44da5 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Ir nepieciešama Premium dalība, lai izmantotu šo iespēju." }, - "enterVerificationCodeApp": { - "message": "Jāievada 6 ciparu apstiprinājuma kods no autentificētāja lietotnes." - }, "authenticationTimeout": { "message": "Autentificēšanās noildze" }, "authenticationSessionTimedOut": { "message": "Iestājās autentificēšanās sesijas noildze. Lūgums sākt pieteikšanos no jauna." }, - "enterVerificationCodeEmail": { - "message": "Jāievada 6 ciparu apstiprinājuma kods, kas tika nosūtīts uz $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pasts apstiprināšanai nosūtīts uz $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Atcerēties mani" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Šajā ierīcē 30 dienas vairs nevaicāt" }, - "sendVerificationCodeEmailAgain": { - "message": "Sūtīt apstiprinājuma koda e-pastu vēlreiz" - }, - "useAnotherTwoStepMethod": { - "message": "Izmantot citu divpakāpju pieteikšanās veidu" - }, "selectAnotherMethod": { "message": "Atlasīt citu veidu", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Izmantot savu atkopes kodu" }, - "insertYubiKey": { - "message": "Ievieto savu YubiKey datora USB ligzdā un pieskaries tā pogai!" - }, "insertU2f": { "message": "Ievieto savu drošības atslēgu datora USB ligzdā! Ja tai ir poga, pieskaries tai!" }, - "webAuthnNewTab": { - "message": "Turpināt WebAuthn 2FA apstiprināšanu jaunā cilnē." - }, - "webAuthnNewTabOpen": { - "message": "Atvērt jaunu cilni" - }, "openInNewTab": { "message": "Atvērt jaunā cilnē" }, @@ -2534,15 +2504,15 @@ "message": "Apvienības paroles ir pakļautas riskam, jo tās ir vājas, atkārtoti izmantotas un/vai noplūdušas.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Riskam pakļauto pieteikšanās vienumu saraksta attēlojums" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Riskam pakļauto pieteikšanās vienumu saraksta attēlojums." }, "generatePasswordSlideDesc": { "message": "Riskam pakļauto vienumu vietnē ar automātiskās aizpildes izvēlni var ātri izveidot stipru, neatkārtojamu paroli.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Bitwarden automātiskās izvēlnes attēlojums, kurā ir redzama izveidota parole" + "generatePasswordSlideImgAltPeriod": { + "message": "Bitwarden automātiskās izvēlnes attēlojums, kurā ir redzama izveidota parole." }, "updateInBitwarden": { "message": "Atjaunināt Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden tad vaicās atjaunināt paroli paroļu pārvaldniekā.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Bitwarden paziņojuma, kas aicina lietotāju atjaunināt pieteikšanās vienumu, attēlojums" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Bitwarden paziņojuma, kas aicina lietotāju atjaunināt pieteikšanās vienumu, attēlojums." }, "turnOnAutofill": { "message": "Ieslēgt automātisko aizpildi" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Kļūda savienojuma izveidošanā ar Duo pakalpojumu. Jāizmanto cits divpakāpju pieteikšanās veids vai jāvēršas pie Duo pēc palīdzības." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Jāpalaiž DUO un jāseko soļiem, lai pabeigtu pieteikšanos." - }, "duoRequiredForAccount": { "message": "Kontam ir nepieciešama Duo divpakāpju pieteikšanās." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Jāatver paplašinājums atsevišķā logā, lai pabeigtu pieteikšanos." - }, "popoutExtension": { "message": "Atvērt paplašinājumu atsevišķi" }, diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 11af6b54202..8a580999709 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "ഈ സവിശേഷത ഉപയോഗിക്കുന്നതിന് പ്രീമിയം അംഗത്വം ആവശ്യമാണ്." }, - "enterVerificationCodeApp": { - "message": "നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷനിൽ നിന്ന് 6 അക്ക സ്ഥിരീകരണ കോഡ് നൽകുക." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ൽ ഇമെയിൽ ചെയ്ത 6 അക്ക സ്ഥിരീകരണ കോഡ് നൽകുക", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "സ്ഥിരീകരണ ഇമെയിൽ $EMAIL$ ലേക്ക് അയച്ചു.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "എന്നെ ഓർക്കുക" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "സ്ഥിരീകരണ കോഡ് ഇമെയിൽ വഴി അയയ്ക്കുക" - }, - "useAnotherTwoStepMethod": { - "message": "മറ്റൊരു രണ്ട് ഘട്ട ലോഗിൻ രീതി ഉപയോഗിക്കുക" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ യു‌എസ്‌ബി പോർട്ടിലേക്ക് യുബിക്കി ഇടുക, തുടർന്ന് അതിന്റെ ബട്ടൺ അമർത്തുക." - }, "insertU2f": { "message": "നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ യുഎസ്ബി പോർട്ടിൽ സുരക്ഷാ കീ ഇടുക. അതിന് ഒരു ബട്ടൺ ഉണ്ടെങ്കിൽ അത് അമർത്തുക." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 472a8378bb7..c794ed94a86 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 0c087ef7de9..19e11bd4579 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 9a52eeea4cb..4eac03f91d6 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Et Premium-medlemskap er påkrevd for å bruke denne funksjonen." }, - "enterVerificationCodeApp": { - "message": "Skriv inn den 6-sifrede verifiseringskoden som står på din autentiseringsapp." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Skriv inn den 6-sifrede verifiseringskoden som ble sendt til", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "En verifiserings-E-post har blitt sendt til $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Husk på meg" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send E-posten med verifiseringskoden på nytt" - }, - "useAnotherTwoStepMethod": { - "message": "Bruk en annen 2-trinnsinnloggingsmetode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sett inn din YubiKey i din datamaskins USB-uttak, og så trykk på dens knapp." - }, "insertU2f": { "message": "Sett din sikkerhetsnøkkel inn i din datamaskins USB-uttak. Dersom den har en knapp, trykk på den." }, - "webAuthnNewTab": { - "message": "For å starte WebAuthn 2FA bekreftelsen. Klikk på knappen nedenfor for å åpne en ny fane og følge instruksene som er gitt i den nye fanen." - }, - "webAuthnNewTabOpen": { - "message": "Åpne ny fane" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 0c087ef7de9..19e11bd4579 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 80877839adb..129dd8e4b7b 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Je hebt een Premium-abonnement nodig om deze functie te gebruiken." }, - "enterVerificationCodeApp": { - "message": "Voer de 6-cijferige verificatiecode uit je authenticatie-app in." - }, "authenticationTimeout": { "message": "Authenticatie-timeout" }, "authenticationSessionTimedOut": { "message": "De verificatiesessie is verlopen. Start het inlogproces opnieuw op." }, - "enterVerificationCodeEmail": { - "message": "Voer de 6-cijferige verificatiecode in die via e-mail is verstuurd naar $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail met verificatiecode is verzonden naar $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Mijn gegevens onthouden" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "30 dagen niet opnieuw vragen op dit apparaat" }, - "sendVerificationCodeEmailAgain": { - "message": "E-mail met verificatiecode opnieuw versturen" - }, - "useAnotherTwoStepMethod": { - "message": "Gebruik een andere methode voor tweestapsaanmelding" - }, "selectAnotherMethod": { "message": "Kies een andere methode", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Gebruik je herstelcode" }, - "insertYubiKey": { - "message": "Plaats je YubiKey in de USB-poort van je computer en druk op de knop." - }, "insertU2f": { "message": "Plaats je beveilingssleutel in de USB-poort van je computer. Als het een knop heeft, druk deze dan in." }, - "webAuthnNewTab": { - "message": "Ga door met WebAuthn 2FA-verificatie in de nieuwe tab." - }, - "webAuthnNewTabOpen": { - "message": "Nieuwe tab openen" - }, "openInNewTab": { "message": "Openen in nieuwe tab" }, @@ -2473,7 +2443,7 @@ } }, "atRiskPasswords": { - "message": "Wachtwoorden in gevaar" + "message": "Risicovolle wachtwoorden" }, "atRiskPasswordDescSingleOrg": { "message": "$ORGANIZATION$ vraagt je om één wachtwoord te wijzigen omdat deze een risico vormt.", @@ -2534,15 +2504,15 @@ "message": "De wachtwoorden van je organisatie zijn in gevaar omdat ze zwak, hergebruikt en/of gelekt zijn.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Voorbeeld van een lijst van risicovolle logins" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Voorbeeld van een lijst van risicovolle inloggegevens." }, "generatePasswordSlideDesc": { "message": "Genereer snel een sterk, uniek wachtwoord met het automatisch invulmenu van Bitwarden op de risicovolle website.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Voorbeeld van het automatisch invulmenu van Bitwarden met een gegenereerd wachtwoord" + "generatePasswordSlideImgAltPeriod": { + "message": "Voorbeeld van het automatisch invulmenu van Bitwarden met een gegenereerd wachtwoord." }, "updateInBitwarden": { "message": "Bijwerken in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden vraagt je vervolgens het wachtwoord bij te werken in de wachtwoordbeheerder.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Voorbeeld van een Bitwarden melding die de gebruiker aanspoort tot het bijwerken van de login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Voorbeeld van een Bitwarden-melding die de gebruiker aanspoort tot het bijwerken van de login." }, "turnOnAutofill": { "message": "Automatisch invullen inschakelen" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fout bij het verbinden met de Duo-service. Gebruik een andere tweestapsaanmeldingsmethode of neem contact op met Duo voor hulp." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Start Duo en volg de stappen om het inloggen te voltooien." - }, "duoRequiredForAccount": { "message": "Jouw account vereist Duo-tweestapsaanmelding." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Open de extensie om in te loggen." - }, "popoutExtension": { "message": "Pop-out extensie" }, diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 0c087ef7de9..19e11bd4579 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 0c087ef7de9..19e11bd4579 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index c345972bd4a..1657aea6f32 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Konto Premium jest wymagane, aby skorzystać z tej funkcji." }, - "enterVerificationCodeApp": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny z aplikacji uwierzytelniającej." - }, "authenticationTimeout": { "message": "Limit czasu uwierzytelniania" }, "authenticationSessionTimedOut": { "message": "Upłynął limit czasu uwierzytelniania. Uruchom ponownie proces logowania." }, - "enterVerificationCodeEmail": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny, który został przesłany na adres $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kod weryfikacyjny został wysłany na adres $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Zapamiętaj mnie" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Nie pytaj ponownie na tym urządzeniu przez 30 dni" }, - "sendVerificationCodeEmailAgain": { - "message": "Wyślij ponownie wiadomość z kodem weryfikacyjnym" - }, - "useAnotherTwoStepMethod": { - "message": "Użyj innej metody logowania dwustopniowego" - }, "selectAnotherMethod": { "message": "Wybierz inną metodę", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Użyj kodu odzyskiwania" }, - "insertYubiKey": { - "message": "Włóż klucz YubiKey do portu USB komputera, a następnie dotknij jego przycisku." - }, "insertU2f": { "message": "Włóż klucz bezpieczeństwa do portu USB komputera. Jeśli klucz posiada przycisk, dotknij go." }, - "webAuthnNewTab": { - "message": "Kontynuuj logowanie dwustopniowe WebAuthn w nowej karcie." - }, - "webAuthnNewTabOpen": { - "message": "Otwórz nową kartę" - }, "openInNewTab": { "message": "Otwórz w nowej karcie" }, @@ -2534,15 +2504,15 @@ "message": "Twoje hasła organizacji są zagrożone, ponieważ są słabe, ponownie używane i/lub narażone.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Ilustracja listy loginów, które są zagrożone" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Ilustracja listy danych logowania, które są zagrożone." }, "generatePasswordSlideDesc": { "message": "Szybko wygeneruj silne, unikalne hasło z menu autouzupełniania Bitwarden na stronie narażonej na ryzyko.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Ilustracja menu autouzupełniania Bitwarden pokazująca wygenerowane hasło" + "generatePasswordSlideImgAltPeriod": { + "message": "Ilustracja menu autouzupełniania Bitwardena pokazująca wygenerowane hasło." }, "updateInBitwarden": { "message": "Aktualizacja w Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden poprosi Cię o aktualizację hasła w menedżerze haseł.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Ilustracja powiadomienia Bitwardena, która prosi użytkownika o aktualizację logowania" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Ilustracja powiadomienia Bitwardena, skłaniająca użytkownika do zaktualizowania danych logowania." }, "turnOnAutofill": { "message": "Włącz autouzupełnienie" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Wystąpił błąd podczas połączenia z usługą Duo. Aby uzyskać pomoc, użyj innej metody dwustopniowego logowania lub skontaktuj się z Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Uruchom DUO i wykonaj kroki, aby zakończyć logowanie." - }, "duoRequiredForAccount": { "message": "Dwustopniowe logowanie Duo jest wymagane dla Twojego konta." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Otwórz rozszerzenie w nowym oknie, aby dokończyć logowanie." - }, "popoutExtension": { "message": "Otwórz rozszerzenie w nowym oknie" }, diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 5aacad23a93..0961f0f596c 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -878,7 +878,7 @@ "message": "Insira sua YubiKey para autenticar" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "A autenticação de dois fatores é necessária para sua conta. Siga os passos abaixo para conseguir entrar." }, "followTheStepsBelowToFinishLoggingIn": { "message": "Siga os passos abaixo para finalizar o login." @@ -1019,7 +1019,7 @@ "message": "Pedir para adicionar um item se um não for encontrado no seu cofre. Aplica-se a todas as contas logadas." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "Sempre mostrar cartões como sugestões de preenchimento automático na Tela do Cofre" }, "showCardsCurrentTab": { "message": "Mostrar cartões em páginas com guias." @@ -1028,7 +1028,7 @@ "message": "Exibir itens de cartão em páginas com abas para simplificar o preenchimento automático" }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "Sempre mostrar identidades como sugestões de preenchimento automático na Tela do Cofre" }, "showIdentitiesCurrentTab": { "message": "Exibir Identidades na Aba Atual" @@ -1037,10 +1037,10 @@ "message": "Liste os itens de identidade na aba atual para facilitar preenchimento automático." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Clique em itens para autopreencher na Tela do Cofre" }, "clickToAutofill": { - "message": "Click items in autofill suggestion to fill" + "message": "Selecione itens sugeridos pelo autopreenchimento" }, "clearClipboard": { "message": "Limpar Área de Transferência", @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Uma conta premium é necessária para usar esse recurso." }, - "enterVerificationCodeApp": { - "message": "Insira o código de verificação de 6 dígitos do seu aplicativo de autenticação." - }, "authenticationTimeout": { "message": "Tempo de autenticação esgotado" }, "authenticationSessionTimedOut": { "message": "A sessão de autenticação expirou. Por favor, reinicie o processo de login." }, - "enterVerificationCodeEmail": { - "message": "Insira o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail de verificação enviado para $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Lembrar de mim" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Não perguntar novamente neste dispositivo por 30 dias" }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar código de verificação para o e-mail novamente" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de verificação em duas etapas" - }, "selectAnotherMethod": { "message": "Escolher outro método", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use seu código de recuperação" }, - "insertYubiKey": { - "message": "Insira a sua YubiKey na porta USB do seu computador, e depois toque no botão da mesma." - }, "insertU2f": { "message": "Insira a sua chave de segurança na porta USB do seu computador. Se ele tiver um botão, toque nele." }, - "webAuthnNewTab": { - "message": "Para iniciar a verificação 2FA WebAuthn. Clique no botão abaixo para abrir uma nova aba e siga as instruções fornecidas na nova aba." - }, - "webAuthnNewTabOpen": { - "message": "Abrir nova aba" - }, "openInNewTab": { "message": "Abrir numa nova aba" }, @@ -1668,7 +1638,7 @@ "message": "Arrastar para ordenar" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "Arraste para reorganizar" }, "cfTypeText": { "message": "Texto" @@ -2176,7 +2146,7 @@ "message": "Novas opções de personalização" }, "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" + "message": "Personalize a experiência do seu cofre com ações de cópia rápida, modo compacto e muito mais!" }, "newCustomizationOptionsCalloutLink": { "message": "Ver todas as configurações de aparência" @@ -2452,13 +2422,13 @@ "message": "O Bitwarden não irá pedir para salvar os detalhes de credencial para estes domínios. Você deve atualizar a página para que as alterações entrem em vigor." }, "blockedDomainsDesc": { - "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." + "message": "\"Autopreencher\" e outros recursos podem não estar disponíveis para estes sites. Atualize a página para que as mudanças surtam efeito." }, "autofillBlockedNoticeV2": { - "message": "Autofill is blocked for this website." + "message": "\"Auto completar\" está bloqueado para este site." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "Altere isso em configurações" }, "change": { "message": "Alterar" @@ -2476,7 +2446,7 @@ "message": "Senhas em risco" }, "atRiskPasswordDescSingleOrg": { - "message": "$ORGANIZATION$ is requesting you change one password because it is at-risk.", + "message": "$ORGANIZATION$ solicita que altere uma senha, pois ela está vulnerável.", "placeholders": { "organization": { "content": "$1", @@ -2485,7 +2455,7 @@ } }, "atRiskPasswordsDescSingleOrgPlural": { - "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "$ORGANIZATION$ solicita que altere $COUNT$ senhas, pois elas estão vulneráveis.", "placeholders": { "organization": { "content": "$1", @@ -2498,7 +2468,7 @@ } }, "atRiskPasswordsDescMultiOrgPlural": { - "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "Suas organizações estão solicitando que altere $COUNT$ senhas porque elas estão vulneráveis.", "placeholders": { "count": { "content": "$1", @@ -2507,10 +2477,10 @@ } }, "reviewAndChangeAtRiskPassword": { - "message": "Review and change one at-risk password" + "message": "Revisar e alterar uma senha vulnerável" }, "reviewAndChangeAtRiskPasswordsPlural": { - "message": "Review and change $COUNT$ at-risk passwords", + "message": "Revisar e alterar $COUNT$ senhas vulneráveis", "placeholders": { "count": { "content": "$1", @@ -2519,40 +2489,40 @@ } }, "changeAtRiskPasswordsFaster": { - "message": "Change at-risk passwords faster" + "message": "Mude senhas vulneráveis rapidamente" }, "changeAtRiskPasswordsFasterDesc": { - "message": "Update your settings so you can quickly autofill your passwords and generate new ones" + "message": "Atualize suas configurações para poder autopreencher ou gerar novas senhas" }, "reviewAtRiskLogins": { - "message": "Review at-risk logins" + "message": "Revisar logins em risco" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords" + "message": "Revisar senhas vulneráveis" }, "reviewAtRiskLoginsSlideDesc": { - "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", + "message": "As senhas da sua organização estão vulneráveis, pois são fracas, reutilizadas e/ou comprometidas.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Ilustração de uma lista de logins em risco." }, "generatePasswordSlideDesc": { - "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", + "message": "Gere rapidamente uma senha forte e única com a opção de autopreenchimento no site vulnerável.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Ilustração do menu de autopreenchimento do Bitwarden exibindo uma senha gerada." }, "updateInBitwarden": { "message": "Atualizar no Bitwarden" }, "updateInBitwardenSlideDesc": { - "message": "Bitwarden will then prompt you to update the password in the password manager.", + "message": "O Bitwarden então solicitará que você atualize a senha no gerenciador de senhas.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Ilustração de umja notificação do Bitwarden solicitando que o usuário atualize o login." }, "turnOnAutofill": { "message": "Ativar preenchimento automático" @@ -2582,7 +2552,7 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Blocked domain changes saved" + "message": "Alterações de domínios bloqueados salvas" }, "excludedDomainsSavedSuccess": { "message": "Mudanças de domínios excluídos salvas" @@ -3008,7 +2978,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Apenas os itens individuais do cofre, incluindo anexos associados ao $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos", "placeholders": { "email": { "content": "$1", @@ -3038,11 +3008,11 @@ "message": "O Bitwarden não pode descriptografar o(s) item(ns) do cofre listado abaixo." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Contato com o cliente feito com sucesso", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "para evitar a perca adicional dos dados.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { @@ -3177,7 +3147,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ recusou sua solicitação. Contate seu provedor de serviços para receber assistência.", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -3187,7 +3157,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ recusou sua solicitação: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3336,13 +3306,13 @@ "message": "Uma notificação foi enviada para seu dispositivo." }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the" + "message": "Desbloqueie o Bitwarden em seu dispositivo ou na" }, "notificationSentDeviceAnchor": { - "message": "web app" + "message": "aplicativo web" }, "notificationSentDevicePart2": { - "message": "Make sure the Fingerprint phrase matches the one below before approving." + "message": "Certifique-se de que a frase de biometria corresponde a frase abaixo antes de aprovar." }, "aNotificationWasSentToYourDevice": { "message": "Uma notificação foi enviada para o seu dispositivo" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro ao se conectar com o serviço Duo. Use um método de verificação de duas etapas diferente ou contate o Duo para assistência." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o Duo e siga os passos para finalizar o login." - }, "duoRequiredForAccount": { "message": "A autenticação em duas etapas do Duo é necessária para sua conta." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Abra a extensão para concluir o login." - }, "popoutExtension": { "message": "Extensão pop-out" }, @@ -4280,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Visualizar item - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Autocompletar - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4708,7 +4672,7 @@ } }, "reorderWebsiteUriButton": { - "message": "Reorder website URI. Use arrow key to move item up or down." + "message": "Reorganize a URI do site. Use as setas para mover o item para cima ou para baixo." }, "reorderFieldUp": { "message": "$LABEL$ se moveu para cima, posição $INDEX$ de $LENGTH$", @@ -4827,7 +4791,7 @@ "message": "Mostrar o número de sugestões de preenchimento automático de login no ícone da extensão" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Mostrar a opção de cópia rápida no Cofre" }, "systemDefault": { "message": "Padrão do sistema" @@ -4899,22 +4863,22 @@ "message": "Você não tem permissão para editar este arquivo" }, "biometricsStatusHelptextUnlockNeeded": { - "message": "Biometric unlock is unavailable because PIN or password unlock is required first." + "message": "O desbloqueio por biometria está indisponível, pois é necessário informar o PIN ou a senha primeiro." }, "biometricsStatusHelptextHardwareUnavailable": { - "message": "Biometric unlock is currently unavailable." + "message": "O desbloqueio por biometria está indisponível no momento." }, "biometricsStatusHelptextAutoSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "O desbloqueio por biometria está indisponível devido a algum erro na configuração dos arquivos de sistema." }, "biometricsStatusHelptextManualSetupNeeded": { - "message": "Biometric unlock is unavailable due to misconfigured system files." + "message": "O desbloqueio por biometria está indisponível devido a algum erro na configuração dos arquivos de sistema." }, "biometricsStatusHelptextDesktopDisconnected": { - "message": "Biometric unlock is unavailable because the Bitwarden desktop app is closed." + "message": "O desbloqueio por biometria está indisponível porque o aplicativo de desktop não está aberto." }, "biometricsStatusHelptextNotEnabledInDesktop": { - "message": "Biometric unlock is unavailable because it is not enabled for $EMAIL$ in the Bitwarden desktop app.", + "message": "O desbloqueio por biometria está indisponível, pois a opção não foi ativada no aplicativo de desktop de $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -4923,7 +4887,7 @@ } }, "biometricsStatusHelptextUnavailableReasonUnknown": { - "message": "Biometric unlock is currently unavailable for an unknown reason." + "message": "O desbloqueio por biometria está indisponível por razões desconhecidas." }, "authenticating": { "message": "Autenticando" @@ -5133,31 +5097,31 @@ "message": "Extra Grande" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "A senha está incorreta." }, "importSshKey": { - "message": "Import" + "message": "Importar" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Confirme a senha" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Insira a senha da chave SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Insira a senha" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "A chave SSH é inválida" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "O tipo de chave SSH não é suportado" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "Importar chave da área de transferência" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "Chave SSH importada com sucesso" }, "cannotRemoveViewOnlyCollections": { "message": "Você não pode remover coleções com permissões de Somente leitura: $COLLECTIONS$", @@ -5169,12 +5133,12 @@ } }, "updateDesktopAppOrDisableFingerprintDialogTitle": { - "message": "Please update your desktop application" + "message": "Atualize seu aplicativo de desktop" }, "updateDesktopAppOrDisableFingerprintDialogMessage": { - "message": "To use biometric unlock, please update your desktop application, or disable fingerprint unlock in the desktop settings." + "message": "Para usar o desbloqueio de biometria, atualize seu aplicativo de desktop ou desative a opção \"desbloqueio por biometria\"." }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "Alterar senhas vulneráveis" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 0e467b65183..bc836cbd03e 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "É necessária uma subscrição Premium para utilizar esta funcionalidade." }, - "enterVerificationCodeApp": { - "message": "Introduza o código de verificação de 6 dígitos da sua aplicação de autenticação." - }, "authenticationTimeout": { "message": "Tempo limite de autenticação" }, "authenticationSessionTimedOut": { "message": "A sessão de autenticação expirou. Por favor, reinicie o processo de início de sessão." }, - "enterVerificationCodeEmail": { - "message": "Introduza o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail de verificação enviado para $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Memorizar" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Não voltar a perguntar neste dispositivo durante 30 dias" }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar e-mail com o código de verificação novamente" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de verificação de dois passos" - }, "selectAnotherMethod": { "message": "Selecionar outro método", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Utilize o seu código de recuperação" }, - "insertYubiKey": { - "message": "Introduza a sua YubiKey na porta USB do seu computador, depois toque no botão da mesma." - }, "insertU2f": { "message": "Introduza a sua chave de segurança na porta USB do seu computador. Se tiver um botão, toque no mesmo." }, - "webAuthnNewTab": { - "message": "Para iniciar a verificação do WebAuthn 2FA, clique no botão abaixo para abrir um novo separador e siga as instruções fornecidas no novo separador." - }, - "webAuthnNewTabOpen": { - "message": "Abrir novo separador" - }, "openInNewTab": { "message": "Abrir num novo separador" }, @@ -2534,15 +2504,15 @@ "message": "As palavras-passe da sua organização estão em risco porque são fracas, reutilizadas e/ou expostas.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Ilustração de uma lista de credenciais que estão em risco" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Ilustração de uma lista de credenciais que estão em risco." }, "generatePasswordSlideDesc": { "message": "Gira rapidamente uma palavra-passe forte e única com o menu de preenchimento automático do Bitwarden no site em risco.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Ilustração do menu de preenchimento automático do Bitwarden com uma palavra-passe gerada" + "generatePasswordSlideImgAltPeriod": { + "message": "Ilustração do menu de preenchimento automático do Bitwarden com uma palavra-passe gerada." }, "updateInBitwarden": { "message": "Atualização no Bitwarden" @@ -2551,8 +2521,8 @@ "message": "O Bitwarden pedir-lhe-á então para atualizar a palavra-passe no gestor de palavras-passe.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Ilustração de uma notificação do Bitwarden a pedir ao utilizador que atualize a credencial" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Ilustração de uma notificação do Bitwarden a pedir ao utilizador que atualize a credencial." }, "turnOnAutofill": { "message": "Ativar o preenchimento automático" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro ao ligar ao serviço Duo. Utilize um método de verificação de dois passos diferente ou contacte o Duo para obter assistência." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o Duo e siga os passos para concluir o início de sessão." - }, "duoRequiredForAccount": { "message": "A verificação de dois passos Duo é necessária para a sua conta." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Abra a extensão para concluir o início de sessão." - }, "popoutExtension": { "message": "Extensão popout" }, diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index fa4d754e99d..6d6fc724ec9 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Pentru a utiliza această funcție este necesar un abonament Premium." }, - "enterVerificationCodeApp": { - "message": "Introducere cod de verificare din 6 cifre din aplicația de autentificare." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Introducere cod de verificare din 6 cifre care a fost trimis prin e-mail la $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mailul de verificare a fost trimis la $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Memorare autentificare" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Retrimitere e-mail cu codul de verificare" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizare de metodă diferită de autentificare în două etape" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Introduceți YubiKey în portul USB al calculatorului apoi apăsați butonul acestuia." - }, "insertU2f": { "message": "Introduceți cheia de securitate în portul USB al computerului. Dacă are un buton, apăsați-l." }, - "webAuthnNewTab": { - "message": "Pentru a începe verificarea WebAuthn 2FA. Faceți clic pe butonul de mai jos pentru a deschide o filă nouă și urmați instrucțiunile furnizate în filă nouă." - }, - "webAuthnNewTabOpen": { - "message": "Deschideți o filă nouă" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index c775bee3289..03ce360c68f 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Для использования этой функции необходим Премиум." }, - "enterVerificationCodeApp": { - "message": "Введите 6-значный код подтверждения из вашего приложения-аутентификатора." - }, "authenticationTimeout": { "message": "Таймаут аутентификации" }, "authenticationSessionTimedOut": { "message": "Сеанс аутентификации завершился по времени. Пожалуйста, попробуйте войти еще раз." }, - "enterVerificationCodeEmail": { - "message": "Введите 6-значный код подтверждения, который был отправлен на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Отправлено письмо подтверждения на $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Запомнить меня" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не спрашивать на этом устройстве в течение 30 дней" }, - "sendVerificationCodeEmailAgain": { - "message": "Отправить код подтверждения еще раз" - }, - "useAnotherTwoStepMethod": { - "message": "Использовать другой метод двухэтапной аутентификации" - }, "selectAnotherMethod": { "message": "Выбрать другой способ", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Использовать код восстановления" }, - "insertYubiKey": { - "message": "Вставьте свой YubiKey в USB-порт компьютера и нажмите его кнопку." - }, "insertU2f": { "message": "Вставьте ключ безопасности в USB-порт компьютера. Если у ключа есть кнопка, нажмите ее." }, - "webAuthnNewTab": { - "message": "Продолжить верификацию 2ЭА WebAuthn в новой вкладке." - }, - "webAuthnNewTabOpen": { - "message": "Открыть новую вкладку" - }, "openInNewTab": { "message": "Открыть в новой вкладке" }, @@ -2534,15 +2504,15 @@ "message": "Пароли вашей организации подвержены риску, потому что они слабые, повторно используются и/или раскрыты.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Иллюстрация списка логинов, которые подвержены риску" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Иллюстрация списка логинов, которые подвержены риску." }, "generatePasswordSlideDesc": { "message": "Быстро сгенерируйте надежный уникальный пароль с помощью меню автозаполнения Bitwarden на сайте, подверженном риску.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Иллюстрация меню автозаполнения Bitwarden, отображающего сгенерированный пароль" + "generatePasswordSlideImgAltPeriod": { + "message": "Иллюстрация меню автозаполнения Bitwarden, отображающего сгенерированный пароль." }, "updateInBitwarden": { "message": "Обновить в Bitwarden" @@ -2551,8 +2521,8 @@ "message": "После этого Bitwarden предложит вам обновить пароль в менеджере паролей.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Иллюстрация уведомления Bitwarden, предлагающего пользователю обновить логин" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Иллюстрация уведомления Bitwarden, предлагающего пользователю обновить логин." }, "turnOnAutofill": { "message": "Включить автозаполнение" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Ошибка при подключении к сервису Duo. Используйте другой метод двухэтапной аутентификации или обратитесь за помощью в Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустите Duo и следуйте шагам для завершения авторизации." - }, "duoRequiredForAccount": { "message": "Для вашего аккаунта требуется двухэтапная аутентификация Duo." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Запустите расширение для завершения авторизации." - }, "popoutExtension": { "message": "Открепить расширение" }, @@ -4280,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Просмотр элемента - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Автозаполнение - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 12bac21e11f..d44ec8188de 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "මෙම අංගය භාවිතා කිරීම සඳහා වාරික සාමාජිකත්වයක් අවශ්ය වේ." }, - "enterVerificationCodeApp": { - "message": "ඔබගේ සත්යාපන යෙදුමෙන් 6 ඉලක්කම් සත්යාපන කේතය ඇතුළත් කරන්න." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$වෙත ඊමේල් කරන ලද 6 ඉලක්කම් සත්යාපන කේතය ඇතුළත් කරන්න.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "සත්යාපන විද්යුත් තැපෑල $EMAIL$වෙත යවා ඇත.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "මාව මතක තබා ගන්න" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "සත්යාපන කේතය නැවත විද්යුත් තැපෑල යවන්න" - }, - "useAnotherTwoStepMethod": { - "message": "තවත් පියවර දෙකක පිවිසුම් ක්රමයක් භාවිතා කරන්න" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "ඔබේ පරිගණකයේ USB පෝට් එකට ඔබගේ YuBiKey ඇතුල් කරන්න, ඉන්පසු එහි බොත්තම ස්පර්ශ කරන්න." - }, "insertU2f": { "message": "ඔබේ ආරක්ෂක යතුර ඔබේ පරිගණකයේ USB පෝට් එකට ඇතුල් කරන්න. එයට බොත්තමක් තිබේ නම් එය ස්පර්ශ කරන්න." }, - "webAuthnNewTab": { - "message": "WebAUTN 2FA සත්යාපනය ආරම්භ කිරීමට. නව පටිත්තක් විවෘත කිරීමට පහත බොත්තම ක්ලික් කර නව පටිත්තෙහි ඇති උපදෙස් අනුගමනය කරන්න." - }, - "webAuthnNewTabOpen": { - "message": "නව ටැබය විවෘත කරන්න" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index cd4095f8ff5..96b042bf7eb 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Pre použitie tejto funkcie je potrebné prémiové členstvo." }, - "enterVerificationCodeApp": { - "message": "Zadajte 6-miestny verifikačný kód z vašej overovacej aplikácie." - }, "authenticationTimeout": { "message": "Časový limit overenia" }, "authenticationSessionTimedOut": { "message": "Relácia overovania skončila. Znovu spustite proces prihlásenia." }, - "enterVerificationCodeEmail": { - "message": "Zadajte 6-miestny verifikačný kód, ktorý vám bol zaslaný emailom", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Overovací e-mail odoslaný na $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Zapamätať si ma" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Nepýtať sa znova na tomto zariadení 30 dní" }, - "sendVerificationCodeEmailAgain": { - "message": "Znovu zaslať overovací kód emailom" - }, - "useAnotherTwoStepMethod": { - "message": "Použiť inú dvojstupňovú metódu prihlásenia" - }, "selectAnotherMethod": { "message": "Vyberte iný spôsob", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Použiť obnovovací kód" }, - "insertYubiKey": { - "message": "Vložte váš YubiKey do USB portu počítača a stlačte jeho tlačidlo." - }, "insertU2f": { "message": "Vložte váš bezpečnostný kľúč do USB portu počítača. Ak má tlačidlo, stlačte ho." }, - "webAuthnNewTab": { - "message": "V overovaní cez WebAuthn 2FA pokračujte na ďalšej záložke." - }, - "webAuthnNewTabOpen": { - "message": "Otvoriť v novej karte" - }, "openInNewTab": { "message": "Otvoriť v novej karte" }, @@ -2534,15 +2504,15 @@ "message": "Heslá vašej organizácie sú v ohrození, pretože sú slabé, opakovane používané a/alebo uniknuté.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Príklady zoznamu prihlásení, ktoré sú ohrozené" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Príklady zoznamu prihlásení, ktoré sú ohrozené." }, "generatePasswordSlideDesc": { "message": "Rýchlo generujte silné, jedinečné heslo pomocu ponuky automatického vypĺňania Bitwardenu na ohrozených stránkach.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Príklad ponuky automatického vypĺňania Bitwardenu zobrazujúca vygenerované heslo" + "generatePasswordSlideImgAltPeriod": { + "message": "Príklad ponuky automatického vypĺňania Bitwardenu zobrazujúca vygenerované heslo." }, "updateInBitwarden": { "message": "Aktualizovať v Bitwardene" @@ -2551,8 +2521,8 @@ "message": "Bitwarden vás vyzve na aktualizáciu hesla v správcovi hesiel.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Príklad upozornenia Bitwardenu na aktualizovanie prihlasovacích údajov" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Príklad upozornenia Bitwardenu na aktualizovanie prihlasovacích údajov." }, "turnOnAutofill": { "message": "Zapnúť automatické vypĺňanie" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Chyba pri pripájaní k službe Duo. Použite inú metódu dvojstupňového prihlásenia alebo kontaktujte Duo a požiadajte o pomoc." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Spustite DUO a postupujte podľa pokynov na dokončenie prihlásenia." - }, "duoRequiredForAccount": { "message": "Pre váš účet je potrebné dvojstupňové prihlásenie Duo." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Ak chcete dokončiť prihlásenie, otvorte rozšírenie." - }, "popoutExtension": { "message": "Zobraziť rozšírenie v novom okne" }, diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index c77d4cb55f4..704a9983d80 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Premium članstvo je potrebno za uporabo te funkcije." }, - "enterVerificationCodeApp": { - "message": "Vnesite 6-mestno verifikacijsko kodo iz svoje aplikacije za avtentikacijo." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Vnesite 6-mestno verifikacijsko kodo, ki vam je bila poslana na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Potrditveno sporočilo poslano na $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Zapomni si me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno pošlji verifikacijsko kodo na email" - }, - "useAnotherTwoStepMethod": { - "message": "Uporabi drugi način prijave v dveh korakih" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Priključi svoj YubiKey v USB priključek, nato pa pritisni na njegovo tipko." - }, "insertU2f": { "message": "Priključi svoj varnostni ključ v USB priključek. Če ima tipko, se jo dotaknite." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Odpri nov zavihek" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 5e325c6a97c..9bc9d122d75 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Премијум чланство је неопходно за употребу ове опције." }, - "enterVerificationCodeApp": { - "message": "Унесите шестоцифрени верификациони код из апликације за утврђивање аутентичности." - }, "authenticationTimeout": { "message": "Истекло је време аутентификације" }, "authenticationSessionTimedOut": { "message": "Истекло је време сесије за аутентификацију. Молим вас покрените процес пријаве поново." }, - "enterVerificationCodeEmail": { - "message": "Унесите шестоцифрени верификациони код који је послан на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Провера имејла послата на $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Запамти ме" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не питајте поново на овом уређају 30 дана" }, - "sendVerificationCodeEmailAgain": { - "message": "Поново послати верификациони код на имејл" - }, - "useAnotherTwoStepMethod": { - "message": "Користите другу методу пријављивања у два корака" - }, "selectAnotherMethod": { "message": "Изаберите другу методу", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Употребите шифру за опоравак" }, - "insertYubiKey": { - "message": "Убаците свој YubiKey у УСБ порт рачунара, а затим додирните његово дугме." - }, "insertU2f": { "message": "Убаците свој сигурносни кључ у УСБ порт рачунара, и ако има дугме , додирните га." }, - "webAuthnNewTab": { - "message": "Да бисте започели WebAuthn верификацију у два корака. Кликните на дугме испод за отваранје новог језичка и пратите упутства у нјему." - }, - "webAuthnNewTabOpen": { - "message": "Отвори нови језичак " - }, "openInNewTab": { "message": "Отвори у новом језичку" }, @@ -2534,15 +2504,15 @@ "message": "Ваше организационе лозинке су ризичне јер су слабе, поново употребљене и/или изложене.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Илустрација листе пријаве које су ризичне" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Илустрација листе пријаве које су ризичне." }, "generatePasswordSlideDesc": { "message": "Брзо генеришите снажну, јединствену лозинку са Bitwarden менијем аутопуњења за коришћење на ризичном сајту.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Илустрација Bitwarden-ског менија аутопуњења који приказују генерисану лозинку" + "generatePasswordSlideImgAltPeriod": { + "message": "Илустрација Bitwarden-ског менија аутопуњења који приказују генерисану лозинку." }, "updateInBitwarden": { "message": "Ажурирања у Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden ће тада затражити да ажурирате лозинку у менаџеру лозинке.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Илустрација Bitwarden-ског обавештења за ажирриање пријаве" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Илустрација Bitwarden-ског обавештења за ажирриање пријаве." }, "turnOnAutofill": { "message": "Омогућите ауто-пуњење" @@ -3008,7 +2978,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Извешће се само појединачни сеф, укључујући прилоге повезане са $EMAIL$. Организациони сефски предмети неће бити укључени", "placeholders": { "email": { "content": "$1", @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Грешка при повезивању са услугом Duo. Користите други метод пријаве у два корака или контактирајте Duo за помоћ." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Покренути DUO и пратите кораке да бисте завршили пријављивање." - }, "duoRequiredForAccount": { "message": "Duo пријава у два корака је потребна за ваш налог." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Искачући додатак да бисте довршили пријаву." - }, "popoutExtension": { "message": "Искачући додатак" }, @@ -4280,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Видети ставку - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4304,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Ауто-пуњење - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index e3ff6986cae..83a6f0a49b6 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Ett premium-medlemskap krävs för att använda den här funktionen." }, - "enterVerificationCodeApp": { - "message": "Ange den 6-siffriga verifieringskoden från din autentiseringsapp." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Ange den 6-siffriga verifieringskoden som skickades till $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifieringsmeddelande har skickats till $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Kom ihåg mig" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Skicka e-postmeddelandet med verifieringskoden igen" - }, - "useAnotherTwoStepMethod": { - "message": "Använd en annan inloggningsmetod för tvåstegsverifiering" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sätt i din YubiKey i en av datorns USB-portar och sätt fingret på knappen." - }, "insertU2f": { "message": "Sätt i din säkerhetsnyckel i en av datorns USB-portar. Om nyckeln har en knapp, sätt fingret på den." }, - "webAuthnNewTab": { - "message": "För att påbörja verifieringen av WebAuthn 2FA. Klicka på knappen nedan för att öppna en ny flik och följ instruktionerna i den nya fliken." - }, - "webAuthnNewTabOpen": { - "message": "Öppna ny flik" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Starta Duo och följ stegen för att slutföra inloggningen." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 0c087ef7de9..19e11bd4579 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index e2225327664..6942485618d 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ส่งโค้ดยืนยันไปยังอีเมล $EMAIL$ แล้ว", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ส่งโค้ดยืนยันไปยังอีเมลอีกครั้ง" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index e8788a00d70..6388b3d04a3 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Bu özelliği kullanmak için premium üyelik gereklidir." }, - "enterVerificationCodeApp": { - "message": "Kimlik doğrulama uygulamanızdaki 6 haneli doğrulama kodunu girin." - }, "authenticationTimeout": { "message": "Kimlik doğrulama zaman aşımı" }, "authenticationSessionTimedOut": { "message": "Kimlik doğrulama oturumu zaman aşımına uğradı. Lütfen giriş sürecini yeniden başlatın." }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ adresine e-postayla gönderdiğimiz 6 haneli doğrulama kodunu girin.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Doğrulama e-postası $EMAIL$ adresine gönderildi.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Beni hatırla" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Doğrulama kodunu yeniden gönder" - }, - "useAnotherTwoStepMethod": { - "message": "Başka bir iki aşamalı giriş yöntemini kullan" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey'i bilgisayarınızın USB portuna takın, ardından düğmesine dokunun." - }, "insertU2f": { "message": "Güvenlik anahtarınızı bilgisayarınızın USB portuna takın. Düğmesi varsa dokunun." }, - "webAuthnNewTab": { - "message": "WebAuthn iki aşamalı doğrulamayı başlatmak için aşağıdaki düğmeye tıklayın ve açılan sekmedeki yönergeleri takip edin." - }, - "webAuthnNewTabOpen": { - "message": "Yeni sekme aç" - }, "openInNewTab": { "message": "Yeni sekmede aç" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Otomatik doldurmayı etkinleştir" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Duo'yu açın ve girişi tamamlamak için adımları izleyin." - }, "duoRequiredForAccount": { "message": "Hesabınız için Duo iki adımlı giriş gereklidir." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Giriş işlemini tamamlamak için uzantıyı dışarı alın." - }, "popoutExtension": { "message": "Uzantıyı dışarı al" }, diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 6bd9ca7fc36..5e7c1bdd660 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Для використання цієї функції необхідна передплата преміум." }, - "enterVerificationCodeApp": { - "message": "Введіть 6-значний код підтвердження з програми автентифікації." - }, "authenticationTimeout": { "message": "Час очікування автентифікації" }, "authenticationSessionTimedOut": { "message": "Час очікування сеансу автентифікації завершився. Перезапустіть процес входу в систему." }, - "enterVerificationCodeEmail": { - "message": "Введіть 6-значний код підтвердження, надісланий на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Код підтвердження надіслано на $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Запам'ятати мене" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Більше не запитувати на цьому пристрої протягом 30 днів" }, - "sendVerificationCodeEmailAgain": { - "message": "Надіслати код підтвердження ще раз" - }, - "useAnotherTwoStepMethod": { - "message": "Інший спосіб двоетапної перевірки" - }, "selectAnotherMethod": { "message": "Обрати інший спосіб", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Скористайтеся своїм кодом відновлення" }, - "insertYubiKey": { - "message": "Вставте свій YubiKey в USB порт комп'ютера, потім торкніться цієї кнопки." - }, "insertU2f": { "message": "Вставте свій ключ безпеки в USB порт комп'ютера. Якщо в нього є кнопка, натисніть її." }, - "webAuthnNewTab": { - "message": "Щоб почати перевірку WebAuthn 2FA, натисніть кнопку внизу для відкриття нової вкладки і дотримуйтесь зазначених на ній настанов." - }, - "webAuthnNewTabOpen": { - "message": "Відкрити нову вкладку" - }, "openInNewTab": { "message": "Відкрити в новій вкладці" }, @@ -2534,15 +2504,15 @@ "message": "Паролі вашої організації ризиковані, оскільки вони ненадійні, повторно використовуються, та/або викриті.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Ілюстрація списку ризикованих записів" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Швидко згенеруйте надійний, унікальний пароль через меню автозаповнення Bitwarden на сайті з ризикованим паролем.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Ілюстрація меню автозаповнення Bitwarden, що показує згенерований пароль" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Оновити в Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Потім Bitwarden запропонує вам оновити пароль у менеджері паролів.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Ілюстрація сповіщення Bitwarden, що спонукає користувача оновити пароль" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Увімкніть автозаповнення" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Помилка під'єднання до служби Duo. Скористайтеся іншим способом двоетапної перевірки або зверніться до служби підтримки Duo по допомогу." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустіть Duo і виконайте дії для завершення входу." - }, "duoRequiredForAccount": { "message": "Для вашого облікового запису необхідна двоетапна перевірка з Duo." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Відкріпіть розширення для завершення входу." - }, "popoutExtension": { "message": "Відкріпити вікно розширення" }, diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 35c553f72f1..c0bded59ef9 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "Cần là thành viên cao cấp để sử dụng tính năng này." }, - "enterVerificationCodeApp": { - "message": "Nhập mã xác nhận 6 chữ số từ ứng dụng xác thực của bạn." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Nhập mã xác nhận 6 chữ số đã được gửi tới email", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email xác minh đã được gửi tới $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Ghi nhớ đăng nhập" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Gửi lại email chứa mã xác nhận" - }, - "useAnotherTwoStepMethod": { - "message": "Sử dụng phương pháp đăng nhập 2 bước khác" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Lắp YubiKey vào cổng USB máy tính của bạn, sau đó chạm vào nút trên nó." - }, "insertU2f": { "message": "Lắp khóa bảo mật vào cổng USB máy tính của bạn. Nếu nó có một nút, hãy nhấn vào nó." }, - "webAuthnNewTab": { - "message": "Để bắt đầu xác minh WebAuthn 2FA. Nhấp vào nút bên dưới để mở tab mới và làm theo hướng dẫn được cung cấp trong tab mới." - }, - "webAuthnNewTabOpen": { - "message": "Mở thẻ mới" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Lỗi kết nối với dịch vụ Duo. Sử dụng phương thức đăng nhập hai bước khác hoặc liên hệ với Duo để được hỗ trợ." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Khởi chạy Duo và làm theo các bước để hoàn tất đăng nhập." - }, "duoRequiredForAccount": { "message": "Tài khoản của bạn yêu cầu xác minh hai bước với Duo." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Bật tiện ích mở rộng để hoàn tất đăng nhập." - }, "popoutExtension": { "message": "Tiện ích mở rộng dạng cửa sổ bật lên" }, diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index fc6f70cb6a4..3683e769914 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -219,7 +219,7 @@ "message": "复制自定义字段名称" }, "noMatchingLogins": { - "message": "无匹配的登录项目" + "message": "没有匹配的登录" }, "noCards": { "message": "无支付卡" @@ -1003,7 +1003,7 @@ "message": "搜索类型" }, "noneFolder": { - "message": "默认文件夹", + "message": "无文件夹", "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { @@ -1019,7 +1019,7 @@ "message": "在密码库中找不到匹配项目时询问添加一个。适用于所有已登录的账户。" }, "showCardsInVaultViewV2": { - "message": "在密码库视图中将支付卡始终显示为自动填充建议" + "message": "在密码库视图中始终将支付卡显示为自动填充建议" }, "showCardsCurrentTab": { "message": "在标签页上显示支付卡" @@ -1028,7 +1028,7 @@ "message": "在标签页上列出支付卡项目,以便于自动填充。" }, "showIdentitiesInVaultViewV2": { - "message": "在密码库视图中将身份始终显示为自动填充建议" + "message": "在密码库视图中始终将身份显示为自动填充建议" }, "showIdentitiesCurrentTab": { "message": "在标签页上显示身份" @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "使用此功能需要高级会员资格。" }, - "enterVerificationCodeApp": { - "message": "请输入您的验证器 App 中的 6 位数验证码。" - }, "authenticationTimeout": { "message": "身份验证超时" }, "authenticationSessionTimedOut": { "message": "身份验证会话超时。请重新启动登录过程。" }, - "enterVerificationCodeEmail": { - "message": "请输入发送给 $EMAIL$ 的 6 位数验证码。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "验证邮件已发送到 $EMAIL$。", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "记住我" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "30 天内在此设备上不再询问" }, - "sendVerificationCodeEmailAgain": { - "message": "再次发送验证码电子邮件" - }, - "useAnotherTwoStepMethod": { - "message": "使用其他两步登录方式" - }, "selectAnotherMethod": { "message": "选择其他方式", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "使用您的恢复代码" }, - "insertYubiKey": { - "message": "将您的 YubiKey 插入计算机的 USB 端口,然后触摸其按钮。" - }, "insertU2f": { "message": "将您的安全密钥插入计算机的 USB 端口。如果它有按钮,请触摸它。" }, - "webAuthnNewTab": { - "message": "要开始 WebAuthn 2FA 验证,请点击下面的按钮打开一个新标签页,并按照新标签页中提供的说明操作。" - }, - "webAuthnNewTabOpen": { - "message": "打开新标签页" - }, "openInNewTab": { "message": "在新标签页中打开" }, @@ -1477,7 +1447,7 @@ "message": "选择两步登录方式" }, "recoveryCodeDesc": { - "message": "无法访问您所有的双重身份提供程序吗?请使用您的恢复代码来关闭您账户中所有的双重身份提供程序。" + "message": "无法访问您所有的双重身份提供程序吗?请使用您的恢复代码来停用您账户中所有的双重身份提供程序。" }, "recoveryCodeTitle": { "message": "恢复代码" @@ -1578,7 +1548,7 @@ "message": "适用于所有已登录的账户。" }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "关闭您浏览器内置的密码管理器设置以避免冲突。" + "message": "停用您浏览器内置的密码管理器设置以避免冲突。" }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "编辑浏览器设置。" @@ -1617,7 +1587,7 @@ "message": "登录项目的默认自动填充设置" }, "defaultAutoFillOnPageLoadDesc": { - "message": "您可以从项目编辑视图中为单个登录项目关闭页面加载时自动填充。" + "message": "您可以从项目编辑视图中为单个登录项目停用页面加载时自动填充。" }, "itemAutoFillOnPageLoad": { "message": "页面加载时自动填充(如果选项中已设置)" @@ -2534,15 +2504,15 @@ "message": "您的组织密码存在风险,因为它们过于简单、被重复使用和/或已暴露。", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "存在风险的登录列表示意图" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "存在风险的登录列表示意图。" }, "generatePasswordSlideDesc": { "message": "在存在风险的网站上,使用 Bitwarden 自动填充菜单快速生成强大且唯一的密码。", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Bitwarden 自动填充菜单显示生成的密码示意图" + "generatePasswordSlideImgAltPeriod": { + "message": "显示生成的密码的 Bitwarden 自动填充菜单示意图。" }, "updateInBitwarden": { "message": "在 Bitwarden 中更新" @@ -2551,14 +2521,14 @@ "message": "然后,Bitwarden 会提示您更新密码管理器中的密码。", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "提示用户更新登录的 Bitwarden 通知示意图" + "updateInBitwardenSlideImgAltPeriod": { + "message": "提示用户更新登录的 Bitwarden 通知示意图。" }, "turnOnAutofill": { - "message": "开启自动填充" + "message": "启用自动填充" }, "turnedOnAutofill": { - "message": "已开启自动填充" + "message": "已启用自动填充" }, "dismiss": { "message": "忽略" @@ -3390,7 +3360,7 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "您的组织策略已开启页面加载时自动填充。" + "message": "您的组织策略已启用页面加载时自动填充。" }, "howToAutofill": { "message": "如何自动填充" @@ -3662,7 +3632,7 @@ "message": "别名域" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "具有主密码重新提示的项目无法在页面加载时自动填充。页面加载时的自动填充功能已关闭。", + "message": "具有主密码重新提示的项目无法在页面加载时自动填充。页面加载时的自动填充功能已停用。", "description": "Toast message for describing that master password re-prompt cannot be autofilled on page load." }, "autofillOnPageLoadSetToDefault": { @@ -3670,7 +3640,7 @@ "description": "Toast message for informing the user that autofill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { - "message": "关闭主密码重新提示以编辑此字段", + "message": "停用主密码重新提示以编辑此字段", "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { @@ -3764,7 +3734,7 @@ "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { - "message": "开启" + "message": "启用" }, "ignore": { "message": "忽略" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "与 Duo 服务连接时出错。请使用其他两步登录方式或联系 Duo 寻求帮助。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "启动 DUO 并按照步骤完成登录。" - }, "duoRequiredForAccount": { "message": "您的账户要求使用 Duo 两步登录。" }, - "popoutTheExtensionToCompleteLogin": { - "message": "弹出扩展以完成登录。" - }, "popoutExtension": { "message": "弹出扩展" }, @@ -3965,10 +3929,10 @@ "message": "没有找到此应用程序的通行密钥。" }, "noMatchingPasskeyLogin": { - "message": "不存在匹配此站点的登录项目。" + "message": "您没有匹配此站点的登录。" }, "noMatchingLoginsForSite": { - "message": "此站点没有匹配的登录项目" + "message": "此站点没有匹配的登录" }, "searchSavePasskeyNewLogin": { "message": "搜索或将通行密钥保存为一个新的登录" @@ -5118,7 +5082,7 @@ "message": "是的,我可以正常访问我的电子邮箱" }, "turnOnTwoStepLogin": { - "message": "开启两步登录" + "message": "启用两步登录" }, "changeAcctEmail": { "message": "更改账户电子邮箱" diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 365aae61ebf..adefe506790 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "進階會員才可使用此功能。" }, - "enterVerificationCodeApp": { - "message": "輸入驗證器應用程式提供的 6 位數驗證碼。" - }, "authenticationTimeout": { "message": "驗證逾時" }, "authenticationSessionTimedOut": { "message": "驗證工作階段因時間過久已逾時。請重試登入。" }, - "enterVerificationCodeEmail": { - "message": "輸入已傳送至 $EMAIL$ 的 6 位數驗證碼。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "已傳送驗證電子郵件至 $EMAIL$。", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "記住我" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "再次傳送​​包含驗證碼的電子郵件" - }, - "useAnotherTwoStepMethod": { - "message": "使用另一種兩步驟登入方法" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "將您的 YubiKey 插入電腦的 USB 連接埠,然後按一下它的按鈕。" - }, "insertU2f": { "message": "將您的安全鑰匙插入電腦的 USB 連接埠,然後觸摸其按鈕(如有的話)。" }, - "webAuthnNewTab": { - "message": "要開始 WebAuthn 2FA 驗證,請點選下面的按鈕開啟一個新分頁,並依照新分頁中提供的說明操作。" - }, - "webAuthnNewTabOpen": { - "message": "開啟新分頁" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -2534,15 +2504,15 @@ "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, - "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "reviewAtRiskLoginSlideImgAltPeriod": { + "message": "Illustration of a list of logins that are at-risk." }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", "description": "Description of the generate password slide on the at-risk password page carousel" }, - "generatePasswordSlideImgAlt": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password" + "generatePasswordSlideImgAltPeriod": { + "message": "Illustration of the Bitwarden autofill menu displaying a generated password." }, "updateInBitwarden": { "message": "Update in Bitwarden" @@ -2551,8 +2521,8 @@ "message": "Bitwarden will then prompt you to update the password in the password manager.", "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, - "updateInBitwardenSlideImgAlt": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login" + "updateInBitwardenSlideImgAltPeriod": { + "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { "message": "Turn on autofill" @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "連接到 Duo 服務時發生錯誤。使用不同的兩階段認證或聯繫 Duo 來獲得支援。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "啟動 Duo 並依照步驟完成登入。" - }, "duoRequiredForAccount": { "message": "您的帳號要求使用 Duo 兩步驟驗證登入。" }, - "popoutTheExtensionToCompleteLogin": { - "message": "彈出擴充套件視窗來完成登入。" - }, "popoutExtension": { "message": "彈出擴充套件視窗" }, diff --git a/apps/browser/store/locales/cy/copy.resx b/apps/browser/store/locales/cy/copy.resx index 983a112c071..0cb03a8a291 100644 --- a/apps/browser/store/locales/cy/copy.resx +++ b/apps/browser/store/locales/cy/copy.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + Rheolydd cyfrineiriau Bitwarden - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Gartref, yn y gweithle, neu ar fynd, mae Bitwarden yn diogelu eich holl gyfrineiriau a gwybodaeth sensitif. Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! @@ -169,7 +169,7 @@ End-to-end encrypted credential management solutions from Bitwarden empower orga - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Gartref, yn y gweithle, neu ar fynd, mae Bitwarden yn diogelu eich holl gyfrineiriau a gwybodaeth sensitif. Gallwch gael mynediad at, a chysoni, eich cell o sawl dyfais From 190b2e87643129908f75eba91d265545c05b2f50 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:06:11 +0200 Subject: [PATCH 03/93] Autosync the updated translations (#14118) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 31 +- apps/web/src/locales/ar/messages.json | 31 +- apps/web/src/locales/az/messages.json | 45 +-- apps/web/src/locales/be/messages.json | 31 +- apps/web/src/locales/bg/messages.json | 31 +- apps/web/src/locales/bn/messages.json | 31 +- apps/web/src/locales/bs/messages.json | 31 +- apps/web/src/locales/ca/messages.json | 31 +- apps/web/src/locales/cs/messages.json | 31 +- apps/web/src/locales/cy/messages.json | 31 +- apps/web/src/locales/da/messages.json | 31 +- apps/web/src/locales/de/messages.json | 31 +- apps/web/src/locales/el/messages.json | 31 +- apps/web/src/locales/en_GB/messages.json | 31 +- apps/web/src/locales/en_IN/messages.json | 31 +- apps/web/src/locales/eo/messages.json | 31 +- apps/web/src/locales/es/messages.json | 31 +- apps/web/src/locales/et/messages.json | 31 +- apps/web/src/locales/eu/messages.json | 31 +- apps/web/src/locales/fa/messages.json | 31 +- apps/web/src/locales/fi/messages.json | 31 +- apps/web/src/locales/fil/messages.json | 31 +- apps/web/src/locales/fr/messages.json | 31 +- apps/web/src/locales/gl/messages.json | 31 +- apps/web/src/locales/he/messages.json | 31 +- apps/web/src/locales/hi/messages.json | 31 +- apps/web/src/locales/hr/messages.json | 31 +- apps/web/src/locales/hu/messages.json | 31 +- apps/web/src/locales/id/messages.json | 31 +- apps/web/src/locales/it/messages.json | 31 +- apps/web/src/locales/ja/messages.json | 31 +- apps/web/src/locales/ka/messages.json | 31 +- apps/web/src/locales/km/messages.json | 31 +- apps/web/src/locales/kn/messages.json | 31 +- apps/web/src/locales/ko/messages.json | 31 +- apps/web/src/locales/lv/messages.json | 33 +- apps/web/src/locales/ml/messages.json | 31 +- apps/web/src/locales/mr/messages.json | 31 +- apps/web/src/locales/my/messages.json | 31 +- apps/web/src/locales/nb/messages.json | 31 +- apps/web/src/locales/ne/messages.json | 31 +- apps/web/src/locales/nl/messages.json | 31 +- apps/web/src/locales/nn/messages.json | 31 +- apps/web/src/locales/or/messages.json | 31 +- apps/web/src/locales/pl/messages.json | 31 +- apps/web/src/locales/pt_BR/messages.json | 467 +++++++++++------------ apps/web/src/locales/pt_PT/messages.json | 31 +- apps/web/src/locales/ro/messages.json | 31 +- apps/web/src/locales/ru/messages.json | 31 +- apps/web/src/locales/si/messages.json | 31 +- apps/web/src/locales/sk/messages.json | 31 +- apps/web/src/locales/sl/messages.json | 31 +- apps/web/src/locales/sr/messages.json | 33 +- apps/web/src/locales/sr_CS/messages.json | 31 +- apps/web/src/locales/sv/messages.json | 31 +- apps/web/src/locales/te/messages.json | 31 +- apps/web/src/locales/th/messages.json | 31 +- apps/web/src/locales/tr/messages.json | 31 +- apps/web/src/locales/uk/messages.json | 31 +- apps/web/src/locales/vi/messages.json | 31 +- apps/web/src/locales/zh_CN/messages.json | 115 +++--- apps/web/src/locales/zh_TW/messages.json | 31 +- 62 files changed, 393 insertions(+), 2067 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index fa25494f4bf..29eb76a1069 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Voer die 6-syferbevestigingskode van u waarmerktoep in." - }, - "enterVerificationCodeEmail": { - "message": "Voer die 8-syferbevestigingskode in wat aan $EMAIL$ gestuur is.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pos met bevestigingskode is na $EMAIL$ gestuur.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Onthou my" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Stuur weer e-pos met bevestigingskode" - }, - "useAnotherTwoStepMethod": { - "message": "Gebruik ’n ander tweestapaantekenmetode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Plaas u YubiKey in u rekenaar se USB-poort en druk dan op sy knop." - }, "insertU2f": { "message": "Plaas u beveilingsleutel in u rekenaar se USB-poort. Indien dit ’n knop het, druk dit dan." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 4a289082039..f12f59b8fba 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "تم إرسال رسالة التحقق إلى $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "تذكرني" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "إرسال رمز التحقق إلى البريد الإلكتروني مرة أخرى" - }, - "useAnotherTwoStepMethod": { - "message": "استخدام طريقة أخرى لتسجيل الدخول بخطوتين" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index dfafeab1877..069986361ca 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -1361,7 +1361,7 @@ "message": "İndi kilidlə" }, "noItemsInList": { - "message": "Siyahılanacaq heç bir element yoxdur." + "message": "Sadalanacaq heç bir element yoxdur." }, "noPermissionToViewAllCollectionItems": { "message": "Bu kolleksiyadakı bütün elementlərə baxmaq üçün icazəniz yoxdur." @@ -1370,19 +1370,19 @@ "message": "Bu kolleksiyaya icazəniz yoxdur" }, "noCollectionsInList": { - "message": "Siyahılanacaq heç bir kolleksiya yoxdur." + "message": "Sadalanacaq heç bir kolleksiya yoxdur." }, "noGroupsInList": { "message": "Sihayıda heç bir məhsul yoxdur." }, "noUsersInList": { - "message": "Siyahılanacaq heç bir element yoxdur." + "message": "Sadalanacaq heç bir istifadəçi yoxdur." }, "noMembersInList": { - "message": "Siyahılanacaq heç bir üzv yoxdur." + "message": "Sadalanacaq heç bir üzv yoxdur." }, "noEventsInList": { - "message": "Siyahılanacaq heç bir element yoxdur." + "message": "Sadalanacaq heç bir tədbir yoxdur." }, "newOrganization": { "message": "Yeni təşkilat" @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Kimlik doğrulayıcı tətbiqindən 6 rəqəmli doğrulama kodunu daxil edin." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ ünvanına göndərilən e-poçtdakı 6 rəqəmli doğrulama kodunu daxil edin.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Doğrulama poçtu $EMAIL$ ünvanına göndərildi.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Məni xatırla" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Bu cihazda 30 gün ərzində soruşulmasın" }, - "sendVerificationCodeEmailAgain": { - "message": "Doğrulama kodu olan e-poçtu yenidən göndər" - }, - "useAnotherTwoStepMethod": { - "message": "Başqa bir iki addımlı giriş üsulu istifadə edin" - }, "selectAnotherMethod": { "message": "Başqa üsul seçin", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Geri qaytarma kodunuzu istifadə edin" }, - "insertYubiKey": { - "message": "\"YubiKey\"i kompüterinizin USB portuna taxın, daha sonra düyməsinə toxunun." - }, "insertU2f": { "message": "Güvənlik açarını kompüterinizin USB portuna taxın. Düyməsi varsa toxunun." }, @@ -1760,7 +1736,7 @@ "message": "Davam etsəniz, yaradıcı tarixçəsindəki bütün girişlər həmişəlik silinəcək. Davam etmək istədiyinizə əminsiniz?" }, "noPasswordsInList": { - "message": "Siyahılanacaq heç bir parol yoxdur." + "message": "Sadalanacaq heç bir parol yoxdur." }, "clearHistory": { "message": "Tarixçəni təmizlə" @@ -5251,7 +5227,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "noSendsInList": { - "message": "Siyahılanacaq heç bir \"Send\" yoxdur.", + "message": "Sadalanacaq heç bir \"Send\" yoxdur.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "emergencyAccess": { @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo xidmətinə bağlanarkən xəta baş verdi. Fərqli iki addımlı giriş üsulu istifadə edin və ya kömək üçün Duo ilə əlaqə saxlayın." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "DUO-nu başladın və giriş prosesini tamamlamaq üçün addımları izləyin." - }, "duoRequiredByOrgForAccount": { "message": "Hesabınız üçün DUO iki addımlı giriş tələb olunur." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Kolleksiya silinməsini sahibləri və adminləri ilə məhdudlaşdır" }, - "limitItemDeletionDesc": { - "message": "Elementin silinməsini \"İdarə edə bilər\" icazəsinə sahib üzvlərlə məhdudlaşdır" + "limitItemDeletionDescription": { + "message": "Element silməni, \"Kolleksiyanı idarə et\" icazəsinə sahib üzvlərlə məhdudlaşdır" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Sahiblər və adminlər bütün kolleksiyaları və elementləri idarə edə bilər" diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index a22b463f4f2..9bb0336777a 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Увядзіце 6 лічбаў праверачнага кода з вашай праграмы аўтэнтыфікацыі." - }, - "enterVerificationCodeEmail": { - "message": "Увядзіце 6 лічбаў праверачнага кода, які быў адпраўлены на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Праверачны ліст адпраўлены на $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Запомніць мяне" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Адправіць праверачны код яшчэ раз" - }, - "useAnotherTwoStepMethod": { - "message": "Выкарыстоўваць іншы метад двухэтапнага ўваходу" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Устаўце свой YubiKey у порт USB камп'ютара, а потым націсніце на кнопку." - }, "insertU2f": { "message": "Устаўце ваш ключ бяспекі ў порт USB камп'ютара. Калі на ім ёсць кнопка, націсніце на яе." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 0599d3a73f2..87396ddfcdc 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Въведете шестцифрения код за потвърждение от приложението за удостоверяване." - }, - "enterVerificationCodeEmail": { - "message": "Въведете шестцифрения код за потвърждение, който е бил изпратен на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Писмото за потвърждение е изпратено на $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Запомняне" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не ме питайте отново на това устройство за 30 дни" }, - "sendVerificationCodeEmailAgain": { - "message": "Повторно изпращане на писмото за потвърждение" - }, - "useAnotherTwoStepMethod": { - "message": "Използвайте друг начин на двустепенно удостоверяване" - }, "selectAnotherMethod": { "message": "Изберете друг метод", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Използване на код за възстановяване" }, - "insertYubiKey": { - "message": "Поставете устройството на YubiKey в USB порт на компютъра и натиснете бутона на устройството." - }, "insertU2f": { "message": "Поставете устройството за удостоверяване в USB порт на компютъра. Ако на устройството има бутон, натиснете го." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Грешка при свързването с услугата на Duo. Използвайте друг метод за двустепенно удостоверяване или се свържете с Duo за съдействие." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Стартирайте DUO и следвайте инструкциите, за да завършите вписването." - }, "duoRequiredByOrgForAccount": { "message": "Вашата регистрация изисква двустепенно удостоверяване чрез DUO." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Ограничаване на изтриването на колекции, така че да може да се извършва само от собствениците и администраторите" }, - "limitItemDeletionDesc": { - "message": "Ограничаване на изтриването на елементи, така че да може да се извършва само от членове с правомощие за управление" + "limitItemDeletionDescription": { + "message": "Ограничаване на изтриването на елементи, така че да може да се извършва само от членове с правомощия за управление на колекции" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Собствениците и администраторите могат да управляват всички колекции и елементи" diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 15ca72e1642..67b602fe256 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "আপনার প্রমাণীকরণকারী অ্যাপ থেকে ৬ সংখ্যার যাচাইকরণ কোডটি প্রবেশ করুন।" - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ এ ইমেইল করা ৬ সংখ্যার যাচাই কোডটি প্রবেশ করুন।", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ এ যাচাইকরণ ইমেইল প্রেরণ করা হয়েছে।", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "আমাকে মনে রাখবেন" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "আবার যাচাইকরণ কোড ইমেইলে প্রেরণ করুন" - }, - "useAnotherTwoStepMethod": { - "message": "অন্য দ্বি-পদক্ষেপ প্রবেশ পদ্ধতি ব্যবহার করুন" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "আপনার কম্পিউটারের ইউএসবি পোর্টে আপনার YubiKey ঢোকান, তারপরে তার বোতামটি স্পর্শ করুন।" - }, "insertU2f": { "message": "আপনার কম্পিউটারের ইউএসবি পোর্টে আপনার সুরক্ষা কী ঢোকান। এটিতে যদি একটি বোতাম থাকে তবে তা স্পর্শ করুন।" }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 2c0f177ad67..58077510f1e 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Unesite 6-cifreni verifikacioni kod iz aplikacije za autentifikaciju." - }, - "enterVerificationCodeEmail": { - "message": "Unesite 6-cifreni verifikacioni kod poslat na imejl $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Imejl za potvrdu poslat na $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno slanje kontrolnog koda imejlom" - }, - "useAnotherTwoStepMethod": { - "message": "Koristiti drugi način prijave u dva koraka" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Povežite Vaš YubiKey preko USB porta na vašem računaru, pa pritisnite dugme na njemu." - }, "insertU2f": { "message": "Povežite Vaš sigurnosni ključ preko USB porta na Vaš računar. Ukoliko ima dugme, pritisnite ga." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index d394a75b70f..6ea513b4490 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Introduïu el codi de verificació de 6 dígits de l'aplicació autenticadora." - }, - "enterVerificationCodeEmail": { - "message": "Introduïu el codi de verificació de 6 dígits que s'ha enviat per correu electrònic a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Correu electrònic de verificació enviat a $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Recorda'm" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Envia el codi de verificació altra vegada" - }, - "useAnotherTwoStepMethod": { - "message": "Utilitzeu un altre mètode d'inici de sessió en dues passes" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Introduïu el vostre YubiKey al port USB de l'ordinador i, a continuació, premeu el seu botó." - }, "insertU2f": { "message": "Introduïu la vostra clau de seguretat al port USB de l'ordinador. Si té un botó, premeu-lo." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicieu DUO i seguiu els passos per finalitzar la sessió." - }, "duoRequiredByOrgForAccount": { "message": "Es requereix l'inici de sessió en dos passos de DUO al vostre compte." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Els propietaris i els administradors poden gestionar totes les col·leccions i articles" diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 552a717ab82..fe431b3a1f0 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Zadejte 6místný kód z ověřovací aplikace." - }, - "enterVerificationCodeEmail": { - "message": "Zadejte 6místný kód z e-mailu, který byl zaslán na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Ověřovací e-mail byl zaslán na $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapamatovat mě" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Neptat se na tomto zařízení 30 dnů" }, - "sendVerificationCodeEmailAgain": { - "message": "Znovu zaslat ověřovací kód na e-mail" - }, - "useAnotherTwoStepMethod": { - "message": "Použít jinou metodu dvoufázového přihlášení" - }, "selectAnotherMethod": { "message": "Vybrat jinou metodu", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Použít obnovovací kód" }, - "insertYubiKey": { - "message": "Vložte YubiKey do USB portu Vašeho počítače a stiskněte jeho tlačítko." - }, "insertU2f": { "message": "Vložte svůj bezpečnostní klíč do USB portu Vašeho počítače a pokud má tlačítko, tak jej stiskněte." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Chyba při připojování ke službě Duo. Použijte jinou dvoufázovou metodu přihlášení nebo kontaktujte Duo o pomoc." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Spusťte Duo a pro dokončení přihlášení postupujte podle kroků." - }, "duoRequiredByOrgForAccount": { "message": "Pro Váš účet je vyžadováno dvoufázové přihlášení Duo." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Omezí mazání kolekce na vlastníky a správce" }, - "limitItemDeletionDesc": { - "message": "Omezit smazání položky na členy s oprávněním ke správě" + "limitItemDeletionDescription": { + "message": "Omezit smazání položky na členy s oprávněním Spravovat kolekci" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Vlastníci a správci mohou spravovat všechny kolekce a předměty" diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index ba8bd6bd8a4..4fcd523f0db 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index dddef79ddd0..525ed048c44 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Angiv den 6-cifrede bekræftelseskode fra godkendelses-appen." - }, - "enterVerificationCodeEmail": { - "message": "Angiv den 6-cifrede bekræftelseskode tilsendt $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Bekræftelsese-mail sendt til $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Husk mig" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send bekræftelseskode-email igen" - }, - "useAnotherTwoStepMethod": { - "message": "Brug en anden totrins-login metode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Indsæt din YubiKey i computerens USB-port og tryk på dens knap." - }, "insertU2f": { "message": "Indsæt din sikkerhedsnøgle i computerens USB-port. Har den en knap, tryk på den." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fejl under forbindelsesoprettelsen til Duo-tjenesten. Brug en anden totrins-indlogningsmetode eller kontakt Duo for hjælp." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Start DUO og følg trinene for at fuldføre indlogningen." - }, "duoRequiredByOrgForAccount": { "message": "Duo totrinsindlogning kræves for kontoen." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Begræns samlingsslettelse til ejere og admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Ejere og admins kan håndtere alle samlinger og emner" diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index b5eeb9db7ce..f34f875f6b0 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Geben Sie den 6-stelligen Verifizierungscode aus Ihrer Authentifizierungs-App ein." - }, - "enterVerificationCodeEmail": { - "message": "Geben Sie den 6-stelligen Verifizierungscode der an $EMAIL$ gesendet wurde an.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Bestätigungsmail wurde an $EMAIL$ gesendet.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Angemeldet bleiben" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Für 30 Tage auf diesem Gerät nicht mehr fragen" }, - "sendVerificationCodeEmailAgain": { - "message": "E-Mail mit Bestätigungscode erneut versenden" - }, - "useAnotherTwoStepMethod": { - "message": "Verwenden sie eine andere Zwei-Faktor-Anmelde-Methode" - }, "selectAnotherMethod": { "message": "Wähle eine andere Methode", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Verwende deinen Wiederherstellungscode" }, - "insertYubiKey": { - "message": "Stecken Sie Ihren YubiKey in einen USB-Port Ihres Computers und berühren Sie dessen Knopf." - }, "insertU2f": { "message": "Stecken Sie Ihren Sicherheitsschlüssel in einen USB-Port des Computers. Falls dieser einen Knopf hat, drücken Sie ihn." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fehler beim Verbinden mit dem Duo-Dienst. Verwende eine andere Zwei-Faktor-Authentifizierungsmethode oder kontaktiere Duo für Hilfe." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Starte DUO und folge den Schritten, um die Anmeldung abzuschließen." - }, "duoRequiredByOrgForAccount": { "message": "Für dein Konto ist die DUO Zwei-Faktor-Authentifizierung erforderlich." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Das Löschen von Sammlungen auf Eigentümer und Administratoren beschränken" }, - "limitItemDeletionDesc": { - "message": "Löschung von Einträgen auf Mitglieder mit der \"Darf verwalten\"-Berechtigung beschränken" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Besitzer und Administratoren können alle Sammlungen und Einträge verwalten" diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index 27e39f9798e..a5a59f4257d 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Εισάγετε τον 6ψήφιο κωδικό από την εφαρμογή επαλήθευσης." - }, - "enterVerificationCodeEmail": { - "message": "Εισάγετε τον 6ψήφιο κωδικό επαλήθευσης, τον οποίο λάβατε στο $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Εστάλη email επαλήθευσης στο $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Να με θυμάσαι" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Αποστολή email κωδικού επαλήθευσης ξανά" - }, - "useAnotherTwoStepMethod": { - "message": "Χρήση άλλης μεθόδου δύο παραγόντων" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Τοποθετήστε το YubiKey στη θύρα USB του υπολογιστή σας και έπειτα πατήστε το κουμπί του." - }, "insertU2f": { "message": "Εισάγετε το κλειδί ασφαλείας στη θύρα USB του υπολογιστή σας. Αν υπάρχει κουμπί, πατήστε το." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Σφάλμα κατά τη σύνδεση με την υπηρεσία Duo. Χρησιμοποιήστε μια διαφορετική μέθοδο σύνδεσης δύο βημάτων ή επικοινωνήστε με το Duo για βοήθεια." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Εκκινήστε το Duo και ακολουθήστε τα βήματα για να ολοκληρώσετε τη σύνδεση." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Οι ιδιοκτήτες και οι διαχειριστές μπορούν να διαχειριστούν όλες τις συλλογές και τα στοιχεία" diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index b4f0ace607a..9f755b303bf 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index a8c4bfca62e..1349e55f7b1 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index c31274e6198..0cafbb8a8ef 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enigu la 6-ciferan konfirmkodon de via aŭtentikiga programo." - }, - "enterVerificationCodeEmail": { - "message": "Enigu la 6-ciferan konfirmkodon, kiu estis retpoŝta al $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kontrola retpoŝto sendita al $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Memoru min" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Sendu retpoŝtan kontrol-kodon denove" - }, - "useAnotherTwoStepMethod": { - "message": "Uzu alian metodon de identigo en du-ŝtupa saluto" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Enmetu vian YubiKey en la USB-havenon de via komputilo, tiam tuŝu ĝian butonon." - }, "insertU2f": { "message": "Enmetu vian sekurecan ŝlosilon en la USB-havenon de via komputilo. Se ĝi havas butonon, tuŝu ĝin." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 80b982bd928..338cc195c0d 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Introduce el código de verificación de 6 dígitos de tu aplicación autenticadora." - }, - "enterVerificationCodeEmail": { - "message": "Introduce el código de verificación de 6 dígitos que fue enviado a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Correo de verificación enviado a $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Recordarme" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Reenviar código de verificación por correo electrónico" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar otro método de autenticación en dos pasos" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Inserta tu YubiKey en el puerto USB de tu equipo y posteriormente pulsa su botón." - }, "insertU2f": { "message": "Inserta tu llave de seguridad en el puerto USB de tu equipo. Si tiene un botón, púlsalo." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Propietarios y administradores pueden gestionar todas las colecciones y elementos" diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index a55fce63349..9c2c407d3e2 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Sisesta autentimise rakendusest 6 kohaline number." - }, - "enterVerificationCodeEmail": { - "message": "Sisesta 6 kohaline number, mis saadeti e-posti aadressile $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kinnituskood saadeti e-posti aadressile $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Jäta mind meelde" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Saada e-postile uus kinnituskood" - }, - "useAnotherTwoStepMethod": { - "message": "Kasuta teist kaheastmelist sisselogimise meetodit" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sisesta oma YubiKey arvuti USB porti ja kliki sellele nupule." - }, "insertU2f": { "message": "Sisesta oma turvaline võti arvuti USB porti. Kui sellel on nupp, siis vajuta seda." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index a8b64594065..e6576e40664 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Sartu zure autentifikazio aplikazioaren 6 digituko egiaztatze-kodea." - }, - "enterVerificationCodeEmail": { - "message": "Sartu $EMAIL$-era bidalitako 6 digituko egiaztatze-kodea.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Egiaztatze emaila $EMAIL$-era bidalia.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Gogora nazazu" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Berbidali email bidezko egiaztatze-kodea" - }, - "useAnotherTwoStepMethod": { - "message": "Erabili bi urratseko saio hasierarako beste modu bat" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sartu zure YubiKey-a ordenagailuko USB atakan, ondoren, sakatu bere botoia." - }, "insertU2f": { "message": "Sartu zure segurtasun-gakoa ordenagailuaren USB atakan. Botoia badu, sakatu ezazu." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index 4657d4a9732..143ac5f9c32 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "کد ۶ رقمی تأیید را از برنامه احراز هویت وارد کنید." - }, - "enterVerificationCodeEmail": { - "message": "کد ۶ رقمی تأیید را که به $EMAIL$ ایمیل شده را وارد کنید.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ایمیل تأیید به $EMAIL$ ارسال شد.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "مرا به خاطر بسپار" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ارسال دوباره ایمیل کد تأیید" - }, - "useAnotherTwoStepMethod": { - "message": "استفاده از روش ورود دو مرحله‌ای دیگر" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey خود را وارد پورت USB رایانه کنید، بعد دکمه آن را بفشارید." - }, "insertU2f": { "message": "کلید امنیتی خود را وارد پورت USB رایانه کنید، اگر دکمه ای دارد آن را بفشارید." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 38671c12f79..9612c8cb4ad 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Syötä todennussovelluksesi näyttämä kuusinumeroinen todennuskoodi." - }, - "enterVerificationCodeEmail": { - "message": "Syötä osoitteeseen $EMAIL$ lähetetty kuusinumeroinen todennuskoodi.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Todennussähköposti lähetettiin osoitteeseen $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Muista minut" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Älä kysy uudelleen tällä laitteella 30 päivään" }, - "sendVerificationCodeEmailAgain": { - "message": "Lähetä todennuskoodi sähköpostitse uudelleen" - }, - "useAnotherTwoStepMethod": { - "message": "Käytä vaihtoehtoista todennustapaa" - }, "selectAnotherMethod": { "message": "Valitse vaihtoehtoinen tapa", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Käytä palautuskoodiasi" }, - "insertYubiKey": { - "message": "Kytke YubiKey-suojausavaimesi tietokoneen USB-porttiin ja kosketa sen painiketta." - }, "insertU2f": { "message": "Kytke suojausavaimesi tietokoneen USB-porttiin ja jos laitteessa on painike, paina sitä." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Virhe yhdistettäessä Duo-palveluun. Käytä vaihtoehtoista todennustapaa tai ole yhteydessä Duon asiakaspalveluun saadaksesi apua." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avaa Duo ja viimeistele kirjautuminen seuraamalla ohjeita." - }, "duoRequiredByOrgForAccount": { "message": "Tilillesi kirjautuminen vaatii Duo-vahvistuksen." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Rajoita kokoelmien poisto omistajille ja ylläpitäjille" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Omistajat ja ylläpitäjät voivat hallita kaikkia kokoelmia ja kohteita" diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 0a07cf17526..a6b82cc1902 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Ilagay ang 6 na numerong code pamberipika mula sa authenticator app mo." - }, - "enterVerificationCodeEmail": { - "message": "Ilagay ang 6 na numerong code pamberipikang in-email sa $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Ipinadala ang email pamberipika sa $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Tandaan ako" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ipadala ulit ang email na naglalaman ng code pamberipika" - }, - "useAnotherTwoStepMethod": { - "message": "Gumamit ng ibang paraan sa dalawang-hakbang na pag-log in" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Ipasok ang YubiKey mo sa USB port ng iyong computer, tapos pindutin ang buton nito." - }, "insertU2f": { "message": "Ipasok ang security key mo sa USB port ng iyong computer. Kung may buton, pindutin ito." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index e26b5ef1250..df113c1e988 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Saisissez le code de vérification à 6 chiffres depuis votre application d'authentification." - }, - "enterVerificationCodeEmail": { - "message": "Saisissez le code de vérification à 6 chiffres qui a été envoyé par courriel à $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Courriel de vérification envoyé à $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Se souvenir de moi" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne plus demander sur cet appareil pendant 30 jours" }, - "sendVerificationCodeEmailAgain": { - "message": "Envoyer à nouveau le courriel de code de vérification" - }, - "useAnotherTwoStepMethod": { - "message": "Utiliser une autre méthode d'authentification à deux facteurs" - }, "selectAnotherMethod": { "message": "Sélectionnez une autre méthode", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Utilisez votre code de récupération" }, - "insertYubiKey": { - "message": "Insérez votre YubiKey dans le port USB de votre ordinateur puis appuyez sur son bouton." - }, "insertU2f": { "message": "Insérez votre clé de sécurité dans le port USB de votre ordinateur. Si elle dispose d'un bouton, appuyez dessus." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erreur de connexion avec le service Duo. Utilisez une autre méthode de connexion en deux étapes ou contactez Duo pour obtenir de l'aide." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Lancez DUO et suivez les étapes pour terminer la connexion." - }, "duoRequiredByOrgForAccount": { "message": "L'authentification à double facteur DUO est requise pour votre compte." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limiter la suppression de collections aux propriétaires et administrateurs" }, - "limitItemDeletionDesc": { - "message": "Limite la suppression de l'élément aux membres avec l'autorisation Peut gérer" + "limitItemDeletionDescription": { + "message": "Limite la suppression de l'élément aux membres avec l'autorisation Peut gérer la collection" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Les propriétaires et les administrateurs peuvent gérer toutes les collections et tous les éléments" diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 6964a867768..c7a62c4fd60 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 115482c021b..13cecb8f4dc 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "הכנס את קוד האימות בן 6 הספרות מאפליקציית האימות שלך." - }, - "enterVerificationCodeEmail": { - "message": "הכנס את קוד האימות בן 6 הספרות שנשלח ל-$EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "מייל אימות נשלח לכתובת $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "זכור אותי" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "אל תשאל אותי שוב במכשיר זה למשך 30 יום" }, - "sendVerificationCodeEmailAgain": { - "message": "שלח שוב קוד אימות לאימייל" - }, - "useAnotherTwoStepMethod": { - "message": "השתמש בשיטה אחרת עבור כניסה דו שלבית" - }, "selectAnotherMethod": { "message": "בחר שיטה אחרת", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "השתמש בקוד השחזור שלך" }, - "insertYubiKey": { - "message": "הכנס את ה-YubiKey אל כניסת ה-USB במחשבך, ואז גע בכפתור שלו." - }, "insertU2f": { "message": "הכנס את מפתח האבטחה שלך אל כניסת ה-USB במחשבך. אם יש לו כפתור, לחץ עליו." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "שגיאה בהתחברות עם השירות Duo. השתמש בשיטת כניסה דו־שלבית אחרת או פנה אל Duo לסיוע." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "פתח את Duo ועקוב אחר השלבים כדי לסיים להיכנס." - }, "duoRequiredByOrgForAccount": { "message": "נדרשת כניסה דו־שלבית של Duo עבור החשבון שלך." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "הגבל מחיקת אוספים לבעלים ומנהלים" }, - "limitItemDeletionDesc": { - "message": "הגבל מחיקת פריטים לחברים עם הרשאת יכולת ניהול" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "בעלים ומנהלים יכולים לנהל את כל האוספים והפריטים" diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index bdd11c6561f..5e71c274ed9 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "मुझे याद रखें" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "फिर से सत्यापन कोड ईमेल भेजें" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 5ae2ddcfc0b..7ab29545495 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Unesi 6-znamenkasti kôd za provjeru iz autentifikatorske aplikacije." - }, - "enterVerificationCodeEmail": { - "message": "Unesi 6-znamenkasti kôd za provjeru poslan e-poštom na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pošta za potvrdu poslana je na $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne pitaj na ovom uređaju idućih 30 dana" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno slanje kontrolnog koda e-poštom" - }, - "useAnotherTwoStepMethod": { - "message": "Koristiti drugi način prijave dvostrukom autentifikacijom" - }, "selectAnotherMethod": { "message": "Odaberi drugi način", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Koristi kôd za oporavak" }, - "insertYubiKey": { - "message": "Umetni svoj YubiKey u USB priključak računala, a zatim dodirni njegovu tipku." - }, "insertU2f": { "message": "Umetni svoj sigurnosni ključ u USB priključak računala. Ako ima tipku, dodirni ju." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Greška pri povezivanju s uslugom Duo. Koristi drugu metodu prijave s dvostrukom autentifikacijom ili kontaktiraj Duo za pomoć." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Pokreni Duo i slijedi korake za dovršetak prijave." - }, "duoRequiredByOrgForAccount": { "message": "Za tvoj račun je potrebna Duo dvostruka autentifikacija." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Omogući brisanje zbirki samo vlasnicima i adminima" }, - "limitItemDeletionDesc": { - "message": "Ograniči brisanje stavke samo članovima koji imaju dozvolu „Moguće upravljanje”" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Vlasnici i admini mogu upravljati svim zbirkama i stavkama" diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index b7a51e5048b..dc50065f5d3 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "A 6 számjegyű ellenőrző kód megadása a hitelesítő alkalmazásból." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ email címre elküldött 6 számjegyű ellenőrző kód megadása.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Az ellenőrző kód elküldésre került $EMAIL$ email címre.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Adatok megjegyzése" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Ne kérdezzen újra ezen az eszközön 30 napig" }, - "sendVerificationCodeEmailAgain": { - "message": "Megerősítő kód ismételt elküldése emailben" - }, - "useAnotherTwoStepMethod": { - "message": "Másik kétlépcsős bejelentkezés használata" - }, "selectAnotherMethod": { "message": "Másik módszer választás", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Helyreállító kód használata" }, - "insertYubiKey": { - "message": "A YubiKey beillesztése a számítógép USB portjába és a rajta levő gomb megnyomása." - }, "insertU2f": { "message": "A biztonsági kulcs beillesztése a számítógép USB portjába. Ha van rajta gomb, nyomjuk meg." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Hiba történt a Duo szolgáltatáshoz csatlakozáskor. Használjunk másik kétlépcsős bejelentkezési módot vagy kérjünk segítséget a Duotól." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Indítsd el a Duo-t és kövesd a lépéseket a bejelentkezés befejezéséhez." - }, "duoRequiredByOrgForAccount": { "message": "A fiókhoz kétlépcsős Duo bejelentkezés szükséges." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "A gyűjtemény törlésének korlátozása tulajdonosokra és adminisztrátorokra" }, - "limitItemDeletionDesc": { - "message": "Az elemek törlésének korlátozása a Kezelheti jogosultsággal rendelkező tagokra" + "limitItemDeletionDescription": { + "message": "Az elemek törlésének korlátozása a Gyűjtemény kezelése jogosultsággal rendelkező tagokra" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index dc3ba77328f..d62c1dfde53 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Masukkan 6 digit kode verifikasi dari aplikasi autentikasi Anda." - }, - "enterVerificationCodeEmail": { - "message": "Masukkan 6 digit kode verifikasi yang dikirim melalui email ke $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email verifikasi dikirim ke $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Ingat saya" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Kirim ulang email kode verifikasi" - }, - "useAnotherTwoStepMethod": { - "message": "Gunakan metode login dua-langkah lainnya" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Masukkan YubiKey Anda ke port USB komputer Anda, lalu sentuh tombol nya." - }, "insertU2f": { "message": "Masukkan kunci keamanan ke port USB komputer Anda. Jika ada tombolnya, tekanlah." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 853c580c82d..9a0ece95033 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Inserisci il codice di verifica a 6 cifre dalla tua app di autenticazione." - }, - "enterVerificationCodeEmail": { - "message": "Inserisci il codice di verifica a 6 cifre inviato a $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email di verifica inviata a $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Ricordami" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Non chiedere più per 30 giorni su questo dispositivo" }, - "sendVerificationCodeEmailAgain": { - "message": "Invia di nuovo l'email con codice di verifica" - }, - "useAnotherTwoStepMethod": { - "message": "Usa un altro metodo di verifica in due passaggi" - }, "selectAnotherMethod": { "message": "Scegli un altro metodo", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Usa un codice di recupero" }, - "insertYubiKey": { - "message": "Inserisci la tua YubiKey nella porta USB del computer e premi il suo pulsante." - }, "insertU2f": { "message": "Inserisci la tua chiave di sicurezza nella porta USB del tuo computer. Se dispone di un pulsante, premilo." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Errore di connessione con il servizio Duo. Utilizza un metodo di login in due passaggi diverso o contatta Duo per assistenza." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Avvia DUO e segui i passaggi per finire di accedere." - }, "duoRequiredByOrgForAccount": { "message": "Per il tuo account è richiesta la verifica in due passaggi DUO." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limita l'eliminazione delle raccolte ai proprietari e agli amministratori" }, - "limitItemDeletionDesc": { - "message": "Limita l'eliminazione di elementi ai membri con il permesso di gestione" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Proprietari e amministratori possono gestire tutte le raccolte e gli elementi" diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index d445184774c..8eb0745bbc1 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "認証アプリに表示された6桁の認証コードを入力してください。" - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ に送信された6桁の認証コードを入力してください。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ に認証コードを送信しました。", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "情報を保存する" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "このデバイスで30日間再表示しない" }, - "sendVerificationCodeEmailAgain": { - "message": "確認コードをメールで再送" - }, - "useAnotherTwoStepMethod": { - "message": "他の2段階認証方法を使用" - }, "selectAnotherMethod": { "message": "別の方法を選択", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "リカバリーコードを使用する" }, - "insertYubiKey": { - "message": "YubiKey を USB ポートに挿入し、ボタンをタッチしてください。" - }, "insertU2f": { "message": "セキュリティキーを USB ポートに挿入し、ボタンがある場合はボタンをタッチしてください。" }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Duo サービスへの接続中にエラーが発生しました。異なる二段階ログイン方法を使用するか、Duo に連絡してください。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "ログインを完了するには DUO を起動し手順に従ってください。" - }, "duoRequiredByOrgForAccount": { "message": "アカウントには DUO 二段階認証が必要です。" }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "コレクションの削除を所有者と管理者のみに制限" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "所有者と管理者はすべてのコレクションとアイテムを管理できます" diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index 5ace08617ff..ed327aff81c 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "შეიყვანეთ 6 ნიშნა ერთჯერადი კოდი თქვენი ავთენტიკატორი აპლიკაციიდან." - }, - "enterVerificationCodeEmail": { - "message": "შეიყვანეთ 6 ნიშნა ერთჯერადი კოდი რომელიც ელ-ფოსთით გაიგზავნა $EMAIL$-ის მისამართით.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ერთჯერადი კოდი გაგზავნილია $EMAIL$-ზე.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "დამიმახსოვრე" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "გამოგზავნა ერთჯერადი კოდის ელ-ფოსტაზე განმეორებით" - }, - "useAnotherTwoStepMethod": { - "message": "გამოყენება სხვა ორსაფეხურიანი შესვლის მეთოდით" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "შეარჭეთ თქვენი YubiKey თქვენს კომპიუტერის USB პორტში, შემდგომ დაადეთ მის ღილაკს." - }, "insertU2f": { "message": "შეარჭეთ თქვენი უსაფრთხოების გასაღები თქვენს კომპიუტერის USB პორტში. თუ ღილაკი აქვს, შეეხეთ." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 59eac9b372b..775494830de 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index 8132c9a2db5..88edbda5e7b 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "ನಿಮ್ಮ ದೃಢೀಕರಣ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ಗೆ ಇಮೇಲ್ ಮಾಡಲಾದ 6 ಅಂಕಿಯ ಪರಿಶೀಲನಾ ಕೋಡ್ ಅನ್ನು ನಮೂದಿಸಿ.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ಪರಿಶೀಲನೆ ಇಮೇಲ್ $EMAIL$ ಗೆ ಕಳುಹಿಸಲಾಗಿದೆ.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "ನನ್ನನ್ನು ನೆನಪಿನಲ್ಲಿ ಇಡು" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ಪರಿಶೀಲನೆ ಕೋಡ್ ಇಮೇಲ್ ಅನ್ನು ಮತ್ತೆ ಕಳುಹಿಸಿ" - }, - "useAnotherTwoStepMethod": { - "message": "ಮತ್ತೊಂದು ಎರಡು-ಹಂತದ ಲಾಗಿನ್ ವಿಧಾನವನ್ನು ಬಳಸಿ" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "ನಿಮ್ಮ ಯುಬಿಕಿಯನ್ನು ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಯುಎಸ್‌ಬಿ ಪೋರ್ಟ್ಗೆ ಸೇರಿಸಿ, ನಂತರ ಅದರ ಗುಂಡಿಯನ್ನು ಸ್ಪರ್ಶಿಸಿ." - }, "insertU2f": { "message": "ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್‌ನ ಯುಎಸ್‌ಬಿ ಪೋರ್ಟ್ಗೆ ನಿಮ್ಮ ಭದ್ರತಾ ಕೀಲಿಯನ್ನು ಸೇರಿಸಿ. ಅದು ಬಟನ್ ಹೊಂದಿದ್ದರೆ, ಅದನ್ನು ಸ್ಪರ್ಶಿಸಿ." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 6e59f0ccf88..355d1cc08cf 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "인증 앱에서 6자리 인증 코드를 입력하세요." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ 주소로 전송된 6자리 인증 코드를 입력하세요.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "$EMAIL$ 주소로 인증 이메일을 보냈습니다.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "기억하기" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "인증 코드 이메일 다시 보내기" - }, - "useAnotherTwoStepMethod": { - "message": "다른 2단계 로그인 방법 사용" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey를 컴퓨터의 USB 포트에 삽입하고 버튼을 누르세요." - }, "insertU2f": { "message": "보안 키를 컴퓨터의 USB 포트에 삽입하고 버튼이 있는 경우 누르세요." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index e59f6078bf5..dceb9b2be60 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Jāievada 6 ciparu apstiprinājuma kods no autentificētāja lietotnes." - }, - "enterVerificationCodeEmail": { - "message": "Jāievada 6 ciparu apstiprinājuma kods, kas tika nosūtīts uz $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-pasts apstiprināšanai nosūtīts uz $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Atcerēties mani" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Šajā ierīcē 30 dienas vairs nevaicāt" }, - "sendVerificationCodeEmailAgain": { - "message": "Atkārtoti nosūtīt apstiprinājuma kodu" - }, - "useAnotherTwoStepMethod": { - "message": "Izmantot citu divpakāpju pieteikšanās veidu" - }, "selectAnotherMethod": { "message": "Atlasīt citu veidu", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Izmantot savu atkopes kodu" }, - "insertYubiKey": { - "message": "Ievietojiet YubiKey datora USB portā un pēc tam pieskarieties tā pogai." - }, "insertU2f": { "message": "Ievietojiet drošības atslēgu datora USB portā. Ja tam ir poga, pieskarieties tai." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Kļūda savienojuma izveidošanā ar Duo pakalpojumu. Jāizmanto cits divpakāpju pieteikšanās veids vai jāvēršas pie Duo pēc palīdzības." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Jāpalaiž DUO un jāseko soļiem, lai pabeigtu pieteikšanos." - }, "duoRequiredByOrgForAccount": { "message": "Kontam ir nepieciešama DUO divpakāpju pieteikšanās." }, @@ -8358,7 +8331,7 @@ "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "dismiss": { - "message": "Noraidīt" + "message": "Atcelt" }, "notAvailableForFreeOrganization": { "message": "Šī iespēja nav pieejama bezmaksas apvienībām. Jāsazinās ar apvienības īpašnieku, lai uzlabotu." @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Ļaut krājumu izdzēšanu tikai īpašniekiem un pārvaldītājiem" }, - "limitItemDeletionDesc": { - "message": "Ierobežot lietotājiem vienumu izdzēšanu ar atļauju \"Var pārvaldīt\"" + "limitItemDeletionDescription": { + "message": "Ļaut vienumu izdzēšanu tikai dalībniekiem ar krājuma pārvaldīšanas atļaujām" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Īpašnieki un pārvaldnieki var pārvaldīt visus krājumus un vienumus" diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index 10ae27a2139..5876b486bbf 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "നിങ്ങളുടെ ഓതന്റിക്കേറ്റർ അപ്ലിക്കേഷനിൽ നിന്ന് 6 അക്ക സ്ഥിരീകരണ കോഡ് നൽകുക." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$-ൽ ഇമെയിൽ ചെയ്ത 6 അക്ക സ്ഥിരീകരണ കോഡ് നൽകുക.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "സ്ഥിരീകരണ ഇമെയിൽ $EMAIL$-ലേക്ക് അയച്ചു.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "എന്നെ ഓർക്കണം" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "സ്ഥിരീകരണ കോഡ് ഇമെയിൽ വഴി വീണ്ടും അയയ്ക്കുക" - }, - "useAnotherTwoStepMethod": { - "message": "മറ്റൊരു രണ്ട് ഘട്ട പ്രവേശന രീതി ഉപയോഗിക്കുക" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ യു‌എസ്‌ബി പോർട്ടിലേക്ക് YubiKey ഇടുക, തുടർന്ന് അതിന്റെ ബട്ടൺ അമർത്തുക." - }, "insertU2f": { "message": "നിങ്ങളുടെ കമ്പ്യൂട്ടറിന്റെ യുഎസ്ബി പോർട്ടിൽ സുരക്ഷാ കീ ഇടുക. അതിന് ഒരു ബട്ടൺ ഉണ്ടെങ്കിൽ അത് അമർത്തുക." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index 59eac9b372b..775494830de 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 59eac9b372b..775494830de 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index bc36ba82ff1..c68d1bf2961 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Skriv inn den 6-sifrede verifiseringskoden som står på din autentiseringsapp." - }, - "enterVerificationCodeEmail": { - "message": "Skriv inn den 6-sifrede verifiseringskoden som ble sendt til $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "En verifiserings-E-post har blitt sendt til $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Husk på meg" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send E-posten med verifiseringskoden på nytt" - }, - "useAnotherTwoStepMethod": { - "message": "Bruk en annen 2-trinnsinnloggingsmetode" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sett inn din YubiKey i din datamaskins USB-uttak, og så trykk på dens knapp." - }, "insertU2f": { "message": "Sett din sikkerhetsnøkkel inn i din datamaskins USB-uttak. Dersom den har en knapp, trykk på den." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index c947c0bb716..f64cfab4ba1 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 1bc731e3ceb..93eca761180 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Voer de 6-cijferige verificatiecode uit je authenticatie-app in." - }, - "enterVerificationCodeEmail": { - "message": "Voer de 6-cijferige verificatiecode in die via e-mail is verstuurd naar $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail met verificatiecode verzonden naar $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Mijn gegevens onthouden" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "30 dagen niet meer vragen op dit apparaat" }, - "sendVerificationCodeEmailAgain": { - "message": "E-mail met verificatiecode opnieuw versturen" - }, - "useAnotherTwoStepMethod": { - "message": "Gebruik een andere methode voor tweestapsaanmelding" - }, "selectAnotherMethod": { "message": "Kies een andere methode", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Gebruik je herstelcode" }, - "insertYubiKey": { - "message": "Plaats je YubiKey in de USB-poort van je computer en druk op de knop." - }, "insertU2f": { "message": "Steek je beveilingssleutel in de USB-poort van je computer. Als het een knop heeft, druk deze dan in." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Fout bij het verbinden met de Duo-service. Gebruik een andere tweestapsaanmeldingsmethode of neem contact op met Duo voor hulp." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Start DUO en volg de stappen om in te loggen." - }, "duoRequiredByOrgForAccount": { "message": "DUO tweestapsaanmelding is vereist voor jouw account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Verwijderen van collecties beperken tot eigenaren en managers" }, - "limitItemDeletionDesc": { - "message": "Beperk het verwijderen van items tot leden met het recht Kan beheren" + "limitItemDeletionDescription": { + "message": "Beperk het verwijderen van items tot leden met recht om collecties te beheren" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Eigenaren en beheerders kunnen alle collecties en items beheren" diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index ae64568bd79..c50af10221a 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Hugsa meg" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Bruk ein annan tofaktormetode for pålogging" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 59eac9b372b..775494830de 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index f793b249148..b4b4c90d44a 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny z aplikacji uwierzytelniającej." - }, - "enterVerificationCodeEmail": { - "message": "Wpisz 6-cyfrowy kod weryfikacyjny, który został przesłany na adres $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Kod weryfikacyjny został wysłany na adres $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapamiętaj mnie" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Nie pytaj ponownie na tym urządzeniu przez 30 dni" }, - "sendVerificationCodeEmailAgain": { - "message": "Wyślij ponownie wiadomość z kodem weryfikacyjnym" - }, - "useAnotherTwoStepMethod": { - "message": "Użyj innej metody logowania dwustopniowego" - }, "selectAnotherMethod": { "message": "Wybierz inną metodę", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Użyj kodu odzyskiwania" }, - "insertYubiKey": { - "message": "Włóż klucz YubiKey do portu USB komputera, a następnie dotknij jego przycisku." - }, "insertU2f": { "message": "Włóż klucz bezpieczeństwa do portu USB komputera. Jeśli klucz posiada przycisk, dotknij go." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Wystąpił błąd podczas połączenia z usługą Duo. Aby uzyskać pomoc, użyj innej metody dwustopniowego logowania lub skontaktuj się z Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Uruchom DUO i wykonaj kroki, aby zakończyć logowanie." - }, "duoRequiredByOrgForAccount": { "message": "Dwustopniowe logowanie DUO jest wymagane dla Twojego konta." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Ogranicz usuwanie kolekcji do właścicieli i administratorów" }, - "limitItemDeletionDesc": { - "message": "Ogranicz usuwanie elementów do członków z uprawnieniami do zarządzania" + "limitItemDeletionDescription": { + "message": "Ogranicz usuwanie elementów do użytkowników z uprawnieniem Zarządzania kolekcją" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Właściciele i administratorzy mogą zarządzać wszystkimi zbiorami i elementami" diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 3ac5afa3110..1b89aa405f0 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -6,7 +6,7 @@ "message": "Aplicações críticas" }, "noCriticalAppsAtRisk": { - "message": "No critical applications at risk" + "message": "Nenhum aplicativo crítico em risco" }, "accessIntelligence": { "message": "Acessar a Inteligência" @@ -117,7 +117,7 @@ "message": "Membros de risco" }, "atRiskMembersWithCount": { - "message": "At-risk members ($COUNT$)", + "message": "Membros em risco ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -126,7 +126,7 @@ } }, "atRiskApplicationsWithCount": { - "message": "At-risk applications ($COUNT$)", + "message": "Aplicações em risco ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -135,13 +135,13 @@ } }, "atRiskMembersDescription": { - "message": "These members are logging into applications with weak, exposed, or reused passwords." + "message": "Esses membros estão logando em aplicativos com senhas fracas, expostas ou reutilizadas." }, "atRiskApplicationsDescription": { - "message": "These applications have weak, exposed, or reused passwords." + "message": "Esses aplicativos têm senhas fracas, expostas ou reutilizadas." }, "atRiskMembersDescriptionWithApp": { - "message": "These members are logging into $APPNAME$ with weak, exposed, or reused passwords.", + "message": "Esses membros estão logando no $APPNAME$ com senhas fracas, expostas ou reutilizadas.", "placeholders": { "appname": { "content": "$1", @@ -159,10 +159,10 @@ "message": "Todos os aplicativos" }, "unmarkAsCriticalApp": { - "message": "Unmark as critical app" + "message": "Desmarcar como aplicativo crítico" }, "criticalApplicationSuccessfullyUnmarked": { - "message": "Critical application successfully unmarked" + "message": "Aplicação crítica desmarcada com sucesso" }, "whatTypeOfItem": { "message": "Que tipo de item é este?" @@ -202,7 +202,7 @@ "message": "Notas" }, "privateNote": { - "message": "Private note" + "message": "Nota privada" }, "note": { "message": "Nota" @@ -429,7 +429,7 @@ "message": "Arrastar para ordenar" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "Arraste para reorganizar" }, "cfTypeText": { "message": "Texto" @@ -474,7 +474,7 @@ "message": "Editar Pasta" }, "editWithName": { - "message": "Edit $ITEM$: $NAME$", + "message": "Editar $ITEM$: $NAME$", "placeholders": { "item": { "content": "$1", @@ -487,16 +487,16 @@ } }, "newFolder": { - "message": "New folder" + "message": "Nova pasta" }, "folderName": { - "message": "Folder name" + "message": "Nome da pasta" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "Aninhe uma pasta adicionando o nome da pasta pai seguido de uma \"/\". Exemplo: Social/Fóruns" }, "deleteFolderPermanently": { - "message": "Are you sure you want to permanently delete this folder?" + "message": "Você tem certeza que deseja excluir esta pasta permanentemente?" }, "baseDomain": { "message": "Domínio de base", @@ -1037,7 +1037,7 @@ "message": "Não" }, "location": { - "message": "Location" + "message": "Localização" }, "loginOrCreateNewAccount": { "message": "Inicie a sessão ou crie uma nova conta para acessar seu cofre seguro." @@ -1175,13 +1175,13 @@ "message": "Inicie a sessão no Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Digite o código enviado por e-mail" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "Insira o código do seu aplicativo autenticador" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Pressione seu YubiKey para autenticar" }, "authenticationTimeout": { "message": "Tempo de autenticação esgotado" @@ -1190,25 +1190,25 @@ "message": "A sessão de autenticação expirou. Por favor, reinicie o processo de “login”." }, "verifyYourIdentity": { - "message": "Verify your Identity" + "message": "Verifique sua identidade" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Não reconhecemos este dispositivo. Digite o código enviado por e-mail para verificar a sua identidade." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Continue acessando" }, "whatIsADevice": { - "message": "What is a device?" + "message": "O que é um dispositivo?" }, "aDeviceIs": { - "message": "A device is a unique installation of the Bitwarden app where you have logged in. Reinstalling, clearing app data, or clearing your cookies could result in a device appearing multiple times." + "message": "Um dispositivo é uma instalação única do aplicativo Bitwarden onde você se conectou. Reinstalar, limpar dados do aplicativo ou limpar seus cookies pode resultar em um dispositivo aparecendo várias vezes." }, "logInInitiated": { "message": "Login iniciado" }, "logInRequestSent": { - "message": "Request sent" + "message": "Pedido enviado" }, "submit": { "message": "Enviar" @@ -1394,13 +1394,13 @@ "message": "Uma notificação foi enviada para seu dispositivo." }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the " + "message": "Desbloqueie o Bitwarden no seu dispositivo ou na " }, "areYouTryingToAccessYourAccount": { - "message": "Are you trying to access your account?" + "message": "Você está tentando acessar sua conta?" }, "accessAttemptBy": { - "message": "Access attempt by $EMAIL$", + "message": "Tentativa de acesso por $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -1409,19 +1409,19 @@ } }, "confirmAccess": { - "message": "Confirm access" + "message": "Confirmar acesso" }, "denyAccess": { - "message": "Deny access" + "message": "Negar acesso" }, "notificationSentDeviceAnchor": { - "message": "web app" + "message": "aplicativo web" }, "notificationSentDevicePart2": { - "message": "Make sure the Fingerprint phrase matches the one below before approving." + "message": "Certifique-se de que a frase Biométrica corresponde à abaixo antes de aprovar." }, "notificationSentDeviceComplete": { - "message": "Unlock Bitwarden on your device. Make sure the Fingerprint phrase matches the one below before approving." + "message": "Desbloqueie o Bitwarden em seu dispositivo. Certifique-se de que a frase biométrica corresponda à abaixo antes de aprovar." }, "aNotificationWasSentToYourDevice": { "message": "Uma notificação foi enviada para seu dispositivo." @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Insira o código de verificação de 6 dígitos do seu aplicativo de autenticação." - }, - "enterVerificationCodeEmail": { - "message": "Insira o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail de verificação enviado para $EMAIL$.", "placeholders": { @@ -1456,27 +1444,15 @@ } } }, - "rememberMe": { - "message": "Lembrar de mim" - }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" - }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar código de verificação para o e-mail novamente" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de verificação em duas etapas" + "message": "Não perguntar novamente neste dispositivo por 30 dias" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Escolher outro método", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" - }, - "insertYubiKey": { - "message": "Insira a sua YubiKey na porta USB do seu computador, e depois toque no botão da mesma." + "message": "Use seu código de recuperação" }, "insertU2f": { "message": "Insira a sua chave de segurança na porta USB do seu computador. Se ele tiver um botão, toque nele." @@ -1494,7 +1470,7 @@ "message": "Opções de login em duas etapas" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "Selecionar método de login em duas etapas" }, "recoveryCodeDesc": { "message": "Perdeu o acesso a todos os seus provedores de duas etapas? Utilize o seu código de recuperação para desativar todos os provedores de duas etapas da sua conta." @@ -1539,7 +1515,7 @@ "message": "(Migrado de FIDO)" }, "openInNewTab": { - "message": "Open in new tab" + "message": "Abrir numa nova aba" }, "emailTitle": { "message": "E-mail" @@ -1809,10 +1785,10 @@ "message": "Por favor, reinicie a sessão." }, "currentSession": { - "message": "Current session" + "message": "Sessão atual" }, "requestPending": { - "message": "Request pending" + "message": "Solicitação pendente" }, "logBackInOthersToo": { "message": "Por favor, reinicie a sessão. Se estiver usando outros aplicativos do Bitwarden, encerre a sessão e reinicie também." @@ -1891,25 +1867,25 @@ "message": "O processo também desconectará você da sua sessão atual, exigindo que você inicie a sessão novamente. Você também será solicitado a efetuar login em duas etapas novamente, se estiver ativado. Sessões ativas em outros dispositivos podem continuar ativas por até uma hora." }, "newDeviceLoginProtection": { - "message": "New device login" + "message": "Novo login de dispositivo" }, "turnOffNewDeviceLoginProtection": { - "message": "Turn off new device login protection" + "message": "Desativar nova proteção de login de dispositivo" }, "turnOnNewDeviceLoginProtection": { - "message": "Turn on new device login protection" + "message": "Ative a nova proteção de login de dispositivo" }, "turnOffNewDeviceLoginProtectionModalDesc": { - "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + "message": "Continue abaixo para desativar os e-mails de verificação que o Bitwarden enviará quando você fizer “login” a partir de um novo dispositivo." }, "turnOnNewDeviceLoginProtectionModalDesc": { - "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + "message": "Prossiga abaixo para o Bitwarden enviar e-mails de verificação quando você fizer o “login” a partir de um novo dispositivo." }, "turnOffNewDeviceLoginProtectionWarning": { - "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + "message": "Com a nova proteção de login de dispositivo desativada, qualquer pessoa com a sua senha mestra pode acessar a sua conta de qualquer dispositivo. Para proteger sua conta sem e-mails de verificação, configure o login em duas etapas." }, "accountNewDeviceLoginProtectionSaved": { - "message": "New device login protection changes saved" + "message": "Mudanças na proteção de novo “login” de dispositivo foram salvas" }, "sessionsDeauthorized": { "message": "Todas as Sessões Desautorizadas" @@ -2175,7 +2151,7 @@ "message": "A configuração de login em duas etapas pode bloqueá-lo permanentemente da sua conta no Bitwarden. Um código de recuperação permite que você acesse sua conta no caso de não poder mais usar seu provedor de login em duas etapas normalmente (exemplo: você perde seu dispositivo). O suporte do Bitwarden não será capaz de ajudá-lo se você perder o acesso à sua conta. Recomendamos que você anote ou imprima o código de recuperação e o mantenha em um lugar seguro." }, "yourSingleUseRecoveryCode": { - "message": "Your single-use recovery code can be used to turn off two-step login in the event that you lose access to your two-step login provider. Bitwarden recommends you write down the recovery code and keep it in a safe place." + "message": "Seu código de recuperação de uso único pode ser usado para desativar o login em duas etapas no caso de você perder acesso ao seu provedor de login em duas etapas. O Bitwarden recomenda que você anote o código de recuperação e o mantenha em um lugar seguro." }, "viewRecoveryCode": { "message": "Ver código de recuperação" @@ -2216,19 +2192,19 @@ "message": "Gerenciar" }, "manageCollection": { - "message": "Manage collection" + "message": "Gerenciar Coleção" }, "viewItems": { - "message": "View items" + "message": "Visualizar itens" }, "viewItemsHidePass": { - "message": "View items, hidden passwords" + "message": "Ver itens, senhas ocultas" }, "editItems": { - "message": "Edit items" + "message": "Editar itens" }, "editItemsHidePass": { - "message": "Edit items, hidden passwords" + "message": "Editar itens, senhas ocultas" }, "disable": { "message": "Desabilitar" @@ -2237,7 +2213,7 @@ "message": "Revogar acesso" }, "revoke": { - "message": "Revoke" + "message": "Revogar" }, "twoStepLoginProviderEnabled": { "message": "Este provedor de login em duas etapas está ativado em sua conta." @@ -2429,7 +2405,7 @@ "message": "Houve um problema ao ler a chave de segurança. Tente novamente." }, "twoFactorWebAuthnWarning1": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." + "message": "Devido as limitações da plataforma, o WebAuthn não pode ser usado em todos os aplicativos do Bitwarden. Configure outro provedor de login em duas etapas para poder acessar sua conta quando a WebAuthn não puder ser usada." }, "twoFactorRecoveryYourCode": { "message": "Seu código de recuperação de login em duas etapas do Bitwarden" @@ -3396,10 +3372,10 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "Você tem 1 convite restante." }, "inviteZeroEmailDesc": { - "message": "You have 0 invites remaining." + "message": "Você tem 0 convites restantes." }, "userUsingTwoStep": { "message": "Este usuário está usando o login em duas etapas para proteger a sua conta." @@ -3853,7 +3829,7 @@ } }, "unlinkedSso": { - "message": "Unlinked SSO." + "message": "SSO desvinculado." }, "unlinkedSsoUser": { "message": "SSO desvinculado para o usuário $ID$.", @@ -3904,22 +3880,22 @@ "message": "Dispositivo" }, "loginStatus": { - "message": "Login status" + "message": "Status do login" }, "firstLogin": { - "message": "First login" + "message": "Primeiro acesso" }, "trusted": { - "message": "Trusted" + "message": "Confiável" }, "needsApproval": { - "message": "Needs approval" + "message": "Precisa de aprovação" }, "areYouTryingtoLogin": { - "message": "Are you trying to log in?" + "message": "Você está tentando fazer login?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "Tentativa de login por $EMAIL$", "placeholders": { "email": { "content": "$1", @@ -3928,22 +3904,22 @@ } }, "deviceType": { - "message": "Device Type" + "message": "Tipo de dispositivo" }, "ipAddress": { - "message": "IP Address" + "message": "Endereço IP" }, "confirmLogIn": { - "message": "Confirm login" + "message": "Confirmar acesso" }, "denyLogIn": { - "message": "Deny login" + "message": "Negar acesso" }, "thisRequestIsNoLongerValid": { - "message": "This request is no longer valid." + "message": "Este pedido não é mais válido." }, "logInConfirmedForEmailOnDevice": { - "message": "Login confirmed for $EMAIL$ on $DEVICE$", + "message": "Acesso confirmado para $EMAIL$ no $DEVICE$", "placeholders": { "email": { "content": "$1", @@ -3956,16 +3932,16 @@ } }, "youDeniedALogInAttemptFromAnotherDevice": { - "message": "You denied a login attempt from another device. If this really was you, try to log in with the device again." + "message": "Você negou uma tentativa de acesso de outro dispositivo. Se isso realmente foi você, tente fazer login com o dispositivo novamente." }, "loginRequestHasAlreadyExpired": { - "message": "Login request has already expired." + "message": "O pedido de login já expirou." }, "justNow": { - "message": "Just now" + "message": "Agora mesmo" }, "requestedXMinutesAgo": { - "message": "Requested $MINUTES$ minutes ago", + "message": "Solicitado há $MINUTES$ minutos", "placeholders": { "minutes": { "content": "$1", @@ -4091,19 +4067,19 @@ "message": "Atualizar Navegador" }, "generatingRiskInsights": { - "message": "Generating your risk insights..." + "message": "Gerando seu panorama de risco..." }, "updateBrowserDesc": { "message": "Você está usando um navegador da Web não suportado. O cofre web pode não funcionar corretamente." }, "youHaveAPendingLoginRequest": { - "message": "You have a pending login request from another device." + "message": "Você tem uma solicitação de login pendente de outro dispositivo." }, "reviewLoginRequest": { - "message": "Review login request" + "message": "Revisar solicitação de login" }, "freeTrialEndPromptCount": { - "message": "Your free trial ends in $COUNT$ days.", + "message": "Seu teste gratuito termina em $COUNT$ dias.", "placeholders": { "count": { "content": "$1", @@ -4112,7 +4088,7 @@ } }, "freeTrialEndPromptMultipleDays": { - "message": "$ORGANIZATION$, your free trial ends in $COUNT$ days.", + "message": "$ORGANIZATION$, seu período de teste gratuito termina em $COUNT$ dias.", "placeholders": { "count": { "content": "$2", @@ -4125,7 +4101,7 @@ } }, "freeTrialEndPromptTomorrow": { - "message": "$ORGANIZATION$, your free trial ends tomorrow.", + "message": "$ORGANIZATION$, o seu teste gratuito termina amanhã.", "placeholders": { "organization": { "content": "$1", @@ -4134,10 +4110,10 @@ } }, "freeTrialEndPromptTomorrowNoOrgName": { - "message": "Your free trial ends tomorrow." + "message": "Seu teste gratuito termina amanhã." }, "freeTrialEndPromptToday": { - "message": "$ORGANIZATION$, your free trial ends today.", + "message": "$ORGANIZATION$, seu período de teste gratuito termina hoje.", "placeholders": { "organization": { "content": "$1", @@ -4146,10 +4122,10 @@ } }, "freeTrialEndingTodayWithoutOrgName": { - "message": "Your free trial ends today." + "message": "Seu teste gratuito termina hoje." }, "clickHereToAddPaymentMethod": { - "message": "Click here to add a payment method." + "message": "Clique aqui para adicionar um método de pagamento." }, "joinOrganization": { "message": "Junte-se a Organização" @@ -4197,7 +4173,7 @@ "message": "Se você não puder acessar sua conta por meio de seus métodos normais de login em duas etapas, poderá usar seu código de recuperação de login em duas etapas para desativar a funcionalidade de duas etapas da sua conta." }, "logInBelowUsingYourSingleUseRecoveryCode": { - "message": "Log in below using your single-use recovery code. This will turn off all two-step providers on your account." + "message": "Faça o login abaixo usando seu código de recuperação de uso único. Isso irá desativar todos os provedores de duas etapas na sua conta." }, "recoverAccountTwoStep": { "message": "Recuperar login em duas etapas da conta" @@ -4491,7 +4467,7 @@ "message": "A atualização da chave de criptografia não pode continuar" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Editar $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4500,7 +4476,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Reordene $LABEL$. Use a tecla de seta para mover o item para cima ou para baixo.", "placeholders": { "label": { "content": "$1", @@ -4509,7 +4485,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ movido para cima, posição $INDEX$ de $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4526,7 +4502,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ movido para baixo, posição $INDEX$ de $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4814,7 +4790,7 @@ "message": "Defina os requisitos mínimos para a força da senha mestra." }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Pontuação de força da senha $SCORE$", "placeholders": { "score": { "content": "$1", @@ -5000,10 +4976,10 @@ "message": "Faça o login usando o portal de login único da sua organização. Por favor, insira o identificador da sua organização para começar." }, "singleSignOnEnterOrgIdentifier": { - "message": "Enter your organization's SSO identifier to begin" + "message": "Insira o identificador SSO da sua organização para começar" }, "singleSignOnEnterOrgIdentifierText": { - "message": "To log in with your SSO provider, enter your organization's SSO identifier to begin. You may need to enter this SSO identifier when you log in from a new device." + "message": "Para fazer login com seu provedor SSO, insira o identificador SSO da sua organização para começar. Talvez seja necessário inserir este identificador SSO quando fizer login a partir de um novo dispositivo." }, "enterpriseSingleSignOn": { "message": "Iniciar Sessão Empresarial Única" @@ -5103,14 +5079,14 @@ "message": "Os Proprietários e Administradores da Organização estão isentos da aplicação desta política." }, "limitSendViews": { - "message": "Limit views" + "message": "Limitar visualização" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "Ninguém pode visualizar este envio depois que o limite foi atingido.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "$ACCESSCOUNT$ Visualizações restantes", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -5120,11 +5096,11 @@ } }, "sendDetails": { - "message": "Send details", + "message": "Enviar detalhes", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "Texto para compartilhar" }, "sendTypeFile": { "message": "Arquivo" @@ -5133,7 +5109,7 @@ "message": "Texto" }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "Adicione uma senha opcional para os destinatários acessarem este Envio.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { @@ -5161,14 +5137,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendPermanentConfirmation": { - "message": "Are you sure you want to permanently delete this Send?", + "message": "Tem certeza de que deseja excluir permanentemente este Envio?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDate": { "message": "Data de Exclusão" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "O envio será permanentemente excluído nesta data.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -5218,7 +5194,7 @@ "message": "Exclusão pendente" }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "Ocultar texto por padrão" }, "expired": { "message": "Expirado" @@ -5689,7 +5665,7 @@ "message": "Ocorreu um erro ao salvar as suas datas de exclusão e validade." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "Oculte seu endereço de e-mail dos visualizadores." }, "webAuthnFallbackMsg": { "message": "Para verificar seu 2FA, por favor, clique no botão abaixo." @@ -5698,10 +5674,10 @@ "message": "Autenticar WebAuthn" }, "readSecurityKey": { - "message": "Read security key" + "message": "Ler chave de segurança" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "Aguardando interação com a chave de segurança..." }, "webAuthnNotSupported": { "message": "O WebAuthn não é suportado neste navegador." @@ -5917,17 +5893,17 @@ "message": "Erro" }, "decryptionError": { - "message": "Decryption error" + "message": "Erro ao descriptografar" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "O Bitwarden não pôde descriptografar o(s) item(ns) do cofre listado abaixo." }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "Contato com o cliente feito com sucesso", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "para evitar a perda adicional dos dados.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -6742,7 +6718,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Apenas os itens individuais do cofre, incluindo anexos associados ao $EMAIL$ serão exportados. Os itens do cofre da organização não serão incluídos", "placeholders": { "email": { "content": "$1", @@ -6854,7 +6830,7 @@ "message": "Use o catch-all configurado no seu domínio." }, "useThisEmail": { - "message": "Use this email" + "message": "Usar este e-mail" }, "random": { "message": "Aleatório", @@ -7006,7 +6982,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ recusou sua solicitação. Contate seu provedor de serviços para receber assistência.", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -7016,7 +6992,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ recusou sua solicitação: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -7252,17 +7228,14 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro ao se conectar com o serviço Duo. Use um método de verificação de duas etapas diferente ou contate o Duo para assistência." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o Duo e siga os passos para finalizar o login." - }, "duoRequiredByOrgForAccount": { "message": "A autenticação em duas etapas do Duo é necessária para sua conta." }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "A autenticação de dois fatores do Duo é necessária para sua conta. Siga os passos abaixo para conseguir entrar." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Siga os passos abaixo para finalizar o login." }, "launchDuo": { "message": "Abrir o Duo" @@ -8415,31 +8388,31 @@ "message": "Dispositivos confiáveis" }, "memberDecryptionOptionTdeDescPart1": { - "message": "Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The", + "message": "Os membros não precisarão de uma senha mestra ao fazer login com SSO. A senha mestra é substituída por uma chave de criptografia armazenada no dispositivo, fazendo com que esse dispositivo seja confiável. O primeiro dispositivo que um membro cria sua conta e os logins serão confiáveis. Novos dispositivos precisarão ser aprovados por um dispositivo confiável existente ou por um administrador. O", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink1": { - "message": "single organization", + "message": "organização única", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart2": { - "message": "policy,", + "message": "política,", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink2": { - "message": "SSO required", + "message": "Necessário SSO", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart3": { - "message": "policy, and", + "message": "política, e", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescLink3": { - "message": "account recovery administration", + "message": "administração de recuperação de conta", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart4": { - "message": "policy will turn on when this option is used.", + "message": "política será ativada quando esta opção for utilizada.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "orgPermissionsUpdatedMustSetPassword": { @@ -8518,16 +8491,16 @@ "message": "Aprovar solicitação" }, "deviceApproved": { - "message": "Device approved" + "message": "Dispositivo aprovado" }, "deviceRemoved": { - "message": "Device removed" + "message": "Dispositivo removido" }, "removeDevice": { - "message": "Remove device" + "message": "Remover dispositivo" }, "removeDeviceConfirmation": { - "message": "Are you sure you want to remove this device?" + "message": "Tem certeza de que deseja remover este dispositivo?" }, "noDeviceRequests": { "message": "Nenhum pedido de dispositivo" @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limitar exclusão de coleção a proprietários e administradores" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limitar exclusão de itens a membros com as permissões de gerenciar coleção" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Proprietários e administradores podem gerenciar todas as coleções e itens" @@ -8849,10 +8822,10 @@ "message": "Você não tem acesso para gerenciar esta coleção." }, "grantManageCollectionWarningTitle": { - "message": "Missing Manage Collection Permissions" + "message": "Faltando Permissões para Gerenciar Coleção" }, "grantManageCollectionWarning": { - "message": "Grant Manage collection permissions to allow full collection management including deletion of collection." + "message": "Conceda permissões de Gerenciamento de Coleções para permitir o gerenciamento completo da coleção, incluindo a exclusão da coleção." }, "grantCollectionAccess": { "message": "Conceder acesso de grupos ou membros a esta coleção." @@ -9348,19 +9321,19 @@ "message": "Configure o gerenciamento de dispositivos para o Bitwarden usando o guia de implementação da sua plataforma." }, "deviceIdMissing": { - "message": "Device ID is missing" + "message": "ID do dispositivo está faltando" }, "deviceTypeMissing": { - "message": "Device type is missing" + "message": "O tipo de dispositivo está faltando" }, "deviceCreationDateMissing": { - "message": "Device creation date is missing" + "message": "Data de criação do dispositivo ausente" }, "desktopRequired": { - "message": "Desktop required" + "message": "Desktop necessário" }, "reopenLinkOnDesktop": { - "message": "Reopen this link from your email on a desktop." + "message": "Reabra este link a partir do seu e-mail em um desktop." }, "integrationCardTooltip": { "message": "Inicie o guia de implementação $INTEGRATION$.", @@ -9429,7 +9402,7 @@ "message": "mês por membro" }, "monthPerMemberBilledAnnually": { - "message": "month per member billed annually" + "message": "mês por membro cobrado anualmente" }, "seats": { "message": "Lugares" @@ -9580,16 +9553,16 @@ "message": "Informações fiscais atualizadas" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "CPF/CNPJ inválido, se você acredita que isto é um erro, contate o suporte." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Não foi possível validar seu CPF/CNPJ, se você acredita que isto é um erro, contate o suporte." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "CPF/CNPJ inválido, se você acredita que isto é um erro, contate o suporte." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Ocorreu um erro ao pré-visualizar a fatura. Tente novamente mais tarde." }, "unverified": { "message": "Não verificado" @@ -9856,13 +9829,13 @@ "message": "Saiba mais sobre a API do Bitwarden" }, "fileSend": { - "message": "File Send" + "message": "Arquivo enviado" }, "fileSends": { "message": "Arquivos enviados" }, "textSend": { - "message": "Text Send" + "message": "Enviar texto" }, "textSends": { "message": "Texto enviado" @@ -9958,13 +9931,13 @@ "message": "Algoritmo da chave" }, "sshPrivateKey": { - "message": "Private key" + "message": "Chave privada" }, "sshPublicKey": { - "message": "Public key" + "message": "Chave pública" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Impressão digital" }, "sshKeyFingerprint": { "message": "Impressão digital" @@ -10117,7 +10090,7 @@ "message": "Auto-hospedado" }, "claim-domain-single-org-warning": { - "message": "Claiming a domain will turn on the single organization policy." + "message": "Reivindicar um domínio ligará a política de organização única." }, "single-org-revoked-user-warning": { "message": "Membros não conformes serão revogados. Os administradores podem restaurar os membros assim que saírem de todas as outras organizações." @@ -10225,22 +10198,22 @@ } }, "importantNotice": { - "message": "Important notice" + "message": "Aviso importante" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Configurar login em duas etapas" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden enviará um código para o seu e-mail para verificar novos dispositivos a partir de fevereiro de 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Você pode configurar o login em duas etapas como uma forma alternativa de proteger sua conta ou mudar seu e-mail para um que você possa acessar." }, "remindMeLater": { - "message": "Remind me later" + "message": "Lembre-me depois" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Você tem acesso ao seu e-mail, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -10249,49 +10222,49 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Não tenho" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Sim, eu tenho" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Ativar login em duas etapas" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Alterar e-mail" }, "removeMembers": { "message": "Remover membro?" }, "devices": { - "message": "Devices" + "message": "Dispositivos" }, "deviceListDescription": { - "message": "Your account was logged in to each of the devices below. If you do not recognize a device, remove it now." + "message": "Sua conta foi conectada a cada um dos dispositivos abaixo. Se você não reconhecer um dispositivo, remova-o agora." }, "deviceListDescriptionTemp": { - "message": "Your account was logged in to each of the devices below." + "message": "Sua conta foi conectada a cada um dos dispositivos abaixo." }, "claimedDomains": { - "message": "Claimed domains" + "message": "Domínios reivindicados" }, "claimDomain": { - "message": "Claim domain" + "message": "Reivindicar domínio" }, "reclaimDomain": { - "message": "Reclaim domain" + "message": "Recuperar domínio" }, "claimDomainNameInputHint": { - "message": "Example: mydomain.com. Subdomains require separate entries to be claimed." + "message": "Exemplo: meudominio.com. Subdomínios requerem entradas separadas para serem reivindicadas." }, "automaticClaimedDomains": { - "message": "Automatic Claimed Domains" + "message": "Domínios Reivindicados Automaticamente" }, "automaticDomainClaimProcess": { - "message": "Bitwarden will attempt to claim the domain 3 times during the first 72 hours. If the domain can’t be claimed, check the DNS record in your host and manually claim. The domain will be removed from your organization in 7 days if it is not claimed." + "message": "O Bitwarden tentará reivindicar o domínio 3 vezes durante as primeiras 72 horas. Se o domínio não puder ser reivindicado, verifique o registro DNS no seu host e reivindique manualmente. O domínio será removido da sua organização em 7 dias, se não for reivindicado." }, "domainNotClaimed": { - "message": "$DOMAIN$ not claimed. Check your DNS records.", + "message": "$DOMAIN$ não reivindicado. Verifique seus registros DNS.", "placeholders": { "DOMAIN": { "content": "$1", @@ -10300,19 +10273,19 @@ } }, "domainStatusClaimed": { - "message": "Claimed" + "message": "Reivindicado" }, "domainStatusUnderVerification": { - "message": "Under verification" + "message": "Em verificação" }, "claimedDomainsDesc": { - "message": "Claim a domain to own all member accounts whose email address matches the domain. Members will be able to skip the SSO identifier when logging in. Administrators will also be able to delete member accounts." + "message": "Reivindique um domínio para se apropriar de todas as contas de membros cujo endereço de e-mail corresponde ao domínio. Os membros serão capazes de pular o identificador SSO ao fazer o login. Administradores também serão capazes de excluir contas de membros." }, "invalidDomainNameClaimMessage": { - "message": "Input is not a valid format. Format: mydomain.com. Subdomains require separate entries to be claimed." + "message": "Entrada não é um formato válido. Formato: meudominio.com. Subdomínios requerem entradas separadas para serem reivindicados." }, "domainClaimedEvent": { - "message": "$DOMAIN$ claimed", + "message": "$DOMAIN$ reivindicado", "placeholders": { "DOMAIN": { "content": "$1", @@ -10321,7 +10294,7 @@ } }, "domainNotClaimedEvent": { - "message": "$DOMAIN$ not claimed", + "message": "$DOMAIN$ não reivindicado", "placeholders": { "DOMAIN": { "content": "$1", @@ -10330,7 +10303,7 @@ } }, "updatedRevokeSponsorshipConfirmationForSentSponsorship": { - "message": "If you remove $EMAIL$, the sponsorship for this Family plan cannot be redeemed. Are you sure you want to continue?", + "message": "Se você remover $EMAIL$, o pagamento deste plano Família não poderá ser resgatado. Tem certeza que deseja continuar?", "placeholders": { "email": { "content": "$1", @@ -10339,7 +10312,7 @@ } }, "updatedRevokeSponsorshipConfirmationForAcceptedSponsorship": { - "message": "If you remove $EMAIL$, the sponsorship for this Family plan will end and the saved payment method will be charged $40 + applicable tax on $DATE$. You will not be able to redeem a new sponsorship until $DATE$. Are you sure you want to continue?", + "message": "Se remover $EMAIL$, o pagamento para este plano Família terminará e o método de pagamento salvo será cobrado por US$ 40 + imposto aplicável em $DATE$. Você não poderá resgatar um novo pagamento até $DATE$. Tem certeza que deseja continuar?", "placeholders": { "email": { "content": "$1", @@ -10352,75 +10325,75 @@ } }, "domainClaimed": { - "message": "Domain claimed" + "message": "Domínio reivindicado" }, "organizationNameMaxLength": { - "message": "Organization name cannot exceed 50 characters." + "message": "O nome da organização não pode exceder 50 caracteres." }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "A senha está incorreta." }, "importSshKey": { - "message": "Import" + "message": "Importar" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Confirme a senha" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Insira a senha da chave SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Insira a senha" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "A chave SSH é inválida" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "O tipo de chave SSH não é compatível" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "Importar chave da área de transferência" }, "sshKeyImported": { - "message": "SSH key imported successfully" + "message": "Chave SSH importada com sucesso" }, "copySSHPrivateKey": { - "message": "Copy private key" + "message": "Copiar chave privada" }, "openingExtension": { - "message": "Opening the Bitwarden browser extension" + "message": "Abrir a extensão do navegador Bitwarden" }, "somethingWentWrong": { - "message": "Something went wrong..." + "message": "Ocorreu um problema..." }, "openingExtensionError": { - "message": "We had trouble opening the Bitwarden browser extension. Click the button to open it now." + "message": "Tivemos problemas ao abrir a extensão Bitwarden. Clique no botão para abri-la agora." }, "openExtension": { - "message": "Open extension" + "message": "Abrir extensão" }, "doNotHaveExtension": { - "message": "Don't have the Bitwarden browser extension?" + "message": "Não tem a extensão do Bitwarden?" }, "installExtension": { - "message": "Install extension" + "message": "Instalar a extensão" }, "openedExtension": { - "message": "Opened the browser extension" + "message": "Abriu a extensão do navegador" }, "openedExtensionViewAtRiskPasswords": { - "message": "Successfully opened the Bitwarden browser extension. You can now review your at-risk passwords." + "message": "A extensão do Bitwarden foi aberta com sucesso. Agora você pode rever suas senhas em risco." }, "openExtensionManuallyPart1": { - "message": "We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon", + "message": "Tivemos problemas ao abrir a extensão Bitwarden. Abra o ícone do Bitwarden", "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon [Bitwarden Icon] from the toolbar.'" }, "openExtensionManuallyPart2": { - "message": "from the toolbar.", + "message": "da barra de ferramentas.", "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon [Bitwarden Icon] from the toolbar.'" }, "resellerRenewalWarningMsg": { - "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "message": "Sua assinatura será renovada em breve. Para garantir o serviço sem interrupções, entre em contato com $RESELLER$ para confirmar sua renovação antes de $RENEWAL_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10433,7 +10406,7 @@ } }, "resellerOpenInvoiceWarningMgs": { - "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "message": "Uma fatura para sua assinatura foi emitida em $ISSUED_DATE$. Para garantir o serviço ininterrupto, entre em contato com $RESELLER$ para confirmar a sua renovação antes de $DUE_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10450,7 +10423,7 @@ } }, "resellerPastDueWarningMsg": { - "message": "The invoice for your subscription has not been paid. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "message": "A fatura da sua assinatura não foi paga. Para garantir o serviço ininterrupto, entre em contato com $RESELLER$ para confirmar sua renovação antes de $GRACE_PERIOD_END$.", "placeholders": { "reseller": { "content": "$1", @@ -10463,13 +10436,13 @@ } }, "restartOrganizationSubscription": { - "message": "Organization subscription restarted" + "message": "Assinatura da organização reiniciada" }, "restartSubscription": { - "message": "Restart your subscription" + "message": "Reinicie sua assinatura" }, "suspendedManagedOrgMessage": { - "message": "Contact $PROVIDER$ for assistance.", + "message": "Entre em contato com $PROVIDER$ para assistência.", "placeholders": { "provider": { "content": "$1", @@ -10478,16 +10451,16 @@ } }, "accountDeprovisioningNotification": { - "message": "Administrators now have the ability to delete member accounts that belong to a claimed domain." + "message": "Os administradores agora têm a capacidade de excluir contas de membros que pertencem a um domínio reivindicado." }, "deleteManagedUserWarningDesc": { - "message": "This action will delete the member account including all items in their vault. This replaces the previous Remove action." + "message": "Esta ação irá excluir a conta de membro, incluindo todos os itens do seu cofre. Isso substitui a ação de Remover anterior." }, "deleteManagedUserWarning": { - "message": "Delete is a new action!" + "message": "Excluir é uma nova ação!" }, "seatsRemaining": { - "message": "You have $REMAINING$ seats remaining out of $TOTAL$ seats assigned to this organization. Contact your provider to manage your subscription.", + "message": "Você tem $REMAINING$ assentos restantes de $TOTAL$ atribuídos a essa organização. Entre em contato com seu provedor para gerenciar sua assinatura.", "placeholders": { "remaining": { "content": "$1", @@ -10500,19 +10473,19 @@ } }, "existingOrganization": { - "message": "Existing organization" + "message": "Organização existente" }, "selectOrganizationProviderPortal": { - "message": "Select an organization to add to your Provider Portal." + "message": "Selecione uma organização para adicionar ao seu Portal do Provedor." }, "noOrganizations": { - "message": "There are no organizations to list" + "message": "Não há organizações para listar" }, "yourProviderSubscriptionCredit": { - "message": "Your provider subscription will receive a credit for any remaining time in the organization's subscription." + "message": "Sua assinatura de provedor receberá um crédito por qualquer tempo restante na assinatura da organização." }, "doYouWantToAddThisOrg": { - "message": "Do you want to add this organization to $PROVIDER$?", + "message": "Você deseja adicionar esta organização ao $PROVIDER$?", "placeholders": { "provider": { "content": "$1", @@ -10521,22 +10494,22 @@ } }, "addedExistingOrganization": { - "message": "Added existing organization" + "message": "Organização existente adicionada" }, "assignedExceedsAvailable": { - "message": "Assigned seats exceed available seats." + "message": "Os assentos atribuídos excedem os disponíveis." }, "changeAtRiskPassword": { - "message": "Change at-risk password" + "message": "Alterar senhas vulneráveis" }, "removeUnlockWithPinPolicyTitle": { - "message": "Remove Unlock with PIN" + "message": "Remover desbloqueio com o PIN" }, "removeUnlockWithPinPolicyDesc": { - "message": "Do not allow members to unlock their account with a PIN." + "message": "Não permitir que os membros desbloqueiem sua conta com um PIN." }, "limitedEventLogs": { - "message": "$PRODUCT_TYPE$ plans do not have access to real event logs", + "message": "Os planos $PRODUCT_TYPE$ não têm acesso aos registros de eventos reais", "placeholders": { "product_type": { "content": "$1", @@ -10545,15 +10518,15 @@ } }, "upgradeForFullEvents": { - "message": "Get full access to organization event logs by upgrading to a Teams or Enterprise plan." + "message": "Obtenha acesso completo aos logs de eventos da organização atualizando para um plano Times ou Empresarial." }, "upgradeEventLogTitle": { - "message": "Upgrade for real event log data" + "message": "Atualizar para dados reais do registro de eventos" }, "upgradeEventLogMessage": { - "message": "These events are examples only and do not reflect real events within your Bitwarden organization." + "message": "Esses eventos são apenas exemplos e não refletem eventos reais na sua organização do Bitwarden." }, "cannotCreateCollection": { - "message": "Free organizations may have up to 2 collections. Upgrade to a paid plan to add more collections." + "message": "Organizações gratuitas podem ter até duas coleções. Faça o upgrade para um plano pago para adicionar mais coleções." } } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 1cd3f9c9b1b..d45484af588 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Introduza o código de verificação de 6 dígitos da sua aplicação de autenticação." - }, - "enterVerificationCodeEmail": { - "message": "Introduza o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mail de verificação enviado para $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Memorizar" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Não voltar a perguntar neste dispositivo durante 30 dias" }, - "sendVerificationCodeEmailAgain": { - "message": "Enviar e-mail com o código de verificação novamente" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizar outro método de verificação de dois passos" - }, "selectAnotherMethod": { "message": "Selecionar outro método", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Utilize o seu código de recuperação" }, - "insertYubiKey": { - "message": "Introduza a sua YubiKey na porta USB do seu computador, depois toque no botão da mesma." - }, "insertU2f": { "message": "Introduza a sua chave de segurança na porta USB do seu computador. Se tiver um botão, toque no mesmo." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Erro ao ligar ao serviço Duo. Utilize um método de verificação de dois passos diferente ou contacte o Duo para obter assistência." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Inicie o DUO e siga os passos para concluir o início de sessão." - }, "duoRequiredByOrgForAccount": { "message": "A verificação de dois passos Duo é necessária para a sua conta." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limitar a eliminação de coleções aos proprietários e administradores" }, - "limitItemDeletionDesc": { - "message": "Limitar a eliminação de itens a membros com a permissão Pode gerir" + "limitItemDeletionDescription": { + "message": "Limitar a eliminação de itens aos membros com as permissões Gerir coleção" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Os proprietários e administradores podem gerir todas as coleções e itens" diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index f67c9550655..9531fdaa59a 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Introducere cod de verificare din 6 cifre din aplicația de autentificare." - }, - "enterVerificationCodeEmail": { - "message": "Introducere cod de verificare din 6 cifre care a fost trimis prin e-mail la $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "E-mailul de verificare a fost trimis la $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Memorare autentificare" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Retrimitere e-mail cu codul de verificare" - }, - "useAnotherTwoStepMethod": { - "message": "Utilizare de metodă diferită de autentificare în două etape" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Introduceți YubiKey în portul USB al calculatorului apoi apăsați butonul acestuia." - }, "insertU2f": { "message": "Introduceți cheia de securitate în portul USB al computerului. Dacă are un buton, apăsați-l." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index 2bdaeb63206..cc2ffc2e524 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Введите 6-значный код подтверждения из вашего приложения-аутентификатора." - }, - "enterVerificationCodeEmail": { - "message": "Введите 6-значный код подтверждения, который был отправлен на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Отправлено письмо подтверждения на $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Запомнить меня" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не спрашивать на этом устройстве в течение 30 дней" }, - "sendVerificationCodeEmailAgain": { - "message": "Отправить код подтверждения еще раз" - }, - "useAnotherTwoStepMethod": { - "message": "Использовать другой метод двухэтапной аутентификации" - }, "selectAnotherMethod": { "message": "Выбрать другой способ", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Использовать код восстановления" }, - "insertYubiKey": { - "message": "Вставьте свой YubiKey в USB-порт компьютера и нажмите его кнопку." - }, "insertU2f": { "message": "Вставьте ключ безопасности в USB-порт компьютера. Если у ключа есть кнопка, нажмите ее." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Ошибка при подключении к сервису Duo. Используйте другой метод двухэтапной аутентификации или обратитесь за помощью в Duo." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустите Duo и следуйте шагам для завершения авторизации." - }, "duoRequiredByOrgForAccount": { "message": "Для вашего аккаунта требуется двухэтапная аутентификация Duo." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Ограничить удаление коллекций владельцам и администраторам" }, - "limitItemDeletionDesc": { - "message": "Ограничить удаление элементов для пользователей с разрешением 'Может управлять'" + "limitItemDeletionDescription": { + "message": "Ограничить удаление элементов для пользователей с правами на управление коллекцией" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Владельцы и администраторы могут управлять всеми коллекциями и элементами" diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index bbb01d1aa49..8583aee42de 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 339a73bbffb..6a1e2ba715b 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Zadajte 6-miestny verifikačný kód z vašej overovacej aplikácie." - }, - "enterVerificationCodeEmail": { - "message": "Zadajte 6-miestny verifikačný kód, ktorý bol zaslaný emailom na $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Overovací e-mail odoslaný na $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapamätaj si ma" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Nepýtať sa znova na tomto zariadení 30 dní" }, - "sendVerificationCodeEmailAgain": { - "message": "Znovu zaslať overovací kód emailom" - }, - "useAnotherTwoStepMethod": { - "message": "Použiť inú dvojstupňovú metódu prihlásenia" - }, "selectAnotherMethod": { "message": "Vyberte iný spôsob", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Použiť obnovovací kód" }, - "insertYubiKey": { - "message": "Vložte váš YubiKey do USB portu počítača a stlačte jeho tlačidlo." - }, "insertU2f": { "message": "Vložte váš bezpečnostný kľúč do USB portu počítača. Ak má tlačidlo, stlačte ho." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Chyba pri pripájaní k službe Duo. Použite inú metódu dvojstupňového prihlásenia alebo kontaktujte Duo a požiadajte o pomoc." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Spustite DUO a postupujte podľa pokynov na dokončenie prihlásenia." - }, "duoRequiredByOrgForAccount": { "message": "Pre váš účet je potrebné dvojstupňové prihlásenie DUO." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Obmedziť vymazávanie zbierky len pre vlastníkov a administrátorov" }, - "limitItemDeletionDesc": { - "message": "Obmedziť vymazávanie položiek na členov s oprávnením \"Môže spravovať\"" + "limitItemDeletionDescription": { + "message": "Obmedziť vymazávanie položiek na členov s oprávnením na správu zbierky" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Vlastníci a správcovia môžu spravovať všetky zbierky a položky" diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index d14b4f13ecc..0357dca3932 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Vnesite 6-mestno potrditveno kodo iz vaše avtorizacijske aplikacije." - }, - "enterVerificationCodeEmail": { - "message": "Vnesite 6-mestno potrditveno kodo, poslano na e-poštni naslov $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Potrditveno sporočilo poslano na $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapomni si me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Ponovno posreduj potrditveno kodo na e-poštni naslov" - }, - "useAnotherTwoStepMethod": { - "message": "Uporabi drug dvostopenjski način vpisa" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Svoj YubiKey ključek vstavite v USB režo in pritisnite na njegovo tipko." - }, "insertU2f": { "message": "Svoj varnostni USB ključek vstavite v USB režo. Če ima gumb, ga sedaj pritisnite." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 2ac4a713189..7ddbbb746de 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Унесите шестоцифрени верификациони код из апликације за утврђивање аутентичности." - }, - "enterVerificationCodeEmail": { - "message": "Унесите шестоцифрени верификациони код који је послан на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Е-пошта за верификацију је послата на $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Запамти ме" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Не питајте поново на овом уређају 30 дана" }, - "sendVerificationCodeEmailAgain": { - "message": "Поново послати верификациони код на Е-пошту" - }, - "useAnotherTwoStepMethod": { - "message": "Користите другу методу пријављивања у два корака" - }, "selectAnotherMethod": { "message": "Изаберите другу методу", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Употребите шифру за опоравак" }, - "insertYubiKey": { - "message": "Убаците свој YubiKey у УСБ порт рачунара, а затим додирните његово дугме." - }, "insertU2f": { "message": "Убаците свој сигурносни кључ у УСБ порт рачунара, и ако има дугме, додирните га." }, @@ -6742,7 +6718,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Извешће се само појединачни сеф, укључујући прилоге повезане са $EMAIL$. Организациони сефски предмети неће бити укључени", "placeholders": { "email": { "content": "$1", @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Грешка при повезивању са услугом Duo. Користите други метод пријаве у два корака или контактирајте Duo за помоћ." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Покренути DUO и пратите кораке да бисте завршили пријављивање." - }, "duoRequiredByOrgForAccount": { "message": "DUO пријава у два корака је потребна за ваш налог." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Ограничите брисање збирке на власнике и администраторе" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Власници и администратори могу да управљају свим колекцијама и ставкама" diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index d84f3192dea..a27221c469e 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Zapamti me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Povežite Vaš YubiKey preko USB porta na vašem računaru, pa pritisnite dugme na njemu." - }, "insertU2f": { "message": "Povežite Vaš sigurnosni ključ preko USB porta na Vaš računar. Ukoliko ima dugme, pritisnite ga." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index e4cc2cdeb67..aced26c606f 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Ange den 6-siffriga verifieringskoden från din autentiseringsapp." - }, - "enterVerificationCodeEmail": { - "message": "Ange den 6-siffriga verifieringskoden som har skickats till $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verifieringsmeddelande har skickats till $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Kom ihåg mig" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Skicka e-postmeddelandet med verifieringskoden igen" - }, - "useAnotherTwoStepMethod": { - "message": "Använd en annan metod för tvåstegsverifiering" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Sätt in din YubiKey i din dators USB-port och tryck på dess knapp." - }, "insertU2f": { "message": "Sätt in din säkerhetsnyckel i din dators USB-port. Om den har en knapp, tryck på den." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Ägare och administratörer kan hantera alla samlingar och objekt" diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 59eac9b372b..775494830de 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index 3b05ffc9000..73d7289939b 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "ป้อนรหัสยืนยัน 6 หลักจากคุณแอป authenticator" - }, - "enterVerificationCodeEmail": { - "message": "ป้อนรหัสยืนยัน 6 หลักที่ส่งทางอีเมล $EMAIL$", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "ส่งรหัสยืนยันไปยังอีเมล $EMAIL$ แล้ว", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "จำการเข้าระบบของฉันไว้" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "ส่งรหัสยืนยันไปยังอีเมลอีกครั้ง" - }, - "useAnotherTwoStepMethod": { - "message": "ใช้วิธีลงชื่อเข้าใช้แบบสองขั้นตอนวิธีอื่น" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Owners and admins can manage all collections and items" diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index ef8701ce4b1..a9b1aaa5edf 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Kimlik doğrulama uygulamanızdaki 6 haneli doğrulama kodunu girin." - }, - "enterVerificationCodeEmail": { - "message": "$EMAIL$ adresine e-postayla gönderdiğimiz 6 haneli doğrulama kodunu girin.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Doğrulama e-postası $EMAIL$ adresine gönderildi.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Beni hatırla" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Doğrulama kodu e-postasını yeniden gönder" - }, - "useAnotherTwoStepMethod": { - "message": "Başka bir iki aşamalı giriş yöntemini kullan" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "YubiKey'inizi bilgisayarınızın USB portuna takın, ardından düğmesine dokunun." - }, "insertU2f": { "message": "Güvenlik anahtarınızı bilgisayarınızın USB portuna takın. Düğmesi varsa dokunun." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Duo'yu başlatın ve oturum açmayı tamamlamak için adımları izleyin." - }, "duoRequiredByOrgForAccount": { "message": "Hesabınız için Duo iki adımlı giriş gereklidir." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Koleksiyon silmeyi sahipler ve yöneticilerle sınırlandırın" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Sahipler ve yöneticiler tüm koleksiyonları ve öğeleri yönetebilir" diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index e175fe99db8..acd79b5dc26 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Введіть 6-значний код підтвердження з програми автентифікації." - }, - "enterVerificationCodeEmail": { - "message": "Введіть 6-значний код підтвердження, надісланий на $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Код підтвердження надіслано на $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Запам'ятати мене" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Більше не запитувати на цьому пристрої протягом 30 днів" }, - "sendVerificationCodeEmailAgain": { - "message": "Надіслати код підтвердження ще раз" - }, - "useAnotherTwoStepMethod": { - "message": "Інший спосіб двоетапної перевірки" - }, "selectAnotherMethod": { "message": "Обрати інший спосіб", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Скористайтеся своїм кодом відновлення" }, - "insertYubiKey": { - "message": "Вставте свій YubiKey в USB порт комп'ютера, потім торкніться цієї кнопки." - }, "insertU2f": { "message": "Вставте свій ключ безпеки в USB порт комп'ютера. Якщо в нього є кнопка, натисніть її." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Помилка під'єднання до служби Duo. Скористайтеся іншим способом двоетапної перевірки або зверніться до служби підтримки Duo по допомогу." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Запустіть Duo і виконайте дії для завершення входу." - }, "duoRequiredByOrgForAccount": { "message": "Для вашого облікового запису необхідна двоетапна перевірка з Duo." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Дозволити видалення збірок лише власникам та адміністраторам" }, - "limitItemDeletionDesc": { - "message": "Обмежити видалення записів для учасників, які мають дозвіл \"Може керувати\"" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Власники та адміністратори можуть керувати всіма збірками та записами" diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index f7e8f9f4037..1acf336af1d 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Nhập mã xác thực 6 chữ số từ ứng dụng xác thực của bạn." - }, - "enterVerificationCodeEmail": { - "message": "Nhập mã xác thực 6 chữ số được gửi tới $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Email xác thực đã được gửi tới $EMAIL$.", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "Ghi nhớ đăng nhập" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Gửi lại email xác minh" - }, - "useAnotherTwoStepMethod": { - "message": "Dùng phương pháp xác mnih hai bước khác" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Cắm YubiKey vào cổng USB trên máy tính bạn và bấm nút trên Yubikey." - }, "insertU2f": { "message": "Cắm khóa bảo mật vào cổng USB trên máy tính bạn và bấm nút trên khóa, nếu có." }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Chủ sở hữu và quản trị viên có thể quản lý tất cả các bộ sưu tập và mục" diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 6bb79aa1971..747db745bb5 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -460,7 +460,7 @@ "message": "未分配" }, "noneFolder": { - "message": "默认文件夹", + "message": "无文件夹", "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { @@ -1124,7 +1124,7 @@ "message": "已用于加密" }, "loginWithPasskeyEnabled": { - "message": "通行密钥登录已开启" + "message": "通行密钥登录已启用" }, "passkeySaved": { "message": "$NAME$ 已保存", @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "请输入您的验证器 App 中的 6 位数验证码。" - }, - "enterVerificationCodeEmail": { - "message": "请输入发送给 $EMAIL$ 的 6 位数验证码。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "验证邮件已发送到 $EMAIL$。", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "记住我" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "30 天内在此设备上不再询问" }, - "sendVerificationCodeEmailAgain": { - "message": "再次发送验证码电子邮件" - }, - "useAnotherTwoStepMethod": { - "message": "使用其他两步登录方式" - }, "selectAnotherMethod": { "message": "选择其他方式", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "使用您的恢复代码" }, - "insertYubiKey": { - "message": "将您的 YubiKey 插入计算机的 USB 端口,然后触摸其按钮。" - }, "insertU2f": { "message": "将您的安全密钥插入计算机的 USB 端口。如果它有按钮,请触摸它。" }, @@ -1497,7 +1473,7 @@ "message": "选择两步登录方式" }, "recoveryCodeDesc": { - "message": "失去对您所有的双重身份验证设备的访问?请使用您的恢复代码来关闭您账户中所有的两步登录提供程序。" + "message": "无法访问您所有的两步登录提供程序吗?请使用您的恢复代码来停用您账户中所有的两步登录提供程序。" }, "recoveryCodeTitle": { "message": "恢复代码" @@ -1894,19 +1870,19 @@ "message": "新设备登录" }, "turnOffNewDeviceLoginProtection": { - "message": "关闭新设备登录保护" + "message": "停用新设备登录保护" }, "turnOnNewDeviceLoginProtection": { - "message": "开启新设备登录保护" + "message": "启用新设备登录保护" }, "turnOffNewDeviceLoginProtectionModalDesc": { - "message": "继续下面的操作以关闭 Bitwarden 在您从新设备登录时发送验证电子邮件的功能。" + "message": "继续下面的操作以停用 Bitwarden 在您从新设备登录时发送验证电子邮件的功能。" }, "turnOnNewDeviceLoginProtectionModalDesc": { - "message": "继续下面的操作以开启 Bitwarden 在您从新设备登录时发送验证电子邮件的功能。" + "message": "继续下面的操作以启用 Bitwarden 在您从新设备登录时发送验证电子邮件的功能。" }, "turnOffNewDeviceLoginProtectionWarning": { - "message": "关闭新设备登录保护后,任何拥有您的主密码的人都可以从任何设备访问您的账户。要在没有验证电子邮件的情况下保护您的账户,请设置两步登录。" + "message": "停用新设备登录保护后,任何拥有您的主密码的人都可以从任何设备访问您的账户。要在没有验证电子邮件的情况下保护您的账户,请设置两步登录。" }, "accountNewDeviceLoginProtectionSaved": { "message": "新设备登录保护更改已保存" @@ -2175,7 +2151,7 @@ "message": "启用两步登录可能会将您永久锁定在 Bitwarden 账户之外。当您无法使用常规的两步登录提供程序(例如您丢失了设备)时,可以使用恢复代码访问您的账户。如果您失去对您账户的访问,Bitwarden 支持也无法帮助您。我们建议您写下或打印恢复代码,并将其妥善保管。" }, "yourSingleUseRecoveryCode": { - "message": "当您无法访问两步登录提供程序时,您的一次性恢复代码可用于关闭两步登录。Bitwarden 建议您写下恢复代码,并将其妥善保管。" + "message": "当您无法访问两步登录提供程序时,您的一次性恢复代码可用于停用两步登录。Bitwarden 建议您写下恢复代码,并将其妥善保管。" }, "viewRecoveryCode": { "message": "查看恢复代码" @@ -2185,10 +2161,10 @@ "description": "Two-step login providers such as YubiKey, Duo, Authenticator apps, Email, etc." }, "enable": { - "message": "开启" + "message": "启用" }, "enabled": { - "message": "已开启" + "message": "已启用" }, "restoreAccess": { "message": "恢复访问权限" @@ -2231,7 +2207,7 @@ "message": "编辑项目,隐藏密码" }, "disable": { - "message": "关闭" + "message": "停用" }, "revokeAccess": { "message": "撤销访问权限" @@ -2291,10 +2267,10 @@ "message": "如果您要把它添加到其他设备,下面是您的验证器 App 所需要的二维码(或密钥)。" }, "twoStepDisableDesc": { - "message": "确定要关闭此两步登录提供程序吗?" + "message": "确定要停用此两步登录提供程序吗?" }, "twoStepDisabled": { - "message": "两步登录提供程序已关闭。" + "message": "两步登录提供程序已停用。" }, "twoFactorYubikeyAdd": { "message": "添加一个新的 YubiKey 到您的账户" @@ -2417,7 +2393,7 @@ "message": "由于平台限制,FIDO U2F 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 FIDO U2F 时可以访问您的账户。支持的平台:" }, "twoFactorU2fSupportWeb": { - "message": "桌面/笔记本电脑上支持 U2F 的浏览器(开启了 FIDO U2F 的 Chrome、Opera、Vivaldi 或 Firefox)中的网页密码库和浏览器扩展。" + "message": "桌面/笔记本电脑上支持 U2F 的浏览器(启用了 FIDO U2F 的 Chrome、Opera、Vivaldi 或 Firefox)中的网页密码库和浏览器扩展。" }, "twoFactorU2fWaiting": { "message": "等待您触摸安全密钥上的按钮" @@ -2936,7 +2912,7 @@ "message": "付款方式" }, "noPaymentMethod": { - "message": "无付款方式" + "message": "无付款方式。" }, "addPaymentMethod": { "message": "添加付款方式" @@ -3495,7 +3471,7 @@ "message": "两步登录已保存" }, "disabled2fa": { - "message": "两步登录已关闭" + "message": "两步登录已停用" }, "recovered2fa": { "message": "从两步登录中恢复了账户。" @@ -4194,16 +4170,16 @@ "message": "记住电子邮箱" }, "recoverAccountTwoStepDesc": { - "message": "如果您无法通过常规的两步登录方式访问您的账户,您可以使用两步登录恢复代码来关闭账户上的所有两步登录提供程序。" + "message": "如果您无法通过常规的两步登录方式访问您的账户,您可以使用两步登录恢复代码来停用账户上的所有两步登录提供程序。" }, "logInBelowUsingYourSingleUseRecoveryCode": { - "message": "在下方使用您的一次性恢复代码登录。这将关闭您账户上的所有两步提供程序。" + "message": "在下方使用您的一次性恢复代码登录。这将停用您账户上的所有两步提供程序。" }, "recoverAccountTwoStep": { "message": "恢复账户两步登录" }, "twoStepRecoverDisabled": { - "message": "两步登录已在您的账户中关闭。" + "message": "两步登录已在您的账户中停用。" }, "learnMore": { "message": "进一步了解" @@ -4832,7 +4808,7 @@ "message": "非所有者或管理员并且其账户未启用两步登录的组织成员将从组织中移除,并将收到一封关于此更改的电子邮件通知。" }, "twoStepLoginPolicyUserWarning": { - "message": "您是组织的成员,该组织要求在您的用户账户上设置两步登录。如果您关闭所有两步登录提供程序,您将被自动从这些组织中移除。" + "message": "您是组织的成员,该组织要求在您的用户账户上设置两步登录。如果您停用所有两步登录提供程序,您将被自动从这些组织中移除。" }, "passwordGeneratorPolicyDesc": { "message": "设置密码生成器要求。" @@ -5094,7 +5070,7 @@ "message": "先决条件" }, "requireSsoPolicyReq": { - "message": "必须先开启「单一组织」企业策略,然后才能激活此策略。" + "message": "必须先启用「单一组织」企业策略,然后才能激活此策略。" }, "requireSsoPolicyReqError": { "message": "单一组织策略未启用。" @@ -5523,7 +5499,7 @@ "message": "管理账户恢复" }, "disableRequiredError": { - "message": "您必须先手动切换 $POLICYNAME$ 策略,然后才能关闭此策略。", + "message": "您必须先手动切换 $POLICYNAME$ 策略,然后才能停用此策略。", "placeholders": { "policyName": { "content": "$1", @@ -5803,10 +5779,10 @@ "message": "基于加密方式,当主密码或受信任设备被遗忘或丢失时恢复账户。" }, "accountRecoveryPolicyWarning": { - "message": "对于具有主密码的现有账户,需要成员自行注册后,管理员才可以恢复他们的账户。对于新的成员,自动注册后将开启账户恢复功能。" + "message": "对于具有主密码的现有账户,需要成员自行注册后,管理员才可以恢复他们的账户。对于新的成员,自动注册后将启用账户恢复功能。" }, "accountRecoverySingleOrgRequirementDesc": { - "message": "必须先开启「单一组织」企业策略,然后才能激活此策略。" + "message": "必须先启用「单一组织」企业策略,然后才能激活此策略。" }, "resetPasswordPolicyAutoEnroll": { "message": "自动注册" @@ -6318,10 +6294,10 @@ "message": "免费 Bitwarden 家庭" }, "sponsoredFamiliesEligible": { - "message": "您和您的家人有资格享受免费的 Bitwarden 家庭版计划。即使您不在公司上班,您也可以使用个人电子邮箱兑换此计划,以保护您的数据安全。" + "message": "您和您的家人有资格获得免费的 Bitwarden 家庭版计划。使用您的个人电子邮箱兑换,即使您不在工作中,也能确保您的数据安全。" }, "sponsoredFamiliesEligibleCard": { - "message": "立即兑换免费的 Bitwarden 家庭版计划,即使您不在公司上班也能确保您的数据安全。" + "message": "立即兑换免费的 Bitwarden 家庭版计划,即使您不在工作中,也能确保您的数据安全。" }, "sponsoredFamiliesInclude": { "message": "Bitwarden 家庭版计划包含" @@ -6516,7 +6492,7 @@ "message": "「SSO 登录和 Key Connector 解密」已启用。此策略仅适用于所有者和管理员。" }, "enabledSso": { - "message": "SSO 已开启" + "message": "SSO 已启用" }, "disabledSso": { "message": "SSO 已关闭" @@ -7087,7 +7063,7 @@ "message": "设备验证" }, "enableDeviceVerification": { - "message": "开启设备验证" + "message": "启用设备验证" }, "deviceVerificationDesc": { "message": "登录未识别的设备时,验证码会发送到您的电子邮箱地址" @@ -7096,7 +7072,7 @@ "message": "更新了设备验证" }, "areYouSureYouWantToEnableDeviceVerificationTheVerificationCodeEmailsWillArriveAtX": { - "message": "确定要开启设备验证吗?验证码电子邮件将发送到:$EMAIL$", + "message": "确定要启用设备验证吗?验证码电子邮件将发送到:$EMAIL$", "placeholders": { "email": { "content": "$1", @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "与 Duo 服务连接时出错。请使用其他两步登录方式或联系 Duo 寻求帮助。" }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "启动 Duo 然后按照步骤完成登录。" - }, "duoRequiredByOrgForAccount": { "message": "您的账户要求使用 Duo 两步登录。" }, @@ -7268,7 +7241,7 @@ "message": "启动 Duo" }, "turnOn": { - "message": "开启" + "message": "启用" }, "on": { "message": "开启" @@ -8439,7 +8412,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescPart4": { - "message": "策略将在使用此选项时开启。", + "message": "策略将在使用此选项时启用。", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Members will not need a master password when logging in with SSO. Master password is replaced with an encryption key stored on the device, making that device trusted. The first device a member creates their account and logs into will be trusted. New devices will need to be approved by an existing trusted device or by an administrator. The single organization policy, SSO required policy, and account recovery administration policy will turn on when this option is used.'" }, "orgPermissionsUpdatedMustSetPassword": { @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "限制为所有者和管理员可以删除集合" }, - "limitItemDeletionDesc": { - "message": "限制为拥有「可以管理」权限的成员可以删除项目" + "limitItemDeletionDescription": { + "message": "限制为具有「管理集合」权限的成员可以删项目" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "所有者和管理员可以管理所有集合和项目" @@ -9305,14 +9278,14 @@ "message": "SDK" }, "sdksDesc": { - "message": "使用以下编程语言中的 Bitwarden 机密管理器 SDK 来构建您自己的应用程序。" + "message": "在以下编程语言中使用 Bitwarden 机密管理器 SDK 来构建您自己的应用程序。" }, "ssoDescStart": { - "message": "配置", + "message": "使用适合您的身份提供程序的实施指南为 Bitwarden 配置", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider." }, "ssoDescEnd": { - "message": "为 Bitwarden(使用您的身份提供程序的实施指南)。", + "message": "。", "description": "This represents the end of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider." }, "userProvisioning": { @@ -9322,30 +9295,30 @@ "message": "SCIM" }, "scimIntegrationDescStart": { - "message": "配置 ", + "message": "使用适合您的身份提供程序的实施指南配置 ", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider" }, "scimIntegrationDescEnd": { - "message": "(跨域身份管理系统)以自动向 Bitwarden 配置用户和群组(使用您的身份提供程序的实施指南)。", + "message": "(跨域身份管理系统)以自动向 Bitwarden 配置用户和群组。", "description": "This represents the end of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider" }, "bwdc": { "message": "Bitwarden Directory Connector" }, "bwdcDesc": { - "message": "使用您的身份提供程序的实施指南配置 Bitwarden Directory Connector 以自动配置用户和群组。" + "message": "使用适合您的身份提供程序的实施指南配置 Bitwarden Directory Connector 以自动配置用户和群组。" }, "eventManagement": { "message": "事件管理" }, "eventManagementDesc": { - "message": "使用适合您平台的实施指南将 Bitwarden 事件日志与您的 SIEM(系统信息和事件管理)系统集成。" + "message": "使用适合您的平台的实施指南将 Bitwarden 事件日志与您的 SIEM(系统信息和事件管理)系统集成。" }, "deviceManagement": { "message": "设备管理" }, "deviceManagementDesc": { - "message": "使用适合您平台的实施指南为 Bitwarden 配置设备管理。" + "message": "使用适合您的平台的实施指南为 Bitwarden 配置设备管理。" }, "deviceIdMissing": { "message": "缺少设备 ID" @@ -10117,7 +10090,7 @@ "message": "自托管" }, "claim-domain-single-org-warning": { - "message": "声明域名将开启单一组织策略。" + "message": "声明域名将启用单一组织策略。" }, "single-org-revoked-user-warning": { "message": "不符合要求的成员将被撤销。管理员可以在他们退出所有其他组织后恢复其成员资格。" @@ -10255,7 +10228,7 @@ "message": "是的,我可以正常访问我的电子邮箱" }, "turnOnTwoStepLogin": { - "message": "开启两步登录" + "message": "启用两步登录" }, "changeAcctEmail": { "message": "更改账户电子邮箱" diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index c23def1464d..d72b53d3aa3 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -1435,18 +1435,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "輸入驗證器應用程式提供的 6 位數驗證碼。" - }, - "enterVerificationCodeEmail": { - "message": "輸入已傳送至 $EMAIL$ 的 6 位數驗證碼。", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "已傳送驗證電子郵件至 $EMAIL$。", "placeholders": { @@ -1456,18 +1444,9 @@ } } }, - "rememberMe": { - "message": "記住我" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "再次傳送​​包含驗證碼的電子郵件" - }, - "useAnotherTwoStepMethod": { - "message": "使用另一種兩步驟登入方法" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1475,9 +1454,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "將您的 YubiKey 插入電腦的 USB 連接埠,然後觸摸其按鈕。" - }, "insertU2f": { "message": "將您的安全鑰匙插入電腦的 USB 連接埠,然後觸摸其按鈕(如有的話)。" }, @@ -7252,9 +7228,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "啟動 Duo 並依照步驟完成登入。" - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, @@ -8735,8 +8708,8 @@ "limitCollectionDeletionDesc": { "message": "Limit collection deletion to owners and admins" }, - "limitItemDeletionDesc": { - "message": "Limit item deletion to members with the Can manage permission" + "limitItemDeletionDescription": { + "message": "Limit item deletion to members with the Manage collection permissions" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "擁有人與管理員可以管理所有分類與項目" From a42868a76d4272f9b1f97c84de87cb4342006499 Mon Sep 17 00:00:00 2001 From: Colton Hurst Date: Fri, 4 Apr 2025 10:10:18 -0400 Subject: [PATCH 04/93] [PM-19253] Add Experimental WebAuthN Functions (#13860) * PM-9126: Initial scaffolding for com object registration * PM-9126: Clean Up PACOMObject trait and impl * PM-9126: Add unsafe tests * PM-9126: Clean up registration PR with a working CoRegisterClassObject call * PM-9126: Add AddAuthenticator fn call * PM-9126: Load AddAuthenticator fn call dynamically * PM-9126: Add AddAuthenticator experiments * PR-9126: add brackets around guids * PM-9126: clean up part 1 * PM-9126: Cleanup changes * Only call the register function if on Windows * PM-9126: Block two generated types that create issues for the i686-pc-windows-msvc target * PM-9126: Refine bindings file * PM-19253: Add experimental WebAuthN functions * PM-9126: Address PR comments part 1 * PM-9126: Address PR comments part 2 * PM-9126: Return result in napi layer * PM-9126: Propogate error from add authenticator call * PM-9126: Change for version update --- .../desktop/desktop_native/windows_plugin_authenticator/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/desktop/desktop_native/windows_plugin_authenticator/build.rs b/apps/desktop/desktop_native/windows_plugin_authenticator/build.rs index 022004c7bd1..4843145bac0 100644 --- a/apps/desktop/desktop_native/windows_plugin_authenticator/build.rs +++ b/apps/desktop/desktop_native/windows_plugin_authenticator/build.rs @@ -13,6 +13,7 @@ fn windows() { .allowlist_type("DWORD") .allowlist_type("PBYTE") .allowlist_type("EXPERIMENTAL.*") + .allowlist_function(".*EXPERIMENTAL.*") .allowlist_function("WebAuthNGetApiVersionNumber") .generate() .expect("Unable to generate bindings."); From 3a4f3424717b321a6b9131fff084952908bf4717 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:16:28 -0400 Subject: [PATCH 05/93] Updated workflows to correctly trigger on pull_request_target (#14115) --- .github/workflows/build-browser-target.yml | 2 +- .github/workflows/build-cli-target.yml | 2 +- .github/workflows/build-desktop-target.yml | 2 +- .github/workflows/build-web-target.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-browser-target.yml b/.github/workflows/build-browser-target.yml index b2e90605d60..6f05cb71934 100644 --- a/.github/workflows/build-browser-target.yml +++ b/.github/workflows/build-browser-target.yml @@ -7,7 +7,7 @@ name: Build Browser on PR Target on: - pull_request: + pull_request_target: types: [opened, synchronize] branches-ignore: - 'l10n_master' diff --git a/.github/workflows/build-cli-target.yml b/.github/workflows/build-cli-target.yml index 589b0cc1667..f817046ff30 100644 --- a/.github/workflows/build-cli-target.yml +++ b/.github/workflows/build-cli-target.yml @@ -7,7 +7,7 @@ name: Build CLI on PR Target on: - pull_request: + pull_request_target: types: [opened, synchronize] branches-ignore: - 'l10n_master' diff --git a/.github/workflows/build-desktop-target.yml b/.github/workflows/build-desktop-target.yml index 42ca2be1370..65772223722 100644 --- a/.github/workflows/build-desktop-target.yml +++ b/.github/workflows/build-desktop-target.yml @@ -8,7 +8,7 @@ name: Build Desktop on PR Target on: - pull_request: + pull_request_target: types: [opened, synchronize] branches-ignore: - 'l10n_master' diff --git a/.github/workflows/build-web-target.yml b/.github/workflows/build-web-target.yml index 390b3c1c578..8f06d066d34 100644 --- a/.github/workflows/build-web-target.yml +++ b/.github/workflows/build-web-target.yml @@ -7,7 +7,7 @@ name: Build Web on PR Target on: - pull_request: + pull_request_target: types: [opened, synchronize] branches-ignore: - 'l10n_master' From 263598d9e0d1298c2885390029f8ddca2e5397f5 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Fri, 4 Apr 2025 10:52:18 -0400 Subject: [PATCH 06/93] [PM-18790] browser intro carousel component (#14097) * build intro carousel for browser to show for new installations --- apps/browser/src/_locales/en/messages.json | 27 ++++++++++ apps/browser/src/popup/app-routing.module.ts | 19 ++++++- .../vault/guards/intro-carousel.guard.spec.ts | 54 +++++++++++++++++++ .../src/vault/guards/intro-carousel.guard.ts | 26 +++++++++ .../intro-carousel.component.html | 49 +++++++++++++++++ .../intro-carousel.component.ts | 45 ++++++++++++++++ .../components/vault-v2/vault-v2.component.ts | 10 ++++ .../popup/services/intro-carousel.service.ts | 34 ++++++++++++ .../src/platform/state/state-definitions.ts | 4 ++ .../carousel-slide.component.html | 2 +- .../carousel-slide.component.ts | 13 ++++- libs/vault/src/icons/index.ts | 4 ++ libs/vault/src/icons/login-cards.ts | 11 ++++ libs/vault/src/icons/secure-devices.ts | 16 ++++++ libs/vault/src/icons/secure-user.ts | 10 ++++ libs/vault/src/icons/security-handshake.ts | 12 +++++ 16 files changed, 333 insertions(+), 3 deletions(-) create mode 100644 apps/browser/src/vault/guards/intro-carousel.guard.spec.ts create mode 100644 apps/browser/src/vault/guards/intro-carousel.guard.ts create mode 100644 apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.html create mode 100644 apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts create mode 100644 apps/browser/src/vault/popup/services/intro-carousel.service.ts create mode 100644 libs/vault/src/icons/login-cards.ts create mode 100644 libs/vault/src/icons/secure-devices.ts create mode 100644 libs/vault/src/icons/secure-user.ts create mode 100644 libs/vault/src/icons/security-handshake.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 8c47db0d331..54024b83f98 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 9948b450e17..8ebf6eb6110 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -79,10 +79,12 @@ import { ImportBrowserV2Component } from "../tools/popup/settings/import/import- import { SettingsV2Component } from "../tools/popup/settings/settings-v2.component"; import { canAccessAtRiskPasswords } from "../vault/guards/at-risk-passwords.guard"; import { clearVaultStateGuard } from "../vault/guards/clear-vault-state.guard"; +import { IntroCarouselGuard } from "../vault/guards/intro-carousel.guard"; import { AtRiskPasswordsComponent } from "../vault/popup/components/at-risk-passwords/at-risk-passwords.component"; import { AddEditV2Component } from "../vault/popup/components/vault-v2/add-edit/add-edit-v2.component"; import { AssignCollections } from "../vault/popup/components/vault-v2/assign-collections/assign-collections.component"; import { AttachmentsV2Component } from "../vault/popup/components/vault-v2/attachments/attachments-v2.component"; +import { IntroCarouselComponent } from "../vault/popup/components/vault-v2/intro-carousel/intro-carousel.component"; import { PasswordHistoryV2Component } from "../vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component"; import { VaultV2Component } from "../vault/popup/components/vault-v2/vault-v2.component"; import { ViewV2Component } from "../vault/popup/components/vault-v2/view-v2/view-v2.component"; @@ -383,7 +385,7 @@ const routes: Routes = [ }, { path: "login", - canActivate: [unauthGuardFn(unauthRouteOverrides)], + canActivate: [unauthGuardFn(unauthRouteOverrides), IntroCarouselGuard], data: { pageIcon: VaultIcon, pageTitle: { @@ -587,6 +589,21 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 2 } satisfies RouteDataProperties, }, + { + path: "intro-carousel", + component: ExtensionAnonLayoutWrapperComponent, + canActivate: [], + children: [ + { + path: "", + component: IntroCarouselComponent, + data: { + hideIcon: true, + hideFooter: true, + }, + }, + ], + }, { path: "new-device-notice", component: ExtensionAnonLayoutWrapperComponent, diff --git a/apps/browser/src/vault/guards/intro-carousel.guard.spec.ts b/apps/browser/src/vault/guards/intro-carousel.guard.spec.ts new file mode 100644 index 00000000000..c9ed994729a --- /dev/null +++ b/apps/browser/src/vault/guards/intro-carousel.guard.spec.ts @@ -0,0 +1,54 @@ +import { TestBed } from "@angular/core/testing"; +import { Router } from "@angular/router"; +import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; + +import { IntroCarouselService } from "../popup/services/intro-carousel.service"; + +import { IntroCarouselGuard } from "./intro-carousel.guard"; + +describe("IntroCarouselGuard", () => { + let mockConfigService: MockProxy; + const mockIntroCarouselService = { + introCarouselState$: of(true), + }; + const createUrlTree = jest.fn(); + + beforeEach(() => { + mockConfigService = mock(); + createUrlTree.mockClear(); + + TestBed.configureTestingModule({ + providers: [ + { provide: Router, useValue: { createUrlTree } }, + { provide: ConfigService, useValue: mockConfigService }, + { + provide: IntroCarouselService, + useValue: mockIntroCarouselService, + }, + ], + }); + }); + + it("should return true if the feature flag is off", async () => { + mockConfigService.getFeatureFlag.mockResolvedValue(false); + const result = await TestBed.runInInjectionContext(async () => await IntroCarouselGuard()); + expect(result).toBe(true); + }); + it("should navigate to intro-carousel route if feature flag is true and dismissed is true", async () => { + mockConfigService.getFeatureFlag.mockResolvedValue(true); + const result = await TestBed.runInInjectionContext(async () => await IntroCarouselGuard()); + expect(result).toBe(true); + }); + + it("should navigate to intro-carousel route if feature flag is true and dismissed is false", async () => { + TestBed.overrideProvider(IntroCarouselService, { + useValue: { introCarouselState$: of(false) }, + }); + mockConfigService.getFeatureFlag.mockResolvedValue(true); + await TestBed.runInInjectionContext(async () => await IntroCarouselGuard()); + expect(createUrlTree).toHaveBeenCalledWith(["/intro-carousel"]); + }); +}); diff --git a/apps/browser/src/vault/guards/intro-carousel.guard.ts b/apps/browser/src/vault/guards/intro-carousel.guard.ts new file mode 100644 index 00000000000..f101f65c0e7 --- /dev/null +++ b/apps/browser/src/vault/guards/intro-carousel.guard.ts @@ -0,0 +1,26 @@ +import { inject } from "@angular/core"; +import { Router } from "@angular/router"; +import { firstValueFrom } from "rxjs"; + +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; + +import { IntroCarouselService } from "../popup/services/intro-carousel.service"; + +export const IntroCarouselGuard = async () => { + const router = inject(Router); + const configService = inject(ConfigService); + const introCarouselService = inject(IntroCarouselService); + + const hasOnboardingNudgesFlag = await configService.getFeatureFlag( + FeatureFlag.PM8851_BrowserOnboardingNudge, + ); + + const hasIntroCarouselDismissed = await firstValueFrom(introCarouselService.introCarouselState$); + + if (!hasOnboardingNudgesFlag || hasIntroCarouselDismissed) { + return true; + } + + return router.createUrlTree(["/intro-carousel"]); +}; diff --git a/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.html b/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.html new file mode 100644 index 00000000000..3c061109945 --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.html @@ -0,0 +1,49 @@ + + +
+ +

{{ "securityPrioritized" | i18n }}

+

{{ "securityPrioritizedBody" | i18n }}

+
+
+ +
+ +

{{ "quickLogin" | i18n }}

+

{{ "quickLoginBody" | i18n }}

+
+
+ +
+ +

{{ "secureUser" | i18n }}

+

{{ "secureUserBody" | i18n }}

+
+
+ +
+ +

{{ "secureDevices" | i18n }}

+

{{ "secureDevicesBody" | i18n }}

+
+
+
+ + + diff --git a/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts b/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts new file mode 100644 index 00000000000..96e1a70306e --- /dev/null +++ b/apps/browser/src/vault/popup/components/vault-v2/intro-carousel/intro-carousel.component.ts @@ -0,0 +1,45 @@ +import { Component } from "@angular/core"; +import { Router } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule, DialogModule, IconModule, TypographyModule } from "@bitwarden/components"; +import { I18nPipe } from "@bitwarden/ui-common"; +import { VaultCarouselModule, VaultIcons } from "@bitwarden/vault"; + +import { IntroCarouselService } from "../../../services/intro-carousel.service"; + +@Component({ + selector: "app-intro-carousel", + templateUrl: "./intro-carousel.component.html", + imports: [ + VaultCarouselModule, + ButtonModule, + IconModule, + DialogModule, + TypographyModule, + JslibModule, + I18nPipe, + ], + standalone: true, +}) +export class IntroCarouselComponent { + protected securityHandshake = VaultIcons.SecurityHandshake; + protected loginCards = VaultIcons.LoginCards; + protected secureUser = VaultIcons.SecureUser; + protected secureDevices = VaultIcons.SecureDevices; + + constructor( + private router: Router, + private introCarouselService: IntroCarouselService, + ) {} + + protected async navigateToSignup() { + await this.introCarouselService.setIntroCarouselDismissed(); + await this.router.navigate(["/signup"]); + } + + protected async navigateToLogin() { + await this.introCarouselService.setIntroCarouselDismissed(); + await this.router.navigate(["/login"]); + } +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index f8bbb930f72..7f5242dcf18 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -18,6 +18,7 @@ import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -28,6 +29,7 @@ import { CurrentAccountComponent } from "../../../../auth/popup/account-switchin import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component"; import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component"; +import { IntroCarouselService } from "../../services/intro-carousel.service"; import { VaultPopupCopyButtonsService } from "../../services/vault-popup-copy-buttons.service"; import { VaultPopupItemsService } from "../../services/vault-popup-items.service"; import { VaultPopupListFiltersService } from "../../services/vault-popup-list-filters.service"; @@ -128,6 +130,8 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { private cipherService: CipherService, private dialogService: DialogService, private vaultCopyButtonsService: VaultPopupCopyButtonsService, + private introCarouselService: IntroCarouselService, + private configService: ConfigService, ) { combineLatest([ this.vaultPopupItemsService.emptyVault$, @@ -165,6 +169,12 @@ export class VaultV2Component implements OnInit, AfterViewInit, OnDestroy { } async ngOnInit() { + const hasVaultNudgeFlag = await this.configService.getFeatureFlag( + FeatureFlag.PM8851_BrowserOnboardingNudge, + ); + if (hasVaultNudgeFlag) { + await this.introCarouselService.setIntroCarouselDismissed(); + } const activeUserId = await firstValueFrom(this.accountService.activeAccount$.pipe(getUserId)); this.cipherService diff --git a/apps/browser/src/vault/popup/services/intro-carousel.service.ts b/apps/browser/src/vault/popup/services/intro-carousel.service.ts new file mode 100644 index 00000000000..2c523c5a93c --- /dev/null +++ b/apps/browser/src/vault/popup/services/intro-carousel.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from "@angular/core"; +import { map, Observable } from "rxjs"; + +import { + GlobalState, + KeyDefinition, + StateProvider, + VAULT_BROWSER_INTRO_CAROUSEL, +} from "@bitwarden/common/platform/state"; + +const INTRO_CAROUSEL = new KeyDefinition( + VAULT_BROWSER_INTRO_CAROUSEL, + "introCarouselDismissed", + { + deserializer: (dismissed) => dismissed, + }, +); + +@Injectable({ + providedIn: "root", +}) +export class IntroCarouselService { + private introCarouselState: GlobalState = this.stateProvider.getGlobal(INTRO_CAROUSEL); + + readonly introCarouselState$: Observable = this.introCarouselState.state$.pipe( + map((x) => x ?? false), + ); + + constructor(private stateProvider: StateProvider) {} + + async setIntroCarouselDismissed(): Promise { + await this.introCarouselState.update(() => true); + } +} diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index 26e324b73c2..70e0c3998dd 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -207,3 +207,7 @@ export const SECURITY_TASKS_DISK = new StateDefinition("securityTasks", "disk"); export const AT_RISK_PASSWORDS_PAGE_DISK = new StateDefinition("atRiskPasswordsPage", "disk"); export const NOTIFICATION_DISK = new StateDefinition("notifications", "disk"); export const VAULT_NUDGES_DISK = new StateDefinition("vaultNudges", "disk"); +export const VAULT_BROWSER_INTRO_CAROUSEL = new StateDefinition( + "vaultBrowserIntroCarousel", + "disk", +); diff --git a/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.html b/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.html index 0c5c6f1cd70..c058b7924f8 100644 --- a/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.html +++ b/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.html @@ -1,7 +1,7 @@
diff --git a/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.ts b/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.ts index 23ce6a3d7db..a516914f0c0 100644 --- a/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.ts +++ b/libs/vault/src/components/carousel/carousel-slide/carousel-slide.component.ts @@ -1,15 +1,26 @@ import { coerceBooleanProperty } from "@angular/cdk/coercion"; import { TemplatePortal } from "@angular/cdk/portal"; -import { Component, Input, OnInit, TemplateRef, ViewChild, ViewContainerRef } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { + booleanAttribute, + Component, + Input, + OnInit, + TemplateRef, + ViewChild, + ViewContainerRef, +} from "@angular/core"; @Component({ selector: "vault-carousel-slide", templateUrl: "./carousel-slide.component.html", standalone: true, + imports: [CommonModule], }) export class VaultCarouselSlideComponent implements OnInit { /** `aria-label` that is assigned to the carousel toggle. */ @Input({ required: true }) label!: string; + @Input({ transform: booleanAttribute }) disablePadding = false; /** * Should be set to true when the slide has no focusable elements. diff --git a/libs/vault/src/icons/index.ts b/libs/vault/src/icons/index.ts index e0be5e637f0..7a412cf050f 100644 --- a/libs/vault/src/icons/index.ts +++ b/libs/vault/src/icons/index.ts @@ -6,3 +6,7 @@ export * from "./exclamation-triangle"; export * from "./user-lock"; export * from "./browser-extension"; export * from "./bitwarden-icon"; +export * from "./security-handshake"; +export * from "./login-cards"; +export * from "./secure-user"; +export * from "./secure-devices"; diff --git a/libs/vault/src/icons/login-cards.ts b/libs/vault/src/icons/login-cards.ts new file mode 100644 index 00000000000..01baf308412 --- /dev/null +++ b/libs/vault/src/icons/login-cards.ts @@ -0,0 +1,11 @@ +import { svgIcon } from "@bitwarden/components"; + +export const LoginCards = svgIcon` + + + + + + + +`; diff --git a/libs/vault/src/icons/secure-devices.ts b/libs/vault/src/icons/secure-devices.ts new file mode 100644 index 00000000000..ee3a6ea6b90 --- /dev/null +++ b/libs/vault/src/icons/secure-devices.ts @@ -0,0 +1,16 @@ +import { svgIcon } from "@bitwarden/components"; + +export const SecureDevices = svgIcon` + + + + + + + + + + + + +`; diff --git a/libs/vault/src/icons/secure-user.ts b/libs/vault/src/icons/secure-user.ts new file mode 100644 index 00000000000..f8f126adbac --- /dev/null +++ b/libs/vault/src/icons/secure-user.ts @@ -0,0 +1,10 @@ +import { svgIcon } from "@bitwarden/components"; + +export const SecureUser = svgIcon` + + + + + + +`; diff --git a/libs/vault/src/icons/security-handshake.ts b/libs/vault/src/icons/security-handshake.ts new file mode 100644 index 00000000000..5a598fd180d --- /dev/null +++ b/libs/vault/src/icons/security-handshake.ts @@ -0,0 +1,12 @@ +import { svgIcon } from "@bitwarden/components"; + +export const SecurityHandshake = svgIcon` + + + + + + + + +`; From 576e438dbdf57470d7eca880897284d91aeec660 Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Fri, 4 Apr 2025 10:42:07 -0500 Subject: [PATCH 07/93] [PM-18918] Navigate directly to at risk passwords page (#14044) * refactor `openPopup` vault message to `OpenAtRiskPasswords` * navigate directly to the at risk passwords page * ensure the at-risk-passwords page navigates back to the vault * reset popup index page * avoid setting `hasNavigated` for the initial route * Revert "avoid setting `hasNavigated` for the initial route" This reverts commit 68bd9268ae4d141f30aaeb4707f8716bfc09914a. * always reset popup page to the index --------- Co-authored-by: Shane Melton --- .../content/content-message-handler.ts | 6 +-- .../browser/src/background/main.background.ts | 20 +++++++++ .../src/background/runtime.background.ts | 44 +++++++++++-------- .../at-risk-passwords.component.html | 7 ++- .../at-risk-passwords.component.ts | 9 ++++ .../browser-extension-prompt.service.spec.ts | 4 +- .../browser-extension-prompt.service.ts | 2 +- .../src/vault/enums/vault-messages.enum.ts | 2 +- 8 files changed, 69 insertions(+), 25 deletions(-) diff --git a/apps/browser/src/autofill/content/content-message-handler.ts b/apps/browser/src/autofill/content/content-message-handler.ts index 55e0c071a55..60f093f8c10 100644 --- a/apps/browser/src/autofill/content/content-message-handler.ts +++ b/apps/browser/src/autofill/content/content-message-handler.ts @@ -17,7 +17,7 @@ const windowMessageHandlers: ContentMessageWindowEventHandlers = { [VaultMessages.checkBwInstalled]: () => handleExtensionInstallCheck(), duoResult: ({ data, referrer }: { data: any; referrer: string }) => handleDuoResultMessage(data, referrer), - [VaultMessages.OpenPopup]: () => handleOpenPopupMessage(), + [VaultMessages.OpenAtRiskPasswords]: () => handleOpenAtRiskPasswordsMessage(), }; /** @@ -73,8 +73,8 @@ function handleWebAuthnResultMessage(data: ContentMessageWindowData, referrer: s sendExtensionRuntimeMessage({ command, data: data.data, remember, referrer }); } -function handleOpenPopupMessage() { - sendExtensionRuntimeMessage({ command: VaultMessages.OpenPopup }); +function handleOpenAtRiskPasswordsMessage() { + sendExtensionRuntimeMessage({ command: VaultMessages.OpenAtRiskPasswords }); } /** diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index dba1235d3a2..ffce7827358 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1620,6 +1620,26 @@ export default class MainBackground { } } + /** Opens the `/at-risk-passwords` page within the popup */ + async openAtRisksPasswordsPage() { + const browserAction = BrowserApi.getBrowserAction(); + + try { + // Set route of the popup before attempting to open it. + // If the vault is locked, this won't have an effect as the auth guards will + // redirect the user to the login page. + await browserAction.setPopup({ popup: "popup/index.html#/at-risk-passwords" }); + + await this.openPopup(); + } finally { + // Reset the popup route to the default route so any subsequent + // popup openings will not open to the at-risk-passwords page. + await browserAction.setPopup({ + popup: "popup/index.html#/", + }); + } + } + async reseedStorage() { if ( !this.platformUtilsService.isChrome() && diff --git a/apps/browser/src/background/runtime.background.ts b/apps/browser/src/background/runtime.background.ts index c1719abbb3a..ec8ff7376e0 100644 --- a/apps/browser/src/background/runtime.background.ts +++ b/apps/browser/src/background/runtime.background.ts @@ -17,6 +17,7 @@ import { devFlagEnabled } from "@bitwarden/common/platform/misc/flags"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { NotificationsService } from "@bitwarden/common/platform/notifications"; import { CipherType } from "@bitwarden/common/vault/enums"; +import { VaultMessages } from "@bitwarden/common/vault/enums/vault-messages.enum"; import { BiometricsCommands } from "@bitwarden/key-management"; import { @@ -289,6 +290,10 @@ export default class RuntimeBackground { case "openPopup": await this.openPopup(); break; + case VaultMessages.OpenAtRiskPasswords: + await this.main.openAtRisksPasswordsPage(); + this.announcePopupOpen(); + break; case "bgUpdateContextMenu": case "editedCipher": case "addedCipher": @@ -418,24 +423,6 @@ export default class RuntimeBackground { private async openPopup() { await this.main.openPopup(); - - const announcePopupOpen = async () => { - const isOpen = await this.platformUtilsService.isViewOpen(); - const tabs = await this.getBwTabs(); - - if (isOpen && tabs.length > 0) { - // Send message to all vault tabs that the extension has opened - for (const tab of tabs) { - await BrowserApi.executeScriptInTab(tab.id, { - file: "content/send-popup-open-message.js", - runAt: "document_end", - }); - } - } - }; - - // Give the popup a buffer to open - setTimeout(announcePopupOpen, 100); } async sendBwInstalledMessageToVault() { @@ -456,4 +443,25 @@ export default class RuntimeBackground { this.logService.error(`Error sending on installed message to vault: ${e}`); } } + + /** Sends a message to each tab that the popup was opened */ + private announcePopupOpen() { + const announceToAllTabs = async () => { + const isOpen = await this.platformUtilsService.isViewOpen(); + const tabs = await this.getBwTabs(); + + if (isOpen && tabs.length > 0) { + // Send message to all vault tabs that the extension has opened + for (const tab of tabs) { + await BrowserApi.executeScriptInTab(tab.id, { + file: "content/send-popup-open-message.js", + runAt: "document_end", + }); + } + } + }; + + // Give the popup a buffer to complete opening + setTimeout(announceToAllTabs, 100); + } } diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html index cd93401c861..87629ce5700 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html @@ -1,5 +1,10 @@ - + diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts index 6711673751c..37c445f6c30 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts @@ -222,4 +222,13 @@ export class AtRiskPasswordsComponent implements OnInit { this.launchingCipher.set(null); } }; + + /** + * This page can be the first page the user sees when the extension launches, + * which can conflict with the `PopupRouterCacheService`. This replaces the + * built-in back button behavior so the user always navigates to the vault. + */ + protected async navigateToVault() { + await this.router.navigate(["/tabs/vault"]); + } } diff --git a/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts b/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts index 3114547df1d..f6f4ec4fdb4 100644 --- a/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts +++ b/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts @@ -68,7 +68,9 @@ describe("BrowserExtensionPromptService", () => { ); expect(window.postMessage).toHaveBeenCalledTimes(2); - expect(window.postMessage).toHaveBeenCalledWith({ command: VaultMessages.OpenPopup }); + expect(window.postMessage).toHaveBeenCalledWith({ + command: VaultMessages.OpenAtRiskPasswords, + }); }); }); diff --git a/apps/web/src/app/vault/services/browser-extension-prompt.service.ts b/apps/web/src/app/vault/services/browser-extension-prompt.service.ts index d59175d4e73..5617d4aef75 100644 --- a/apps/web/src/app/vault/services/browser-extension-prompt.service.ts +++ b/apps/web/src/app/vault/services/browser-extension-prompt.service.ts @@ -55,7 +55,7 @@ export class BrowserExtensionPromptService { /** Post a message to the extension to open */ openExtension(setManualErrorTimeout = false) { - window.postMessage({ command: VaultMessages.OpenPopup }); + window.postMessage({ command: VaultMessages.OpenAtRiskPasswords }); // Optionally, configure timeout to show the manual open error state if // the extension does not open within one second. diff --git a/libs/common/src/vault/enums/vault-messages.enum.ts b/libs/common/src/vault/enums/vault-messages.enum.ts index 4cc038be849..73272564432 100644 --- a/libs/common/src/vault/enums/vault-messages.enum.ts +++ b/libs/common/src/vault/enums/vault-messages.enum.ts @@ -1,7 +1,7 @@ const VaultMessages = { HasBwInstalled: "hasBwInstalled", checkBwInstalled: "checkIfBWExtensionInstalled", - OpenPopup: "openPopup", + OpenAtRiskPasswords: "openAtRiskPasswords", PopupOpened: "popupOpened", } as const; From 15db9d61a9cfcaf908d287e8c75adf976432496c Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Fri, 4 Apr 2025 20:38:19 +0200 Subject: [PATCH 08/93] Add Edge (csv) as a import format option (#13971) Co-authored-by: Daniel James Smith --- libs/importer/src/components/import.component.html | 7 ++++++- libs/importer/src/models/import-options.ts | 1 + libs/importer/src/services/import.service.ts | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libs/importer/src/components/import.component.html b/libs/importer/src/components/import.component.html index 072271f8205..23a9afa1111 100644 --- a/libs/importer/src/components/import.component.html +++ b/libs/importer/src/components/import.component.html @@ -165,7 +165,12 @@ --> The process is exactly the same as importing from Google Chrome. diff --git a/libs/importer/src/models/import-options.ts b/libs/importer/src/models/import-options.ts index bd3202067ca..a8c4b4e0a8a 100644 --- a/libs/importer/src/models/import-options.ts +++ b/libs/importer/src/models/import-options.ts @@ -46,6 +46,7 @@ export const regularImportOptions = [ { id: "ascendocsv", name: "Ascendo DataVault (csv)" }, { id: "meldiumcsv", name: "Meldium (csv)" }, { id: "passkeepcsv", name: "PassKeep (csv)" }, + { id: "edgecsv", name: "Edge (csv)" }, { id: "operacsv", name: "Opera (csv)" }, { id: "vivaldicsv", name: "Vivaldi (csv)" }, { id: "gnomejson", name: "GNOME Passwords and Keys/Seahorse (json)" }, diff --git a/libs/importer/src/services/import.service.ts b/libs/importer/src/services/import.service.ts index cc9cdc39320..bd18e78d542 100644 --- a/libs/importer/src/services/import.service.ts +++ b/libs/importer/src/services/import.service.ts @@ -239,6 +239,7 @@ export class ImportService implements ImportServiceAbstraction { return new PadlockCsvImporter(); case "keepass2xml": return new KeePass2XmlImporter(); + case "edgecsv": case "chromecsv": case "operacsv": case "vivaldicsv": From b385dd430ecc2126bea05dc8c165fedff0f9be57 Mon Sep 17 00:00:00 2001 From: Leslie Tilton <23057410+Banrion@users.noreply.github.com> Date: Fri, 4 Apr 2025 13:58:28 -0500 Subject: [PATCH 09/93] [PM-17500] Migrate reports-layout to use tailwind (#14102) * Migrate reports-layout to use tailwind --- apps/web/src/app/tools/reports/reports-layout.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/src/app/tools/reports/reports-layout.component.html b/apps/web/src/app/tools/reports/reports-layout.component.html index e011d47d7aa..283d9213cc7 100644 --- a/apps/web/src/app/tools/reports/reports-layout.component.html +++ b/apps/web/src/app/tools/reports/reports-layout.component.html @@ -1,7 +1,7 @@ -
-
+
+
{{ "backToReports" | i18n }} From 1af8fe2012063894cd29e755f1f3b0eac94cce1c Mon Sep 17 00:00:00 2001 From: Patrick-Pimentel-Bitwarden Date: Fri, 4 Apr 2025 15:44:48 -0400 Subject: [PATCH 10/93] feat(device-approval-persistence): [PM-19380] Device Approval Persistence (#13958) * feat(device-approval-persistence): [PM-19380] Device Approval Persistence - Added lookup on standard auth requests. * fix(device-approval-persistence): [PM-19380] Device Approval Persistence - Fixed issue with null value trying to be parsed from the fromJSON function. --------- Co-authored-by: Todd Martin --- .../local-backed-session-storage.service.ts | 1 - .../abstractions/view-cache.service.ts | 2 +- .../auth_request_login_readme.md | 203 +++++++ .../login-via-auth-request.component.html | 110 ++-- .../login-via-auth-request.component.ts | 564 ++++++++++-------- ...gin-via-auth-request-cache.service.spec.ts | 52 +- ...lt-login-via-auth-request-cache.service.ts | 17 +- .../view/login-via-auth-request.view.ts | 13 +- 8 files changed, 605 insertions(+), 357 deletions(-) create mode 100644 libs/auth/src/angular/login-via-auth-request/auth_request_login_readme.md diff --git a/apps/browser/src/platform/services/local-backed-session-storage.service.ts b/apps/browser/src/platform/services/local-backed-session-storage.service.ts index b030ff46270..0e6922e3083 100644 --- a/apps/browser/src/platform/services/local-backed-session-storage.service.ts +++ b/apps/browser/src/platform/services/local-backed-session-storage.service.ts @@ -90,7 +90,6 @@ export class LocalBackedSessionStorageService this.logService.warning( `Possible unnecessary write to local session storage. Key: ${key}`, ); - this.logService.warning(obj as any); } } catch (err) { this.logService.warning(`Error while comparing values for key: ${key}`); diff --git a/libs/angular/src/platform/abstractions/view-cache.service.ts b/libs/angular/src/platform/abstractions/view-cache.service.ts index 0ee09afb812..a282ef67967 100644 --- a/libs/angular/src/platform/abstractions/view-cache.service.ts +++ b/libs/angular/src/platform/abstractions/view-cache.service.ts @@ -9,7 +9,7 @@ type Deserializer = { * @param jsonValue The JSON object representation of your state. * @returns The fully typed version of your state. */ - readonly deserializer?: (jsonValue: Jsonify) => T; + readonly deserializer?: (jsonValue: Jsonify) => T | null; }; type BaseCacheOptions = { diff --git a/libs/auth/src/angular/login-via-auth-request/auth_request_login_readme.md b/libs/auth/src/angular/login-via-auth-request/auth_request_login_readme.md new file mode 100644 index 00000000000..240316f788c --- /dev/null +++ b/libs/auth/src/angular/login-via-auth-request/auth_request_login_readme.md @@ -0,0 +1,203 @@ +# Authentication Flows Documentation + +## Standard Auth Request Flows + +### Flow 1: Unauthed user requests approval from device; Approving device has a masterKey in memory + +1. Unauthed user clicks "Login with device" +2. Navigates to /login-with-device which creates a StandardAuthRequest +3. Receives approval from a device with authRequestPublicKey(masterKey) +4. Decrypts masterKey +5. Decrypts userKey +6. Proceeds to vault + +### Flow 2: Unauthed user requests approval from device; Approving device does NOT have a masterKey in memory + +1. Unauthed user clicks "Login with device" +2. Navigates to /login-with-device which creates a StandardAuthRequest +3. Receives approval from a device with authRequestPublicKey(userKey) +4. Decrypts userKey +5. Proceeds to vault + +**Note:** This flow is an uncommon scenario and relates to TDE off-boarding. The following describes how a user could +get into this flow: + +1. An SSO TD user logs into a device via an Admin auth request approval, therefore this device does NOT have a masterKey + in memory +2. The org admin: + - Changes the member decryption options from "Trusted devices" to "Master password" AND + - Turns off the "Require single sign-on authentication" policy +3. On another device, the user clicks "Login with device", which they can do because the org no longer requires SSO +4. The user approves from the device they had previously logged into with SSO TD, which does NOT have a masterKey in + memory + +### Flow 3: Authed SSO TD user requests approval from device; Approving device has a masterKey in memory + +1. SSO TD user authenticates via SSO +2. Navigates to /login-initiated +3. Clicks "Approve from your other device" +4. Navigates to /login-with-device which creates a StandardAuthRequest +5. Receives approval from device with authRequestPublicKey(masterKey) +6. Decrypts masterKey +7. Decrypts userKey +8. Establishes trust (if required) +9. Proceeds to vault + +### Flow 4: Authed SSO TD user requests approval from device; Approving device does NOT have a masterKey in memory + +1. SSO TD user authenticates via SSO +2. Navigates to /login-initiated +3. Clicks "Approve from your other device" +4. Navigates to /login-with-device which creates a StandardAuthRequest +5. Receives approval from device with authRequestPublicKey(userKey) +6. Decrypts userKey +7. Establishes trust (if required) +8. Proceeds to vault + +## Admin Auth Request Flow + +### Flow: Authed SSO TD user requests admin approval + +1. SSO TD user authenticates via SSO +2. Navigates to /login-initiated +3. Clicks "Request admin approval" +4. Navigates to /admin-approval-requested which creates an AdminAuthRequest +5. Receives approval from device with authRequestPublicKey(userKey) +6. Decrypts userKey +7. Establishes trust (if required) +8. Proceeds to vault + +**Note:** TDE users are required to be enrolled in admin account recovery, which gives the admin access to the user's +userKey. This is how admins are able to send over the authRequestPublicKey(userKey) to the user to allow them to unlock. + +## Summary Table + +| Flow | Auth Status | Clicks Button [active route] | Navigates to | Approving device has masterKey in memory\* | +| --------------- | ----------- | --------------------------------------------------- | ------------------------- | ------------------------------------------------- | +| Standard Flow 1 | unauthed | "Login with device" [/login] | /login-with-device | yes | +| Standard Flow 2 | unauthed | "Login with device" [/login] | /login-with-device | no | +| Standard Flow 3 | authed | "Approve from your other device" [/login-initiated] | /login-with-device | yes | +| Standard Flow 4 | authed | "Approve from your other device" [/login-initiated] | /login-with-device | no | +| Admin Flow | authed | "Request admin approval" [/login-initiated] | /admin-approval-requested | NA - admin requests always send encrypted userKey | + +**Note:** The phrase "in memory" here is important. It is possible for a user to have a master password for their +account, but not have a masterKey IN MEMORY for a specific device. For example, if a user registers an account with a +master password, then joins an SSO TD org, then logs in to a device via SSO and admin auth request, they are now logged +into that device but that device does not have masterKey IN MEMORY. + +## State Management + +### View Cache + +The component uses `LoginViaAuthRequestCacheService` to manage persistent state across extension close and reopen. +This cache stores: + +- Auth Request ID +- Private Key +- Access Code + +The cache is used to: + +1. Preserve authentication state during extension close +2. Allow resumption of pending auth requests +3. Enable processing of approved requests after extension close and reopen. + +### Component State Variables + +Key state variables maintained during the authentication process: + +#### Authentication Keys + +``` +private authRequestKeyPair: { + publicKey: Uint8Array | undefined; + privateKey: Uint8Array | undefined; +} | undefined +``` + +- Stores the RSA key pair used for secure communication +- Generated during auth request initialization +- Required for decrypting approved auth responses + +#### Access Code + +``` +private accessCode: string | undefined +``` + +- 25-character generated password +- Used for retrieving auth responses when user is not authenticated +- Required for standard auth flows + +#### Authentication Status + +``` +private authStatus: AuthenticationStatus | undefined +``` + +- Tracks whether user is authenticated via SSO +- Determines available flows and API endpoints +- Affects navigation paths (`/login` vs `/login-initiated`) + +#### Flow Control + +``` +protected flow = Flow.StandardAuthRequest +``` + +- Determines current authentication flow (Standard vs Admin) +- Affects UI rendering and request handling +- Set based on route and authentication state + +### State Flow Examples + +#### Standard Auth Request Cache Flow + +1. User initiates login with device +2. Component generates auth request and keys +3. Cache service stores: + ``` + cacheLoginView( + authRequestResponse.id, + authRequestKeyPair.privateKey, + accessCode + ) + ``` +4. On page refresh/revisit: + - Component retrieves cached view + - Reestablishes connection using cached credentials + - Continues monitoring for approval + +#### Admin Auth Request State Flow + +1. User requests admin approval +2. Component stores admin request in `AuthRequestService`: + ``` + setAdminAuthRequest( + new AdminAuthRequestStorable({ + id: authRequestResponse.id, + privateKey: authRequestKeyPair.privateKey + }), + userId + ) + ``` +3. On subsequent visits: + - Component checks for existing admin requests + - Either resumes monitoring or starts new request + - Clears state after successful approval + +### State Cleanup + +State cleanup occurs in several scenarios: + +- Component destruction (`ngOnDestroy`) +- Successful authentication +- Request denial or timeout +- Manual navigation away + +Key cleanup actions: + +1. Hub connection termination +2. Cache clearance +3. Admin request state removal +4. Key pair disposal diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html index d6b91b960b0..38dc874cd0f 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.html @@ -1,57 +1,65 @@ -
- -

- {{ "notificationSentDevicePart1" | i18n }} - {{ "notificationSentDeviceAnchor" | i18n }}. {{ "notificationSentDevicePart2" | i18n }} -

-

- {{ "notificationSentDeviceComplete" | i18n }} -

+ +
+ +
+
-
{{ "fingerprintPhraseHeader" | i18n }}
- {{ fingerprintPhrase }} + +
+ +

+ {{ "notificationSentDevicePart1" | i18n }} + {{ "notificationSentDeviceAnchor" | i18n }}. {{ "notificationSentDevicePart2" | i18n }} +

+

+ {{ "notificationSentDeviceComplete" | i18n }} +

- +
{{ "fingerprintPhraseHeader" | i18n }}
+ {{ fingerprintPhrase }} -
- {{ "needAnotherOptionV1" | i18n }}  - {{ - "viewAllLogInOptions" | i18n - }} -
-
+ - -

{{ "youWillBeNotifiedOnceTheRequestIsApproved" | i18n }}

+
+ {{ "needAnotherOptionV1" | i18n }}  + {{ + "viewAllLogInOptions" | i18n + }} +
+
-
{{ "fingerprintPhraseHeader" | i18n }}
- {{ fingerprintPhrase }} + +

{{ "youWillBeNotifiedOnceTheRequestIsApproved" | i18n }}

-
- {{ "troubleLoggingIn" | i18n }}  - {{ - "viewAllLogInOptions" | i18n - }} -
-
-
+
{{ "fingerprintPhraseHeader" | i18n }}
+ {{ fingerprintPhrase }} + +
+ {{ "troubleLoggingIn" | i18n }}  + {{ + "viewAllLogInOptions" | i18n + }} +
+
+
+ diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts index ea753a3f0c5..8e79bd54f76 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts @@ -62,12 +62,13 @@ const matchOptions: IsActiveMatchOptions = { providers: [{ provide: LoginViaAuthRequestCacheService }], }) export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { - private authRequest: AuthRequest | undefined = undefined; private authRequestKeyPair: | { publicKey: Uint8Array | undefined; privateKey: Uint8Array | undefined } | undefined = undefined; + private accessCode: string | undefined = undefined; private authStatus: AuthenticationStatus | undefined = undefined; private showResendNotificationTimeoutSeconds = 12; + protected loading = true; protected backToRoute = "/login"; protected clientType: ClientType; @@ -110,13 +111,14 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { this.authRequestService.authRequestPushNotification$ .pipe(takeUntilDestroyed()) .subscribe((requestId) => { - this.verifyAndHandleApprovedAuthReq(requestId).catch((e: Error) => { + this.loading = true; + this.handleExistingAuthRequestLogin(requestId).catch((e: Error) => { this.toastService.showToast({ variant: "error", title: this.i18nService.t("error"), message: e.message, }); - + this.loading = false; this.logService.error("Failed to use approved auth request: " + e.message); }); }); @@ -149,24 +151,12 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { } else { await this.initStandardAuthRequestFlow(); } + this.loading = false; } private async initAdminAuthRequestFlow(): Promise { this.flow = Flow.AdminAuthRequest; - // Get email from state for admin auth requests because it is available and also - // prevents it from being lost on refresh as the loginEmailService email does not persist. - this.email = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.email)), - ); - - if (!this.email) { - await this.handleMissingEmail(); - return; - } - - // We only allow a single admin approval request to be active at a time - // so we must check state to see if we have an existing one or not const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; if (!userId) { this.logService.error( @@ -175,12 +165,13 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { return; } - const existingAdminAuthRequest = await this.authRequestService.getAdminAuthRequest(userId); + // [Admin Request Flow State Management] Check cached auth request + const existingAdminAuthRequest = await this.reloadCachedAdminAuthRequest(userId); if (existingAdminAuthRequest) { - await this.handleExistingAdminAuthRequest(existingAdminAuthRequest, userId); + await this.handleExistingAdminAuthRequestLogin(existingAdminAuthRequest, userId); } else { - await this.startAdminAuthRequestLogin(); + await this.handleNewAdminAuthRequestLogin(); } } @@ -194,7 +185,24 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { return; } - await this.startStandardAuthRequestLogin(); + // [Standard Flow State Management] Check cached auth request + const cachedAuthRequest: LoginViaAuthRequestView | null = + this.loginViaAuthRequestCacheService.getCachedLoginViaAuthRequestView(); + + if (cachedAuthRequest) { + this.logService.info("Found cached auth request."); + if (!cachedAuthRequest.id) { + this.logService.error( + "No id on the cached auth request when in the standard auth request flow.", + ); + return; + } + + await this.reloadCachedStandardAuthRequest(cachedAuthRequest); + await this.handleExistingAuthRequestLogin(cachedAuthRequest.id); + } else { + await this.handleNewStandardAuthRequestLogin(); + } } private async handleMissingEmail(): Promise { @@ -212,11 +220,17 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { this.loginViaAuthRequestCacheService.clearCacheLoginView(); } - private async startAdminAuthRequestLogin(): Promise { + private async handleNewAdminAuthRequestLogin(): Promise { try { - await this.buildAuthRequest(AuthRequestType.AdminApproval); + if (!this.email) { + this.logService.error("No email when starting admin auth request login."); + return; + } - if (!this.authRequest) { + // At this point we know there is no + const authRequest = await this.buildAuthRequest(this.email, AuthRequestType.AdminApproval); + + if (!authRequest) { this.logService.error("Auth request failed to build."); return; } @@ -226,9 +240,9 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { return; } - const authRequestResponse = await this.authRequestApiService.postAdminAuthRequest( - this.authRequest as AuthRequest, - ); + const authRequestResponse = + await this.authRequestApiService.postAdminAuthRequest(authRequest); + const adminAuthReqStorable = new AdminAuthRequestStorable({ id: authRequestResponse.id, privateKey: this.authRequestKeyPair.privateKey, @@ -253,104 +267,154 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { } } - protected async startStandardAuthRequestLogin( - clearCachedRequest: boolean = false, + /** + * We only allow a single admin approval request to be active at a time + * so we can check to see if it's stored in state with the state service + * provider. + * @param userId + * @protected + */ + protected async reloadCachedAdminAuthRequest( + userId: UserId, + ): Promise { + // Get email from state for admin auth requests because it is available and also + // prevents it from being lost on refresh as the loginEmailService email does not persist. + this.email = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.email)), + ); + + if (!this.email) { + await this.handleMissingEmail(); + return null; + } + + return await this.authRequestService.getAdminAuthRequest(userId); + } + + /** + * Restores a cached authentication request into the component's state. + * + * This function checks for the presence of a cached authentication request and, + * if available, updates the component's state with the necessary details to + * continue processing the request. It ensures that the user's email and the + * private key from the cached request are available. + * + * The private key is converted from Base64 to an ArrayBuffer, and a fingerprint + * phrase is derived to verify the request's integrity. The function then sets + * the authentication request key pair in the component's state, preparing it + * to handle any responses or approvals. + * + * @param cachedAuthRequest The request to load into the component state + * @returns Promise to await for completion + */ + protected async reloadCachedStandardAuthRequest( + cachedAuthRequest: LoginViaAuthRequestView, ): Promise { + if (cachedAuthRequest) { + if (!this.email) { + this.logService.error( + "Email not defined when trying to reload cached standard auth request.", + ); + return; + } + + if (!cachedAuthRequest.privateKey) { + this.logService.error( + "No private key on the cached auth request when trying to reload cached standard auth request.", + ); + return; + } + + if (!cachedAuthRequest.accessCode) { + this.logService.error( + "No access code on the cached auth request when trying to reload cached standard auth request.", + ); + return; + } + + const privateKey = Utils.fromB64ToArray(cachedAuthRequest.privateKey); + + // Re-derive the user's fingerprint phrase + // It is important to not use the server's public key here as it could have been compromised via MITM + const derivedPublicKeyArrayBuffer = + await this.cryptoFunctionService.rsaExtractPublicKey(privateKey); + + this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase( + this.email, + derivedPublicKeyArrayBuffer, + ); + + // We don't need the public key for handling the authentication request because + // the handleExistingAuthRequestLogin function will receive the public key back + // from the looked up auth request, and all we need is to make sure that + // we can use the cached private key that is associated with it. + this.authRequestKeyPair = { + privateKey: privateKey, + publicKey: undefined, + }; + + this.accessCode = cachedAuthRequest.accessCode; + } + } + + protected async handleNewStandardAuthRequestLogin(): Promise { this.showResendNotification = false; - if (await this.configService.getFeatureFlag(FeatureFlag.PM9112_DeviceApprovalPersistence)) { - // Used for manually refreshing the auth request when clicking the resend auth request - // on the ui. - if (clearCachedRequest) { - this.loginViaAuthRequestCacheService.clearCacheLoginView(); + try { + if (!this.email) { + this.logService.error("Email not defined when starting standard auth request login."); + return; } - try { - const loginAuthRequestView: LoginViaAuthRequestView | null = - this.loginViaAuthRequestCacheService.getCachedLoginViaAuthRequestView(); + const authRequest = await this.buildAuthRequest( + this.email, + AuthRequestType.AuthenticateAndUnlock, + ); - if (!loginAuthRequestView) { - await this.buildAuthRequest(AuthRequestType.AuthenticateAndUnlock); - - // I tried several ways to get the IDE/linter to play nice with checking for null values - // in less code / more efficiently, but it struggles to identify code paths that - // are more complicated than this. - if (!this.authRequest) { - this.logService.error("AuthRequest failed to initialize from buildAuthRequest."); - return; - } - - if (!this.fingerprintPhrase) { - this.logService.error("FingerprintPhrase failed to initialize from buildAuthRequest."); - return; - } - - if (!this.authRequestKeyPair) { - this.logService.error("KeyPair failed to initialize from buildAuthRequest."); - return; - } - - const authRequestResponse: AuthRequestResponse = - await this.authRequestApiService.postAuthRequest(this.authRequest); - - this.loginViaAuthRequestCacheService.cacheLoginView( - this.authRequest, - authRequestResponse, - this.fingerprintPhrase, - this.authRequestKeyPair, - ); - - if (authRequestResponse.id) { - await this.anonymousHubService.createHubConnection(authRequestResponse.id); - } - } else { - // Grab the cached information and store it back in component state. - // We don't need the public key for handling the authentication request because - // the verifyAndHandleApprovedAuthReq function will receive the public key back - // from the looked up auth request and all we need is to make sure that - // we can use the cached private key that is associated with it. - this.authRequest = loginAuthRequestView.authRequest; - this.fingerprintPhrase = loginAuthRequestView.fingerprintPhrase; - this.authRequestKeyPair = { - privateKey: loginAuthRequestView.privateKey - ? Utils.fromB64ToArray(loginAuthRequestView.privateKey) - : undefined, - publicKey: undefined, - }; - - if (!loginAuthRequestView.authRequestResponse) { - this.logService.error("No cached auth request response."); - return; - } - - if (loginAuthRequestView.authRequestResponse.id) { - await this.anonymousHubService.createHubConnection( - loginAuthRequestView.authRequestResponse.id, - ); - } - } - } catch (e) { - this.logService.error(e); + // I tried several ways to get the IDE/linter to play nice with checking for null values + // in less code / more efficiently, but it struggles to identify code paths that + // are more complicated than this. + if (!authRequest) { + this.logService.error("AuthRequest failed to initialize from buildAuthRequest."); + return; } - } else { - try { - await this.buildAuthRequest(AuthRequestType.AuthenticateAndUnlock); - if (!this.authRequest) { - this.logService.error("No auth request found."); + if (!this.fingerprintPhrase) { + this.logService.error("FingerprintPhrase failed to initialize from buildAuthRequest."); + return; + } + + if (!this.authRequestKeyPair) { + this.logService.error("KeyPair failed to initialize from buildAuthRequest."); + return; + } + + const authRequestResponse: AuthRequestResponse = + await this.authRequestApiService.postAuthRequest(authRequest); + + if (await this.configService.getFeatureFlag(FeatureFlag.PM9112_DeviceApprovalPersistence)) { + if (!this.authRequestKeyPair.privateKey) { + this.logService.error("No private key when trying to cache the login view."); return; } - const authRequestResponse = await this.authRequestApiService.postAuthRequest( - this.authRequest, - ); - - if (authRequestResponse.id) { - await this.anonymousHubService.createHubConnection(authRequestResponse.id); + if (!this.accessCode) { + this.logService.error("No access code when trying to cache the login view."); + return; } - } catch (e) { - this.logService.error(e); + + this.loginViaAuthRequestCacheService.cacheLoginView( + authRequestResponse.id, + this.authRequestKeyPair.privateKey, + this.accessCode, + ); } + + if (authRequestResponse.id) { + await this.anonymousHubService.createHubConnection(authRequestResponse.id); + } + } catch (e) { + this.logService.error(e); } setTimeout(() => { @@ -358,7 +422,10 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { }, this.showResendNotificationTimeoutSeconds * 1000); } - private async buildAuthRequest(authRequestType: AuthRequestType): Promise { + private async buildAuthRequest( + email: string, + authRequestType: AuthRequestType, + ): Promise { const authRequestKeyPairArray = await this.cryptoFunctionService.rsaGenerateKeyPair(2048); this.authRequestKeyPair = { @@ -369,36 +436,27 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { const deviceIdentifier = await this.appIdService.getAppId(); if (!this.authRequestKeyPair.publicKey) { - this.logService.error("AuthRequest public key not set to value in building auth request."); - return; + const errorMessage = "No public key when building an auth request."; + this.logService.error(errorMessage); + throw new Error(errorMessage); } - const publicKey = Utils.fromBufferToB64(this.authRequestKeyPair.publicKey); - const accessCode = await this.passwordGenerationService.generatePassword({ + this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase( + email, + this.authRequestKeyPair.publicKey, + ); + + this.accessCode = await this.passwordGenerationService.generatePassword({ type: "password", length: 25, }); - if (!this.email) { - this.logService.error("Email not defined when building auth request."); - return; - } + const b64PublicKey = Utils.fromBufferToB64(this.authRequestKeyPair.publicKey); - this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase( - this.email, - this.authRequestKeyPair.publicKey, - ); - - this.authRequest = new AuthRequest( - this.email, - deviceIdentifier, - publicKey, - authRequestType, - accessCode, - ); + return new AuthRequest(email, deviceIdentifier, b64PublicKey, authRequestType, this.accessCode); } - private async handleExistingAdminAuthRequest( + private async handleExistingAdminAuthRequestLogin( adminAuthRequestStorable: AdminAuthRequestStorable, userId: UserId, ): Promise { @@ -414,7 +472,7 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { ); } catch (error) { if (error instanceof ErrorResponse && error.statusCode === HttpStatusCode.NotFound) { - return await this.handleExistingAdminAuthReqDeletedOrDenied(userId); + return await this.clearExistingAdminAuthRequestAndStartNewRequest(userId); } this.logService.error(error); return; @@ -422,28 +480,12 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { // Request doesn't exist anymore if (!adminAuthRequestResponse) { - return await this.handleExistingAdminAuthReqDeletedOrDenied(userId); + return await this.clearExistingAdminAuthRequestAndStartNewRequest(userId); } - // Re-derive the user's fingerprint phrase - // It is important to not use the server's public key here as it could have been compromised via MITM - const derivedPublicKeyArrayBuffer = await this.cryptoFunctionService.rsaExtractPublicKey( - adminAuthRequestStorable.privateKey, - ); - - if (!this.email) { - this.logService.error("Email not defined when handling an existing an admin auth request."); - return; - } - - this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase( - this.email, - derivedPublicKeyArrayBuffer, - ); - // Request denied if (adminAuthRequestResponse.isAnswered && !adminAuthRequestResponse.requestApproved) { - return await this.handleExistingAdminAuthReqDeletedOrDenied(userId); + return await this.clearExistingAdminAuthRequestAndStartNewRequest(userId); } // Request approved @@ -455,6 +497,22 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { ); } + if (!this.email) { + this.logService.error("Email not defined when handling an existing an admin auth request."); + return; + } + + // Re-derive the user's fingerprint phrase + // It is important to not use the server's public key here as it could have been compromised via MITM + const derivedPublicKeyArrayBuffer = await this.cryptoFunctionService.rsaExtractPublicKey( + adminAuthRequestStorable.privateKey, + ); + + this.fingerprintPhrase = await this.authRequestService.getFingerprintPhrase( + this.email, + derivedPublicKeyArrayBuffer, + ); + // Request still pending response from admin set keypair and create hub connection // so that any approvals will be received via push notification this.authRequestKeyPair = { @@ -464,117 +522,99 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { await this.anonymousHubService.createHubConnection(adminAuthRequestStorable.id); } - private async verifyAndHandleApprovedAuthReq(requestId: string): Promise { - /** - * *********************************** - * Standard Auth Request Flows - * *********************************** - * - * Flow 1: Unauthed user requests approval from device; Approving device has a masterKey in memory. - * - * Unauthed user clicks "Login with device" > navigates to /login-with-device which creates a StandardAuthRequest - * > receives approval from a device with authRequestPublicKey(masterKey) > decrypts masterKey > decrypts userKey > proceed to vault - * - * Flow 2: Unauthed user requests approval from device; Approving device does NOT have a masterKey in memory. - * - * Unauthed user clicks "Login with device" > navigates to /login-with-device which creates a StandardAuthRequest - * > receives approval from a device with authRequestPublicKey(userKey) > decrypts userKey > proceeds to vault - * - * Note: this flow is an uncommon scenario and relates to TDE off-boarding. The following describes how a user could get into this flow: - * 1) An SSO TD user logs into a device via an Admin auth request approval, therefore this device does NOT have a masterKey in memory. - * 2) The org admin... - * (2a) Changes the member decryption options from "Trusted devices" to "Master password" AND - * (2b) Turns off the "Require single sign-on authentication" policy - * 3) On another device, the user clicks "Login with device", which they can do because the org no longer requires SSO. - * 4) The user approves from the device they had previously logged into with SSO TD, which does NOT have a masterKey in memory (see step 1 above). - * - * Flow 3: Authed SSO TD user requests approval from device; Approving device has a masterKey in memory. - * - * SSO TD user authenticates via SSO > navigates to /login-initiated > clicks "Approve from your other device" - * > navigates to /login-with-device which creates a StandardAuthRequest > receives approval from device with authRequestPublicKey(masterKey) - * > decrypts masterKey > decrypts userKey > establishes trust (if required) > proceeds to vault - * - * Flow 4: Authed SSO TD user requests approval from device; Approving device does NOT have a masterKey in memory. - * - * SSO TD user authenticates via SSO > navigates to /login-initiated > clicks "Approve from your other device" - * > navigates to /login-with-device which creates a StandardAuthRequest > receives approval from device with authRequestPublicKey(userKey) - * > decrypts userKey > establishes trust (if required) > proceeds to vault - * - * *********************************** - * Admin Auth Request Flow - * *********************************** - * - * Flow: Authed SSO TD user requests admin approval. - * - * SSO TD user authenticates via SSO > navigates to /login-initiated > clicks "Request admin approval" - * > navigates to /admin-approval-requested which creates an AdminAuthRequest > receives approval from device with authRequestPublicKey(userKey) - * > decrypts userKey > establishes trust (if required) > proceeds to vault - * - * Note: TDE users are required to be enrolled in admin password reset, which gives the admin access to the user's userKey. - * This is how admins are able to send over the authRequestPublicKey(userKey) to the user to allow them to unlock. - * - * - * Summary Table - * |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - * | Flow | Auth Status | Clicks Button [active route] | Navigates to | Approving device has masterKey in memory (see note 1) | - * |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - * | Standard Flow 1 | unauthed | "Login with device" [/login] | /login-with-device | yes | - * | Standard Flow 2 | unauthed | "Login with device" [/login] | /login-with-device | no | - * | Standard Flow 3 | authed | "Approve from your other device" [/login-initiated] | /login-with-device | yes | - * | Standard Flow 4 | authed | "Approve from your other device" [/login-initiated] | /login-with-device | no | - * | Admin Flow | authed | "Request admin approval" [/login-initiated] | /admin-approval-requested | NA - admin requests always send encrypted userKey | - * |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - * * Note 1: The phrase "in memory" here is important. It is possible for a user to have a master password for their account, but not have a masterKey IN MEMORY for - * a specific device. For example, if a user registers an account with a master password, then joins an SSO TD org, then logs in to a device via SSO and - * admin auth request, they are now logged into that device but that device does not have masterKey IN MEMORY. - */ - + /** + * This is used for trying to get the auth request back out of state. + * @param requestId + * @private + */ + private async retrieveAuthRequest(requestId: string): Promise { + let authRequestResponse: AuthRequestResponse | undefined = undefined; try { + // There are two cases here, the first being const userHasAuthenticatedViaSSO = this.authStatus === AuthenticationStatus.Locked; + // Get the response based on whether we've authenticated or not. We need to call a different API method + // based on whether we have a token or need to use the accessCode. if (userHasAuthenticatedViaSSO) { - // Get the auth request from the server - // User is authenticated, therefore the endpoint does not require an access code. - const authRequestResponse = await this.authRequestApiService.getAuthRequest(requestId); - - if (authRequestResponse.requestApproved) { - // Handles Standard Flows 3-4 and Admin Flow - await this.handleAuthenticatedFlows(authRequestResponse); - } + authRequestResponse = await this.authRequestApiService.getAuthRequest(requestId); } else { - if (!this.authRequest) { - this.logService.error("No auth request defined when handling approved auth request."); - return; + if (!this.accessCode) { + const errorMessage = "No access code available when handling approved auth request."; + this.logService.error(errorMessage); + throw new Error(errorMessage); } - - // Get the auth request from the server - // User is unauthenticated, therefore the endpoint requires an access code for user verification. - const authRequestResponse = await this.authRequestApiService.getAuthResponse( + authRequestResponse = await this.authRequestApiService.getAuthResponse( requestId, - this.authRequest.accessCode, + this.accessCode, ); + } + } catch (error) { + // If the request no longer exists, we treat it as if it's been answered (and denied). + if (error instanceof ErrorResponse && error.statusCode === HttpStatusCode.NotFound) { + authRequestResponse = undefined; + } else { + this.logService.error(error); + } + } - if (authRequestResponse.requestApproved) { - // Handles Standard Flows 1-2 - await this.handleUnauthenticatedFlows(authRequestResponse, requestId); + if (authRequestResponse === undefined) { + throw new Error("Auth request response not generated"); + } + + return authRequestResponse; + } + + /** + * Determines if the Auth Request has been approved, deleted or denied, and handles + * the response accordingly. + * @param requestId The ID of the Auth Request to process + * @returns A boolean indicating whether the Auth Request was successfully processed + */ + private async handleExistingAuthRequestLogin(requestId: string): Promise { + this.showResendNotification = false; + + try { + const authRequestResponse = await this.retrieveAuthRequest(requestId); + + // Request doesn't exist anymore, so we'll clear the cache and start a new request. + if (!authRequestResponse) { + return await this.clearExistingStandardAuthRequestAndStartNewRequest(); + } + + // Request denied, so we'll clear the cache and start a new request. + if (authRequestResponse.isAnswered && !authRequestResponse.requestApproved) { + return await this.clearExistingStandardAuthRequestAndStartNewRequest(); + } + + // Request approved, so we'll log the user in. + if (authRequestResponse.requestApproved) { + const userHasAuthenticatedViaSSO = this.authStatus === AuthenticationStatus.Locked; + if (userHasAuthenticatedViaSSO) { + // [Standard Flow 3-4] Handle authenticated SSO TD user flows + return await this.handleAuthenticatedFlows(authRequestResponse); + } else { + // [Standard Flow 1-2] Handle unauthenticated user flows + return await this.handleUnauthenticatedFlows(authRequestResponse, requestId); } } + + // At this point, we know that the request is still pending, so we'll start a hub connection to listen for a response. + await this.anonymousHubService.createHubConnection(requestId); } catch (error) { if (error instanceof ErrorResponse) { await this.router.navigate([this.backToRoute]); this.validationService.showError(error); - return; } - this.logService.error(error); - } finally { - // Manually clean out the cache to make sure sensitive - // data does not persist longer than it needs to. - this.loginViaAuthRequestCacheService.clearCacheLoginView(); } + + setTimeout(() => { + this.showResendNotification = true; + }, this.showResendNotificationTimeoutSeconds * 1000); } private async handleAuthenticatedFlows(authRequestResponse: AuthRequestResponse) { + // [Standard Flow 3-4] Handle authenticated SSO TD user flows const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; if (!userId) { this.logService.error( @@ -599,6 +639,7 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { authRequestResponse: AuthRequestResponse, requestId: string, ) { + // [Standard Flow 1-2] Handle unauthenticated user flows const authRequestLoginCredentials = await this.buildAuthRequestLoginCredentials( requestId, authRequestResponse, @@ -609,6 +650,9 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { return; } + // Clear the cached auth request from state since we're using it to log in. + this.loginViaAuthRequestCacheService.clearCacheLoginView(); + // Note: keys are set by AuthRequestLoginStrategy success handling const authResult = await this.loginStrategyService.logIn(authRequestLoginCredentials); @@ -621,21 +665,20 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { userId: UserId, ): Promise { /** - * See verifyAndHandleApprovedAuthReq() for flow details. - * + * [Flow Type Detection] * We determine the type of `key` based on the presence or absence of `masterPasswordHash`: - * - If `masterPasswordHash` has a value, we receive the `key` as an authRequestPublicKey(masterKey) [plus we have authRequestPublicKey(masterPasswordHash)] - * - If `masterPasswordHash` does not have a value, we receive the `key` as an authRequestPublicKey(userKey) + * - If `masterPasswordHash` exists: Standard Flow 1 or 3 (device has masterKey) + * - If no `masterPasswordHash`: Standard Flow 2, 4, or Admin Flow (device sends userKey) */ if (authRequestResponse.masterPasswordHash) { - // ...in Standard Auth Request Flow 3 + // [Standard Flow 1 or 3] Device has masterKey await this.authRequestService.setKeysAfterDecryptingSharedMasterKeyAndHash( authRequestResponse, privateKey, userId, ); } else { - // ...in Standard Auth Request Flow 4 or Admin Auth Request Flow + // [Standard Flow 2, 4, or Admin Flow] Device sends userKey await this.authRequestService.setUserKeyAfterDecryptingSharedUserKey( authRequestResponse, privateKey, @@ -643,15 +686,20 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { ); } + // [Admin Flow Cleanup] Clear one-time use admin auth request // clear the admin auth request from state so it cannot be used again (it's a one time use) // TODO: this should eventually be enforced via deleting this on the server once it is used await this.authRequestService.clearAdminAuthRequest(userId); + // [Standard Flow Cleanup] Clear the cached auth request from state + this.loginViaAuthRequestCacheService.clearCacheLoginView(); + this.toastService.showToast({ variant: "success", message: this.i18nService.t("loginApproved"), }); + // [Device Trust] Establish trust if required // Now that we have a decrypted user key in memory, we can check if we // need to establish trust on the current device const activeAccount = await firstValueFrom(this.accountService.activeAccount$); @@ -686,9 +734,9 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { return; } - if (!this.authRequest) { + if (!this.accessCode) { this.logService.error( - "AuthRequest not defined when building auth request login credentials.", + "Access code not defined when building auth request login credentials.", ); return; } @@ -711,7 +759,7 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { return new AuthRequestLoginCredentials( this.email, - this.authRequest.accessCode, + this.accessCode, requestId, null, // no userKey masterKey, @@ -725,7 +773,7 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { ); return new AuthRequestLoginCredentials( this.email, - this.authRequest.accessCode, + this.accessCode, requestId, userKey, null, // no masterKey @@ -734,12 +782,20 @@ export class LoginViaAuthRequestComponent implements OnInit, OnDestroy { } } - private async handleExistingAdminAuthReqDeletedOrDenied(userId: UserId) { + private async clearExistingAdminAuthRequestAndStartNewRequest(userId: UserId) { // clear the admin auth request from state await this.authRequestService.clearAdminAuthRequest(userId); // start new auth request - await this.startAdminAuthRequestLogin(); + await this.handleNewAdminAuthRequestLogin(); + } + + private async clearExistingStandardAuthRequestAndStartNewRequest(): Promise { + // clear the auth request from state + this.loginViaAuthRequestCacheService.clearCacheLoginView(); + + // start new auth request + await this.handleNewStandardAuthRequestLogin(); } private async handlePostLoginNavigation(loginResponse: AuthResult) { diff --git a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts index 82ac0f1006d..89b78500f1f 100644 --- a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts +++ b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.spec.ts @@ -2,11 +2,9 @@ import { signal } from "@angular/core"; import { TestBed } from "@angular/core/testing"; import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; -import { AuthRequestType } from "@bitwarden/common/auth/enums/auth-request-type"; -import { AuthRequest } from "@bitwarden/common/auth/models/request/auth.request"; -import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { LoginViaAuthRequestCacheService } from "./default-login-via-auth-request-cache.service"; @@ -39,12 +37,12 @@ describe("LoginViaAuthRequestCache", () => { }); it("`getCachedLoginViaAuthRequestView` returns the cached data", async () => { - cacheSignal.set({ ...buildAuthenticMockAuthView() }); + cacheSignal.set({ ...buildMockState() }); service = testBed.inject(LoginViaAuthRequestCacheService); await service.init(); expect(service.getCachedLoginViaAuthRequestView()).toEqual({ - ...buildAuthenticMockAuthView(), + ...buildMockState(), }); }); @@ -54,20 +52,19 @@ describe("LoginViaAuthRequestCache", () => { const parameters = buildAuthenticMockAuthView(); - service.cacheLoginView( - parameters.authRequest, - parameters.authRequestResponse, - parameters.fingerprintPhrase, - { publicKey: new Uint8Array(), privateKey: new Uint8Array() }, - ); + service.cacheLoginView(parameters.id, parameters.privateKey, parameters.accessCode); - expect(cacheSignal.set).toHaveBeenCalledWith(parameters); + expect(cacheSignal.set).toHaveBeenCalledWith({ + id: parameters.id, + privateKey: Utils.fromBufferToB64(parameters.privateKey), + accessCode: parameters.accessCode, + }); }); }); describe("feature disabled", () => { beforeEach(async () => { - cacheSignal.set({ ...buildAuthenticMockAuthView() } as LoginViaAuthRequestView); + cacheSignal.set({ ...buildMockState() } as LoginViaAuthRequestView); getFeatureFlag.mockResolvedValue(false); cacheSetMock.mockClear(); @@ -82,12 +79,7 @@ describe("LoginViaAuthRequestCache", () => { it("does not update the signal value", () => { const params = buildAuthenticMockAuthView(); - service.cacheLoginView( - params.authRequest, - params.authRequestResponse, - params.fingerprintPhrase, - { publicKey: new Uint8Array(), privateKey: new Uint8Array() }, - ); + service.cacheLoginView(params.id, params.privateKey, params.accessCode); expect(cacheSignal.set).not.toHaveBeenCalled(); }); @@ -95,17 +87,17 @@ describe("LoginViaAuthRequestCache", () => { const buildAuthenticMockAuthView = () => { return { - fingerprintPhrase: "", - privateKey: "", - publicKey: "", - authRequest: new AuthRequest( - "test@gmail.com", - "deviceIdentifier", - "publicKey", - AuthRequestType.Unlock, - "accessCode", - ), - authRequestResponse: new AuthRequestResponse({}), + id: "testId", + privateKey: new Uint8Array(), + accessCode: "testAccessCode", + }; + }; + + const buildMockState = () => { + return { + id: "testId", + privateKey: Utils.fromBufferToB64(new Uint8Array()), + accessCode: "testAccessCode", }; }; }); diff --git a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts index 30ba8879546..493fea5c14b 100644 --- a/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts +++ b/libs/auth/src/common/services/auth-request/default-login-via-auth-request-cache.service.ts @@ -1,8 +1,6 @@ import { inject, Injectable, WritableSignal } from "@angular/core"; import { ViewCacheService } from "@bitwarden/angular/platform/abstractions/view-cache.service"; -import { AuthRequest } from "@bitwarden/common/auth/models/request/auth.request"; -import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { LoginViaAuthRequestView } from "@bitwarden/common/auth/models/view/login-via-auth-request.view"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -45,12 +43,7 @@ export class LoginViaAuthRequestCacheService { /** * Update the cache with the new LoginView. */ - cacheLoginView( - authRequest: AuthRequest, - authRequestResponse: AuthRequestResponse, - fingerprintPhrase: string, - keys: { privateKey: Uint8Array | undefined; publicKey: Uint8Array | undefined }, - ): void { + cacheLoginView(id: string, privateKey: Uint8Array, accessCode: string): void { if (!this.featureEnabled) { return; } @@ -59,11 +52,9 @@ export class LoginViaAuthRequestCacheService { // data can be properly formed when json-ified. If not done, they are not stored properly and // will not be parsable by the cryptography library after coming out of storage. this.defaultLoginViaAuthRequestCache.set({ - authRequest, - authRequestResponse, - fingerprintPhrase, - privateKey: keys.privateKey ? Utils.fromBufferToB64(keys.privateKey.buffer) : undefined, - publicKey: keys.publicKey ? Utils.fromBufferToB64(keys.publicKey.buffer) : undefined, + id: id, + privateKey: Utils.fromBufferToB64(privateKey.buffer), + accessCode: accessCode, } as LoginViaAuthRequestView); } diff --git a/libs/common/src/auth/models/view/login-via-auth-request.view.ts b/libs/common/src/auth/models/view/login-via-auth-request.view.ts index 0691b8efd86..c2113415cfd 100644 --- a/libs/common/src/auth/models/view/login-via-auth-request.view.ts +++ b/libs/common/src/auth/models/view/login-via-auth-request.view.ts @@ -1,17 +1,16 @@ import { Jsonify } from "type-fest"; -import { AuthRequest } from "@bitwarden/common/auth/models/request/auth.request"; -import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { View } from "@bitwarden/common/models/view/view"; export class LoginViaAuthRequestView implements View { - authRequest: AuthRequest | undefined = undefined; - authRequestResponse: AuthRequestResponse | undefined = undefined; - fingerprintPhrase: string | undefined = undefined; + id: string | undefined = undefined; + accessCode: string | undefined = undefined; privateKey: string | undefined = undefined; - publicKey: string | undefined = undefined; - static fromJSON(obj: Partial>): LoginViaAuthRequestView { + static fromJSON(obj: Partial>): LoginViaAuthRequestView | null { + if (obj == null) { + return null; + } return Object.assign(new LoginViaAuthRequestView(), obj); } } From a7fe4877d7dea66780a1c18c952a677c84f33235 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Fri, 4 Apr 2025 13:42:44 -0700 Subject: [PATCH 11/93] [PM-17563] Security task background synchronization (#14086) * [PM-17563] Implement listenForTaskNotifications in default-task.service.ts * [PM-17563] Update syncService to include userId in syncCompleted message payload * [PM-17563] Update default-task.service to react to both pending task notifications and completed syncs * [PM-17563] Add unit tests around task notification listening * [PM-17563] Only check for at risk password tasks if tasks are enabled * [PM-17563] Make userId required even if undefined * [PM-17563] Use abstract TaskService instead of default implementation in MainBackground * [PM-17563] Cleanup userId filtering --- .../browser/src/background/main.background.ts | 17 ++ .../at-risk-password-callout.component.ts | 29 +- .../src/services/jslib-services.module.ts | 10 +- .../src/enums/notification-type.enum.ts | 2 + .../src/platform/sync/core-sync.service.ts | 32 +-- .../src/platform/sync/default-sync.service.ts | 14 +- .../vault/tasks/abstractions/task.service.ts | 7 +- .../services/default-task.service.spec.ts | 249 +++++++++++++++++- .../tasks/services/default-task.service.ts | 79 +++++- 9 files changed, 400 insertions(+), 39 deletions(-) diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index ffce7827358..663fc863f5e 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -200,6 +200,7 @@ import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service"; import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service"; +import { DefaultTaskService, TaskService } from "@bitwarden/common/vault/tasks"; import { legacyPasswordGenerationServiceFactory, legacyUsernameGenerationServiceFactory, @@ -400,6 +401,7 @@ export default class MainBackground { sdkLoadService: SdkLoadService; cipherAuthorizationService: CipherAuthorizationService; inlineMenuFieldQualificationService: InlineMenuFieldQualificationService; + taskService: TaskService; onUpdatedRan: boolean; onReplacedRan: boolean; @@ -1296,6 +1298,16 @@ export default class MainBackground { this.configService, ); + this.taskService = new DefaultTaskService( + this.stateProvider, + this.apiService, + this.organizationService, + this.configService, + this.authService, + this.notificationsService, + messageListener, + ); + this.inlineMenuFieldQualificationService = new InlineMenuFieldQualificationService(); } @@ -1377,6 +1389,11 @@ export default class MainBackground { await this.fullSync(false); this.backgroundSyncService.init(); this.notificationsService.startListening(); + + if (await this.configService.getFeatureFlag(FeatureFlag.SecurityTasks)) { + this.taskService.listenForTaskNotifications(); + } + resolve(); }, 500); }); diff --git a/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts b/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts index eb5cd459111..fa4137d9849 100644 --- a/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-callout/at-risk-password-callout.component.ts @@ -1,16 +1,14 @@ import { CommonModule } from "@angular/common"; import { Component, inject } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { map, switchMap } from "rxjs"; +import { map, of, switchMap } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { SecurityTaskType, TaskService } from "@bitwarden/common/vault/tasks"; -import { filterOutNullish } from "@bitwarden/common/vault/utils/observable-utilities"; import { AnchorLinkDirective, CalloutModule } from "@bitwarden/components"; import { I18nPipe } from "@bitwarden/ui-common"; -// TODO: This component will need to be reworked to use the new EndUserNotificationService in PM-10609 - @Component({ selector: "vault-at-risk-password-callout", standalone: true, @@ -19,15 +17,24 @@ import { I18nPipe } from "@bitwarden/ui-common"; }) export class AtRiskPasswordCalloutComponent { private taskService = inject(TaskService); - private activeAccount$ = inject(AccountService).activeAccount$.pipe(filterOutNullish()); + private activeAccount$ = inject(AccountService).activeAccount$.pipe(getUserId); protected pendingTasks$ = this.activeAccount$.pipe( - switchMap((user) => - this.taskService - .pendingTasks$(user.id) - .pipe( - map((tasks) => tasks.filter((t) => t.type === SecurityTaskType.UpdateAtRiskCredential)), - ), + switchMap((userId) => + this.taskService.tasksEnabled$(userId).pipe( + switchMap((enabled) => { + if (!enabled) { + return of([]); + } + return this.taskService + .pendingTasks$(userId) + .pipe( + map((tasks) => + tasks.filter((t) => t.type === SecurityTaskType.UpdateAtRiskCredential), + ), + ); + }), + ), ), ); } diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index fc8be749c94..42fca029ec5 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1475,7 +1475,15 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: TaskService, useClass: DefaultTaskService, - deps: [StateProvider, ApiServiceAbstraction, OrganizationServiceAbstraction, ConfigService], + deps: [ + StateProvider, + ApiServiceAbstraction, + OrganizationServiceAbstraction, + ConfigService, + AuthServiceAbstraction, + NotificationsService, + MessageListener, + ], }), safeProvider({ provide: EndUserNotificationService, diff --git a/libs/common/src/enums/notification-type.enum.ts b/libs/common/src/enums/notification-type.enum.ts index c366af1eb61..0e4d0bfee3d 100644 --- a/libs/common/src/enums/notification-type.enum.ts +++ b/libs/common/src/enums/notification-type.enum.ts @@ -26,4 +26,6 @@ export enum NotificationType { SyncOrganizationCollectionSettingChanged = 19, Notification = 20, NotificationStatus = 21, + + PendingSecurityTasks = 22, } diff --git a/libs/common/src/platform/sync/core-sync.service.ts b/libs/common/src/platform/sync/core-sync.service.ts index 92a10baf6d2..1865ffb852f 100644 --- a/libs/common/src/platform/sync/core-sync.service.ts +++ b/libs/common/src/platform/sync/core-sync.service.ts @@ -105,14 +105,14 @@ export abstract class CoreSyncService implements SyncService { if (remoteFolder != null) { await this.folderService.upsert(new FolderData(remoteFolder), userId); this.messageSender.send("syncedUpsertedFolder", { folderId: notification.id }); - return this.syncCompleted(true); + return this.syncCompleted(true, userId); } } } catch (e) { this.logService.error(e); } } - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } async syncDeleteFolder(notification: SyncFolderNotification, userId: UserId): Promise { @@ -123,10 +123,10 @@ export abstract class CoreSyncService implements SyncService { if (authStatus >= AuthenticationStatus.Locked) { await this.folderService.delete(notification.id, userId); this.messageSender.send("syncedDeletedFolder", { folderId: notification.id }); - this.syncCompleted(true); + this.syncCompleted(true, userId); return true; } - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } async syncUpsertCipher( @@ -183,18 +183,18 @@ export abstract class CoreSyncService implements SyncService { if (remoteCipher != null) { await this.cipherService.upsert(new CipherData(remoteCipher)); this.messageSender.send("syncedUpsertedCipher", { cipherId: notification.id }); - return this.syncCompleted(true); + return this.syncCompleted(true, userId); } } } catch (e) { if (e != null && e.statusCode === 404 && isEdit) { await this.cipherService.delete(notification.id, userId); this.messageSender.send("syncedDeletedCipher", { cipherId: notification.id }); - return this.syncCompleted(true); + return this.syncCompleted(true, userId); } } } - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } async syncDeleteCipher(notification: SyncCipherNotification, userId: UserId): Promise { @@ -204,9 +204,9 @@ export abstract class CoreSyncService implements SyncService { if (authStatus >= AuthenticationStatus.Locked) { await this.cipherService.delete(notification.id, userId); this.messageSender.send("syncedDeletedCipher", { cipherId: notification.id }); - return this.syncCompleted(true); + return this.syncCompleted(true, userId); } - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } async syncUpsertSend(notification: SyncSendNotification, isEdit: boolean): Promise { @@ -234,14 +234,15 @@ export abstract class CoreSyncService implements SyncService { if (remoteSend != null) { await this.sendService.upsert(new SendData(remoteSend)); this.messageSender.send("syncedUpsertedSend", { sendId: notification.id }); - return this.syncCompleted(true); + return this.syncCompleted(true, activeUserId); } } } catch (e) { this.logService.error(e); } } - return this.syncCompleted(false); + // TODO: Update syncCompleted userId when send service allows modification of non-active users + return this.syncCompleted(false, undefined); } async syncDeleteSend(notification: SyncSendNotification): Promise { @@ -249,10 +250,11 @@ export abstract class CoreSyncService implements SyncService { if (await this.stateService.getIsAuthenticated()) { await this.sendService.delete(notification.id); this.messageSender.send("syncedDeletedSend", { sendId: notification.id }); - this.syncCompleted(true); + // TODO: Update syncCompleted userId when send service allows modification of non-active users + this.syncCompleted(true, undefined); return true; } - return this.syncCompleted(false); + return this.syncCompleted(false, undefined); } // Helpers @@ -262,9 +264,9 @@ export abstract class CoreSyncService implements SyncService { this.messageSender.send("syncStarted"); } - protected syncCompleted(successfully: boolean): boolean { + protected syncCompleted(successfully: boolean, userId: UserId | undefined): boolean { this.syncInProgress = false; - this.messageSender.send("syncCompleted", { successfully: successfully }); + this.messageSender.send("syncCompleted", { successfully: successfully, userId }); return successfully; } } diff --git a/libs/common/src/platform/sync/default-sync.service.ts b/libs/common/src/platform/sync/default-sync.service.ts index 30a59e9c165..a6b1b974645 100644 --- a/libs/common/src/platform/sync/default-sync.service.ts +++ b/libs/common/src/platform/sync/default-sync.service.ts @@ -3,9 +3,9 @@ import { firstValueFrom, map } from "rxjs"; import { - CollectionService, CollectionData, CollectionDetailsResponse, + CollectionService, } from "@bitwarden/admin-console/common"; import { KeyService } from "@bitwarden/key-management"; @@ -107,7 +107,7 @@ export class DefaultSyncService extends CoreSyncService { this.syncStarted(); const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId)); if (authStatus === AuthenticationStatus.LoggedOut) { - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } const now = new Date(); @@ -116,14 +116,14 @@ export class DefaultSyncService extends CoreSyncService { needsSync = await this.needsSyncing(forceSync); } catch (e) { if (allowThrowOnError) { - this.syncCompleted(false); + this.syncCompleted(false, userId); throw e; } } if (!needsSync) { await this.setLastSync(now, userId); - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } try { @@ -139,13 +139,13 @@ export class DefaultSyncService extends CoreSyncService { await this.syncPolicies(response.policies, response.profile.id); await this.setLastSync(now, userId); - return this.syncCompleted(true); + return this.syncCompleted(true, userId); } catch (e) { if (allowThrowOnError) { - this.syncCompleted(false); + this.syncCompleted(false, userId); throw e; } else { - return this.syncCompleted(false); + return this.syncCompleted(false, userId); } } } diff --git a/libs/common/src/vault/tasks/abstractions/task.service.ts b/libs/common/src/vault/tasks/abstractions/task.service.ts index 4a0c086330e..79cefff0b71 100644 --- a/libs/common/src/vault/tasks/abstractions/task.service.ts +++ b/libs/common/src/vault/tasks/abstractions/task.service.ts @@ -1,4 +1,4 @@ -import { Observable } from "rxjs"; +import { Observable, Subscription } from "rxjs"; import { SecurityTaskId, UserId } from "@bitwarden/common/types/guid"; @@ -43,4 +43,9 @@ export abstract class TaskService { * @param userId - The user who is completing the task. */ abstract markAsComplete(taskId: SecurityTaskId, userId: UserId): Promise; + + /** + * Creates a subscription for pending security task notifications or completed syncs for unlocked users. + */ + abstract listenForTaskNotifications(): Subscription; } diff --git a/libs/common/src/vault/tasks/services/default-task.service.spec.ts b/libs/common/src/vault/tasks/services/default-task.service.spec.ts index c38fa0e9e72..4d468d09766 100644 --- a/libs/common/src/vault/tasks/services/default-task.service.spec.ts +++ b/libs/common/src/vault/tasks/services/default-task.service.spec.ts @@ -1,9 +1,15 @@ -import { BehaviorSubject, firstValueFrom } from "rxjs"; +import { BehaviorSubject, firstValueFrom, Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { NotificationType } from "@bitwarden/common/enums"; +import { NotificationResponse } from "@bitwarden/common/models/response/notification.response"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { Message, MessageListener } from "@bitwarden/common/platform/messaging"; +import { NotificationsService } from "@bitwarden/common/platform/notifications"; import { SecurityTaskId, UserId } from "@bitwarden/common/types/guid"; import { FakeStateProvider, mockAccountServiceWith } from "../../../../spec"; @@ -16,10 +22,13 @@ import { DefaultTaskService } from "./default-task.service"; describe("Default task service", () => { let fakeStateProvider: FakeStateProvider; + const userId = "user-id" as UserId; const mockApiSend = jest.fn(); const mockGetAllOrgs$ = jest.fn(); const mockGetFeatureFlag$ = jest.fn(); - + const mockAuthStatuses$ = new BehaviorSubject>({}); + const mockNotifications$ = new Subject(); + const mockMessages$ = new Subject>>(); let service: DefaultTaskService; beforeEach(async () => { @@ -27,12 +36,15 @@ describe("Default task service", () => { mockGetAllOrgs$.mockClear(); mockGetFeatureFlag$.mockClear(); - fakeStateProvider = new FakeStateProvider(mockAccountServiceWith("user-id" as UserId)); + fakeStateProvider = new FakeStateProvider(mockAccountServiceWith(userId)); service = new DefaultTaskService( fakeStateProvider, { send: mockApiSend } as unknown as ApiService, { organizations$: mockGetAllOrgs$ } as unknown as OrganizationService, { getFeatureFlag$: mockGetFeatureFlag$ } as unknown as ConfigService, + { authStatuses$: mockAuthStatuses$.asObservable() } as unknown as AuthService, + { notifications$: mockNotifications$.asObservable() } as unknown as NotificationsService, + { allMessages$: mockMessages$.asObservable() } as unknown as MessageListener, ); }); @@ -257,4 +269,235 @@ describe("Default task service", () => { ]); }); }); + + describe("listenForTaskNotifications()", () => { + it("should not subscribe to notifications when there are no unlocked users", () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Locked, + }); + + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn()); + const syncCompletedHelper$ = (service["syncCompletedMessage$"] = jest.fn()); + + const subscription = service.listenForTaskNotifications(); + + expect(notificationHelper$).not.toHaveBeenCalled(); + expect(syncCompletedHelper$).not.toHaveBeenCalled(); + subscription.unsubscribe(); + }); + + it("should not subscribe to notifications when no users have tasks enabled", () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(false)); + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn()); + const syncCompletedHelper$ = (service["syncCompletedMessage$"] = jest.fn()); + + const subscription = service.listenForTaskNotifications(); + + expect(notificationHelper$).not.toHaveBeenCalled(); + expect(syncCompletedHelper$).not.toHaveBeenCalled(); + subscription.unsubscribe(); + }); + + it("should subscribe to notifications when there are unlocked users with tasks enabled", () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn()); + const syncCompletedHelper$ = (service["syncCompletedMessage$"] = jest.fn()); + + const subscription = service.listenForTaskNotifications(); + + expect(notificationHelper$).toHaveBeenCalled(); + expect(syncCompletedHelper$).toHaveBeenCalled(); + subscription.unsubscribe(); + }); + + describe("notification handling", () => { + it("should refresh tasks when a notification is received for an allowed user", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const syncCompletedHelper$ = (service["syncCompletedMessage$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + const notification = { + type: NotificationType.PendingSecurityTasks, + } as NotificationResponse; + mockNotifications$.next([notification, userId]); + + await new Promise(process.nextTick); + + expect(syncCompletedHelper$).toHaveBeenCalled(); + expect(refreshTasks).toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + + it("should ignore notifications for other users", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const syncCompletedHelper$ = (service["syncCompletedMessage$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + const notification = { + type: NotificationType.PendingSecurityTasks, + } as NotificationResponse; + mockNotifications$.next([notification, "other-user-id" as UserId]); + + await new Promise(process.nextTick); + + expect(syncCompletedHelper$).toHaveBeenCalled(); + expect(refreshTasks).not.toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + + it("should ignore other notifications types", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const syncCompletedHelper$ = (service["syncCompletedMessage$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + const notification = { + type: NotificationType.SyncSettings, + } as NotificationResponse; + mockNotifications$.next([notification, userId]); + + await new Promise(process.nextTick); + + expect(syncCompletedHelper$).toHaveBeenCalled(); + expect(refreshTasks).not.toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + }); + + describe("sync completed handling", () => { + it("should refresh tasks when a sync completed message is received for an allowed user", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + mockMessages$.next({ + command: "syncCompleted", + userId, + successfully: true, + }); + + await new Promise(process.nextTick); + + expect(notificationHelper$).toHaveBeenCalled(); + expect(refreshTasks).toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + + it("should ignore non syncCompleted messages", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + mockMessages$.next({ + command: "other-command", + }); + + await new Promise(process.nextTick); + + expect(notificationHelper$).toHaveBeenCalled(); + expect(refreshTasks).not.toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + + it("should ignore failed sync messages", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + mockMessages$.next({ + command: "syncCompleted", + userId, + successfully: false, + }); + + await new Promise(process.nextTick); + + expect(notificationHelper$).toHaveBeenCalled(); + expect(refreshTasks).not.toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + + it("should ignore sync messages for other users", async () => { + mockAuthStatuses$.next({ + [userId]: AuthenticationStatus.Unlocked, + }); + service.tasksEnabled$ = jest.fn(() => new BehaviorSubject(true)); + + const notificationHelper$ = (service["securityTaskNotifications$"] = jest.fn( + () => new Subject(), + )); + const refreshTasks = jest.spyOn(service, "refreshTasks"); + + const subscription = service.listenForTaskNotifications(); + + mockMessages$.next({ + command: "syncCompleted", + userId: "other-user-id" as UserId, + successfully: true, + }); + + await new Promise(process.nextTick); + + expect(notificationHelper$).toHaveBeenCalled(); + expect(refreshTasks).not.toHaveBeenCalledWith(userId); + subscription.unsubscribe(); + }); + }); + }); }); diff --git a/libs/common/src/vault/tasks/services/default-task.service.ts b/libs/common/src/vault/tasks/services/default-task.service.ts index ff370229663..016eed2e7d6 100644 --- a/libs/common/src/vault/tasks/services/default-task.service.ts +++ b/libs/common/src/vault/tasks/services/default-task.service.ts @@ -1,10 +1,15 @@ -import { combineLatest, map, switchMap } from "rxjs"; +import { combineLatest, filter, map, merge, Observable, of, Subscription, switchMap } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { NotificationType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; +import { MessageListener } from "@bitwarden/common/platform/messaging"; +import { NotificationsService } from "@bitwarden/common/platform/notifications"; import { StateProvider } from "@bitwarden/common/platform/state"; import { SecurityTaskId, UserId } from "@bitwarden/common/types/guid"; @@ -14,12 +19,21 @@ import { SecurityTaskStatus } from "../enums"; import { SecurityTask, SecurityTaskData, SecurityTaskResponse } from "../models"; import { SECURITY_TASKS } from "../state/security-task.state"; +const getUnlockedUserIds = map, UserId[]>((authStatuses) => + Object.entries(authStatuses ?? {}) + .filter(([, status]) => status >= AuthenticationStatus.Unlocked) + .map(([userId]) => userId as UserId), +); + export class DefaultTaskService implements TaskService { constructor( private stateProvider: StateProvider, private apiService: ApiService, private organizationService: OrganizationService, private configService: ConfigService, + private authService: AuthService, + private notificationService: NotificationsService, + private messageListener: MessageListener, ) {} tasksEnabled$ = perUserCache$((userId) => { @@ -36,6 +50,7 @@ export class DefaultTaskService implements TaskService { switchMap(async (tasks) => { if (tasks == null) { await this.fetchTasksFromApi(userId); + return null; } return tasks; }), @@ -97,4 +112,66 @@ export class DefaultTaskService implements TaskService { ): Promise { return this.taskState(userId).update(() => tasks); } + + /** + * Helper observable that filters the list of unlocked user IDs to only those with tasks enabled. + * @private + */ + private getOnlyTaskEnabledUsers = switchMap>((unlockedUserIds) => { + if (unlockedUserIds.length === 0) { + return of([]); + } + + return combineLatest( + unlockedUserIds.map((userId) => + this.tasksEnabled$(userId).pipe(map((enabled) => (enabled ? userId : null))), + ), + ).pipe(map((userIds) => userIds.filter((userId) => userId !== null) as UserId[])); + }); + + /** + * Helper observable that emits whenever a security task notification is received for a user in the provided list. + * @private + */ + private securityTaskNotifications$(filterByUserIds: UserId[]) { + return this.notificationService.notifications$.pipe( + filter( + ([notification, userId]) => + notification.type === NotificationType.PendingSecurityTasks && + filterByUserIds.includes(userId), + ), + map(([, userId]) => userId), + ); + } + + /** + * Helper observable that emits whenever a sync is completed for a user in the provided list. + */ + private syncCompletedMessage$(filterByUserIds: UserId[]) { + return this.messageListener.allMessages$.pipe( + filter((msg) => msg.command === "syncCompleted" && !!msg.successfully && !!msg.userId), + map((msg) => msg.userId as UserId), + filter((userId) => filterByUserIds.includes(userId)), + ); + } + + /** + * Creates a subscription for pending security task notifications or completed syncs for unlocked users. + */ + listenForTaskNotifications(): Subscription { + return this.authService.authStatuses$ + .pipe( + getUnlockedUserIds, + this.getOnlyTaskEnabledUsers, + filter((allowedUserIds) => allowedUserIds.length > 0), + switchMap((allowedUserIds) => + merge( + this.securityTaskNotifications$(allowedUserIds), + this.syncCompletedMessage$(allowedUserIds), + ), + ), + switchMap((userId) => this.refreshTasks(userId)), + ) + .subscribe(); + } } From 6503cc64fdc93e17dc789f6e57eb05d05e4a1486 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Fri, 4 Apr 2025 15:34:02 -0700 Subject: [PATCH 12/93] [PM-19906] Add appStopClick to prevent default event (#14134) --- libs/vault/src/cipher-view/cipher-view.component.html | 2 +- .../login-credentials/login-credentials-view.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/vault/src/cipher-view/cipher-view.component.html b/libs/vault/src/cipher-view/cipher-view.component.html index c441c921c39..99f1b1e47f5 100644 --- a/libs/vault/src/cipher-view/cipher-view.component.html +++ b/libs/vault/src/cipher-view/cipher-view.component.html @@ -10,7 +10,7 @@ [title]="''" > - + {{ "changeAtRiskPassword" | i18n }} diff --git a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.html b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.html index e44f1ebb3d8..2c1acf96a14 100644 --- a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.html +++ b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.html @@ -90,7 +90,7 @@ > - + {{ "changeAtRiskPassword" | i18n }} From 2a0b688017206fbe96bfc473b2bb94a3d64e1c4c Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 09:58:34 +0200 Subject: [PATCH 13/93] Autosync the updated translations (#14151) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/de/messages.json | 4 ++-- apps/desktop/src/locales/el/messages.json | 2 +- apps/desktop/src/locales/zh_CN/messages.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 0433e68d761..1aedecedc5c 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -2467,7 +2467,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Nur die einzelnen Tresor-Einträge einschließlich Anhängen von $EMAIL$ werden exportiert. Tresor-Einträge der Organisation werden nicht berücksichtigt", "placeholders": { "email": { "content": "$1", @@ -3563,6 +3563,6 @@ "message": "Gefährdetes Passwort ändern" }, "move": { - "message": "Move" + "message": "Verschieben" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 168618ca6f3..189f3648984 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -649,7 +649,7 @@ "message": "Σύνδεση στο Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Εισάγετε τον κωδικό που στάλθηκε στο email σας" }, "enterTheCodeFromYourAuthenticatorApp": { "message": "Enter the code from your authenticator app" diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 7a168fb4e05..cb6e63e398c 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -2788,13 +2788,13 @@ "message": "通知已发送到您的设备" }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the " + "message": "解锁您设备上的 Bitwarden 或通过" }, "notificationSentDeviceAnchor": { "message": "网页 App" }, "notificationSentDevicePart2": { - "message": "在批准前,请确保指纹短语与下面的相匹配。" + "message": "批准前,请确保指纹短语与下面的相匹配。" }, "needAnotherOptionV1": { "message": "需要其他选项吗?" From af5ea4233c19fa285239faaf221fc4a4b1efd8ed Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 09:59:42 +0200 Subject: [PATCH 14/93] Autosync the updated translations (#14152) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/de/messages.json | 4 ++-- apps/web/src/locales/zh_CN/messages.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index f34f875f6b0..edf253fac8b 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -6718,7 +6718,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Nur die einzelnen Tresor-Einträge einschließlich Anhängen von $EMAIL$ werden exportiert. Tresor-Einträge der Organisation werden nicht berücksichtigt", "placeholders": { "email": { "content": "$1", @@ -8709,7 +8709,7 @@ "message": "Das Löschen von Sammlungen auf Eigentümer und Administratoren beschränken" }, "limitItemDeletionDescription": { - "message": "Limit item deletion to members with the Manage collection permissions" + "message": "Die Löschung von Einträgen auf Mitglieder mit den Berechtigungen zur Verwaltung von Sammlungen beschränken" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "Besitzer und Administratoren können alle Sammlungen und Einträge verwalten" diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 747db745bb5..f8bb62b0b00 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1394,7 +1394,7 @@ "message": "通知已发送到您的设备。" }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the " + "message": "解锁您设备上的 Bitwarden 或通过" }, "areYouTryingToAccessYourAccount": { "message": "您正在尝试访问您的账户吗?" @@ -1418,7 +1418,7 @@ "message": "网页 App" }, "notificationSentDevicePart2": { - "message": "在批准前,请确保指纹短语与下面的相匹配。" + "message": "批准前,请确保指纹短语与下面的相匹配。" }, "notificationSentDeviceComplete": { "message": "解锁您设备上的 Bitwarden。批准前,请确保指纹短语与下面的相匹配。" From 66360b76d20992398d83634c50e35cd0f7c3e5aa Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 7 Apr 2025 10:05:51 +0200 Subject: [PATCH 15/93] Autosync the updated translations (#14153) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 27 +++++++++ apps/browser/src/_locales/az/messages.json | 27 +++++++++ apps/browser/src/_locales/be/messages.json | 27 +++++++++ apps/browser/src/_locales/bg/messages.json | 27 +++++++++ apps/browser/src/_locales/bn/messages.json | 27 +++++++++ apps/browser/src/_locales/bs/messages.json | 27 +++++++++ apps/browser/src/_locales/ca/messages.json | 27 +++++++++ apps/browser/src/_locales/cs/messages.json | 27 +++++++++ apps/browser/src/_locales/cy/messages.json | 27 +++++++++ apps/browser/src/_locales/da/messages.json | 27 +++++++++ apps/browser/src/_locales/de/messages.json | 45 ++++++++++++--- apps/browser/src/_locales/el/messages.json | 27 +++++++++ apps/browser/src/_locales/en_GB/messages.json | 27 +++++++++ apps/browser/src/_locales/en_IN/messages.json | 27 +++++++++ apps/browser/src/_locales/es/messages.json | 27 +++++++++ apps/browser/src/_locales/et/messages.json | 27 +++++++++ apps/browser/src/_locales/eu/messages.json | 27 +++++++++ apps/browser/src/_locales/fa/messages.json | 27 +++++++++ apps/browser/src/_locales/fi/messages.json | 27 +++++++++ apps/browser/src/_locales/fil/messages.json | 27 +++++++++ apps/browser/src/_locales/fr/messages.json | 27 +++++++++ apps/browser/src/_locales/gl/messages.json | 27 +++++++++ apps/browser/src/_locales/he/messages.json | 27 +++++++++ apps/browser/src/_locales/hi/messages.json | 27 +++++++++ apps/browser/src/_locales/hr/messages.json | 27 +++++++++ apps/browser/src/_locales/hu/messages.json | 27 +++++++++ apps/browser/src/_locales/id/messages.json | 27 +++++++++ apps/browser/src/_locales/it/messages.json | 27 +++++++++ apps/browser/src/_locales/ja/messages.json | 27 +++++++++ apps/browser/src/_locales/ka/messages.json | 27 +++++++++ apps/browser/src/_locales/km/messages.json | 27 +++++++++ apps/browser/src/_locales/kn/messages.json | 27 +++++++++ apps/browser/src/_locales/ko/messages.json | 27 +++++++++ apps/browser/src/_locales/lt/messages.json | 27 +++++++++ apps/browser/src/_locales/lv/messages.json | 27 +++++++++ apps/browser/src/_locales/ml/messages.json | 27 +++++++++ apps/browser/src/_locales/mr/messages.json | 27 +++++++++ apps/browser/src/_locales/my/messages.json | 27 +++++++++ apps/browser/src/_locales/nb/messages.json | 27 +++++++++ apps/browser/src/_locales/ne/messages.json | 27 +++++++++ apps/browser/src/_locales/nl/messages.json | 27 +++++++++ apps/browser/src/_locales/nn/messages.json | 27 +++++++++ apps/browser/src/_locales/or/messages.json | 27 +++++++++ apps/browser/src/_locales/pl/messages.json | 27 +++++++++ apps/browser/src/_locales/pt_BR/messages.json | 27 +++++++++ apps/browser/src/_locales/pt_PT/messages.json | 27 +++++++++ apps/browser/src/_locales/ro/messages.json | 27 +++++++++ apps/browser/src/_locales/ru/messages.json | 27 +++++++++ apps/browser/src/_locales/si/messages.json | 27 +++++++++ apps/browser/src/_locales/sk/messages.json | 27 +++++++++ apps/browser/src/_locales/sl/messages.json | 27 +++++++++ apps/browser/src/_locales/sr/messages.json | 27 +++++++++ apps/browser/src/_locales/sv/messages.json | 55 ++++++++++++++----- apps/browser/src/_locales/te/messages.json | 27 +++++++++ apps/browser/src/_locales/th/messages.json | 27 +++++++++ apps/browser/src/_locales/tr/messages.json | 41 +++++++++++--- apps/browser/src/_locales/uk/messages.json | 27 +++++++++ apps/browser/src/_locales/vi/messages.json | 27 +++++++++ apps/browser/src/_locales/zh_CN/messages.json | 31 ++++++++++- apps/browser/src/_locales/zh_TW/messages.json | 27 +++++++++ 60 files changed, 1652 insertions(+), 32 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 55a9dbca20a..0a8884951bb 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index a6d885898a2..358a7596f56 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Riskli parolları dəyişdir" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index fcf9786a210..ab2889ec99a 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index bdba04b0f46..347fba7e93f 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Промяна на парола в риск" + }, + "introCarouselLabel": { + "message": "Добре дошли в Битуорден" + }, + "securityPrioritized": { + "message": "Защитата е от първостепенна важност" + }, + "securityPrioritizedBody": { + "message": "Съхранявайте данни за вписване, карти и самоличности в своя защитен трезор. Битуорден използва шифроване от край до край за да пази това, което е важно за Вас." + }, + "quickLogin": { + "message": "Бързо и лесно вписване" + }, + "quickLoginBody": { + "message": "Настройте отключването чрез биометрични данни и автоматичното попълване, за да се вписвате в регистрациите си без да натискате и един клавиш." + }, + "secureUser": { + "message": "Подобрете данните си за вписване" + }, + "secureUserBody": { + "message": "Използвайте генератора, за да създавате и запазвате сложни, уникални пароли за всичките си регистрации." + }, + "secureDevices": { + "message": "Вашите данни – когато и където Ви потрябват" + }, + "secureDevicesBody": { + "message": "Съхранявайте неограничен брой пароли на множество устройства – с приложенията на Битуорден за мобилни телефони, браузър и компютър." } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index e7ac4f6b729..0806f936677 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index e277f2cee8f..3d17255e801 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index a6b3820971f..59631bc1670 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 7f03e3f0598..be338aee089 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Změnit ohrožené heslo" + }, + "introCarouselLabel": { + "message": "Vítejte v Bitwardenu" + }, + "securityPrioritized": { + "message": "Bezpečnost, priorita" + }, + "securityPrioritizedBody": { + "message": "Uložte si přihlašovací údaje, karty a identity do zabezpečeného trezoru. Bitwarden používá šifrování end-to-end s nulovou znalostí, aby ochránil to, co je pro Vás důležité." + }, + "quickLogin": { + "message": "Rychlé a snadné přihlášení" + }, + "quickLoginBody": { + "message": "Nastavte biometrické odemknutí a automatické vyplňování pro přihlášení k Vašim účtům bez zadání jediného písmene." + }, + "secureUser": { + "message": "Zvýšit úroveň přihlašování" + }, + "secureUserBody": { + "message": "Použijte generátor k vytvoření a uložení silných, jedinečných hesel pro všechny Vaše účty." + }, + "secureDevices": { + "message": "Vaše data, kdy a kde je potřebujete" + }, + "secureDevicesBody": { + "message": "Uložte neomezená hesla na neomezených zařízeních s Bitwardenem na mobilu, prohlížeči a desktopové aplikaci." } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 3a59bca3f71..c6a59456c46 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 55e68031f03..55d6cad20e4 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index ba129609937..fa77ca964ad 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -1150,7 +1150,7 @@ "description": "Default URI match detection for autofill." }, "defaultUriMatchDetectionDesc": { - "message": "Wähle die Standardmethode, mit der die URI-Match-Erkennung für Anmeldungen bei Aktionen wie dem automatischen Ausfüllen behandelt wird." + "message": "Wähle die Standardmethode, mit der die URI-Übereinstimmungserkennung für Anmeldungen bei Aktionen wie dem automatischen Ausfüllen behandelt wird." }, "theme": { "message": "Design" @@ -1584,7 +1584,7 @@ "message": "Erfahre mehr über Auto-Ausfüllen" }, "defaultAutoFillOnPageLoad": { - "message": "Standard Auto-Ausfüllen Einstellung für Login-Einträge" + "message": "Standard Auto-Ausfüllen Einstellung für Zugangsdaten-Einträge" }, "defaultAutoFillOnPageLoadDesc": { "message": "Du kannst Auto-Ausfüllen beim Laden der Seite für einzelne Zugangsdaten-Einträge in der Bearbeiten-Ansicht des Eintrags deaktivieren." @@ -1965,7 +1965,7 @@ "description": "URI match detection for autofill." }, "defaultMatchDetection": { - "message": "Standard-Match-Erkennung", + "message": "Standard Übereinstimmungserkennung", "description": "Default URI match detection for autofill." }, "toggleOptions": { @@ -2505,14 +2505,14 @@ "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAltPeriod": { - "message": "Illustration of a list of logins that are at-risk." + "message": "Illustration einer Liste gefährdeter Zugangsdaten." }, "generatePasswordSlideDesc": { "message": "Generiere schnell ein starkes, einzigartiges Passwort mit dem Bitwarden Auto-Ausfüllen-Menü auf der gefährdeten Website.", "description": "Description of the generate password slide on the at-risk password page carousel" }, "generatePasswordSlideImgAltPeriod": { - "message": "Illustration of the Bitwarden autofill menu displaying a generated password." + "message": "Illustration des Bitwarden Auto-Ausfüllen-Menüs, das ein generiertes Passwort anzeigt." }, "updateInBitwarden": { "message": "In Bitwarden aktualisieren" @@ -2522,7 +2522,7 @@ "description": "Description of the update in Bitwarden slide on the at-risk password page carousel" }, "updateInBitwardenSlideImgAltPeriod": { - "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." + "message": "Illustration einer Bitwarden-Benachrichtigung, die den Benutzer dazu auffordert, die Zugangsdaten zu aktualisieren." }, "turnOnAutofill": { "message": "Auto-Ausfüllen aktivieren" @@ -2978,7 +2978,7 @@ } }, "exportingIndividualVaultWithAttachmentsDescription": { - "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "message": "Nur die einzelnen Tresor-Einträge einschließlich Anhängen von $EMAIL$ werden exportiert. Tresor-Einträge der Organisation werden nicht berücksichtigt", "placeholders": { "email": { "content": "$1", @@ -4244,7 +4244,7 @@ } }, "viewItemTitleWithField": { - "message": "View item - $ITEMNAME$ - $FIELD$", + "message": "Eintrag ansehen - $ITEMNAME$ - $FIELD$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4268,7 +4268,7 @@ } }, "autofillTitleWithField": { - "message": "Autofill - $ITEMNAME$ - $FIELD$", + "message": "Auto-Ausfüllen - $ITEMNAME$ - $FIELD$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Gefährdetes Passwort ändern" + }, + "introCarouselLabel": { + "message": "Willkommen bei Bitwarden" + }, + "securityPrioritized": { + "message": "Sicherheit, priorisiert" + }, + "securityPrioritizedBody": { + "message": "Speichere Zugangsdaten, Karten und Identitäten in deinem sicheren Tresor. Bitwarden verwendet Zero-Knowledge und Ende-zu-Ende-Verschlüsselung, um das zu schützen, was für dich wichtig ist." + }, + "quickLogin": { + "message": "Schnelle und einfache Anmeldung" + }, + "quickLoginBody": { + "message": "Richte biometrisches Entsperren und Auto-Ausfüllen ein, um dich ohne einen einzigen Buchstaben einzugeben bei deinen Konten anzumelden." + }, + "secureUser": { + "message": "Optimiere deine Zugangsdaten" + }, + "secureUserBody": { + "message": "Verwende den Generator, um einzigartige Passwörter für alle deine Konten zu erstellen und zu speichern." + }, + "secureDevices": { + "message": "Deine Daten, wann und wo du sie brauchst" + }, + "secureDevicesBody": { + "message": "Speicher eine unbegrenzte Anzahl von Passwörter auf unbegrenzt vielen Geräten mit Bitwarden-Apps für Smartphones, Browser und Desktop." } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index a4564b3705e..f1e6c6cb6e1 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index f19382347b0..321e17eaa75 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritised" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index eb86d90a74e..2432a120295 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritised" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 11d21e74d0f..55379670548 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 8576ee1db7e..9a1b4037b8f 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 542c9a0d03f..2d04203bc01 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 91acd3c7081..e7d5f58e49c 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 0875639868e..e108f2ceab6 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Vaihda vaarantunut salasana" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 939137c36ce..e288bd2195a 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 488cec4066d..254c18556f7 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Changer le mot de passe à risque" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 23a29400e25..efed6c4bbd4 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index bff75506ad0..7350c865e5e 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "שנה סיסמה בסיכון" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 215ea3e9cd4..1815ab4118b 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 1549c5c793a..5c6cf17f02c 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Promijeni rizičnu lozinku" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 92745a09c3d..50f02f2bc75 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Kockázatos jelszó megváltoztatása" + }, + "introCarouselLabel": { + "message": "Üdvözlet a Bitwardenben" + }, + "securityPrioritized": { + "message": "Biztonság, prioritásos" + }, + "securityPrioritizedBody": { + "message": "Mentsük el a bejelentkezési adatokat, kártyákat és azonosításokat a biztonságos széfbe. A Bitwarden tudás nélküli, végpontok közötti titkosítást használ a felhasználók számára fontos dolgok védelmére." + }, + "quickLogin": { + "message": "Gyors és könnyű bejelentkezés" + }, + "quickLoginBody": { + "message": "Állítsuk be a biometrikus feloldást és az automatikus kitöltést, hogy egyetlen betű beírása nélkül jelentkezzünk be a fiókokba." + }, + "secureUser": { + "message": "A bejelentkezések magasabb szintre emelése" + }, + "secureUserBody": { + "message": "Használjuk a generátort, hogy erős, egyedi jelszavakat hozzunk létre és mentsük az összes fióknál." + }, + "secureDevices": { + "message": "Saját adatok, mikor és hol van rá szükség" + }, + "secureDevicesBody": { + "message": "Mentsünk el a korlátlan jelszót korlátlan számú eszközön a Bitwarden mobil, böngésző és asztali alkalmazásokkal." } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index b9218126dbb..91a4447b9b2 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Ubah kata sandi yang berrisiko" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index cd7daff61f5..c3ecb237732 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Cambia parola d'accesso a rischio" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index c49688b9e7a..9bacc66bce3 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "危険なパスワードの変更" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 71032cbedf9..8ad1efeb4a2 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 19e11bd4579..c43d83029c9 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index dc82624e0df..8415a9fbf3f 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 990f43d5d7d..00d3c7e31ac 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index fb010417cee..53dc8a85743 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 85e08f44da5..d9438c91bcb 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 8a580999709..a1447331124 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index c794ed94a86..8832e30fa0c 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 19e11bd4579..c43d83029c9 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 4eac03f91d6..303f9fc8487 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 19e11bd4579..c43d83029c9 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 129dd8e4b7b..2f1ecad557f 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Risicovol wachtwoord wijzigen" + }, + "introCarouselLabel": { + "message": "Welkom bij Bitwarden" + }, + "securityPrioritized": { + "message": "Security, geprioriteerd" + }, + "securityPrioritizedBody": { + "message": "Logins, kaarten en identiteiten in je beveiligde kluis opslaan. Bitwarden gebruikt zero-knowledge, end-to-end versleuteling om te beschermen wat belangrijk voor jou is." + }, + "quickLogin": { + "message": "Snel en eenvoudig inloggen" + }, + "quickLoginBody": { + "message": "Biometrische ontgrendelen en automatisch invullen instellen zodat je kunt inloggen op je accounts zonder één letter te typen." + }, + "secureUser": { + "message": "Versterk je logins" + }, + "secureUserBody": { + "message": "Gebruik de generator voor het aanmaken en bewaren van sterke, unieke wachtwoorden voor al je accounts." + }, + "secureDevices": { + "message": "Jouw gegevens, wanneer en waar je ze nodig hebt" + }, + "secureDevicesBody": { + "message": "Onbeperkt wachtwoorden opslaan op alle apparaten met Bitwarden-apps voor mobiel, browser en desktop." } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 19e11bd4579..c43d83029c9 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 19e11bd4579..c43d83029c9 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 1657aea6f32..13587a74e52 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Zmień hasło zagrożone" + }, + "introCarouselLabel": { + "message": "Witaj w Bitwarden" + }, + "securityPrioritized": { + "message": "Bezpieczeństwo priorytetem" + }, + "securityPrioritizedBody": { + "message": "Zapisz dane logowania, karty i tożsamości w bezpiecznym sejfie. Bitwarden stosuje szyfrowanie end-to-end z wiedzą zerową, aby chronić to, co jest dla Ciebie ważne." + }, + "quickLogin": { + "message": "Szybkie i łatwe logowanie" + }, + "quickLoginBody": { + "message": "Skonfiguruj odblokowanie i autouzupełnianie biometryczne, aby zalogować się na swoje konta bez wpisywania pojedynczej litery." + }, + "secureUser": { + "message": "Ulepsz swoje loginy" + }, + "secureUserBody": { + "message": "Użyj generatora do tworzenia i zapisywania silnych, unikalnych haseł dla wszystkich kont." + }, + "secureDevices": { + "message": "Twoje dane, kiedy i gdzie potrzebujesz" + }, + "secureDevicesBody": { + "message": "Zapisuj nieograniczoną liczbę haseł na nieograniczonej liczbie urządzeń dzięki aplikacjom Bitwarden na urządzenia mobilne, przeglądarki i komputery stacjonarne." } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 0961f0f596c..3ffceca3611 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Alterar senhas vulneráveis" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index bc836cbd03e..a4e0a0de541 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Alterar palavra-passe em risco" + }, + "introCarouselLabel": { + "message": "Bem-vindo ao Bitwarden" + }, + "securityPrioritized": { + "message": "Segurança, com prioridade" + }, + "securityPrioritizedBody": { + "message": "Guarde credenciais, cartões e identidades no seu cofre seguro. O Bitwarden utiliza encriptação de ponto a ponto e conhecimento zero para proteger o que é importante para si." + }, + "quickLogin": { + "message": "Início de sessão rápido e fácil" + }, + "quickLoginBody": { + "message": "Configure o desbloqueio biométrico e o preenchimento automático para iniciar sessão nas suas contas sem escrever uma única letra." + }, + "secureUser": { + "message": "Eleve o nível das suas credenciais" + }, + "secureUserBody": { + "message": "Utilize o gerador para criar e guardar palavras-passe fortes e únicas para todas as suas contas." + }, + "secureDevices": { + "message": "Os seus dados, quando e onde precisar" + }, + "secureDevicesBody": { + "message": "Guarde palavras-passe ilimitadas em dispositivos ilimitados com as apps Bitwarden para telemóvel, navegador e computador." } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 6d6fc724ec9..9ce305ff74c 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 03ce360c68f..3847f3eb4fc 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Изменить пароль, подверженный риску" + }, + "introCarouselLabel": { + "message": "Добро пожаловать в Bitwarden" + }, + "securityPrioritized": { + "message": "Безопасность, приоритет" + }, + "securityPrioritizedBody": { + "message": "Сохраняйте логины, карты и личные данные в своем защищенном хранилище. Bitwarden использует сквозное шифрование, чтобы защитить то, что для вас важно." + }, + "quickLogin": { + "message": "Быстрая и простая авторизация" + }, + "quickLoginBody": { + "message": "Настройте биометрическую разблокировку и автозаполнение, чтобы входить в свои аккаунты, не набирая ни одной буквы." + }, + "secureUser": { + "message": "Сделайте авторизацию еще проще" + }, + "secureUserBody": { + "message": "Используйте генератор для создания и сохранения надежных, уникальных паролей для всех ваших аккаунтов." + }, + "secureDevices": { + "message": "Ваши данные, в любое время в любом месте" + }, + "secureDevicesBody": { + "message": "Сохраняйте неограниченное количество паролей на неограниченном количестве устройств с помощью мобильных, браузерных и десктопных приложений Bitwarden." } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index d44ec8188de..db54d7f7c18 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 96b042bf7eb..555e01fec20 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Zmeniť rizikové heslá" + }, + "introCarouselLabel": { + "message": "Vitajte v Bitwardene" + }, + "securityPrioritized": { + "message": "Bezpečnosť na prvom mieste" + }, + "securityPrioritizedBody": { + "message": "Ukladajte prihlasovacie údaje, karty a identity do zabezpečeného trezoru. Bitwarden používa šifrovanie s nulovou znalosťou od začiatku do konca na ochranu toho, čo je pre vás dôležité." + }, + "quickLogin": { + "message": "Rýchle a jednoduché prihlásenie" + }, + "quickLoginBody": { + "message": "Nastavte si odomykanie biometrickými údajmi a automatické vypĺňanie na prihlasovanie do účtov bez zadávania jediného písmena." + }, + "secureUser": { + "message": "Posuňte prihlasovanie na vyššiu úroveň" + }, + "secureUserBody": { + "message": "Pomocou generátora vytvorte a uložte silné a jedinečné heslá pre všetky svoje účty." + }, + "secureDevices": { + "message": "Vaše údaje, kedykoľvek a kdekoľvek ich potrebujete" + }, + "secureDevicesBody": { + "message": "Ukladajte neobmedzený počet hesiel na neobmedzenom počte zariadení pomocou mobilných aplikácií, prehliadačov a desktopových aplikácií Bitwardenu." } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 704a9983d80..c7dc9590fe0 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 9bc9d122d75..2fdbad437c9 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Променити ризичну лозинку" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 83a6f0a49b6..15de82320b8 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -194,7 +194,7 @@ "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { - "message": "Fyll i automatiskt" + "message": "Autofyll" }, "autoFillLogin": { "message": "Autofyll inloggning" @@ -1530,10 +1530,10 @@ "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "Förslag för autofyll" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "Visa förslag för autofyll i formulärfält" }, "showInlineMenuIdentitiesLabel": { "message": "Visa identiteter som förslag" @@ -1566,7 +1566,7 @@ "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "Autofyll vid sidladdning" }, "enableAutoFillOnPageLoad": { "message": "Aktivera automatisk ifyllnad vid sidhämtning" @@ -2428,7 +2428,7 @@ "message": "Autofill is blocked for this website." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "Ändra detta i inställningar" }, "change": { "message": "Change" @@ -2525,10 +2525,10 @@ "message": "Illustration of a Bitwarden’s notification prompting the user to update the login." }, "turnOnAutofill": { - "message": "Turn on autofill" + "message": "Aktivera autofyll" }, "turnedOnAutofill": { - "message": "Turned on autofill" + "message": "Aktiverade autofyll" }, "dismiss": { "message": "Dismiss" @@ -3384,7 +3384,7 @@ "message": "Inställningar för automatisk ifyllnad" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Kortkommando för autofyll" }, "autofillKeyboardShortcutUpdateLabel": { "message": "Ändra genväg" @@ -3396,7 +3396,7 @@ "message": "Tangentbordsgenväg för automatisk ifyllnad" }, "autofillLoginShortcutNotSet": { - "message": "The autofill login shortcut is not set. Change this in the browser's settings." + "message": "Kortkommandot för autofyll av inloggning är inte inställt. Du kan ändra det i webbläsarens inställningar." }, "autofillLoginShortcutText": { "message": "The autofill login shortcut is $COMMAND$. Manage all shortcuts in the browser's settings.", @@ -4365,7 +4365,7 @@ "message": "Objekt utan mapp" }, "itemDetails": { - "message": "Item details" + "message": "Objektdetaljer" }, "itemName": { "message": "Objektnamn" @@ -4456,13 +4456,13 @@ } }, "personalDetails": { - "message": "Personal details" + "message": "Personuppgifter" }, "identification": { "message": "Identifikation" }, "contactInfo": { - "message": "Contact info" + "message": "Kontaktuppgifter" }, "downloadAttachment": { "message": "Download - $ITEMNAME$", @@ -4478,13 +4478,13 @@ "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Login credentials" + "message": "Inloggningsuppgifter" }, "authenticatorKey": { "message": "Autentiseringsnyckel" }, "autofillOptions": { - "message": "Autofill options" + "message": "Alternativ för autofyll" }, "websiteUri": { "message": "Webbplats (URI)" @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 19e11bd4579..c43d83029c9 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 6942485618d..8ac6e7197d8 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 6388b3d04a3..a19d4977ed5 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -881,7 +881,7 @@ "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Girişi tamamlamak için aşağıdaki adımları izleyin." }, "restartRegistration": { "message": "Kaydı yeniden başlat" @@ -1407,14 +1407,14 @@ } }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" + "message": "Bu cihazda 30 gün boyunca sorma" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Başka bir yöntem seç", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" + "message": "Kurtarma kodu kullan" }, "insertU2f": { "message": "Güvenlik anahtarınızı bilgisayarınızın USB portuna takın. Düğmesi varsa dokunun." @@ -1426,7 +1426,7 @@ "message": "WebAutn ile doğrula" }, "readSecurityKey": { - "message": "Read security key" + "message": "Güvenlik anahtarını oku" }, "awaitingSecurityKeyInteraction": { "message": "Awaiting security key interaction..." @@ -1444,7 +1444,7 @@ "message": "İki aşamalı giriş seçenekleri" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "İki aşamalı giriş yöntemini seçin" }, "recoveryCodeDesc": { "message": "İki aşamalı doğrulama sağlayıcılarınıza ulaşamıyor musunuz? Kurtarma kodunuzu kullanarak hesabınızdaki tüm iki aşamalı giriş sağlayıcılarını devre dışı bırakabilirsiniz." @@ -2149,7 +2149,7 @@ "message": "Customize your vault experience with quick copy actions, compact mode, and more!" }, "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" + "message": "Görünüm ayarlarının hepsini göster" }, "lock": { "message": "Kilitle", @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Bitwarden’a hoş geldiniz" + }, + "securityPrioritized": { + "message": "Önce güvenlik" + }, + "securityPrioritizedBody": { + "message": "Hesaplarınızı, kartlarınızı ve kimliklerinizi güvenli kasanıza kaydedin. Bitwarden'ın sıfır bilgi ispatlı uçtan uca şifrelemesi sizin için önemli olan her şeyi korur." + }, + "quickLogin": { + "message": "Hızlı ve kolay giriş" + }, + "quickLoginBody": { + "message": "Hesaplarınıza parola yazmadan giriş yapmak için biyometrik kilit açmayı ayarlayabilirsiniz." + }, + "secureUser": { + "message": "Hesaplarınızı güçlendirin" + }, + "secureUserBody": { + "message": "Hesaplarınız için güçlü ve benzersiz parolalar oluşturmak amacıyla üreteci kullanabilirsiniz." + }, + "secureDevices": { + "message": "Verilerinize her zaman, her yerden ulaşın" + }, + "secureDevicesBody": { + "message": "Bitwarden mobil, tarayıcı ve masaüstü uygulamalarıyla istediğiniz kadar cihaza istediğiniz kadar parola kaydedebilirsiniz." } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 5e7c1bdd660..6558796bfb5 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Змінити ризикований пароль" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index c0bded59ef9..a2b6756785c 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 3683e769914..adbc102c496 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -3306,13 +3306,13 @@ "message": "通知已发送到您的设备。" }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the" + "message": "解锁您设备上的 Bitwarden 或通过" }, "notificationSentDeviceAnchor": { "message": "网页 App" }, "notificationSentDevicePart2": { - "message": "在批准前,请确保指纹短语与下面的相匹配。" + "message": "批准前,请确保指纹短语与下面的相匹配。" }, "aNotificationWasSentToYourDevice": { "message": "通知已发送到您的设备" @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "更改有风险的密码" + }, + "introCarouselLabel": { + "message": "欢迎使用 Bitwarden" + }, + "securityPrioritized": { + "message": "安全优先" + }, + "securityPrioritizedBody": { + "message": "将登录、支付卡和身份保存到您的安全密码库。Bitwarden 使用零知识、端到端的加密来保护您的重要信息。" + }, + "quickLogin": { + "message": "快速便捷的登录" + }, + "quickLoginBody": { + "message": "设置生物识别解锁和自动填充,无需输入任何字符即可登录您的账户。" + }, + "secureUser": { + "message": "提升您的登录体验" + }, + "secureUserBody": { + "message": "使用生成器创建并保存强大且唯一的密码,以保护您的所有账户。" + }, + "secureDevices": { + "message": "随时随地在您需要时获取您的数据" + }, + "secureDevicesBody": { + "message": "使用 Bitwarden 移动端、浏览器和桌面 App 在无限制的设备上保存无限数量的密码。" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index adefe506790..d5d55725444 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -5140,5 +5140,32 @@ }, "changeAtRiskPassword": { "message": "Change at-risk password" + }, + "introCarouselLabel": { + "message": "Welcome to Bitwarden" + }, + "securityPrioritized": { + "message": "Security, prioritized" + }, + "securityPrioritizedBody": { + "message": "Save logins, cards, and identities to your secure vault. Bitwarden uses zero-knowledge, end-to-end encryption to protect what’s important to you." + }, + "quickLogin": { + "message": "Quick and easy login" + }, + "quickLoginBody": { + "message": "Set up biometric unlock and autofill to log into your accounts without typing a single letter." + }, + "secureUser": { + "message": "Level up your logins" + }, + "secureUserBody": { + "message": "Use the generator to create and save strong, unique passwords for all your accounts." + }, + "secureDevices": { + "message": "Your data, when and where you need it" + }, + "secureDevicesBody": { + "message": "Save unlimited passwords across unlimited devices with Bitwarden mobile, browser, and desktop apps." } } From 2e7b50ed2f73464ca890a5d04d6f818004adcb9f Mon Sep 17 00:00:00 2001 From: Github Actions Date: Mon, 7 Apr 2025 10:58:28 +0000 Subject: [PATCH 16/93] Bumped client version(s) --- apps/web/package.json | 2 +- package-lock.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 2af524c92b7..1f4ae9c29cf 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2025.3.1", + "version": "2025.4.0", "scripts": { "build:oss": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" webpack", "build:bit": "cross-env NODE_OPTIONS=\"--max-old-space-size=8192\" webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/package-lock.json b/package-lock.json index d3bb0b9eb0c..7d5d56b46bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -244,7 +244,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2025.3.1" + "version": "2025.4.0" }, "libs/admin-console": { "name": "@bitwarden/admin-console", From c6821608d01842ae8d970a591633be9614454a44 Mon Sep 17 00:00:00 2001 From: Maximilian Power Date: Mon, 7 Apr 2025 13:24:26 +0200 Subject: [PATCH 17/93] [PM-19522] fix for member-access-report columns (#13994) * fix for member-access-report columns * restored tw-w-[278px] classes --------- Co-authored-by: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> --- .../member-access-report.component.html | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/tools/reports/member-access-report/member-access-report.component.html b/bitwarden_license/bit-web/src/app/tools/reports/member-access-report/member-access-report.component.html index f2e550cb68e..31eb54d6110 100644 --- a/bitwarden_license/bit-web/src/app/tools/reports/member-access-report/member-access-report.component.html +++ b/bitwarden_license/bit-web/src/app/tools/reports/member-access-report/member-access-report.component.html @@ -34,20 +34,12 @@

{{ "loading" | i18n }}

- - + - - {{ "members" | i18n }} - {{ "groups" | i18n }} - {{ "collections" | i18n }} - {{ "items" | i18n }} - + {{ "members" | i18n }} + {{ "groups" | i18n }} + {{ "collections" | i18n }} + {{ "items" | i18n }} @@ -64,8 +56,8 @@
- {{ row.groupsCount }} - {{ row.collectionsCount }} - {{ row.itemsCount }} + {{ row.groupsCount }} + {{ row.collectionsCount }} + {{ row.itemsCount }} From 1c44640ea582eb2501a5b8440c70dc16b3207796 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 7 Apr 2025 13:41:19 +0200 Subject: [PATCH 18/93] [PM-16541] Key rotation & enrollment trust for emergency access & organizations (#12655) * Implement key rotation v2 * Pass through masterpassword hint * Properly split old and new code * Mark legacy rotation as deprecated * Throw when data is null * Cleanup * Add tests * Fix build * Update libs/key-management/src/key.service.spec.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Update apps/web/src/app/auth/settings/change-password.component.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Add documentation * Centralize loading logic * Implement trust dialogs * Fix build and clean up * Add tests for accept organization component * Fix enrollment * Update apps/web/src/app/admin-console/organizations/manage/organization-trust.component.html Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Cleanup according to feedback * Change div to ng-container * Init uninited strings * Fix type errors on dialog config * Fix typing * Fix build * Fix build * Update libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.ts Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> * Fix linting * Undo legacy component import change * Simplify dialog text --------- Co-authored-by: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> --- .../manage/organization-trust.component.html | 23 ++++ .../manage/organization-trust.component.ts | 69 ++++++++++ .../organization-user-reset-password-entry.ts | 11 ++ ...zation-user-reset-password.service.spec.ts | 81 ++++++----- ...rganization-user-reset-password.service.ts | 57 ++++++-- .../enroll-master-password-reset.component.ts | 33 ++++- .../models/emergency-access.ts | 4 + .../services/emergency-access.service.spec.ts | 29 +++- .../services/emergency-access.service.ts | 107 +++++++++++---- .../accept-organization.service.spec.ts | 61 ++++++++- .../accept-organization.service.ts | 18 ++- .../user-key-rotation.service.spec.ts | 126 +++++++++++++++++- .../key-rotation/user-key-rotation.service.ts | 98 ++++++++++++-- .../src/app/shared/loose-components.module.ts | 3 + .../organization-options.component.ts | 6 +- apps/web/src/locales/en/messages.json | 54 ++++++++ libs/key-management-ui/src/index.ts | 3 + .../key-rotation-trust-info.component.html | 26 ++++ .../key-rotation-trust-info.component.ts | 58 ++++++++ .../account-recovery-trust.component.html | 21 +++ .../trust/account-recovery-trust.component.ts | 94 +++++++++++++ .../emergency-access-trust.component.html | 32 +++++ .../trust/emergency-access-trust.component.ts | 94 +++++++++++++ .../src/abstractions/key.service.ts | 11 ++ ...ation-key-recovery-provider.abstraction.ts | 31 +++++ libs/key-management/src/index.ts | 1 + 26 files changed, 1048 insertions(+), 103 deletions(-) create mode 100644 apps/web/src/app/admin-console/organizations/manage/organization-trust.component.html create mode 100644 apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts create mode 100644 apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password-entry.ts create mode 100644 libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.html create mode 100644 libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.ts create mode 100644 libs/key-management-ui/src/trust/account-recovery-trust.component.html create mode 100644 libs/key-management-ui/src/trust/account-recovery-trust.component.ts create mode 100644 libs/key-management-ui/src/trust/emergency-access-trust.component.html create mode 100644 libs/key-management-ui/src/trust/emergency-access-trust.component.ts create mode 100644 libs/key-management/src/abstractions/user-key-rotation-key-recovery-provider.abstraction.ts diff --git a/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.html b/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.html new file mode 100644 index 00000000000..9a0310fde2a --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.html @@ -0,0 +1,23 @@ +
+ + + {{ "orgTrustWarning" | i18n }} +

+ {{ "fingerprintPhrase" | i18n }} {{ fingerprint }} +

+
+ + + + +
+
diff --git a/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts b/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts new file mode 100644 index 00000000000..3f013c9fc74 --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/manage/organization-trust.component.ts @@ -0,0 +1,69 @@ +import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, OnInit, Inject } from "@angular/core"; +import { FormBuilder } from "@angular/forms"; + +import { OrganizationManagementPreferencesService } from "@bitwarden/common/admin-console/abstractions/organization-management-preferences/organization-management-preferences.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { DialogService } from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; + +type OrganizationTrustDialogData = { + /** display name of the organization */ + name: string; + /** identifies the organization */ + orgId: string; + /** org public key */ + publicKey: Uint8Array; +}; +@Component({ + selector: "organization-trust", + templateUrl: "organization-trust.component.html", +}) +export class OrganizationTrustComponent implements OnInit { + loading = true; + fingerprint: string = ""; + confirmForm = this.formBuilder.group({}); + + constructor( + @Inject(DIALOG_DATA) protected params: OrganizationTrustDialogData, + private formBuilder: FormBuilder, + private keyService: KeyService, + protected organizationManagementPreferencesService: OrganizationManagementPreferencesService, + private logService: LogService, + private dialogRef: DialogRef, + ) {} + + async ngOnInit() { + try { + const fingerprint = await this.keyService.getFingerprint( + this.params.orgId, + this.params.publicKey, + ); + if (fingerprint != null) { + this.fingerprint = fingerprint.join("-"); + } + } catch (e) { + this.logService.error(e); + } + this.loading = false; + } + + submit = async () => { + if (this.loading) { + return; + } + + this.dialogRef.close(true); + }; + + /** + * Strongly typed helper to open a OrganizationTrustComponent + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param data The data to pass to the dialog + */ + static open(dialogService: DialogService, data: OrganizationTrustDialogData) { + return dialogService.open(OrganizationTrustComponent, { + data, + }); + } +} diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password-entry.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password-entry.ts new file mode 100644 index 00000000000..64dbef574c7 --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password-entry.ts @@ -0,0 +1,11 @@ +export class OrganizationUserResetPasswordEntry { + orgId: string; + publicKey: Uint8Array; + orgName: string; + + constructor(orgId: string, publicKey: Uint8Array, orgName: string) { + this.orgId = orgId; + this.publicKey = publicKey; + this.orgName = orgName; + } +} diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts index eff417ead32..ce167950727 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { mock, MockProxy } from "jest-mock-extended"; -import { of } from "rxjs"; +import { BehaviorSubject, of } from "rxjs"; import { OrganizationUserApiService, @@ -14,6 +14,7 @@ import { OrganizationApiService } from "@bitwarden/common/admin-console/services import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { EncryptionType } from "@bitwarden/common/platform/enums"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; @@ -23,6 +24,9 @@ import { KdfType, KeyService } from "@bitwarden/key-management"; import { OrganizationUserResetPasswordService } from "./organization-user-reset-password.service"; +const mockUserKey = new SymmetricCryptoKey(new Uint8Array(64) as CsprngArray) as UserKey; +const mockPublicKeys = [Utils.fromUtf8ToArray("test-public-key")]; + describe("OrganizationUserResetPasswordService", () => { let sut: OrganizationUserResetPasswordService; @@ -51,6 +55,21 @@ describe("OrganizationUserResetPasswordService", () => { ); }); + beforeEach(() => { + organizationService.organizations$.mockReturnValue( + new BehaviorSubject([ + createOrganization("1", "org1", true), + createOrganization("2", "org2", false), + ]), + ); + organizationApiService.getKeys.mockResolvedValue( + new OrganizationKeysResponse({ + privateKey: "privateKey", + publicKey: "publicKey", + }), + ); + }); + afterEach(() => { jest.resetAllMocks(); }); @@ -59,55 +78,47 @@ describe("OrganizationUserResetPasswordService", () => { expect(sut).toBeTruthy(); }); - describe("getRecoveryKey", () => { + describe("buildRecoveryKey", () => { const mockOrgId = "test-org-id"; beforeEach(() => { organizationApiService.getKeys.mockResolvedValue( new OrganizationKeysResponse({ privateKey: "test-private-key", - publicKey: "test-public-key", + publicKey: Utils.fromUtf8ToArray("test-public-key"), }), ); - const mockRandomBytes = new Uint8Array(64) as CsprngArray; - const mockUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey; - keyService.getUserKey.mockResolvedValue(mockUserKey); - encryptService.rsaEncrypt.mockResolvedValue( new EncString(EncryptionType.Rsa2048_OaepSha1_B64, "mockEncryptedUserKey"), ); }); it("should return an encrypted user key", async () => { - const encryptedString = await sut.buildRecoveryKey(mockOrgId); + const encryptedString = await sut.buildRecoveryKey(mockOrgId, mockUserKey, mockPublicKeys); expect(encryptedString).toBeDefined(); }); - it("should only use the user key from memory if one is not provided", async () => { - const mockRandomBytes = new Uint8Array(64) as CsprngArray; - const mockUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey; - - await sut.buildRecoveryKey(mockOrgId, mockUserKey); - - expect(keyService.getUserKey).not.toHaveBeenCalled(); - }); - it("should throw an error if the organization keys are null", async () => { organizationApiService.getKeys.mockResolvedValue(null); - await expect(sut.buildRecoveryKey(mockOrgId)).rejects.toThrow(); + await expect(sut.buildRecoveryKey(mockOrgId, mockUserKey, mockPublicKeys)).rejects.toThrow(); }); it("should throw an error if the user key can't be found", async () => { keyService.getUserKey.mockResolvedValue(null); - await expect(sut.buildRecoveryKey(mockOrgId)).rejects.toThrow(); + await expect(sut.buildRecoveryKey(mockOrgId, null, mockPublicKeys)).rejects.toThrow(); }); it("should rsa encrypt the user key", async () => { - await sut.buildRecoveryKey(mockOrgId); - + await sut.buildRecoveryKey(mockOrgId, mockUserKey, mockPublicKeys); expect(encryptService.rsaEncrypt).toHaveBeenCalledWith(expect.anything(), expect.anything()); }); + + it("should throw an error if the public key is not trusted", async () => { + await expect( + sut.buildRecoveryKey(mockOrgId, mockUserKey, [new Uint8Array(64)]), + ).rejects.toThrow(); + }); }); describe("resetMasterPassword", () => { @@ -163,6 +174,20 @@ describe("OrganizationUserResetPasswordService", () => { }); }); + describe("getPublicKeys", () => { + it("should return public keys for organizations that have reset password enrolled", async () => { + const result = await sut.getPublicKeys("userId" as UserId); + expect(result).toHaveLength(1); + }); + + it("should result should contain the correct data for the org", async () => { + const result = await sut.getPublicKeys("userId" as UserId); + expect(result[0].orgId).toBe("1"); + expect(result[0].orgName).toBe("org1"); + expect(result[0].publicKey).toEqual(Utils.fromB64ToArray("publicKey")); + }); + }); + describe("getRotatedData", () => { beforeEach(() => { organizationService.organizations$.mockReturnValue( @@ -171,7 +196,7 @@ describe("OrganizationUserResetPasswordService", () => { organizationApiService.getKeys.mockResolvedValue( new OrganizationKeysResponse({ privateKey: "test-private-key", - publicKey: "test-public-key", + publicKey: Utils.fromUtf8ToArray("test-public-key"), }), ); encryptService.rsaEncrypt.mockResolvedValue( @@ -182,7 +207,7 @@ describe("OrganizationUserResetPasswordService", () => { it("should return all re-encrypted account recovery keys", async () => { const result = await sut.getRotatedData( new SymmetricCryptoKey(new Uint8Array(64)) as UserKey, - new SymmetricCryptoKey(new Uint8Array(64)) as UserKey, + mockPublicKeys, "mockUserId" as UserId, ); @@ -191,22 +216,18 @@ describe("OrganizationUserResetPasswordService", () => { it("throws if the new user key is null", async () => { await expect( - sut.getRotatedData( - new SymmetricCryptoKey(new Uint8Array(64)) as UserKey, - null, - "mockUserId" as UserId, - ), + sut.getRotatedData(null, mockPublicKeys, "mockUserId" as UserId), ).rejects.toThrow("New user key is required for rotation."); }); }); }); -function createOrganization(id: string, name: string) { +function createOrganization(id: string, name: string, resetPasswordEnrolled = true): Organization { const org = new Organization(); org.id = id; org.name = name; org.identifier = name; org.isMember = true; - org.resetPasswordEnrolled = true; + org.resetPasswordEnrolled = resetPasswordEnrolled; return org; } diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts index 8e583d3106c..4b5c03a5a5b 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts @@ -21,16 +21,22 @@ import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig, - UserKeyRotationDataProvider, + UserKeyRotationKeyRecoveryProvider, KeyService, KdfType, } from "@bitwarden/key-management"; +import { OrganizationUserResetPasswordEntry } from "./organization-user-reset-password-entry"; + @Injectable({ providedIn: "root", }) export class OrganizationUserResetPasswordService - implements UserKeyRotationDataProvider + implements + UserKeyRotationKeyRecoveryProvider< + OrganizationUserResetPasswordWithIdRequest, + OrganizationUserResetPasswordEntry + > { constructor( private keyService: KeyService, @@ -42,11 +48,17 @@ export class OrganizationUserResetPasswordService ) {} /** - * Returns the user key encrypted by the organization's public key. - * Intended for use in enrollment + * Builds a recovery key for a user to recover their account. + * * @param orgId desired organization + * @param userKey user key + * @param trustedPublicKeys public keys of organizations that the user trusts */ - async buildRecoveryKey(orgId: string, userKey?: UserKey): Promise { + async buildRecoveryKey( + orgId: string, + userKey: UserKey, + trustedPublicKeys: Uint8Array[], + ): Promise { // Retrieve Public Key const orgKeys = await this.organizationApiService.getKeys(orgId); if (orgKeys == null) { @@ -55,13 +67,16 @@ export class OrganizationUserResetPasswordService const publicKey = Utils.fromB64ToArray(orgKeys.publicKey); - // RSA Encrypt user key with organization's public key - userKey ??= await this.keyService.getUserKey(); - if (userKey == null) { - throw new Error("No user key found"); + if ( + !trustedPublicKeys.some( + (key) => Utils.fromBufferToHex(key) === Utils.fromBufferToHex(publicKey), + ) + ) { + throw new Error("Untrusted public key"); } - const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey); + // RSA Encrypt user key with organization's public key + const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey); return encryptedKey.encryptedString; } @@ -138,6 +153,21 @@ export class OrganizationUserResetPasswordService ); } + async getPublicKeys(userId: UserId): Promise { + const allOrgs = (await firstValueFrom(this.organizationService.organizations$(userId))).filter( + (org) => org.resetPasswordEnrolled, + ); + + const entries: OrganizationUserResetPasswordEntry[] = []; + for (const org of allOrgs) { + const publicKey = await this.organizationApiService.getKeys(org.id); + const encodedPublicKey = Utils.fromB64ToArray(publicKey.publicKey); + const entry = new OrganizationUserResetPasswordEntry(org.id, encodedPublicKey, org.name); + entries.push(entry); + } + return entries; + } + /** * Returns existing account recovery keys re-encrypted with the new user key. * @param originalUserKey the original user key @@ -147,8 +177,8 @@ export class OrganizationUserResetPasswordService * @returns a list of account recovery keys that have been re-encrypted with the new user key */ async getRotatedData( - originalUserKey: UserKey, newUserKey: UserKey, + trustedPublicKeys: Uint8Array[], userId: UserId, ): Promise { if (newUserKey == null) { @@ -156,9 +186,8 @@ export class OrganizationUserResetPasswordService } const allOrgs = await firstValueFrom(this.organizationService.organizations$(userId)); - if (!allOrgs) { - return; + throw new Error("Could not get organizations"); } const requests: OrganizationUserResetPasswordWithIdRequest[] = []; @@ -169,7 +198,7 @@ export class OrganizationUserResetPasswordService } // Re-enroll - encrypt user key with organization public key - const encryptedKey = await this.buildRecoveryKey(org.id, newUserKey); + const encryptedKey = await this.buildRecoveryKey(org.id, newUserKey, trustedPublicKeys); // Create/Execute request const request = new OrganizationUserResetPasswordWithIdRequest(); diff --git a/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts b/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts index d603f154dfd..15e7af1cd2d 100644 --- a/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts +++ b/apps/web/src/app/admin-console/organizations/users/enroll-master-password-reset.component.ts @@ -1,19 +1,25 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { firstValueFrom, lastValueFrom } from "rxjs"; + import { OrganizationUserApiService, OrganizationUserResetPasswordEnrollmentRequest, } from "@bitwarden/admin-console/common"; import { UserVerificationDialogComponent } from "@bitwarden/auth/angular"; +import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationWithSecret } from "@bitwarden/common/auth/types/verification"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; +import { OrganizationTrustComponent } from "../manage/organization-trust.component"; import { OrganizationUserResetPasswordService } from "../members/services/organization-user-reset-password/organization-user-reset-password.service"; interface EnrollMasterPasswordResetData { @@ -28,12 +34,14 @@ export class EnrollMasterPasswordReset { data: EnrollMasterPasswordResetData, resetPasswordService: OrganizationUserResetPasswordService, organizationUserApiService: OrganizationUserApiService, - platformUtilsService: PlatformUtilsService, i18nService: I18nService, syncService: SyncService, logService: LogService, userVerificationService: UserVerificationService, toastService: ToastService, + keyService: KeyService, + accountService: AccountService, + organizationApiService: OrganizationApiServiceAbstraction, ) { const result = await UserVerificationDialogComponent.open(dialogService, { title: "enrollAccountRecovery", @@ -44,12 +52,33 @@ export class EnrollMasterPasswordReset { verificationType: { type: "custom", verificationFn: async (secret: VerificationWithSecret) => { + const activeUserId = (await firstValueFrom(accountService.activeAccount$)).id; + + const publicKey = Utils.fromB64ToArray( + (await organizationApiService.getKeys(data.organization.id)).publicKey, + ); + const request = await userVerificationService.buildRequest( secret, ); + const dialogRef = OrganizationTrustComponent.open(dialogService, { + name: data.organization.name, + orgId: data.organization.id, + publicKey, + }); + const result = await lastValueFrom(dialogRef.closed); + if (result !== true) { + throw new Error("Organization not trusted, aborting user key rotation"); + } + + const trustedOrgPublicKeys = [publicKey]; + const userKey = await firstValueFrom(keyService.userKey$(activeUserId)); + request.resetPasswordKey = await resetPasswordService.buildRecoveryKey( data.organization.id, + userKey, + trustedOrgPublicKeys, ); // Process the enrollment request, which is an endpoint that is diff --git a/apps/web/src/app/auth/emergency-access/models/emergency-access.ts b/apps/web/src/app/auth/emergency-access/models/emergency-access.ts index 8fe53f52e57..b8ae5907bb9 100644 --- a/apps/web/src/app/auth/emergency-access/models/emergency-access.ts +++ b/apps/web/src/app/auth/emergency-access/models/emergency-access.ts @@ -42,3 +42,7 @@ export class ViewTypeEmergencyAccess { keyEncrypted: string; ciphers: CipherResponse[] = []; } + +export class GranteeEmergencyAccessWithPublicKey extends GranteeEmergencyAccess { + publicKey: Uint8Array; +} diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts index dfeb53f0c19..6ad2c4de70e 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts @@ -11,6 +11,7 @@ import { UserKeyResponse } from "@bitwarden/common/models/response/user-key.resp import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { EncryptionType } from "@bitwarden/common/platform/enums"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; @@ -41,6 +42,9 @@ describe("EmergencyAccessService", () => { let emergencyAccessService: EmergencyAccessService; let configService: ConfigService; + const mockNewUserKey = new SymmetricCryptoKey(new Uint8Array(64)) as UserKey; + const mockTrustedPublicKeys = [Utils.fromUtf8ToArray("trustedPublicKey")]; + beforeAll(() => { emergencyAccessApiService = mock(); apiService = mock(); @@ -226,10 +230,6 @@ describe("EmergencyAccessService", () => { }); describe("getRotatedData", () => { - const mockRandomBytes = new Uint8Array(64) as CsprngArray; - const mockOriginalUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey; - const mockNewUserKey = new SymmetricCryptoKey(mockRandomBytes) as UserKey; - const allowedStatuses = [ EmergencyAccessStatusType.Confirmed, EmergencyAccessStatusType.RecoveryInitiated, @@ -250,7 +250,7 @@ describe("EmergencyAccessService", () => { emergencyAccessApiService.getEmergencyAccessTrusted.mockResolvedValue(mockEmergencyAccess); apiService.getUserPublicKey.mockResolvedValue({ userId: "mockUserId", - publicKey: "mockPublicKey", + publicKey: Utils.fromUtf8ToB64("trustedPublicKey"), } as UserKeyResponse); encryptService.rsaEncrypt.mockImplementation((plainValue, publicKey) => { @@ -262,17 +262,32 @@ describe("EmergencyAccessService", () => { it("Only returns emergency accesses with allowed statuses", async () => { const result = await emergencyAccessService.getRotatedData( - mockOriginalUserKey, mockNewUserKey, + mockTrustedPublicKeys, "mockUserId" as UserId, ); expect(result).toHaveLength(allowedStatuses.length); }); + it("Throws if emergency access public key is not trusted", async () => { + apiService.getUserPublicKey.mockResolvedValue({ + userId: "mockUserId", + publicKey: Utils.fromUtf8ToB64("untrustedPublicKey"), + } as UserKeyResponse); + + await expect( + emergencyAccessService.getRotatedData( + mockNewUserKey, + mockTrustedPublicKeys, + "mockUserId" as UserId, + ), + ).rejects.toThrow("Public key for user is not trusted."); + }); + it("throws if new user key is null", async () => { await expect( - emergencyAccessService.getRotatedData(mockOriginalUserKey, null, "mockUserId" as UserId), + emergencyAccessService.getRotatedData(null, mockTrustedPublicKeys, "mockUserId" as UserId), ).rejects.toThrow("New user key is required for rotation."); }); }); diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts index 7ac2f21a223..e86e0822ef3 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts @@ -22,14 +22,18 @@ import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig, - UserKeyRotationDataProvider, KeyService, KdfType, + UserKeyRotationKeyRecoveryProvider, } from "@bitwarden/key-management"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; -import { GranteeEmergencyAccess, GrantorEmergencyAccess } from "../models/emergency-access"; +import { + GranteeEmergencyAccess, + GranteeEmergencyAccessWithPublicKey, + GrantorEmergencyAccess, +} from "../models/emergency-access"; import { EmergencyAccessAcceptRequest } from "../request/emergency-access-accept.request"; import { EmergencyAccessConfirmRequest } from "../request/emergency-access-confirm.request"; import { EmergencyAccessInviteRequest } from "../request/emergency-access-invite.request"; @@ -38,12 +42,17 @@ import { EmergencyAccessUpdateRequest, EmergencyAccessWithIdRequest, } from "../request/emergency-access-update.request"; +import { EmergencyAccessGranteeDetailsResponse } from "../response/emergency-access.response"; import { EmergencyAccessApiService } from "./emergency-access-api.service"; @Injectable() export class EmergencyAccessService - implements UserKeyRotationDataProvider + implements + UserKeyRotationKeyRecoveryProvider< + EmergencyAccessWithIdRequest, + GranteeEmergencyAccessWithPublicKey + > { constructor( private emergencyAccessApiService: EmergencyAccessApiService, @@ -301,30 +310,12 @@ export class EmergencyAccessService this.emergencyAccessApiService.postEmergencyAccessPassword(id, request); } - /** - * Returns existing emergency access keys re-encrypted with new user key. - * Intended for grantor. - * @param originalUserKey the original user key - * @param newUserKey the new user key - * @param userId the user id - * @throws Error if newUserKey is nullish - * @returns an array of re-encrypted emergency access requests or an empty array if there are no requests - */ - async getRotatedData( - originalUserKey: UserKey, - newUserKey: UserKey, - userId: UserId, - ): Promise { - if (newUserKey == null) { - throw new Error("New user key is required for rotation."); - } - - const requests: EmergencyAccessWithIdRequest[] = []; + private async getEmergencyAccessData(): Promise { const existingEmergencyAccess = await this.emergencyAccessApiService.getEmergencyAccessTrusted(); if (!existingEmergencyAccess || existingEmergencyAccess.data.length === 0) { - return requests; + return []; } // Any Invited or Accepted requests won't have the key yet, so we don't need to update them @@ -337,13 +328,73 @@ export class EmergencyAccessService allowedStatuses.has(d.status), ); - for (const details of filteredAccesses) { - // Get public key of grantee - const publicKeyResponse = await this.apiService.getUserPublicKey(details.granteeId); - const publicKey = Utils.fromB64ToArray(publicKeyResponse.publicKey); + return filteredAccesses; + } + + async getPublicKeys(): Promise { + const emergencyAccessData = await this.getEmergencyAccessData(); + const emergencyAccessDataWithPublicKeys = await Promise.all( + emergencyAccessData.map(async (details) => { + const grantee = new GranteeEmergencyAccessWithPublicKey(); + grantee.id = details.id; + grantee.granteeId = details.granteeId; + grantee.name = details.name; + grantee.email = details.email; + grantee.type = details.type; + grantee.status = details.status; + grantee.waitTimeDays = details.waitTimeDays; + grantee.creationDate = details.creationDate; + grantee.avatarColor = details.avatarColor; + grantee.publicKey = Utils.fromB64ToArray( + (await this.apiService.getUserPublicKey(details.granteeId)).publicKey, + ); + return grantee; + }), + ); + + return emergencyAccessDataWithPublicKeys; + } + + /** + * Returns existing emergency access keys re-encrypted with new user key. + * Intended for grantor. + * @param newUserKey the new user key + * @param trustedPublicKeys the public keys of the emergency access grantors. These *must* be trusted somehow, and MUST NOT be passed in untrusted + * @param userId the user id + * @throws Error if newUserKey is nullish + * @returns an array of re-encrypted emergency access requests or an empty array if there are no requests + */ + async getRotatedData( + newUserKey: UserKey, + trustedPublicKeys: Uint8Array[], + userId: UserId, + ): Promise { + if (newUserKey == null) { + throw new Error("New user key is required for rotation."); + } + + const requests: EmergencyAccessWithIdRequest[] = []; + + this.logService.info( + "Starting emergency access rotation, with trusted keys: ", + trustedPublicKeys, + ); + + const allDetails = await this.getPublicKeys(); + for (const details of allDetails) { + if ( + trustedPublicKeys.find( + (pk) => Utils.fromBufferToHex(pk) === Utils.fromBufferToHex(details.publicKey), + ) == null + ) { + this.logService.info( + `Public key for user ${details.granteeId} is not trusted, skipping rotation.`, + ); + throw new Error("Public key for user is not trusted."); + } // Encrypt new user key with public key - const encryptedKey = await this.encryptKey(newUserKey, publicKey); + const encryptedKey = await this.encryptKey(newUserKey, details.publicKey); const updateRequest = new EmergencyAccessWithIdRequest(); updateRequest.id = details.id; diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts b/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts index f613bdc7ddc..e7137e1d5bb 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts +++ b/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts @@ -2,6 +2,7 @@ // @ts-strict-ignore import { FakeGlobalStateProvider } from "@bitwarden/common/../spec/fake-state-provider"; import { MockProxy, mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; import { OrganizationUserApiService } from "@bitwarden/admin-console/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; @@ -11,14 +12,19 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { ResetPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/reset-password-policy-options"; +import { OrganizationKeysResponse } from "@bitwarden/common/admin-console/models/response/organization-keys.response"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { FakeGlobalState } from "@bitwarden/common/spec/fake-state"; import { OrgKey } from "@bitwarden/common/types/key"; +import { DialogService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +import { OrganizationTrustComponent } from "../../admin-console/organizations/manage/organization-trust.component"; import { I18nService } from "../../core/i18n.service"; import { @@ -41,6 +47,8 @@ describe("AcceptOrganizationInviteService", () => { let i18nService: MockProxy; let globalStateProvider: FakeGlobalStateProvider; let globalState: FakeGlobalState; + let dialogService: MockProxy; + let accountService: MockProxy; beforeEach(() => { apiService = mock(); @@ -55,6 +63,8 @@ describe("AcceptOrganizationInviteService", () => { i18nService = mock(); globalStateProvider = new FakeGlobalStateProvider(); globalState = globalStateProvider.getFake(ORGANIZATION_INVITE); + dialogService = mock(); + accountService = mock(); sut = new AcceptOrganizationInviteService( apiService, @@ -68,6 +78,8 @@ describe("AcceptOrganizationInviteService", () => { organizationUserApiService, i18nService, globalStateProvider, + dialogService, + accountService, ); }); @@ -142,7 +154,7 @@ describe("AcceptOrganizationInviteService", () => { expect(authService.logOut).not.toHaveBeenCalled(); }); - it("accepts the invitation request when the org has a master password policy, but the user has already passed it", async () => { + it("accepts the invitation request when the org has a master password policy, but the user has already passed it and autoenroll is not enabled", async () => { const invite = createOrgInvite(); policyApiService.getPoliciesByToken.mockResolvedValue([ { @@ -167,6 +179,53 @@ describe("AcceptOrganizationInviteService", () => { expect(organizationUserApiService.postOrganizationUserAcceptInit).not.toHaveBeenCalled(); expect(authService.logOut).not.toHaveBeenCalled(); }); + + it("accepts the invitation request and enrolls when autoenroll is enabled", async () => { + const invite = createOrgInvite(); + policyApiService.getPoliciesByToken.mockResolvedValue([ + { + type: PolicyType.MasterPassword, + enabled: true, + } as Policy, + ]); + organizationApiService.getKeys.mockResolvedValue( + new OrganizationKeysResponse({ + privateKey: "privateKey", + publicKey: "publicKey", + }), + ); + accountService.activeAccount$ = new BehaviorSubject({ id: "activeUserId" }) as any; + keyService.userKey$.mockReturnValue(new BehaviorSubject({ key: "userKey" } as any)); + encryptService.rsaEncrypt.mockResolvedValue({ + encryptedString: "encryptedString", + } as EncString); + + jest.mock("../../admin-console/organizations/manage/organization-trust.component"); + OrganizationTrustComponent.open = jest.fn().mockReturnValue({ + closed: new BehaviorSubject(true), + }); + + await globalState.update(() => invite); + + policyService.getResetPasswordPolicyOptions.mockReturnValue([ + { + autoEnrollEnabled: true, + } as ResetPasswordPolicyOptions, + true, + ]); + + const result = await sut.validateAndAcceptInvite(invite); + + expect(result).toBe(true); + expect(OrganizationTrustComponent.open).toHaveBeenCalled(); + expect(encryptService.rsaEncrypt).toHaveBeenCalledWith( + "userKey", + Utils.fromB64ToArray("publicKey"), + ); + expect(organizationUserApiService.postOrganizationUserAccept).toHaveBeenCalled(); + expect(organizationUserApiService.postOrganizationUserAcceptInit).not.toHaveBeenCalled(); + expect(authService.logOut).not.toHaveBeenCalled(); + }); }); }); diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.service.ts b/apps/web/src/app/auth/organization-invite/accept-organization.service.ts index 22a79ef3696..837031380f3 100644 --- a/apps/web/src/app/auth/organization-invite/accept-organization.service.ts +++ b/apps/web/src/app/auth/organization-invite/accept-organization.service.ts @@ -15,6 +15,7 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -27,8 +28,11 @@ import { ORGANIZATION_INVITE_DISK, } from "@bitwarden/common/platform/state"; import { OrgKey } from "@bitwarden/common/types/key"; +import { DialogService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +import { OrganizationTrustComponent } from "../../admin-console/organizations/manage/organization-trust.component"; + import { OrganizationInvite } from "./organization-invite"; // We're storing the organization invite for 2 reasons: @@ -63,6 +67,8 @@ export class AcceptOrganizationInviteService { private readonly organizationUserApiService: OrganizationUserApiService, private readonly i18nService: I18nService, private readonly globalStateProvider: GlobalStateProvider, + private readonly dialogService: DialogService, + private readonly accountService: AccountService, ) { this.organizationInvitationState = this.globalStateProvider.get(ORGANIZATION_INVITE); } @@ -183,9 +189,19 @@ export class AcceptOrganizationInviteService { } const publicKey = Utils.fromB64ToArray(response.publicKey); + const dialogRef = OrganizationTrustComponent.open(this.dialogService, { + name: invite.organizationName, + orgId: invite.organizationId, + publicKey, + }); + const result = await firstValueFrom(dialogRef.closed); + if (result !== true) { + throw new Error("Organization not trusted, aborting user key rotation"); + } + const activeUserId = (await firstValueFrom(this.accountService.activeAccount$)).id; + const userKey = await firstValueFrom(this.keyService.userKey$(activeUserId)); // RSA Encrypt user's encKey.key with organization public key - const userKey = await this.keyService.getUserKey(); const encryptedKey = await this.encryptService.rsaEncrypt(userKey.key, publicKey); // Add reset password key to accept request diff --git a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts index 4aa0a753f63..18ee9462f4f 100644 --- a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts +++ b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts @@ -23,17 +23,47 @@ import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.serv import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherWithIdRequest } from "@bitwarden/common/vault/models/request/cipher-with-id.request"; import { FolderWithIdRequest } from "@bitwarden/common/vault/models/request/folder-with-id.request"; -import { ToastService } from "@bitwarden/components"; -import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; +import { DialogService, ToastService } from "@bitwarden/components"; +import { KeyService, DEFAULT_KDF_CONFIG } from "@bitwarden/key-management"; +import { + AccountRecoveryTrustComponent, + EmergencyAccessTrustComponent, + KeyRotationTrustInfoComponent, +} from "@bitwarden/key-management-ui"; import { OrganizationUserResetPasswordService } from "../../admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service"; -import { WebauthnLoginAdminService } from "../../auth/core"; +import { WebauthnLoginAdminService } from "../../auth"; import { EmergencyAccessService } from "../../auth/emergency-access"; +import { EmergencyAccessStatusType } from "../../auth/emergency-access/enums/emergency-access-status-type"; +import { EmergencyAccessType } from "../../auth/emergency-access/enums/emergency-access-type"; import { EmergencyAccessWithIdRequest } from "../../auth/emergency-access/request/emergency-access-update.request"; import { UserKeyRotationApiService } from "./user-key-rotation-api.service"; import { UserKeyRotationService } from "./user-key-rotation.service"; +const initialPromptedOpenTrue = jest.fn(); +initialPromptedOpenTrue.mockReturnValue({ closed: new BehaviorSubject(true) }); +const initialPromptedOpenFalse = jest.fn(); +initialPromptedOpenFalse.mockReturnValue({ closed: new BehaviorSubject(false) }); + +const emergencyAccessTrustOpenTrusted = jest.fn(); +emergencyAccessTrustOpenTrusted.mockReturnValue({ + closed: new BehaviorSubject(true), +}); +const emergencyAccessTrustOpenUntrusted = jest.fn(); +emergencyAccessTrustOpenUntrusted.mockReturnValue({ + closed: new BehaviorSubject(false), +}); + +const accountRecoveryTrustOpenTrusted = jest.fn(); +accountRecoveryTrustOpenTrusted.mockReturnValue({ + closed: new BehaviorSubject(true), +}); +const accountRecoveryTrustOpenUntrusted = jest.fn(); +accountRecoveryTrustOpenUntrusted.mockReturnValue({ + closed: new BehaviorSubject(false), +}); + describe("KeyRotationService", () => { let keyRotationService: UserKeyRotationService; @@ -52,6 +82,7 @@ describe("KeyRotationService", () => { let mockWebauthnLoginAdminService: MockProxy; let mockLogService: MockProxy; let mockVaultTimeoutService: MockProxy; + let mockDialogService: MockProxy; let mockToastService: MockProxy; let mockI18nService: MockProxy; @@ -62,6 +93,8 @@ describe("KeyRotationService", () => { name: "mockName", }; + const mockTrustedPublicKeys = [Utils.fromUtf8ToArray("test-public-key")]; + beforeAll(() => { mockUserVerificationService = mock(); mockApiService = mock(); @@ -69,7 +102,32 @@ describe("KeyRotationService", () => { mockFolderService = mock(); mockSendService = mock(); mockEmergencyAccessService = mock(); + mockEmergencyAccessService.getPublicKeys.mockResolvedValue( + mockTrustedPublicKeys.map((key) => { + return { + publicKey: key, + id: "mockId", + granteeId: "mockGranteeId", + name: "mockName", + email: "mockEmail", + type: EmergencyAccessType.Takeover, + status: EmergencyAccessStatusType.Accepted, + waitTimeDays: 5, + creationDate: "mockCreationDate", + avatarColor: "mockAvatarColor", + }; + }), + ); mockResetPasswordService = mock(); + mockResetPasswordService.getPublicKeys.mockResolvedValue( + mockTrustedPublicKeys.map((key) => { + return { + publicKey: key, + orgId: "mockOrgId", + orgName: "mockOrgName", + }; + }), + ); mockDeviceTrustService = mock(); mockKeyService = mock(); mockEncryptService = mock(); @@ -80,6 +138,7 @@ describe("KeyRotationService", () => { mockVaultTimeoutService = mock(); mockToastService = mock(); mockI18nService = mock(); + mockDialogService = mock(); keyRotationService = new UserKeyRotationService( mockUserVerificationService, @@ -98,9 +157,14 @@ describe("KeyRotationService", () => { mockVaultTimeoutService, mockToastService, mockI18nService, + mockDialogService, ); }); + beforeEach(() => { + jest.mock("@bitwarden/key-management-ui"); + }); + beforeEach(() => { jest.clearAllMocks(); }); @@ -134,6 +198,8 @@ describe("KeyRotationService", () => { // Mock user key mockKeyService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any)); + mockKeyService.getFingerprint.mockResolvedValue(["a", "b"]); + // Mock private key privateKey = new BehaviorSubject("mockPrivateKey" as any); mockKeyService.userPrivateKeyWithLegacySupport$.mockReturnValue(privateKey); @@ -184,15 +250,21 @@ describe("KeyRotationService", () => { expect(arg.webauthnKeys.length).toBe(2); }); - it("rotates the user key and encrypted data", async () => { + it("rotates the userkey and encrypted data and changes master password", async () => { + KeyRotationTrustInfoComponent.open = initialPromptedOpenTrue; + EmergencyAccessTrustComponent.open = emergencyAccessTrustOpenTrusted; + AccountRecoveryTrustComponent.open = accountRecoveryTrustOpenTrusted; await keyRotationService.rotateUserKeyMasterPasswordAndEncryptedData( "mockMasterPassword", - "mockNewMasterPassword", + "newMasterPassword", mockUser, ); expect(mockApiService.postUserKeyUpdateV2).toHaveBeenCalled(); const arg = mockApiService.postUserKeyUpdateV2.mock.calls[0][0]; + expect(arg.accountUnlockData.masterPasswordUnlockData.masterKeyEncryptedUserKey).toBe( + "mockNewUserKey", + ); expect(arg.oldMasterKeyAuthenticationHash).toBe("mockMasterPasswordHash"); expect(arg.accountUnlockData.masterPasswordUnlockData.email).toBe("mockEmail"); expect(arg.accountUnlockData.masterPasswordUnlockData.kdfType).toBe( @@ -201,11 +273,52 @@ describe("KeyRotationService", () => { expect(arg.accountUnlockData.masterPasswordUnlockData.kdfIterations).toBe( DEFAULT_KDF_CONFIG.iterations, ); + expect(arg.accountKeys.accountPublicKey).toBe(Utils.fromUtf8ToB64("mockPublicKey")); expect(arg.accountKeys.userKeyEncryptedAccountPrivateKey).toBe("mockEncryptedData"); + expect(arg.accountData.ciphers.length).toBe(2); expect(arg.accountData.folders.length).toBe(2); expect(arg.accountData.sends.length).toBe(2); + expect(arg.accountUnlockData.emergencyAccessUnlockData.length).toBe(1); + expect(arg.accountUnlockData.organizationAccountRecoveryUnlockData.length).toBe(1); + expect(arg.accountUnlockData.passkeyUnlockData.length).toBe(2); + }); + + it("returns early when first trust warning dialog is declined", async () => { + KeyRotationTrustInfoComponent.open = initialPromptedOpenFalse; + EmergencyAccessTrustComponent.open = emergencyAccessTrustOpenTrusted; + AccountRecoveryTrustComponent.open = accountRecoveryTrustOpenTrusted; + await keyRotationService.rotateUserKeyMasterPasswordAndEncryptedData( + "mockMasterPassword", + "newMasterPassword", + mockUser, + ); + expect(mockApiService.postUserKeyUpdateV2).not.toHaveBeenCalled(); + }); + + it("returns early when emergency access trust warning dialog is declined", async () => { + KeyRotationTrustInfoComponent.open = initialPromptedOpenTrue; + EmergencyAccessTrustComponent.open = emergencyAccessTrustOpenUntrusted; + AccountRecoveryTrustComponent.open = accountRecoveryTrustOpenTrusted; + await keyRotationService.rotateUserKeyMasterPasswordAndEncryptedData( + "mockMasterPassword", + "newMasterPassword", + mockUser, + ); + expect(mockApiService.postUserKeyUpdateV2).not.toHaveBeenCalled(); + }); + + it("returns early when account recovery trust warning dialog is declined", async () => { + KeyRotationTrustInfoComponent.open = initialPromptedOpenTrue; + EmergencyAccessTrustComponent.open = emergencyAccessTrustOpenTrusted; + AccountRecoveryTrustComponent.open = accountRecoveryTrustOpenUntrusted; + await keyRotationService.rotateUserKeyMasterPasswordAndEncryptedData( + "mockMasterPassword", + "newMasterPassword", + mockUser, + ); + expect(mockApiService.postUserKeyUpdateV2).not.toHaveBeenCalled(); }); it("legacy throws if master password provided is falsey", async () => { @@ -296,6 +409,9 @@ describe("KeyRotationService", () => { }); it("throws if server rotation fails", async () => { + KeyRotationTrustInfoComponent.open = initialPromptedOpenTrue; + EmergencyAccessTrustComponent.open = emergencyAccessTrustOpenTrusted; + AccountRecoveryTrustComponent.open = accountRecoveryTrustOpenTrusted; mockApiService.postUserKeyUpdateV2.mockRejectedValueOnce(new Error("mockError")); await expect( diff --git a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts index 9dc844c0104..7d00e970ad7 100644 --- a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts +++ b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts @@ -19,8 +19,13 @@ import { UserKey } from "@bitwarden/common/types/key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { ToastService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { KeyService } from "@bitwarden/key-management"; +import { + AccountRecoveryTrustComponent, + EmergencyAccessTrustComponent, + KeyRotationTrustInfoComponent, +} from "@bitwarden/key-management-ui"; import { OrganizationUserResetPasswordService } from "../../admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service"; import { WebauthnLoginAdminService } from "../../auth/core"; @@ -53,6 +58,7 @@ export class UserKeyRotationService { private vaultTimeoutService: VaultTimeoutService, private toastService: ToastService, private i18nService: I18nService, + private dialogService: DialogService, ) {} /** @@ -81,6 +87,20 @@ export class UserKeyRotationService { ); } + const emergencyAccessGrantees = await this.emergencyAccessService.getPublicKeys(); + const orgs = await this.resetPasswordService.getPublicKeys(user.id); + if (orgs.length > 0 || emergencyAccessGrantees.length > 0) { + const trustInfoDialog = KeyRotationTrustInfoComponent.open(this.dialogService, { + numberOfEmergencyAccessUsers: emergencyAccessGrantees.length, + orgName: orgs.length > 0 ? orgs[0].orgName : undefined, + }); + const result = await firstValueFrom(trustInfoDialog.closed); + if (!result) { + this.logService.info("[Userkey rotation] Trust info dialog closed. Aborting!"); + return; + } + } + const { masterKey: oldMasterKey, email, @@ -156,25 +176,70 @@ export class UserKeyRotationService { } const accountDataRequest = new UserDataRequest(rotatedCiphers, rotatedFolders, rotatedSends); + for (const details of emergencyAccessGrantees) { + this.logService.info("[Userkey rotation] Emergency access grantee: " + details.name); + this.logService.info( + "[Userkey rotation] Emergency access grantee fingerprint: " + + (await this.keyService.getFingerprint(details.granteeId, details.publicKey)).join("-"), + ); + + const dialogRef = EmergencyAccessTrustComponent.open(this.dialogService, { + name: details.name, + userId: details.granteeId, + publicKey: details.publicKey, + }); + const result = await firstValueFrom(dialogRef.closed); + if (result === true) { + this.logService.info("[Userkey rotation] Emergency access grantee confirmed"); + } else { + this.logService.info("[Userkey rotation] Emergency access grantee not confirmed"); + return; + } + } + const trustedUserPublicKeys = emergencyAccessGrantees.map((d) => d.publicKey); + const emergencyAccessUnlockData = await this.emergencyAccessService.getRotatedData( - originalUserKey, newUnencryptedUserKey, + trustedUserPublicKeys, user.id, ); + + for (const organization of orgs) { + this.logService.info( + "[Userkey rotation] Reset password organization: " + organization.orgName, + ); + this.logService.info( + "[Userkey rotation] Trusted organization public key: " + organization.publicKey, + ); + const fingerprint = await this.keyService.getFingerprint( + organization.orgId, + organization.publicKey, + ); + this.logService.info( + "[Userkey rotation] Trusted organization fingerprint: " + fingerprint.join("-"), + ); + + const dialogRef = AccountRecoveryTrustComponent.open(this.dialogService, { + name: organization.orgName, + orgId: organization.orgId, + publicKey: organization.publicKey, + }); + const result = await firstValueFrom(dialogRef.closed); + if (result === true) { + this.logService.info("[Userkey rotation] Organization trusted"); + } else { + this.logService.info("[Userkey rotation] Organization not trusted"); + return; + } + } + const trustedOrgPublicKeys = orgs.map((d) => d.publicKey); // Note: Reset password keys request model has user verification // properties, but the rotation endpoint uses its own MP hash. - const organizationAccountRecoveryUnlockData = await this.resetPasswordService.getRotatedData( - originalUserKey, + const organizationAccountRecoveryUnlockData = (await this.resetPasswordService.getRotatedData( newUnencryptedUserKey, + trustedOrgPublicKeys, user.id, - ); - if (organizationAccountRecoveryUnlockData == null) { - this.logService.info( - "[Userkey rotation] Organization account recovery data is null. Aborting!", - ); - throw new Error("Organization account recovery data is null"); - } - + ))!; const passkeyUnlockData = await this.webauthnLoginAdminService.getRotatedData( originalUserKey, newUnencryptedUserKey, @@ -236,6 +301,9 @@ export class UserKeyRotationService { ); } + const emergencyAccessGrantees = await this.emergencyAccessService.getPublicKeys(); + const orgs = await this.resetPasswordService.getPublicKeys(user.id); + // Verify master password // UV service sets master key on success since it is stored in memory and can be lost on refresh const verification = { @@ -307,20 +375,22 @@ export class UserKeyRotationService { request.sends = rotatedSends; } + const trustedUserPublicKeys = emergencyAccessGrantees.map((d) => d.publicKey); const rotatedEmergencyAccessKeys = await this.emergencyAccessService.getRotatedData( - originalUserKey, newUserKey, + trustedUserPublicKeys, user.id, ); if (rotatedEmergencyAccessKeys != null) { request.emergencyAccessKeys = rotatedEmergencyAccessKeys; } + const trustedOrgPublicKeys = orgs.map((d) => d.publicKey); // Note: Reset password keys request model has user verification // properties, but the rotation endpoint uses its own MP hash. const rotatedResetPasswordKeys = await this.resetPasswordService.getRotatedData( originalUserKey, - newUserKey, + trustedOrgPublicKeys, user.id, ); if (rotatedResetPasswordKeys != null) { diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index 0f1a4c5b6ef..b6b0ccb4984 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -9,6 +9,7 @@ import { LayoutComponent, NavigationModule } from "@bitwarden/components"; import { OrganizationLayoutComponent } from "../admin-console/organizations/layouts/organization-layout.component"; import { EventsComponent as OrgEventsComponent } from "../admin-console/organizations/manage/events.component"; +import { OrganizationTrustComponent } from "../admin-console/organizations/manage/organization-trust.component"; import { UserConfirmComponent as OrgUserConfirmComponent } from "../admin-console/organizations/manage/user-confirm.component"; import { VerifyRecoverDeleteOrgComponent } from "../admin-console/organizations/manage/verify-recover-delete-org.component"; import { AcceptFamilySponsorshipComponent } from "../admin-console/organizations/sponsorships/accept-family-sponsorship.component"; @@ -128,6 +129,7 @@ import { SharedModule } from "./shared.module"; OrgReusedPasswordsReportComponent, OrgUnsecuredWebsitesReportComponent, OrgUserConfirmComponent, + OrganizationTrustComponent, OrgWeakPasswordsReportComponent, PreferencesComponent, PremiumBadgeComponent, @@ -186,6 +188,7 @@ import { SharedModule } from "./shared.module"; OrgReusedPasswordsReportComponent, OrgUnsecuredWebsitesReportComponent, OrgUserConfirmComponent, + OrganizationTrustComponent, OrgWeakPasswordsReportComponent, PreferencesComponent, PremiumBadgeComponent, diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts b/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts index 4abf8a9ee9c..666424c7add 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts @@ -32,6 +32,7 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { DialogService, ToastService } from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; import { OrganizationUserResetPasswordService } from "../../../../admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service"; import { EnrollMasterPasswordReset } from "../../../../admin-console/organizations/users/enroll-master-password-reset.component"; @@ -70,6 +71,7 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy { private toastService: ToastService, private configService: ConfigService, private organizationService: OrganizationService, + private keyService: KeyService, private accountService: AccountService, private linkSsoService: LinkSsoService, ) {} @@ -221,12 +223,14 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy { { organization: org }, this.resetPasswordService, this.organizationUserApiService, - this.platformUtilsService, this.i18nService, this.syncService, this.logService, this.userVerificationService, this.toastService, + this.keyService, + this.accountService, + this.organizationApiService, ); } else { // Remove reset password diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 5922e80cb3d..e2258b10fbc 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -5902,6 +5902,9 @@ "fingerprint": { "message": "Fingerprint" }, + "fingerprintPhrase": { + "message": "Fingerprint phrase:" + }, "removeUsers": { "message": "Remove users" }, @@ -10355,6 +10358,33 @@ "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." }, + "rotationCompletedTitle": { + "message": "Key rotation successful" + }, + "rotationCompletedDesc": { + "message": "Your master password and encryption keys have been updated. Your other devices have been logged out." + }, + "trustUserEmergencyAccess": { + "message": "Trust and confirm user" + }, + "trustOrganization": { + "message": "Trust organization" + }, + "trust": { + "message": "Trust" + }, + "doNotTrust": { + "message": "Do not trust" + }, + "emergencyAccessTrustWarning": { + "message": "For the security of your account, only confirm if you have granted emergency access to this user and their fingerprint matches what is displayed in their account" + }, + "orgTrustWarning": { + "message": "For the security of your account, only proceed if you are a member of this organization, have account recovery enabled, and the fingerprint displayed below matches the organization's fingerprint." + }, + "trustUser":{ + "message": "Trust user" + }, "sshKeyWrongPassword": { "message": "The password you entered is incorrect." }, @@ -10524,6 +10554,30 @@ "assignedExceedsAvailable": { "message": "Assigned seats exceed available seats." }, + "userkeyRotationDisclaimerEmergencyAccessText": { + "message": "Fingerprint phrase for $NUM_USERS$ contacts for which you have enabled emergency access.", + "placeholders": { + "num_users": { + "content": "$1", + "example": "5" + } + } + }, + "userkeyRotationDisclaimerAccountRecoveryOrgsText": { + "message": "Fingerprint phrase for the organization $ORG_NAME$ for which you have enabled account recovery.", + "placeholders": { + "org_name": { + "content": "$1", + "example": "My org" + } + } + }, + "userkeyRotationDisclaimerDescription": { + "message": "Rotating your encryption keys will require you to trust keys of any organizations that can recover your account, and any contacts that can you have enabled emergency access for. To continue, make sure you can verify the following:" + }, + "userkeyRotationDisclaimerTitle": { + "message": "Untrusted encryption keys" + }, "changeAtRiskPassword": { "message": "Change at-risk password" }, diff --git a/libs/key-management-ui/src/index.ts b/libs/key-management-ui/src/index.ts index 1eb9b88b072..2f98538caad 100644 --- a/libs/key-management-ui/src/index.ts +++ b/libs/key-management-ui/src/index.ts @@ -4,3 +4,6 @@ export { LockComponent } from "./lock/components/lock.component"; export { LockComponentService, UnlockOptions } from "./lock/services/lock-component.service"; +export { KeyRotationTrustInfoComponent } from "./key-rotation/key-rotation-trust-info.component"; +export { AccountRecoveryTrustComponent } from "./trust/account-recovery-trust.component"; +export { EmergencyAccessTrustComponent } from "./trust/emergency-access-trust.component"; diff --git a/libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.html b/libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.html new file mode 100644 index 00000000000..f9aee3c1470 --- /dev/null +++ b/libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.html @@ -0,0 +1,26 @@ + + + {{ "userkeyRotationDisclaimerTitle" | i18n }} + + + {{ "userkeyRotationDisclaimerDescription" | i18n }} +
    +
  • + {{ "userkeyRotationDisclaimerAccountRecoveryOrgsText" | i18n: params.orgName }} +
  • +
  • + {{ + "userkeyRotationDisclaimerEmergencyAccessText" | i18n: params.numberOfEmergencyAccessUsers + }} +
  • +
+
+ + + {{ "continue" | i18n }} + + + +
diff --git a/libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.ts b/libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.ts new file mode 100644 index 00000000000..51e6058ae5b --- /dev/null +++ b/libs/key-management-ui/src/key-rotation/key-rotation-trust-info.component.ts @@ -0,0 +1,58 @@ +import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component, Inject } from "@angular/core"; +import { FormsModule, ReactiveFormsModule } from "@angular/forms"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { + AsyncActionsModule, + ButtonModule, + DialogModule, + DialogService, +} from "@bitwarden/components"; + +type KeyRotationTrustDialogData = { + orgName?: string; + numberOfEmergencyAccessUsers: number; +}; + +@Component({ + selector: "key-rotation-trust-info", + templateUrl: "key-rotation-trust-info.component.html", + standalone: true, + imports: [ + CommonModule, + JslibModule, + DialogModule, + ButtonModule, + ReactiveFormsModule, + AsyncActionsModule, + FormsModule, + ], +}) +export class KeyRotationTrustInfoComponent { + constructor( + @Inject(DIALOG_DATA) protected params: KeyRotationTrustDialogData, + private logService: LogService, + private dialogRef: DialogRef, + ) {} + + async submit() { + try { + this.dialogRef.close(true); + } catch (e) { + this.logService.error(e); + } + } + /** + * Strongly typed helper to open a KeyRotationTrustComponent + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param data The data to pass to the dialog + */ + static open(dialogService: DialogService, data: KeyRotationTrustDialogData) { + return dialogService.open(KeyRotationTrustInfoComponent, { + data, + }); + } +} diff --git a/libs/key-management-ui/src/trust/account-recovery-trust.component.html b/libs/key-management-ui/src/trust/account-recovery-trust.component.html new file mode 100644 index 00000000000..5829558dd69 --- /dev/null +++ b/libs/key-management-ui/src/trust/account-recovery-trust.component.html @@ -0,0 +1,21 @@ + + + {{ "orgTrustWarning" | i18n }} +

+ {{ "fingerprintPhrase" | i18n }} {{ fingerprint }} +

+
+ + + + +
diff --git a/libs/key-management-ui/src/trust/account-recovery-trust.component.ts b/libs/key-management-ui/src/trust/account-recovery-trust.component.ts new file mode 100644 index 00000000000..e1ec390a460 --- /dev/null +++ b/libs/key-management-ui/src/trust/account-recovery-trust.component.ts @@ -0,0 +1,94 @@ +import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component, OnInit, Inject } from "@angular/core"; +import { FormBuilder, FormsModule, ReactiveFormsModule } from "@angular/forms"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { + AsyncActionsModule, + ButtonModule, + CalloutModule, + DialogModule, + DialogService, + FormFieldModule, + LinkModule, + TypographyModule, +} from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; + +type AccountRecoveryTrustDialogData = { + /** display name of the user */ + name: string; + /** org id */ + orgId: string; + /** org public key */ + publicKey: Uint8Array; +}; +@Component({ + selector: "account-recovery-trust", + templateUrl: "account-recovery-trust.component.html", + standalone: true, + imports: [ + CommonModule, + JslibModule, + DialogModule, + ButtonModule, + LinkModule, + TypographyModule, + ReactiveFormsModule, + FormFieldModule, + AsyncActionsModule, + FormsModule, + CalloutModule, + ], +}) +export class AccountRecoveryTrustComponent implements OnInit { + loading = true; + fingerprint: string = ""; + confirmForm = this.formBuilder.group({}); + + constructor( + @Inject(DIALOG_DATA) protected params: AccountRecoveryTrustDialogData, + private formBuilder: FormBuilder, + private keyService: KeyService, + private logService: LogService, + private dialogRef: DialogRef, + ) {} + + async ngOnInit() { + try { + const fingerprint = await this.keyService.getFingerprint( + this.params.orgId, + this.params.publicKey, + ); + if (fingerprint != null) { + this.fingerprint = fingerprint.join("-"); + } + } catch (e) { + this.logService.error(e); + } + this.loading = false; + } + + async submit() { + if (this.loading) { + return; + } + + this.dialogRef.close(true); + } + /** + * Strongly typed helper to open a AccountRecoveryTrustComponent + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param data The data to pass to the dialog + */ + static open(dialogService: DialogService, data: AccountRecoveryTrustDialogData) { + return dialogService.open( + AccountRecoveryTrustComponent, + { + data, + }, + ); + } +} diff --git a/libs/key-management-ui/src/trust/emergency-access-trust.component.html b/libs/key-management-ui/src/trust/emergency-access-trust.component.html new file mode 100644 index 00000000000..13f1ce4cc8e --- /dev/null +++ b/libs/key-management-ui/src/trust/emergency-access-trust.component.html @@ -0,0 +1,32 @@ + + + {{ "emergencyAccessTrustWarning" | i18n }} +

+ {{ "fingerprintEnsureIntegrityVerify" | i18n }} + + {{ "learnMore" | i18n }} +

+

+ {{ fingerprint }} +

+
+ + + + +
diff --git a/libs/key-management-ui/src/trust/emergency-access-trust.component.ts b/libs/key-management-ui/src/trust/emergency-access-trust.component.ts new file mode 100644 index 00000000000..29ee64798e9 --- /dev/null +++ b/libs/key-management-ui/src/trust/emergency-access-trust.component.ts @@ -0,0 +1,94 @@ +import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component, OnInit, Inject } from "@angular/core"; +import { FormBuilder, FormsModule, ReactiveFormsModule } from "@angular/forms"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { + AsyncActionsModule, + ButtonModule, + CalloutModule, + DialogModule, + DialogService, + FormFieldModule, + LinkModule, + TypographyModule, +} from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; + +type EmergencyAccessTrustDialogData = { + /** display name of the user */ + name: string; + /** userid of the user */ + userId: string; + /** user public key */ + publicKey: Uint8Array; +}; +@Component({ + selector: "emergency-access-trust", + templateUrl: "emergency-access-trust.component.html", + standalone: true, + imports: [ + CommonModule, + JslibModule, + DialogModule, + ButtonModule, + LinkModule, + TypographyModule, + ReactiveFormsModule, + FormFieldModule, + AsyncActionsModule, + FormsModule, + CalloutModule, + ], +}) +export class EmergencyAccessTrustComponent implements OnInit { + loading = true; + fingerprint: string = ""; + confirmForm = this.formBuilder.group({}); + + constructor( + @Inject(DIALOG_DATA) protected params: EmergencyAccessTrustDialogData, + private formBuilder: FormBuilder, + private keyService: KeyService, + private logService: LogService, + private dialogRef: DialogRef, + ) {} + + async ngOnInit() { + try { + const fingerprint = await this.keyService.getFingerprint( + this.params.userId, + this.params.publicKey, + ); + if (fingerprint != null) { + this.fingerprint = fingerprint.join("-"); + } + } catch (e) { + this.logService.error(e); + } + this.loading = false; + } + + async submit() { + if (this.loading) { + return; + } + + this.dialogRef.close(true); + } + /** + * Strongly typed helper to open a EmergencyAccessTrustComponent + * @param dialogService Instance of the dialog service that will be used to open the dialog + * @param data The data to pass to the dialog + */ + static open(dialogService: DialogService, data: EmergencyAccessTrustDialogData) { + return dialogService.open( + EmergencyAccessTrustComponent, + { + data, + }, + ); + } +} diff --git a/libs/key-management/src/abstractions/key.service.ts b/libs/key-management/src/abstractions/key.service.ts index 4b257fbbebd..d67fec4c98e 100644 --- a/libs/key-management/src/abstractions/key.service.ts +++ b/libs/key-management/src/abstractions/key.service.ts @@ -337,6 +337,17 @@ export abstract class KeyService { userId: UserId, ): Observable<{ privateKey: UserPrivateKey; publicKey: UserPublicKey } | null>; + /** + * Gets an observable stream of the given users decrypted private key and public key, guaranteed to be consistent. + * Will emit null if the user doesn't have a userkey to decrypt the encrypted private key, or null if the user doesn't have a private key + * at all. + * + * @param userId The user id of the user to get the data for. + */ + abstract userEncryptionKeyPair$( + userId: UserId, + ): Observable<{ privateKey: UserPrivateKey; publicKey: UserPublicKey } | null>; + /** * Generates a fingerprint phrase for the user based on their public key * diff --git a/libs/key-management/src/abstractions/user-key-rotation-key-recovery-provider.abstraction.ts b/libs/key-management/src/abstractions/user-key-rotation-key-recovery-provider.abstraction.ts new file mode 100644 index 00000000000..12a621e4cac --- /dev/null +++ b/libs/key-management/src/abstractions/user-key-rotation-key-recovery-provider.abstraction.ts @@ -0,0 +1,31 @@ +import { UserId } from "@bitwarden/common/types/guid"; +import { UserKey } from "@bitwarden/common/types/key"; + +/** + * Constructs key rotation requests for key recovery encryption of the userkey. + * @typeparam TRequest A request model that contains the newly encrypted userkey must have an id property + */ +export interface UserKeyRotationKeyRecoveryProvider< + TRequest extends { id: string } | { organizationId: string }, + TPublicKeyData, +> { + /** + * Get the public keys for this recovery method from the server. + * WARNING these are NOT trusted, and need to either be manually trusted by the user, or compared against + * a signed trust database for the user. THE SERVER CAN SPOOF THESE. + */ + getPublicKeys(userId: UserId): Promise; + + /** + * Provides re-encrypted data for the user key rotation process + * @param newUserKey The new user key + * @param trustedPublicKeys The public keys that the user trusted + * @param userId The owner of the data, useful for fetching data + * @returns A list of data that has been re-encrypted with the new user key + */ + getRotatedData( + newUserKey: UserKey, + trustedPublicKeys: Uint8Array[], + userId: UserId, + ): Promise; +} diff --git a/libs/key-management/src/index.ts b/libs/key-management/src/index.ts index f3efd75b098..d21b79540e0 100644 --- a/libs/key-management/src/index.ts +++ b/libs/key-management/src/index.ts @@ -10,6 +10,7 @@ export * from "./biometrics/biometric.state"; export { CipherDecryptionKeys, KeyService } from "./abstractions/key.service"; export { DefaultKeyService } from "./key.service"; export { UserKeyRotationDataProvider } from "./abstractions/user-key-rotation-data-provider.abstraction"; +export { UserKeyRotationKeyRecoveryProvider } from "./abstractions/user-key-rotation-key-recovery-provider.abstraction"; export { PBKDF2KdfConfig, Argon2KdfConfig, From 647781bedd167e982e997d9dc93bc83364fc65cb Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 7 Apr 2025 14:28:34 +0200 Subject: [PATCH 19/93] Fix typo (#14157) --- apps/web/src/locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index e2258b10fbc..6c730338fea 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -10573,7 +10573,7 @@ } }, "userkeyRotationDisclaimerDescription": { - "message": "Rotating your encryption keys will require you to trust keys of any organizations that can recover your account, and any contacts that can you have enabled emergency access for. To continue, make sure you can verify the following:" + "message": "Rotating your encryption keys will require you to trust keys of any organizations that can recover your account, and any contacts that you have enabled emergency access for. To continue, make sure you can verify the following:" }, "userkeyRotationDisclaimerTitle": { "message": "Untrusted encryption keys" From ad2e3a40397eda5013faaf6c4e362df866b8363f Mon Sep 17 00:00:00 2001 From: Jared McCannon Date: Mon, 7 Apr 2025 07:45:24 -0500 Subject: [PATCH 20/93] [PM-17361] Migrating providers.component.html to TW (#14133) * removing bootstrap. * Fixed width. --- .../providers/providers.component.html | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/providers.component.html index 560c164415c..1c8c12a1fe1 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers.component.html @@ -1,22 +1,22 @@ -

+

{{ "loading" | i18n }}

- - - - - + - - -
+ + + +
+ {{ p.name }} @@ -24,7 +24,7 @@
+ +
From c8967bf4b357f114116f6622f38f9ebf75de89ea Mon Sep 17 00:00:00 2001 From: Vince Grassia <593223+vgrassia@users.noreply.github.com> Date: Mon, 7 Apr 2025 06:57:55 -0700 Subject: [PATCH 21/93] Update build web workflow (#14111) --- .github/workflows/build-web.yml | 37 ++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index f706bba610d..12748a47748 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -82,7 +82,7 @@ jobs: build-containers: - name: Build artifacts and container images + name: "Build [${{matrix.artifact_name}}], image tag: [${{matrix.image_name}}]" runs-on: ubuntu-24.04 permissions: security-events: write @@ -158,6 +158,17 @@ jobs: mv package.json.tmp package.json ########## Set up Docker ########## + - name: Set up Docker + uses: docker/setup-docker-action@b60f85385d03ac8acfca6d9996982511d8620a19 # v4.3.0 + with: + daemon-config: | + { + "debug": true, + "features": { + "containerd-snapshotter": true + } + } + - name: Set up QEMU emulators uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 @@ -175,20 +186,6 @@ jobs: if: ${{ needs.setup.outputs.has_secrets == 'true' }} run: az acr login -n ${_AZ_REGISTRY%.azurecr.io} - - name: Login to Azure - CI Subscription - if: ${{ needs.setup.outputs.has_secrets == 'true' }} - uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 - with: - creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }} - - - name: Retrieve github PAT secrets - if: ${{ needs.setup.outputs.has_secrets == 'true' }} - id: retrieve-secret-pat - uses: bitwarden/gh-actions/get-keyvault-secrets@main - with: - keyvault: "bitwarden-ci" - secrets: "github-pat-bitwarden-devops-bot-repo-scope" - ########## Generate image tag and build Docker image ########## - name: Generate container image tag id: tag @@ -220,7 +217,6 @@ jobs: run: echo "name=$_AZ_REGISTRY/${PROJECT_NAME}:${IMAGE_TAG}" >> $GITHUB_OUTPUT - name: Build Docker image - if: ${{ needs.setup.outputs.has_secrets == 'true' }} id: build-container uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0 with: @@ -229,13 +225,20 @@ jobs: NPM_COMMAND=${{ matrix.npm_command }} context: . file: apps/web/Dockerfile + load: true platforms: | linux/amd64, linux/arm/v7, linux/arm64 - push: true + push: false tags: ${{ steps.image-name.outputs.name }} + - name: Push images + if: ${{ needs.setup.outputs.has_secrets == 'true' }} + env: + IMAGE_NAME: ${{ steps.image-name.outputs.name }} + run: docker push $IMAGE_NAME + - name: Zip project working-directory: apps/web env: From 31cc2c57eed5fb9ab725b3f6fb55e6cb0916b17b Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Mon, 7 Apr 2025 10:37:34 -0400 Subject: [PATCH 22/93] [CL-421] add new notification variant to badge (#14130) * add new notification variant to badge --- libs/components/src/badge/badge.component.ts | 19 ++++++++++++++++++- libs/components/src/badge/badge.stories.ts | 11 +++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libs/components/src/badge/badge.component.ts b/libs/components/src/badge/badge.component.ts index 0f8a64ee998..893257ff225 100644 --- a/libs/components/src/badge/badge.component.ts +++ b/libs/components/src/badge/badge.component.ts @@ -5,7 +5,14 @@ import { Component, ElementRef, HostBinding, Input } from "@angular/core"; import { FocusableElement } from "../shared/focusable-element"; -export type BadgeVariant = "primary" | "secondary" | "success" | "danger" | "warning" | "info"; +export type BadgeVariant = + | "primary" + | "secondary" + | "success" + | "danger" + | "warning" + | "info" + | "notification"; const styles: Record = { primary: ["tw-bg-primary-100", "tw-border-primary-700", "!tw-text-primary-700"], @@ -14,6 +21,11 @@ const styles: Record = { danger: ["tw-bg-danger-100", "tw-border-danger-700", "!tw-text-danger-700"], warning: ["tw-bg-warning-100", "tw-border-warning-700", "!tw-text-warning-700"], info: ["tw-bg-info-100", "tw-border-info-700", "!tw-text-info-700"], + notification: [ + "tw-bg-notification-100", + "tw-border-notification-600", + "!tw-text-notification-600", + ], }; const hoverStyles: Record = { @@ -27,6 +39,11 @@ const hoverStyles: Record = { danger: ["hover:tw-bg-danger-600", "hover:tw-border-danger-600", "hover:!tw-text-contrast"], warning: ["hover:tw-bg-warning-600", "hover:tw-border-warning-600", "hover:!tw-text-black"], info: ["hover:tw-bg-info-600", "hover:tw-border-info-600", "hover:!tw-text-black"], + notification: [ + "hover:tw-bg-notification-600", + "hover:tw-border-notification-600", + "hover:!tw-text-contrast", + ], }; @Component({ diff --git a/libs/components/src/badge/badge.stories.ts b/libs/components/src/badge/badge.stories.ts index bff9eec6163..6473ba8c867 100644 --- a/libs/components/src/badge/badge.stories.ts +++ b/libs/components/src/badge/badge.stories.ts @@ -36,6 +36,7 @@ export const Variants: Story = { +

Hover @@ -44,6 +45,7 @@ export const Variants: Story = { +

Focus Visible @@ -52,6 +54,7 @@ export const Variants: Story = { +

Disabled @@ -60,6 +63,7 @@ export const Variants: Story = { + `, }), }; @@ -112,6 +116,13 @@ export const Info: Story = { }, }; +export const Notification: Story = { + ...Primary, + args: { + variant: "notification", + }, +}; + export const Truncated: Story = { ...Primary, args: { From 254cad29b37c8c7ae79b5386317fa74792b7c1ca Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 7 Apr 2025 10:39:26 -0400 Subject: [PATCH 23/93] [PM-8951] set pin validation to min length of 4 (#13312) * set pin validation to min length of 4 * use reactive forms * PM-8951 - SetPin - remove dialog close logic if pin is invalid so validation errors can be shown to the user. --------- Co-authored-by: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Co-authored-by: Jared Snider --- .../src/auth/components/set-pin.component.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/angular/src/auth/components/set-pin.component.ts b/libs/angular/src/auth/components/set-pin.component.ts index 9f63e5e923f..d2fceb34bb9 100644 --- a/libs/angular/src/auth/components/set-pin.component.ts +++ b/libs/angular/src/auth/components/set-pin.component.ts @@ -16,7 +16,7 @@ export class SetPinComponent implements OnInit { showMasterPasswordOnClientRestartOption = true; setPinForm = this.formBuilder.group({ - pin: ["", [Validators.required]], + pin: ["", [Validators.required, Validators.minLength(4)]], requireMasterPasswordOnClientRestart: true, }); @@ -37,24 +37,26 @@ export class SetPinComponent implements OnInit { } submit = async () => { - const pin = this.setPinForm.get("pin").value; + const pinFormControl = this.setPinForm.controls.pin; const requireMasterPasswordOnClientRestart = this.setPinForm.get( "requireMasterPasswordOnClientRestart", ).value; - if (Utils.isNullOrWhitespace(pin)) { - this.dialogRef.close(false); + if (Utils.isNullOrWhitespace(pinFormControl.value) || pinFormControl.invalid) { return; } const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; const userKey = await this.keyService.getUserKey(); - const userKeyEncryptedPin = await this.pinService.createUserKeyEncryptedPin(pin, userKey); + const userKeyEncryptedPin = await this.pinService.createUserKeyEncryptedPin( + pinFormControl.value, + userKey, + ); await this.pinService.setUserKeyEncryptedPin(userKeyEncryptedPin, userId); const pinKeyEncryptedUserKey = await this.pinService.createPinKeyEncryptedUserKey( - pin, + pinFormControl.value, userKey, userId, ); From 38f193ee6c4d28529a999c57d60fa99794ba28a0 Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Mon, 7 Apr 2025 17:00:19 +0200 Subject: [PATCH 24/93] =?UTF-8?q?[PM-19713][BEEEP]=20Improve=20performance?= =?UTF-8?q?=20of=20whether=20user=20can=20view=20subsc=E2=80=A6=20(#14062)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../billing-account-profile-state.service.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libs/common/src/billing/services/account/billing-account-profile-state.service.ts b/libs/common/src/billing/services/account/billing-account-profile-state.service.ts index 155ce1493b4..efb22086075 100644 --- a/libs/common/src/billing/services/account/billing-account-profile-state.service.ts +++ b/libs/common/src/billing/services/account/billing-account-profile-state.service.ts @@ -68,15 +68,18 @@ export class DefaultBillingAccountProfileStateService implements BillingAccountP this.hasPremiumFromAnyOrganization$(userId), ]).pipe( concatMap(async ([hasPremiumPersonally, hasPremiumFromOrg]) => { - const isCloud = !this.platformUtilsService.isSelfHost(); - - let billing = null; - if (isCloud) { - billing = await this.apiService.getUserBillingHistory(); + if (hasPremiumPersonally === true || !hasPremiumFromOrg === true) { + return true; } - const cloudAndBillingHistory = isCloud && !billing?.hasNoHistory; - return hasPremiumPersonally || !hasPremiumFromOrg || cloudAndBillingHistory; + const isCloud = !this.platformUtilsService.isSelfHost(); + + if (isCloud) { + const billing = await this.apiService.getUserBillingHistory(); + return !billing?.hasNoHistory; + } + + return false; }), ); } From d95c3c63a8784a13f2d923cf343c8a7f10318640 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Mon, 7 Apr 2025 17:48:44 +0200 Subject: [PATCH 25/93] Add support for Zen browser integration on mac (#13895) --- apps/desktop/resources/entitlements.mas.plist | 1 + apps/desktop/src/main/native-messaging.main.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/desktop/resources/entitlements.mas.plist b/apps/desktop/resources/entitlements.mas.plist index bb06ae10431..f3bc20011ff 100644 --- a/apps/desktop/resources/entitlements.mas.plist +++ b/apps/desktop/resources/entitlements.mas.plist @@ -35,6 +35,7 @@ /Library/Application Support/Microsoft Edge Dev/NativeMessagingHosts/ /Library/Application Support/Microsoft Edge Canary/NativeMessagingHosts/ /Library/Application Support/Vivaldi/NativeMessagingHosts/ + /Library/Application Support/Zen/NativeMessagingHosts/ com.apple.security.cs.allow-jit diff --git a/apps/desktop/src/main/native-messaging.main.ts b/apps/desktop/src/main/native-messaging.main.ts index 107d546811c..93525164ff5 100644 --- a/apps/desktop/src/main/native-messaging.main.ts +++ b/apps/desktop/src/main/native-messaging.main.ts @@ -172,7 +172,7 @@ export class NativeMessagingMain { const p = path.join(value, "NativeMessagingHosts", "com.8bit.bitwarden.json"); let manifest: any = chromeJson; - if (key === "Firefox") { + if (key === "Firefox" || key === "Zen") { manifest = firefoxJson; } @@ -313,6 +313,7 @@ export class NativeMessagingMain { "Microsoft Edge Dev": `${this.homedir()}/Library/Application\ Support/Microsoft\ Edge\ Dev/`, "Microsoft Edge Canary": `${this.homedir()}/Library/Application\ Support/Microsoft\ Edge\ Canary/`, Vivaldi: `${this.homedir()}/Library/Application\ Support/Vivaldi/`, + Zen: `${this.homedir()}/Library/Application\ Support/Zen/`, }; /* eslint-enable no-useless-escape */ } From ea860b2f35e55da35bc4b99b75c975a2f6cda89c Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Mon, 7 Apr 2025 12:55:53 -0400 Subject: [PATCH 26/93] [PM-17933] Rename github-action group to no longer be minor-only (#13799) * Renamed groups and added consistent periods * Fixed punctuation Co-authored-by: Matt Bishop --------- Co-authored-by: Matt Bishop --- .github/renovate.json5 | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/renovate.json5 b/.github/renovate.json5 index fe5ae09deaa..973ba700349 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -4,10 +4,10 @@ enabledManagers: ["cargo", "github-actions", "npm"], packageRules: [ { - // Group all build/test/lint workflows for GitHub Actions together for Platform - // Since they are code owners we don't need to assign a review team in Renovate - // Any changes here should also be reflected in CODEOWNERS - groupName: "github-action minor", + // Group all build/test/lint workflows for GitHub Actions together for Platform. + // Since they are code owners we don't need to assign a review team in Renovate. + // Any changes here should also be reflected in CODEOWNERS. + groupName: "github-action", matchManagers: ["github-actions"], matchFileNames: [ "./github/workflows/automatic-issue-responses.yml", @@ -30,10 +30,10 @@ commitMessagePrefix: "[deps] Platform:", }, { - // Group all release-related workflows for GitHub Actions together for BRE - // Since they are code owners we don't need to assign a review team in Renovate - // Any changes here should also be reflected in CODEOWNERS - groupName: "github-action minor", + // Group all release-related workflows for GitHub Actions together for BRE. + // Since they are code owners we don't need to assign a review team in Renovate. + // Any changes here should also be reflected in CODEOWNERS. + groupName: "github-action", matchManagers: ["github-actions"], matchFileNames: [ "./github/workflows/brew-bump-desktop.yml", @@ -51,7 +51,7 @@ commitMessagePrefix: "[deps] BRE:", }, { - // Disable major and minor updates for TypeScript and Zone.js because they are managed by Angular + // Disable major and minor updates for TypeScript and Zone.js because they are managed by Angular. matchPackageNames: ["typescript", "zone.js"], matchUpdateTypes: ["major", "minor"], description: "Determined by Angular", @@ -72,27 +72,27 @@ enabled: false, }, { - // Renovate should manage patch updates for TypeScript and Zone.js, despite ignoring major and minor + // Renovate should manage patch updates for TypeScript and Zone.js, despite ignoring major and minor. matchPackageNames: ["typescript", "zone.js"], matchUpdateTypes: "patch", }, { - // We want to update all the Jest-related packages together, to reduce PR noise + // We want to update all the Jest-related packages together, to reduce PR noise. groupName: "jest", matchPackageNames: ["@types/jest", "jest", "ts-jest", "jest-preset-angular"], }, { - // We need to group all napi-related packages together to avoid build errors caused by version incompatibilities + // We need to group all napi-related packages together to avoid build errors caused by version incompatibilities. groupName: "napi", matchPackageNames: ["napi", "napi-build", "napi-derive"], }, { - // We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities + // We need to group all macOS/iOS binding-related packages together to avoid build errors caused by version incompatibilities. groupName: "macOS/iOS bindings", matchPackageNames: ["core-foundation", "security-framework", "security-framework-sys"], }, { - // We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities + // We need to group all zbus-related packages together to avoid build errors caused by version incompatibilities. groupName: "zbus", matchPackageNames: ["zbus", "zbus_polkit"], }, From 7f58cee41b33714449117434b995ca4f755fa909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lison=20Fernandes?= Date: Mon, 7 Apr 2025 19:20:29 +0100 Subject: [PATCH 27/93] [PM-18897] Add workflow to auto-reply / auto-close GitHub Discussions (#13682) --- .../DISCUSSION_TEMPLATE/password-manager.yml | 11 ++ .../DISCUSSION_TEMPLATE/secrets-manager.yml | 11 ++ .github/workflows/auto-reply-discussions.yml | 112 ++++++++++++++++++ 3 files changed, 134 insertions(+) create mode 100644 .github/workflows/auto-reply-discussions.yml diff --git a/.github/DISCUSSION_TEMPLATE/password-manager.yml b/.github/DISCUSSION_TEMPLATE/password-manager.yml index bf2d0900db9..bc3938c1962 100644 --- a/.github/DISCUSSION_TEMPLATE/password-manager.yml +++ b/.github/DISCUSSION_TEMPLATE/password-manager.yml @@ -1,8 +1,19 @@ +labels: ["discussions-new"] body: - type: markdown attributes: value: | If you would like to contribute code to the Bitwarden codebase for consideration, please review [https://contributing.bitwarden.com/](https://contributing.bitwarden.com/) before posting. To keep discussion on topic, posts that do not include a proposal for a code contribution you wish to develop will be removed. For feature requests and community discussion, please visit https://community.bitwarden.com/ + - type: dropdown + attributes: + label: Select Topic Area + description: "What would you like to discuss? :warning: For feature requests and product feedback, please visit https://community.bitwarden.com/" + options: + - "✅ Code Contribution Proposal" + - "🚫 Product Feedback" + - "🚫 Feature Request" + validations: + required: true - type: textarea attributes: label: Code Contribution Proposal diff --git a/.github/DISCUSSION_TEMPLATE/secrets-manager.yml b/.github/DISCUSSION_TEMPLATE/secrets-manager.yml index bf2d0900db9..bc3938c1962 100644 --- a/.github/DISCUSSION_TEMPLATE/secrets-manager.yml +++ b/.github/DISCUSSION_TEMPLATE/secrets-manager.yml @@ -1,8 +1,19 @@ +labels: ["discussions-new"] body: - type: markdown attributes: value: | If you would like to contribute code to the Bitwarden codebase for consideration, please review [https://contributing.bitwarden.com/](https://contributing.bitwarden.com/) before posting. To keep discussion on topic, posts that do not include a proposal for a code contribution you wish to develop will be removed. For feature requests and community discussion, please visit https://community.bitwarden.com/ + - type: dropdown + attributes: + label: Select Topic Area + description: "What would you like to discuss? :warning: For feature requests and product feedback, please visit https://community.bitwarden.com/" + options: + - "✅ Code Contribution Proposal" + - "🚫 Product Feedback" + - "🚫 Feature Request" + validations: + required: true - type: textarea attributes: label: Code Contribution Proposal diff --git a/.github/workflows/auto-reply-discussions.yml b/.github/workflows/auto-reply-discussions.yml new file mode 100644 index 00000000000..8becc7471c5 --- /dev/null +++ b/.github/workflows/auto-reply-discussions.yml @@ -0,0 +1,112 @@ +name: Auto-reply to Discussions + +on: + discussion: + types: created + +jobs: + reply: + name: Auto-reply + runs-on: ubuntu-22.04 + + steps: + - name: Get discussion label and template name + id: discussion-label + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + script: | + const discussion = context.payload.discussion; + const template_name = discussion.category.slug; + const label = discussion.labels?.[0]?.name ?? ''; + console.log('Discussion label:', label); + console.log('Discussion category slug:', template_name); + + core.setOutput('label', label); + core.setOutput('template_name', template_name); + + - name: Get selected topic + id: get_selected_topic + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + with: + result-encoding: string + script: | + try { + const body = context.payload.discussion.body; + const match = body.match(/### Select Topic Area\n\n(.*?)\n\n/); + console.log('Match:', match); + console.log('Match1:', match[1]); + return match ? match[1].trim() : ""; + } catch (error) { + console.error('Error getting selected topic:', error); + return ""; + } + + - name: Reply or close Discussion + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + env: + TEMPLATE_NAME: ${{ steps.discussion-label.outputs.template_name }} + TOPIC: ${{ steps.get_selected_topic.outputs.result }} + with: + script: | + async function addComment(discussionId, body) { + await github.graphql(` + mutation AddDiscussionComment($discussionId: ID!, $body: String!) { + addDiscussionComment(input: {discussionId: $discussionId, body: $body}) { + comment { + id + } + } + } + `, { + discussionId, + body + }); + } + + async function closeDiscussion(discussionId) { + await github.graphql(` + mutation { + closeDiscussion(input: {discussionId: "${discussionId}"}) { + discussion { + id + } + } + } + `); + console.log('♻️ Closing discussion'); + } + + const discussion = context.payload.discussion; + const isFeatureRequest = process.env.TEMPLATE_NAME === 'feature-request'; + const isTopicEmpty = !process.env.TOPIC || process.env.TOPIC.trim() === ''; // topic step may have failed + const isCodeTopic = process.env.TOPIC.includes('Code Contribution Proposal'); + const shouldClose = isFeatureRequest || (!isTopicEmpty && !isCodeTopic); + + console.log('Template name:', process.env.TEMPLATE_NAME); + console.log('Topic:', process.env.TOPIC); + console.log('isTopicEmpty:', isTopicEmpty); + console.log('isCodeTopic:', isCodeTopic); + console.log('shouldClose:', shouldClose); + + if (shouldClose) { + const closeMessage = + "Thank you for your contribution! GitHub Discussions is specifically for [proposing code](https://contributing.bitwarden.com/) that you would like to write for the Bitwarden codebase. Since this post does not appear to include a proposal, it will be closed. If you believe this was done in error or have any questions, please feel free to reach out to us!\n\n" + + "- :bulb: For feature requests and general discussions, please visit the [Bitwarden Community Forums](https://community.bitwarden.com/).\n" + + "- :information_source: For questions and support, visit the [Bitwarden Help Center](https://bitwarden.com/help/).\n" + + "- :bug: To report a potential bug, please visit the appropriate repository: [Server](https://github.com/bitwarden/server/issues) | [Clients](https://github.com/bitwarden/clients/issues) | [iOS](https://github.com/bitwarden/ios/issues) | [Android](https://github.com/bitwarden/android/issues)."; + + await addComment(discussion.node_id, closeMessage); + await closeDiscussion(discussion.node_id); + return; + } + + const replyMessage = + ":sparkles: Thank you for your code contribution proposal! While the Bitwarden team reviews your submission, we encourage you to check out our [contribution guidelines](https://contributing.bitwarden.com/).\n\n" + + "Please ensure that your code contribution includes a detailed description of what you would like to contribute, along with any relevant screenshots and links to existing feature requests. This information helps us gather feedback from the community and Bitwarden team members before you start writing code.\n\n" + + "To keep discussions focused, posts that do not include a proposal for a code contribution will be removed.\n\n" + + "- :bulb: For feature requests and general discussion, please visit the [Bitwarden Community Forums](https://community.bitwarden.com/).\n" + + "- :information_source: For questions and support, visit the [Bitwarden Help Center](https://bitwarden.com/help/).\n" + + "- :bug: To report a potential bug, please visit the corresponding repo. [Server](https://github.com/bitwarden/server/issues) | [Clients](https://github.com/bitwarden/clients/issues) | [iOS](https://github.com/bitwarden/ios/issues) | [Android](https://github.com/bitwarden/android/issues)\n\n" + + "Thank you for contributing to Bitwarden!"; + + await addComment(discussion.node_id, replyMessage); From 22678768605b5554c0b2b22043c508261d9a8b47 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Mon, 7 Apr 2025 11:58:50 -0700 Subject: [PATCH 28/93] refactor(set-change-password): [Auth/PM-18206] Update InputPasswordComponent to handle multiple flows (#13745) Updates the InputPasswordComponent so that it can eventually be used in multiple set/change password scenarios. Most importantly, this PR adds an InputPasswordFlow enum and @Input so that parent components can dictate which UI elements to show. --- apps/browser/src/_locales/en/messages.json | 3 + apps/desktop/src/locales/en/messages.json | 3 + .../web-registration-finish.service.spec.ts | 14 +- .../complete-trial-initiation.component.html | 6 +- .../complete-trial-initiation.component.ts | 10 +- apps/web/src/locales/en/messages.json | 3 + .../input-password.component.html | 76 +++++++-- .../input-password.component.ts | 156 ++++++++++++++---- .../angular/input-password/input-password.mdx | 90 +++++++--- .../input-password/input-password.stories.ts | 91 +++++++++- .../input-password/password-input-result.ts | 12 +- ...efault-registration-finish.service.spec.ts | 6 +- .../default-registration-finish.service.ts | 2 +- .../registration-finish.component.html | 3 +- .../registration-finish.component.ts | 9 +- .../default-set-password-jit.service.spec.ts | 6 +- .../default-set-password-jit.service.ts | 6 +- .../set-password-jit.component.html | 3 +- .../set-password-jit.component.ts | 6 +- .../set-password-jit.service.abstraction.ts | 2 +- 20 files changed, 394 insertions(+), 113 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 54024b83f98..586e7e1f2cf 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2297,6 +2297,9 @@ "privacyPolicy": { "message": "Privacy Policy" }, + "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { + "message": "Your new password cannot be the same as your current password." + }, "hintEqualsPassword": { "message": "Your password hint cannot be the same as your password." }, diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index f1c63780793..8850cbe5a3f 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -2072,6 +2072,9 @@ "personalOwnershipSubmitError": { "message": "Due to an enterprise policy, you are restricted from saving items to your individual vault. Change the ownership option to an organization and choose from available collections." }, + "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { + "message": "Your new password cannot be the same as your current password." + }, "hintEqualsPassword": { "message": "Your password hint cannot be the same as your password." }, diff --git a/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts b/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts index 48b74dc5e2e..aa02e28b3b3 100644 --- a/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts +++ b/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts @@ -187,11 +187,11 @@ describe("WebRegistrationFinishService", () => { masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; passwordInputResult = { masterKey: masterKey, - masterKeyHash: "masterKeyHash", + serverMasterKeyHash: "serverMasterKeyHash", localMasterKeyHash: "localMasterKeyHash", kdfConfig: DEFAULT_KDF_CONFIG, hint: "hint", - password: "password", + newPassword: "newPassword", }; userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey; @@ -239,7 +239,7 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: emailVerificationToken, - masterPasswordHash: passwordInputResult.masterKeyHash, + masterPasswordHash: passwordInputResult.serverMasterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { @@ -277,7 +277,7 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.masterKeyHash, + masterPasswordHash: passwordInputResult.serverMasterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { @@ -320,7 +320,7 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.masterKeyHash, + masterPasswordHash: passwordInputResult.serverMasterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { @@ -365,7 +365,7 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.masterKeyHash, + masterPasswordHash: passwordInputResult.serverMasterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { @@ -412,7 +412,7 @@ describe("WebRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: undefined, - masterPasswordHash: passwordInputResult.masterKeyHash, + masterPasswordHash: passwordInputResult.serverMasterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { diff --git a/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html b/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html index 416d4004260..8118b1e512d 100644 --- a/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html +++ b/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.html @@ -1,19 +1,21 @@
diff --git a/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts b/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts index 27ce4dc9f5d..e2a4149a58d 100644 --- a/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts +++ b/apps/web/src/app/billing/trial-initiation/complete-trial-initiation/complete-trial-initiation.component.ts @@ -6,7 +6,11 @@ import { FormBuilder, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { firstValueFrom, Subject, switchMap, takeUntil } from "rxjs"; -import { PasswordInputResult, RegistrationFinishService } from "@bitwarden/auth/angular"; +import { + InputPasswordFlow, + PasswordInputResult, + RegistrationFinishService, +} from "@bitwarden/auth/angular"; import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitwarden/auth/common"; import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; @@ -47,6 +51,8 @@ export type InitiationPath = export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { @ViewChild("stepper", { static: false }) verticalStepper: VerticalStepperComponent; + InputPasswordFlow = InputPasswordFlow; + /** Password Manager or Secrets Manager */ product: ProductType; /** The tier of product being subscribed to */ @@ -363,7 +369,7 @@ export class CompleteTrialInitiationComponent implements OnInit, OnDestroy { return; } - await this.logIn(passwordInputResult.password, captchaToken); + await this.logIn(passwordInputResult.newPassword, captchaToken); this.submitting = false; diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 6c730338fea..3300f73eb3b 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -5707,6 +5707,9 @@ "webAuthnSuccess": { "message": "WebAuthn verified successfully! You may close this tab." }, + "yourNewPasswordCannotBeTheSameAsYourCurrentPassword": { + "message": "Your new password cannot be the same as your current password." + }, "hintEqualsPassword": { "message": "Your password hint cannot be the same as your password." }, diff --git a/libs/auth/src/angular/input-password/input-password.component.html b/libs/auth/src/angular/input-password/input-password.component.html index 114d9b8fb8d..39995f9f44f 100644 --- a/libs/auth/src/angular/input-password/input-password.component.html +++ b/libs/auth/src/angular/input-password/input-password.component.html @@ -4,14 +4,36 @@ [policy]="masterPasswordPolicyOptions" > + + {{ "currentMasterPass" | i18n }} + + + +
- {{ "masterPassword" | i18n }} + {{ "newMasterPass" | i18n }}
@@ -38,10 +60,10 @@ {{ "confirmMasterPassword" | i18n }} + + + {{ "rotateAccountEncKey" | i18n }} + + + + + + +
+ + + +
diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index c613cf5f533..2f8e5d5b01d 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -1,7 +1,5 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, EventEmitter, Input, Output } from "@angular/core"; -import { ReactiveFormsModule, FormBuilder, Validators } from "@angular/forms"; +import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { ReactiveFormsModule, FormBuilder, Validators, FormGroup } from "@angular/forms"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { @@ -23,6 +21,7 @@ import { IconButtonModule, InputModule, ToastService, + Translation, } from "@bitwarden/components"; import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; @@ -36,6 +35,29 @@ import { PasswordCalloutComponent } from "../password-callout/password-callout.c import { PasswordInputResult } from "./password-input-result"; +/** + * Determines which form input elements will be displayed in the UI. + */ +export enum InputPasswordFlow { + /** + * - Input: New password + * - Input: Confirm new password + * - Input: Hint + * - Checkbox: Check for breaches + */ + SetInitialPassword, + /** + * Everything above, plus: + * - Input: Current password (as the first element in the UI) + */ + ChangePassword, + /** + * Everything above, plus: + * - Checkbox: Rotate account encryption key (as the last element in the UI) + */ + ChangePasswordWithOptionalUserKeyRotation, +} + @Component({ standalone: true, selector: "auth-input-password", @@ -54,44 +76,58 @@ import { PasswordInputResult } from "./password-input-result"; JslibModule, ], }) -export class InputPasswordComponent { +export class InputPasswordComponent implements OnInit { @Output() onPasswordFormSubmit = new EventEmitter(); + @Output() onSecondaryButtonClick = new EventEmitter(); - @Input({ required: true }) email: string; - @Input() buttonText: string; + @Input({ required: true }) inputPasswordFlow!: InputPasswordFlow; + @Input({ required: true }) email!: string; + + @Input() loading = false; @Input() masterPasswordPolicyOptions: MasterPasswordPolicyOptions | null = null; - @Input() loading: boolean = false; - @Input() btnBlock: boolean = true; + @Input() inlineButtons = false; + @Input() primaryButtonText?: Translation; + protected primaryButtonTextStr: string = ""; + @Input() secondaryButtonText?: Translation; + protected secondaryButtonTextStr: string = ""; + + protected InputPasswordFlow = InputPasswordFlow; private minHintLength = 0; protected maxHintLength = 50; protected minPasswordLength = Utils.minimumPasswordLength; protected minPasswordMsg = ""; - protected passwordStrengthScore: PasswordStrengthScore; + protected passwordStrengthScore: PasswordStrengthScore = 0; protected showErrorSummary = false; protected showPassword = false; - protected formGroup = this.formBuilder.group( + protected formGroup = this.formBuilder.nonNullable.group( { - password: ["", [Validators.required, Validators.minLength(this.minPasswordLength)]], - confirmedPassword: ["", Validators.required], + newPassword: ["", [Validators.required, Validators.minLength(this.minPasswordLength)]], + confirmNewPassword: ["", Validators.required], hint: [ "", // must be string (not null) because we check length in validation [Validators.minLength(this.minHintLength), Validators.maxLength(this.maxHintLength)], ], - checkForBreaches: true, + checkForBreaches: [true], }, { validators: [ + InputsFieldMatch.compareInputs( + "doNotMatch", + "currentPassword", + "newPassword", + this.i18nService.t("yourNewPasswordCannotBeTheSameAsYourCurrentPassword"), + ), InputsFieldMatch.compareInputs( "match", - "password", - "confirmedPassword", + "newPassword", + "confirmNewPassword", this.i18nService.t("masterPassDoesntMatch"), ), InputsFieldMatch.compareInputs( "doNotMatch", - "password", + "newPassword", "hint", this.i18nService.t("hintEqualsPassword"), ), @@ -109,6 +145,41 @@ export class InputPasswordComponent { private toastService: ToastService, ) {} + ngOnInit(): void { + if ( + this.inputPasswordFlow === InputPasswordFlow.ChangePassword || + this.inputPasswordFlow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation + ) { + // https://github.com/angular/angular/issues/48794 + (this.formGroup as FormGroup).addControl( + "currentPassword", + this.formBuilder.control("", Validators.required), + ); + } + + if (this.inputPasswordFlow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation) { + // https://github.com/angular/angular/issues/48794 + (this.formGroup as FormGroup).addControl( + "rotateUserKey", + this.formBuilder.control(false), + ); + } + + if (this.primaryButtonText) { + this.primaryButtonTextStr = this.i18nService.t( + this.primaryButtonText.key, + ...(this.primaryButtonText?.placeholders ?? []), + ); + } + + if (this.secondaryButtonText) { + this.secondaryButtonTextStr = this.i18nService.t( + this.secondaryButtonText.key, + ...(this.secondaryButtonText?.placeholders ?? []), + ); + } + } + get minPasswordLengthMsg() { if ( this.masterPasswordPolicyOptions != null && @@ -132,10 +203,10 @@ export class InputPasswordComponent { return; } - const password = this.formGroup.controls.password.value; + const newPassword = this.formGroup.controls.newPassword.value; - const passwordEvaluatedSuccessfully = await this.evaluatePassword( - password, + const passwordEvaluatedSuccessfully = await this.evaluateNewPassword( + newPassword, this.passwordStrengthScore, this.formGroup.controls.checkForBreaches.value, ); @@ -152,38 +223,55 @@ export class InputPasswordComponent { } const masterKey = await this.keyService.makeMasterKey( - password, + newPassword, this.email.trim().toLowerCase(), kdfConfig, ); - const masterKeyHash = await this.keyService.hashMasterKey(password, masterKey); + const serverMasterKeyHash = await this.keyService.hashMasterKey( + newPassword, + masterKey, + HashPurpose.ServerAuthorization, + ); const localMasterKeyHash = await this.keyService.hashMasterKey( - password, + newPassword, masterKey, HashPurpose.LocalAuthorization, ); - this.onPasswordFormSubmit.emit({ - masterKey, - masterKeyHash, - localMasterKeyHash, - kdfConfig, + const passwordInputResult: PasswordInputResult = { + newPassword, hint: this.formGroup.controls.hint.value, - password, - }); + kdfConfig, + masterKey, + serverMasterKeyHash, + localMasterKeyHash, + }; + + if ( + this.inputPasswordFlow === InputPasswordFlow.ChangePassword || + this.inputPasswordFlow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation + ) { + passwordInputResult.currentPassword = this.formGroup.get("currentPassword")?.value; + } + + if (this.inputPasswordFlow === InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation) { + passwordInputResult.rotateUserKey = this.formGroup.get("rotateUserKey")?.value; + } + + this.onPasswordFormSubmit.emit(passwordInputResult); }; // Returns true if the password passes all checks, false otherwise - private async evaluatePassword( - password: string, + private async evaluateNewPassword( + newPassword: string, passwordStrengthScore: PasswordStrengthScore, checkForBreaches: boolean, ) { // Check if the password is breached, weak, or both const passwordIsBreached = - checkForBreaches && (await this.auditService.passwordLeaked(password)); + checkForBreaches && (await this.auditService.passwordLeaked(newPassword)); const passwordWeak = passwordStrengthScore != null && passwordStrengthScore < 3; @@ -224,7 +312,7 @@ export class InputPasswordComponent { this.masterPasswordPolicyOptions != null && !this.policyService.evaluateMasterPassword( this.passwordStrengthScore, - password, + newPassword, this.masterPasswordPolicyOptions, ) ) { diff --git a/libs/auth/src/angular/input-password/input-password.mdx b/libs/auth/src/angular/input-password/input-password.mdx index 5110e2b3130..c1edcc254a7 100644 --- a/libs/auth/src/angular/input-password/input-password.mdx +++ b/libs/auth/src/angular/input-password/input-password.mdx @@ -6,9 +6,9 @@ import * as stories from "./input-password.stories.ts"; # InputPassword Component -The `InputPasswordComponent` allows a user to enter a master password and hint. On submission it -creates a master key, master key hash, and emits those values to the parent (along with the hint and -default kdfConfig). +The `InputPasswordComponent` allows a user to enter master password related credentials. On +submission it creates a master key, master key hash, and emits those values to the parent (along +with the other values found in `PasswordInputResult`). The component is intended for re-use in different scenarios throughout the application. Therefore it is mostly presentational and simply emits values rather than acting on them itself. It is the job of @@ -18,26 +18,66 @@ the parent component to act on those values as needed. ## `@Input()`'s -- `email` (**required**) - the parent component must provide an email so that the - `InputPasswordComponent` can create a master key. -- `buttonText` (optional) - an `i18n` translated string that can be used as button text (default - text is "Set master password"). -- `masterPasswordPolicyOptions` (optional) - used to display and enforce master password policy - requirements. +**Required** + +- `inputPasswordFlow` - the parent component must provide the correct flow, which is used to + determine which form input elements will be displayed in the UI. +- `email` - the parent component must provide an email so that the `InputPasswordComponent` can + create a master key. + +**Optional** + +- `loading` - a boolean used to indicate that the parent component is performing some + long-running/async operation and that the form should be disabled until the operation is complete. + The primary button will also show a spinner if `loading` true. +- `masterPasswordPolicyOptions` - used to display and enforce master password policy requirements. +- `inlineButtons` - takes a boolean that determines if the button(s) should be displayed inline (as + opposed to full-width) +- `primaryButtonText` - takes a `Translation` object that can be used as button text +- `secondaryButtonText` - takes a `Translation` object that can be used as button text + +## `@Output()`'s + +- `onPasswordFormSubmit` - on form submit, emits a `PasswordInputResult` object +- `onSecondaryButtonClick` - on click, emits a notice that the secondary button has been clicked. + The parent component can listen for this event and take some custom action as needed (go back, + cancel, logout, etc.)
## Form Input Fields -The `InputPasswordComponent` allows a user to enter: +The `InputPasswordComponent` can handle up to 6 different form input fields, depending on the +`InputPasswordFlow` provided by the parent component. -1. Master password -2. Master password confirmation -3. Hint (optional) -4. Chooses whether to check for password breaches (checkbox) +**InputPasswordFlow.SetInitialPassword** -Validation ensures that the master password and confirmed master password are the same, and that the -master password and hint values are not the same. +- Input: New password +- Input: Confirm new password +- Input: Hint +- Checkbox: Check for breaches + +**InputPasswordFlow.ChangePassword** + +Includes everything above, plus: + +- Input: Current password (as the first element in the UI) + +**InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation** + +Includes everything above, plus: + +- Checkbox: Rotate account encryption key (as the last element in the UI) + +
+ +## Validation + +Validation ensures that: + +- The current password and new password are NOT the same +- The new password and confirmed new password are the same +- The new password and password hint are NOT the same
@@ -57,19 +97,23 @@ When the form is submitted, the `InputPasswordComponent` does the following in o ```typescript export interface PasswordInputResult { - masterKey: MasterKey; - masterKeyHash: string; - kdfConfig: PBKDF2KdfConfig; + newPassword: string; hint: string; + kdfConfig: PBKDF2KdfConfig; + masterKey: MasterKey; + serverMasterKeyHash: string; + localMasterKeyHash: string; + currentPassword?: string; // included if the flow is ChangePassword or ChangePasswordWithOptionalUserKeyRotation + rotateUserKey?: boolean; // included if the flow is ChangePasswordWithOptionalUserKeyRotation } ``` -# Default Example +# Example - InputPasswordFlow.SetInitialPassword - +
-# With Policy Requrements +# Example - With Policy Requrements - + diff --git a/libs/auth/src/angular/input-password/input-password.stories.ts b/libs/auth/src/angular/input-password/input-password.stories.ts index 41577328f87..beda97a2c16 100644 --- a/libs/auth/src/angular/input-password/input-password.stories.ts +++ b/libs/auth/src/angular/input-password/input-password.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { importProvidersFrom } from "@angular/core"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { action } from "@storybook/addon-actions"; @@ -18,7 +16,7 @@ import { KeyService } from "@bitwarden/key-management"; // eslint-disable-next-line import/no-restricted-paths, no-restricted-imports import { PreloadedEnglishI18nModule } from "../../../../../apps/web/src/app/core/tests"; -import { InputPasswordComponent } from "./input-password.component"; +import { InputPasswordComponent, InputPasswordFlow } from "./input-password.component"; export default { title: "Auth/Input Password", @@ -62,7 +60,7 @@ export default { provide: PasswordStrengthServiceAbstraction, useValue: { getPasswordStrength: (password) => { - let score = 0; + let score: number | null = null; if (password.length === 0) { score = null; } else if (password.length <= 4) { @@ -88,6 +86,12 @@ export default { }), ], args: { + InputPasswordFlow: { + SetInitialPassword: InputPasswordFlow.SetInitialPassword, + ChangePassword: InputPasswordFlow.ChangePassword, + ChangePasswordWithOptionalUserKeyRotation: + InputPasswordFlow.ChangePasswordWithOptionalUserKeyRotation, + }, masterPasswordPolicyOptions: { minComplexity: 4, minLength: 14, @@ -96,25 +100,77 @@ export default { requireNumbers: true, requireSpecial: true, } as MasterPasswordPolicyOptions, + argTypes: { + onSecondaryButtonClick: { action: "onSecondaryButtonClick" }, + }, }, } as Meta; type Story = StoryObj; -export const Default: Story = { +export const SetInitialPassword: Story = { render: (args) => ({ props: args, template: ` - + `, }), }; -export const WithPolicy: Story = { +export const ChangePassword: Story = { render: (args) => ({ props: args, template: ` - + + `, + }), +}; + +export const ChangePasswordWithOptionalUserKeyRotation: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), +}; + +export const WithPolicies: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), +}; + +export const SecondaryButton: Story = { + render: (args) => ({ + props: args, + template: ` + + `, + }), +}; + +export const SecondaryButtonWithPlaceHolderText: Story = { + render: (args) => ({ + props: args, + template: ` + `, }), }; @@ -123,7 +179,24 @@ export const InlineButton: Story = { render: (args) => ({ props: args, template: ` - + + `, + }), +}; + +export const InlineButtons: Story = { + render: (args) => ({ + props: args, + template: ` + `, }), }; diff --git a/libs/auth/src/angular/input-password/password-input-result.ts b/libs/auth/src/angular/input-password/password-input-result.ts index 07157aaf4ca..c64225e2eb5 100644 --- a/libs/auth/src/angular/input-password/password-input-result.ts +++ b/libs/auth/src/angular/input-password/password-input-result.ts @@ -2,10 +2,12 @@ import { MasterKey } from "@bitwarden/common/types/key"; import { PBKDF2KdfConfig } from "@bitwarden/key-management"; export interface PasswordInputResult { - masterKey: MasterKey; - masterKeyHash: string; - localMasterKeyHash: string; - kdfConfig: PBKDF2KdfConfig; + newPassword: string; hint: string; - password: string; + kdfConfig: PBKDF2KdfConfig; + masterKey: MasterKey; + serverMasterKeyHash: string; + localMasterKeyHash: string; + currentPassword?: string; + rotateUserKey?: boolean; } diff --git a/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts b/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts index 14600cebf1d..c288f30d812 100644 --- a/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts +++ b/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts @@ -60,11 +60,11 @@ describe("DefaultRegistrationFinishService", () => { masterKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as MasterKey; passwordInputResult = { masterKey: masterKey, - masterKeyHash: "masterKeyHash", + serverMasterKeyHash: "serverMasterKeyHash", localMasterKeyHash: "localMasterKeyHash", kdfConfig: DEFAULT_KDF_CONFIG, hint: "hint", - password: "password", + newPassword: "password", }; userKey = new SymmetricCryptoKey(new Uint8Array(64).buffer as CsprngArray) as UserKey; @@ -101,7 +101,7 @@ describe("DefaultRegistrationFinishService", () => { expect.objectContaining({ email, emailVerificationToken: emailVerificationToken, - masterPasswordHash: passwordInputResult.masterKeyHash, + masterPasswordHash: passwordInputResult.serverMasterKeyHash, masterPasswordHint: passwordInputResult.hint, userSymmetricKey: userKeyEncString.encryptedString, userAsymmetricKeys: { diff --git a/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.ts b/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.ts index 72e26720134..7d844ce8cb0 100644 --- a/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.ts +++ b/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.ts @@ -81,7 +81,7 @@ export class DefaultRegistrationFinishService implements RegistrationFinishServi const registerFinishRequest = new RegisterFinishRequest( email, - passwordInputResult.masterKeyHash, + passwordInputResult.serverMasterKeyHash, passwordInputResult.hint, encryptedUserKey, userAsymmetricKeysRequest, diff --git a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html index e42ed91166a..ccc502bd7b6 100644 --- a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html +++ b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.html @@ -5,8 +5,9 @@ diff --git a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts index c419e1f427f..506b7475db1 100644 --- a/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts +++ b/libs/auth/src/angular/registration/registration-finish/registration-finish.component.ts @@ -22,7 +22,10 @@ import { PasswordLoginCredentials, } from "../../../common"; import { AnonLayoutWrapperDataService } from "../../anon-layout/anon-layout-wrapper-data.service"; -import { InputPasswordComponent } from "../../input-password/input-password.component"; +import { + InputPasswordComponent, + InputPasswordFlow, +} from "../../input-password/input-password.component"; import { PasswordInputResult } from "../../input-password/password-input-result"; import { RegistrationFinishService } from "./registration-finish.service"; @@ -36,6 +39,8 @@ import { RegistrationFinishService } from "./registration-finish.service"; export class RegistrationFinishComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); + InputPasswordFlow = InputPasswordFlow; + loading = true; submitting = false; email: string; @@ -176,7 +181,7 @@ export class RegistrationFinishComponent implements OnInit, OnDestroy { try { const credentials = new PasswordLoginCredentials( this.email, - passwordInputResult.password, + passwordInputResult.newPassword, captchaBypassToken, null, ); diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts index bd62092a4b6..cbcebd14526 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts @@ -112,11 +112,11 @@ describe("DefaultSetPasswordJitService", () => { passwordInputResult = { masterKey: masterKey, - masterKeyHash: "masterKeyHash", + serverMasterKeyHash: "serverMasterKeyHash", localMasterKeyHash: "localMasterKeyHash", hint: "hint", kdfConfig: DEFAULT_KDF_CONFIG, - password: "password", + newPassword: "password", }; credentials = { @@ -131,7 +131,7 @@ describe("DefaultSetPasswordJitService", () => { userDecryptionOptionsService.userDecryptionOptions$ = userDecryptionOptionsSubject; setPasswordRequest = new SetPasswordRequest( - passwordInputResult.masterKeyHash, + passwordInputResult.serverMasterKeyHash, protectedUserKey[1].encryptedString, passwordInputResult.hint, orgSsoIdentifier, diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts index 42d964f3de0..174760aae21 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts @@ -44,7 +44,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService { async setPassword(credentials: SetPasswordCredentials): Promise { const { masterKey, - masterKeyHash, + serverMasterKeyHash, localMasterKeyHash, hint, kdfConfig, @@ -70,7 +70,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService { const [keyPair, keysRequest] = await this.makeKeyPairAndRequest(protectedUserKey); const request = new SetPasswordRequest( - masterKeyHash, + serverMasterKeyHash, protectedUserKey[1].encryptedString, hint, orgSsoIdentifier, @@ -92,7 +92,7 @@ export class DefaultSetPasswordJitService implements SetPasswordJitService { await this.masterPasswordService.setMasterKeyHash(localMasterKeyHash, userId); if (resetPasswordAutoEnroll) { - await this.handleResetPasswordAutoEnroll(masterKeyHash, orgId, userId); + await this.handleResetPasswordAutoEnroll(serverMasterKeyHash, orgId, userId); } } diff --git a/libs/auth/src/angular/set-password-jit/set-password-jit.component.html b/libs/auth/src/angular/set-password-jit/set-password-jit.component.html index aa6a1229937..3a4956ef7e9 100644 --- a/libs/auth/src/angular/set-password-jit/set-password-jit.component.html +++ b/libs/auth/src/angular/set-password-jit/set-password-jit.component.html @@ -13,7 +13,8 @@ Date: Mon, 7 Apr 2025 22:00:31 +0100 Subject: [PATCH 29/93] Fix the bug for free bitwarden Families menu (#14155) --- .../src/app/billing/services/free-families-policy.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/web/src/app/billing/services/free-families-policy.service.ts b/apps/web/src/app/billing/services/free-families-policy.service.ts index 8d4e89d40a0..81cb970cdbe 100644 --- a/apps/web/src/app/billing/services/free-families-policy.service.ts +++ b/apps/web/src/app/billing/services/free-families-policy.service.ts @@ -59,8 +59,8 @@ export class FreeFamiliesPolicyService { return false; } const { belongToOneEnterpriseOrgs, isFreeFamilyPolicyEnabled } = orgStatus; - const canManageSponsorships = organizations.filter((org) => org.canManageSponsorships); - return canManageSponsorships && !(belongToOneEnterpriseOrgs && isFreeFamilyPolicyEnabled); + const hasSponsorshipOrgs = organizations.some((org) => org.canManageSponsorships); + return hasSponsorshipOrgs && !(belongToOneEnterpriseOrgs && isFreeFamilyPolicyEnabled); } checkEnterpriseOrganizationsAndFetchPolicy(): Observable { From 19d59212a893de1e1296eec7d9d8e79e74d4e009 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Mon, 7 Apr 2025 17:20:45 -0400 Subject: [PATCH 30/93] Add save-exact=true (#14169) --- .npmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 00000000000..cffe8cdef13 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +save-exact=true From ecb4b2d0b72ce7150571755e7021a1bcd9ca318a Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Mon, 7 Apr 2025 15:04:24 -0700 Subject: [PATCH 31/93] refactor(set-change-password): [Auth/PM-17649] Move and test compareInputs validator (#13553) - Move the `compareInputs` validator to `libs/auth` - Add tests for the `compareInputs` validator - Delete the deprecated `InputsFieldMatch` class (inputs-field-match.validator.ts) --- .../inputs-field-match.validator.ts | 167 -------------- libs/auth/src/angular/index.ts | 3 + .../input-password.component.ts | 22 +- .../compare-inputs.validator.spec.ts | 218 ++++++++++++++++++ .../validators/compare-inputs.validator.ts | 134 +++++++++++ 5 files changed, 365 insertions(+), 179 deletions(-) delete mode 100644 libs/angular/src/auth/validators/inputs-field-match.validator.ts create mode 100644 libs/auth/src/angular/validators/compare-inputs.validator.spec.ts create mode 100644 libs/auth/src/angular/validators/compare-inputs.validator.ts diff --git a/libs/angular/src/auth/validators/inputs-field-match.validator.ts b/libs/angular/src/auth/validators/inputs-field-match.validator.ts deleted file mode 100644 index 5f3acd73bc6..00000000000 --- a/libs/angular/src/auth/validators/inputs-field-match.validator.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { AbstractControl, UntypedFormGroup, ValidationErrors, ValidatorFn } from "@angular/forms"; - -import { FormGroupControls } from "../../platform/abstractions/form-validation-errors.service"; - -export class InputsFieldMatch { - /** - * Check to ensure two fields do not have the same value - * - * @deprecated Use compareInputs() instead - */ - static validateInputsDoesntMatch(matchTo: string, errorMessage: string): ValidatorFn { - return (control: AbstractControl) => { - if (control.parent && control.parent.controls) { - return control?.value === (control?.parent?.controls as FormGroupControls)[matchTo].value - ? { - inputsMatchError: { - message: errorMessage, - }, - } - : null; - } - - return null; - }; - } - - //check to ensure two fields have the same value - static validateInputsMatch(matchTo: string, errorMessage: string): ValidatorFn { - return (control: AbstractControl) => { - if (control.parent && control.parent.controls) { - return control?.value === (control?.parent?.controls as FormGroupControls)[matchTo].value - ? null - : { - inputsDoesntMatchError: { - message: errorMessage, - }, - }; - } - - return null; - }; - } - - /** - * Checks the formGroup if two fields have the same value and validation is controlled from either field - * - * @deprecated - * Use compareInputs() instead. - * - * For more info on deprecation - * - Do not use untyped `options` object in formBuilder.group() {@link https://angular.dev/api/forms/UntypedFormBuilder} - * - Use formBuilder.group() overload with AbstractControlOptions type instead {@link https://angular.dev/api/forms/AbstractControlOptions} - * - * Remove this method after deprecated instances are replaced - */ - static validateFormInputsMatch(field: string, fieldMatchTo: string, errorMessage: string) { - return (formGroup: UntypedFormGroup) => { - const fieldCtrl = formGroup.controls[field]; - const fieldMatchToCtrl = formGroup.controls[fieldMatchTo]; - - if (fieldCtrl.value !== fieldMatchToCtrl.value) { - fieldMatchToCtrl.setErrors({ - inputsDoesntMatchError: { - message: errorMessage, - }, - }); - } else { - fieldMatchToCtrl.setErrors(null); - } - }; - } - - /** - * Checks whether two form controls do or do not have the same input value (except for empty string values). - * - * - Validation is controlled from either form control. - * - The error message is displayed under controlB by default, but can be set to controlA. - * - * @param validationGoal Whether you want to verify that the form control input values match or do not match - * @param controlNameA The name of the first form control to compare. - * @param controlNameB The name of the second form control to compare. - * @param errorMessage The error message to display if there is an error. This will probably - * be an i18n translated string. - * @param showErrorOn The control under which you want to display the error (default is controlB). - */ - static compareInputs( - validationGoal: "match" | "doNotMatch", - controlNameA: string, - controlNameB: string, - errorMessage: string, - showErrorOn: "controlA" | "controlB" = "controlB", - ): ValidatorFn { - return (control: AbstractControl): ValidationErrors | null => { - const controlA = control.get(controlNameA); - const controlB = control.get(controlNameB); - - if (!controlA || !controlB) { - return null; - } - - const controlThatShowsError = showErrorOn === "controlA" ? controlA : controlB; - - // Don't compare empty strings - if (controlA.value === "" && controlB.value === "") { - return pass(); - } - - const controlValuesMatch = controlA.value === controlB.value; - - if (validationGoal === "match") { - if (controlValuesMatch) { - return pass(); - } else { - return fail(); - } - } - - if (validationGoal === "doNotMatch") { - if (!controlValuesMatch) { - return pass(); - } else { - return fail(); - } - } - - return null; // default return - - function fail() { - controlThatShowsError.setErrors({ - // Preserve any pre-existing errors - ...controlThatShowsError.errors, - // Add new inputMatchError - inputMatchError: { - message: errorMessage, - }, - }); - - return { - inputMatchError: { - message: errorMessage, - }, - }; - } - - function pass(): null { - // Get the current errors object - const errorsObj = controlThatShowsError?.errors; - - if (errorsObj != null) { - // Remove any inputMatchError if it exists, since that is the sole error we are targeting with this validator - if (errorsObj?.inputMatchError) { - delete errorsObj.inputMatchError; - } - - // Check if the errorsObj is now empty - const isEmptyObj = Object.keys(errorsObj).length === 0; - - // If the errorsObj is empty, set errors to null, otherwise set the errors to an object of pre-existing errors (other than inputMatchError) - controlThatShowsError.setErrors(isEmptyObj ? null : errorsObj); - } - - // Return null for this validator - return null; - } - }; - } -} diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index bb2956b7569..91d34a34838 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -77,3 +77,6 @@ export * from "./two-factor-auth"; // device verification export * from "./new-device-verification/new-device-verification.component"; + +// validators +export * from "./validators/compare-inputs.validator"; diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index 2f8e5d5b01d..bc7f4121fbe 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -25,13 +25,11 @@ import { } from "@bitwarden/components"; import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { InputsFieldMatch } from "../../../../angular/src/auth/validators/inputs-field-match.validator"; // FIXME: remove `src` and fix import // eslint-disable-next-line no-restricted-imports import { SharedModule } from "../../../../components/src/shared"; import { PasswordCalloutComponent } from "../password-callout/password-callout.component"; +import { compareInputs, ValidationGoal } from "../validators/compare-inputs.validator"; import { PasswordInputResult } from "./password-input-result"; @@ -113,21 +111,21 @@ export class InputPasswordComponent implements OnInit { }, { validators: [ - InputsFieldMatch.compareInputs( - "doNotMatch", + compareInputs( + ValidationGoal.InputsShouldNotMatch, "currentPassword", "newPassword", this.i18nService.t("yourNewPasswordCannotBeTheSameAsYourCurrentPassword"), ), - InputsFieldMatch.compareInputs( - "match", - "newPassword", - "confirmNewPassword", + compareInputs( + ValidationGoal.InputsShouldMatch, + "password", + "confirmedPassword", this.i18nService.t("masterPassDoesntMatch"), ), - InputsFieldMatch.compareInputs( - "doNotMatch", - "newPassword", + compareInputs( + ValidationGoal.InputsShouldNotMatch, + "password", "hint", this.i18nService.t("hintEqualsPassword"), ), diff --git a/libs/auth/src/angular/validators/compare-inputs.validator.spec.ts b/libs/auth/src/angular/validators/compare-inputs.validator.spec.ts new file mode 100644 index 00000000000..b9ce8c1590a --- /dev/null +++ b/libs/auth/src/angular/validators/compare-inputs.validator.spec.ts @@ -0,0 +1,218 @@ +import { FormControl, FormGroup, ValidationErrors } from "@angular/forms"; + +import { compareInputs, ValidationGoal } from "./compare-inputs.validator"; + +describe("compareInputs", () => { + let validationErrorsObj: ValidationErrors; + + beforeEach(() => { + // Use a fresh object for each test so that a mutation in one test doesn't affect another test + validationErrorsObj = { + compareInputsError: { + message: "Custom error message", + }, + }; + }); + + it("should throw an error if compareInputs is not being applied to a FormGroup", () => { + const notAFormGroup = new FormControl("form-control"); + + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", + "Custom error message", + ); + + // Assert + expect(() => validatorFn(notAFormGroup)).toThrow( + "compareInputs only supports validation at the FormGroup level", + ); + }); + + it("should return null if either control is not found", () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl("content"), + }); + + // Act + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", // ctrlB is missing above + "Custom error message", + ); + + const result = validatorFn(formGroup); + + // Assert + expect(result).toBeNull(); + }); + + it("should return null if both controls have empty string values", () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl(""), + ctrlB: new FormControl(""), + }); + + // Act + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", + "Custom error message", + ); + + const result = validatorFn(formGroup); + + // Assert + expect(result).toBeNull(); + }); + + it("should call setErrors() on ctrlB if validation fails", () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl("apple"), + ctrlB: new FormControl("banana"), + }); + + const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); + + // Act + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", + "Custom error message", + ); + + validatorFn(formGroup); + + // Assert + expect(ctrlBSetErrorsSpy).toHaveBeenCalledWith(validationErrorsObj); + }); + + it("should call setErrors() on ctrlA if validation fails and 'showErrorOn' is set to 'controlA'", () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl("apple"), + ctrlB: new FormControl("banana"), + }); + + const ctrlASetErrorsSpy = jest.spyOn(formGroup.controls.ctrlA, "setErrors"); + const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); + + // Act + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", + "Custom error message", + "controlA", + ); + + validatorFn(formGroup); + + // Assert + expect(ctrlASetErrorsSpy).toHaveBeenCalledWith(validationErrorsObj); + expect(ctrlBSetErrorsSpy).not.toHaveBeenCalled(); + }); + + it("should not call setErrors() on ctrlB if validation passes and there is not a pre-existing error on ctrlB", () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl("apple"), + ctrlB: new FormControl("apple"), + }); + + const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); + + // Act + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", + "Custom error message", + ); + + validatorFn(formGroup); + + // Assert + expect(ctrlBSetErrorsSpy).not.toHaveBeenCalled(); + }); + + it("should call setErrors(null) on ctrlB if validation passes and there is a pre-existing error on ctrlB", () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl("apple"), + ctrlB: new FormControl("apple"), + }); + + const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); + + formGroup.controls.ctrlB.setErrors(validationErrorsObj); // the pre-existing error + + // Act + const validatorFn = compareInputs( + ValidationGoal.InputsShouldMatch, + "ctrlA", + "ctrlB", + "Custom error message", + ); + + validatorFn(formGroup); + + // Assert + expect(ctrlBSetErrorsSpy).toHaveBeenCalledWith(null); + }); + + const cases = [ + { + expected: null, + goal: ValidationGoal.InputsShouldMatch, + matchStatus: "match", + values: { ctrlA: "apple", ctrlB: "apple" }, + }, + { + expected: "a ValidationErrors object", + goal: ValidationGoal.InputsShouldMatch, + matchStatus: "do not match", + values: { ctrlA: "apple", ctrlB: "banana" }, + }, + { + expected: null, + goal: ValidationGoal.InputsShouldNotMatch, + matchStatus: "do not match", + values: { ctrlA: "apple", ctrlB: "banana" }, + }, + { + expected: "a ValidationErrors object", + goal: ValidationGoal.InputsShouldNotMatch, + matchStatus: "match", + values: { ctrlA: "apple", ctrlB: "apple" }, + }, + ]; + + cases.forEach(({ goal, expected, matchStatus, values }) => { + const goalString = + goal === ValidationGoal.InputsShouldMatch ? "InputsShouldMatch" : "InputsShouldNotMatch"; + + it(`should return ${expected} if the goal is ${goalString} and the inputs ${matchStatus}`, () => { + // Arrange + const formGroup = new FormGroup({ + ctrlA: new FormControl(values.ctrlA), + ctrlB: new FormControl(values.ctrlB), + }); + + // Act + const validatorFn = compareInputs(goal, "ctrlA", "ctrlB", "Custom error message"); + + const result = validatorFn(formGroup); + + // Assert + expect(result).toEqual(expected === null ? null : validationErrorsObj); + }); + }); +}); diff --git a/libs/auth/src/angular/validators/compare-inputs.validator.ts b/libs/auth/src/angular/validators/compare-inputs.validator.ts new file mode 100644 index 00000000000..cb31ac664f5 --- /dev/null +++ b/libs/auth/src/angular/validators/compare-inputs.validator.ts @@ -0,0 +1,134 @@ +import { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms"; + +export enum ValidationGoal { + InputsShouldMatch, + InputsShouldNotMatch, +} + +/** + * A cross-field validator that evaluates whether two form controls do or do + * not have the same input value (except for empty string values). This validator + * gets added to the entire FormGroup, not to an individual FormControl, like so: + * + * > ``` + * > formGroup = new FormGroup({ + * > password: new FormControl(), + * > confirmPassword: new FormControl(), + * > }, + * > { + * > validators: compareInputs(...), + * > }); + * > ``` + * + * Notes: + * - Validation is controlled from either form control. + * - The error message is displayed under controlB by default, but can be set to controlA. + * - For more info on custom validators and cross-field validation: + * - https://v18.angular.dev/guide/forms/form-validation#defining-custom-validators + * - https://v18.angular.dev/guide/forms/form-validation#cross-field-validation + * + * @param validationGoal Whether you want to verify that the form controls do or do not have matching input values. + * @param controlNameA The name of the first form control to compare. + * @param controlNameB The name of the second form control to compare. + * @param errorMessage The error message to display if there is an error. This will probably + * be an i18n translated string. + * @param showErrorOn The control under which you want to display the error (default is controlB). + * + * @returns A validator function that can be used on a FormGroup. + */ +export function compareInputs( + validationGoal: ValidationGoal, + controlNameA: string, + controlNameB: string, + errorMessage: string, + showErrorOn: "controlA" | "controlB" = "controlB", +): ValidatorFn { + /** + * Documentation for the inner ValidatorFn that gets returned: + * + * @param formGroup The AbstractControl that we want to perform validation on. In this case we + * perform validation on the FormGroup, which is a subclass of AbstractControl. + * The reason we validate at the FormGroup level and not at the FormControl level + * is because we want to compare two child FormControls in a single validator, so + * we use the FormGroup as the common ancestor. + * + * @returns A ValidationErrors object if the validation fails, or null if the validation passes. + */ + return (formGroup: AbstractControl): ValidationErrors | null => { + if (!(formGroup instanceof FormGroup)) { + throw new Error("compareInputs only supports validation at the FormGroup level"); + } + + const controlA = formGroup.get(controlNameA); + const controlB = formGroup.get(controlNameB); + + if (!controlA || !controlB) { + return null; + } + + const controlThatShowsError = showErrorOn === "controlA" ? controlA : controlB; + + // Don't compare empty strings + if (controlA.value === "" && controlB.value === "") { + return pass(); + } + + const controlValuesMatch = controlA.value === controlB.value; + + if (validationGoal === ValidationGoal.InputsShouldMatch) { + if (controlValuesMatch) { + return pass(); + } else { + return fail(); + } + } + + if (validationGoal === ValidationGoal.InputsShouldNotMatch) { + if (!controlValuesMatch) { + return pass(); + } else { + return fail(); + } + } + + return null; // default return + + function fail() { + controlThatShowsError.setErrors({ + // Preserve any pre-existing errors + ...(controlThatShowsError.errors || {}), + // Add new compareInputsError + compareInputsError: { + message: errorMessage, + }, + }); + + return { + compareInputsError: { + message: errorMessage, + }, + }; + } + + function pass(): null { + // Get the current errors object + const errorsObj = controlThatShowsError?.errors; + + if (errorsObj != null) { + // Remove any compareInputsError if it exists, since that is the sole error we are targeting with this validator + if (errorsObj?.compareInputsError) { + delete errorsObj.compareInputsError; + } + + // Check if the errorsObj is now empty + const isEmptyObj = Object.keys(errorsObj).length === 0; + + // If the errorsObj is empty, set errors to null, otherwise set the errors to an object of pre-existing errors (other than compareInputsError) + controlThatShowsError.setErrors(isEmptyObj ? null : errorsObj); + } + + // Return null for this validator + return null; + } + }; +} From 81350a2ee10d297a5cbd9faf9a56e8b202b7b84c Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Mon, 7 Apr 2025 18:34:35 -0700 Subject: [PATCH 32/93] =?UTF-8?q?Revert=20"refactor(set-change-password):?= =?UTF-8?q?=20[Auth/PM-17649]=20Move=20and=20test=20compareI=E2=80=A6"=20(?= =?UTF-8?q?#14171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit ecb4b2d0b72ce7150571755e7021a1bcd9ca318a. --- .../inputs-field-match.validator.ts | 167 ++++++++++++++ libs/auth/src/angular/index.ts | 3 - .../input-password.component.ts | 22 +- .../compare-inputs.validator.spec.ts | 218 ------------------ .../validators/compare-inputs.validator.ts | 134 ----------- 5 files changed, 179 insertions(+), 365 deletions(-) create mode 100644 libs/angular/src/auth/validators/inputs-field-match.validator.ts delete mode 100644 libs/auth/src/angular/validators/compare-inputs.validator.spec.ts delete mode 100644 libs/auth/src/angular/validators/compare-inputs.validator.ts diff --git a/libs/angular/src/auth/validators/inputs-field-match.validator.ts b/libs/angular/src/auth/validators/inputs-field-match.validator.ts new file mode 100644 index 00000000000..5f3acd73bc6 --- /dev/null +++ b/libs/angular/src/auth/validators/inputs-field-match.validator.ts @@ -0,0 +1,167 @@ +import { AbstractControl, UntypedFormGroup, ValidationErrors, ValidatorFn } from "@angular/forms"; + +import { FormGroupControls } from "../../platform/abstractions/form-validation-errors.service"; + +export class InputsFieldMatch { + /** + * Check to ensure two fields do not have the same value + * + * @deprecated Use compareInputs() instead + */ + static validateInputsDoesntMatch(matchTo: string, errorMessage: string): ValidatorFn { + return (control: AbstractControl) => { + if (control.parent && control.parent.controls) { + return control?.value === (control?.parent?.controls as FormGroupControls)[matchTo].value + ? { + inputsMatchError: { + message: errorMessage, + }, + } + : null; + } + + return null; + }; + } + + //check to ensure two fields have the same value + static validateInputsMatch(matchTo: string, errorMessage: string): ValidatorFn { + return (control: AbstractControl) => { + if (control.parent && control.parent.controls) { + return control?.value === (control?.parent?.controls as FormGroupControls)[matchTo].value + ? null + : { + inputsDoesntMatchError: { + message: errorMessage, + }, + }; + } + + return null; + }; + } + + /** + * Checks the formGroup if two fields have the same value and validation is controlled from either field + * + * @deprecated + * Use compareInputs() instead. + * + * For more info on deprecation + * - Do not use untyped `options` object in formBuilder.group() {@link https://angular.dev/api/forms/UntypedFormBuilder} + * - Use formBuilder.group() overload with AbstractControlOptions type instead {@link https://angular.dev/api/forms/AbstractControlOptions} + * + * Remove this method after deprecated instances are replaced + */ + static validateFormInputsMatch(field: string, fieldMatchTo: string, errorMessage: string) { + return (formGroup: UntypedFormGroup) => { + const fieldCtrl = formGroup.controls[field]; + const fieldMatchToCtrl = formGroup.controls[fieldMatchTo]; + + if (fieldCtrl.value !== fieldMatchToCtrl.value) { + fieldMatchToCtrl.setErrors({ + inputsDoesntMatchError: { + message: errorMessage, + }, + }); + } else { + fieldMatchToCtrl.setErrors(null); + } + }; + } + + /** + * Checks whether two form controls do or do not have the same input value (except for empty string values). + * + * - Validation is controlled from either form control. + * - The error message is displayed under controlB by default, but can be set to controlA. + * + * @param validationGoal Whether you want to verify that the form control input values match or do not match + * @param controlNameA The name of the first form control to compare. + * @param controlNameB The name of the second form control to compare. + * @param errorMessage The error message to display if there is an error. This will probably + * be an i18n translated string. + * @param showErrorOn The control under which you want to display the error (default is controlB). + */ + static compareInputs( + validationGoal: "match" | "doNotMatch", + controlNameA: string, + controlNameB: string, + errorMessage: string, + showErrorOn: "controlA" | "controlB" = "controlB", + ): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const controlA = control.get(controlNameA); + const controlB = control.get(controlNameB); + + if (!controlA || !controlB) { + return null; + } + + const controlThatShowsError = showErrorOn === "controlA" ? controlA : controlB; + + // Don't compare empty strings + if (controlA.value === "" && controlB.value === "") { + return pass(); + } + + const controlValuesMatch = controlA.value === controlB.value; + + if (validationGoal === "match") { + if (controlValuesMatch) { + return pass(); + } else { + return fail(); + } + } + + if (validationGoal === "doNotMatch") { + if (!controlValuesMatch) { + return pass(); + } else { + return fail(); + } + } + + return null; // default return + + function fail() { + controlThatShowsError.setErrors({ + // Preserve any pre-existing errors + ...controlThatShowsError.errors, + // Add new inputMatchError + inputMatchError: { + message: errorMessage, + }, + }); + + return { + inputMatchError: { + message: errorMessage, + }, + }; + } + + function pass(): null { + // Get the current errors object + const errorsObj = controlThatShowsError?.errors; + + if (errorsObj != null) { + // Remove any inputMatchError if it exists, since that is the sole error we are targeting with this validator + if (errorsObj?.inputMatchError) { + delete errorsObj.inputMatchError; + } + + // Check if the errorsObj is now empty + const isEmptyObj = Object.keys(errorsObj).length === 0; + + // If the errorsObj is empty, set errors to null, otherwise set the errors to an object of pre-existing errors (other than inputMatchError) + controlThatShowsError.setErrors(isEmptyObj ? null : errorsObj); + } + + // Return null for this validator + return null; + } + }; + } +} diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index 91d34a34838..bb2956b7569 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -77,6 +77,3 @@ export * from "./two-factor-auth"; // device verification export * from "./new-device-verification/new-device-verification.component"; - -// validators -export * from "./validators/compare-inputs.validator"; diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index bc7f4121fbe..2f8e5d5b01d 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -25,11 +25,13 @@ import { } from "@bitwarden/components"; import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; +// FIXME: remove `src` and fix import +// eslint-disable-next-line no-restricted-imports +import { InputsFieldMatch } from "../../../../angular/src/auth/validators/inputs-field-match.validator"; // FIXME: remove `src` and fix import // eslint-disable-next-line no-restricted-imports import { SharedModule } from "../../../../components/src/shared"; import { PasswordCalloutComponent } from "../password-callout/password-callout.component"; -import { compareInputs, ValidationGoal } from "../validators/compare-inputs.validator"; import { PasswordInputResult } from "./password-input-result"; @@ -111,21 +113,21 @@ export class InputPasswordComponent implements OnInit { }, { validators: [ - compareInputs( - ValidationGoal.InputsShouldNotMatch, + InputsFieldMatch.compareInputs( + "doNotMatch", "currentPassword", "newPassword", this.i18nService.t("yourNewPasswordCannotBeTheSameAsYourCurrentPassword"), ), - compareInputs( - ValidationGoal.InputsShouldMatch, - "password", - "confirmedPassword", + InputsFieldMatch.compareInputs( + "match", + "newPassword", + "confirmNewPassword", this.i18nService.t("masterPassDoesntMatch"), ), - compareInputs( - ValidationGoal.InputsShouldNotMatch, - "password", + InputsFieldMatch.compareInputs( + "doNotMatch", + "newPassword", "hint", this.i18nService.t("hintEqualsPassword"), ), diff --git a/libs/auth/src/angular/validators/compare-inputs.validator.spec.ts b/libs/auth/src/angular/validators/compare-inputs.validator.spec.ts deleted file mode 100644 index b9ce8c1590a..00000000000 --- a/libs/auth/src/angular/validators/compare-inputs.validator.spec.ts +++ /dev/null @@ -1,218 +0,0 @@ -import { FormControl, FormGroup, ValidationErrors } from "@angular/forms"; - -import { compareInputs, ValidationGoal } from "./compare-inputs.validator"; - -describe("compareInputs", () => { - let validationErrorsObj: ValidationErrors; - - beforeEach(() => { - // Use a fresh object for each test so that a mutation in one test doesn't affect another test - validationErrorsObj = { - compareInputsError: { - message: "Custom error message", - }, - }; - }); - - it("should throw an error if compareInputs is not being applied to a FormGroup", () => { - const notAFormGroup = new FormControl("form-control"); - - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", - "Custom error message", - ); - - // Assert - expect(() => validatorFn(notAFormGroup)).toThrow( - "compareInputs only supports validation at the FormGroup level", - ); - }); - - it("should return null if either control is not found", () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl("content"), - }); - - // Act - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", // ctrlB is missing above - "Custom error message", - ); - - const result = validatorFn(formGroup); - - // Assert - expect(result).toBeNull(); - }); - - it("should return null if both controls have empty string values", () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl(""), - ctrlB: new FormControl(""), - }); - - // Act - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", - "Custom error message", - ); - - const result = validatorFn(formGroup); - - // Assert - expect(result).toBeNull(); - }); - - it("should call setErrors() on ctrlB if validation fails", () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl("apple"), - ctrlB: new FormControl("banana"), - }); - - const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); - - // Act - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", - "Custom error message", - ); - - validatorFn(formGroup); - - // Assert - expect(ctrlBSetErrorsSpy).toHaveBeenCalledWith(validationErrorsObj); - }); - - it("should call setErrors() on ctrlA if validation fails and 'showErrorOn' is set to 'controlA'", () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl("apple"), - ctrlB: new FormControl("banana"), - }); - - const ctrlASetErrorsSpy = jest.spyOn(formGroup.controls.ctrlA, "setErrors"); - const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); - - // Act - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", - "Custom error message", - "controlA", - ); - - validatorFn(formGroup); - - // Assert - expect(ctrlASetErrorsSpy).toHaveBeenCalledWith(validationErrorsObj); - expect(ctrlBSetErrorsSpy).not.toHaveBeenCalled(); - }); - - it("should not call setErrors() on ctrlB if validation passes and there is not a pre-existing error on ctrlB", () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl("apple"), - ctrlB: new FormControl("apple"), - }); - - const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); - - // Act - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", - "Custom error message", - ); - - validatorFn(formGroup); - - // Assert - expect(ctrlBSetErrorsSpy).not.toHaveBeenCalled(); - }); - - it("should call setErrors(null) on ctrlB if validation passes and there is a pre-existing error on ctrlB", () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl("apple"), - ctrlB: new FormControl("apple"), - }); - - const ctrlBSetErrorsSpy = jest.spyOn(formGroup.controls.ctrlB, "setErrors"); - - formGroup.controls.ctrlB.setErrors(validationErrorsObj); // the pre-existing error - - // Act - const validatorFn = compareInputs( - ValidationGoal.InputsShouldMatch, - "ctrlA", - "ctrlB", - "Custom error message", - ); - - validatorFn(formGroup); - - // Assert - expect(ctrlBSetErrorsSpy).toHaveBeenCalledWith(null); - }); - - const cases = [ - { - expected: null, - goal: ValidationGoal.InputsShouldMatch, - matchStatus: "match", - values: { ctrlA: "apple", ctrlB: "apple" }, - }, - { - expected: "a ValidationErrors object", - goal: ValidationGoal.InputsShouldMatch, - matchStatus: "do not match", - values: { ctrlA: "apple", ctrlB: "banana" }, - }, - { - expected: null, - goal: ValidationGoal.InputsShouldNotMatch, - matchStatus: "do not match", - values: { ctrlA: "apple", ctrlB: "banana" }, - }, - { - expected: "a ValidationErrors object", - goal: ValidationGoal.InputsShouldNotMatch, - matchStatus: "match", - values: { ctrlA: "apple", ctrlB: "apple" }, - }, - ]; - - cases.forEach(({ goal, expected, matchStatus, values }) => { - const goalString = - goal === ValidationGoal.InputsShouldMatch ? "InputsShouldMatch" : "InputsShouldNotMatch"; - - it(`should return ${expected} if the goal is ${goalString} and the inputs ${matchStatus}`, () => { - // Arrange - const formGroup = new FormGroup({ - ctrlA: new FormControl(values.ctrlA), - ctrlB: new FormControl(values.ctrlB), - }); - - // Act - const validatorFn = compareInputs(goal, "ctrlA", "ctrlB", "Custom error message"); - - const result = validatorFn(formGroup); - - // Assert - expect(result).toEqual(expected === null ? null : validationErrorsObj); - }); - }); -}); diff --git a/libs/auth/src/angular/validators/compare-inputs.validator.ts b/libs/auth/src/angular/validators/compare-inputs.validator.ts deleted file mode 100644 index cb31ac664f5..00000000000 --- a/libs/auth/src/angular/validators/compare-inputs.validator.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from "@angular/forms"; - -export enum ValidationGoal { - InputsShouldMatch, - InputsShouldNotMatch, -} - -/** - * A cross-field validator that evaluates whether two form controls do or do - * not have the same input value (except for empty string values). This validator - * gets added to the entire FormGroup, not to an individual FormControl, like so: - * - * > ``` - * > formGroup = new FormGroup({ - * > password: new FormControl(), - * > confirmPassword: new FormControl(), - * > }, - * > { - * > validators: compareInputs(...), - * > }); - * > ``` - * - * Notes: - * - Validation is controlled from either form control. - * - The error message is displayed under controlB by default, but can be set to controlA. - * - For more info on custom validators and cross-field validation: - * - https://v18.angular.dev/guide/forms/form-validation#defining-custom-validators - * - https://v18.angular.dev/guide/forms/form-validation#cross-field-validation - * - * @param validationGoal Whether you want to verify that the form controls do or do not have matching input values. - * @param controlNameA The name of the first form control to compare. - * @param controlNameB The name of the second form control to compare. - * @param errorMessage The error message to display if there is an error. This will probably - * be an i18n translated string. - * @param showErrorOn The control under which you want to display the error (default is controlB). - * - * @returns A validator function that can be used on a FormGroup. - */ -export function compareInputs( - validationGoal: ValidationGoal, - controlNameA: string, - controlNameB: string, - errorMessage: string, - showErrorOn: "controlA" | "controlB" = "controlB", -): ValidatorFn { - /** - * Documentation for the inner ValidatorFn that gets returned: - * - * @param formGroup The AbstractControl that we want to perform validation on. In this case we - * perform validation on the FormGroup, which is a subclass of AbstractControl. - * The reason we validate at the FormGroup level and not at the FormControl level - * is because we want to compare two child FormControls in a single validator, so - * we use the FormGroup as the common ancestor. - * - * @returns A ValidationErrors object if the validation fails, or null if the validation passes. - */ - return (formGroup: AbstractControl): ValidationErrors | null => { - if (!(formGroup instanceof FormGroup)) { - throw new Error("compareInputs only supports validation at the FormGroup level"); - } - - const controlA = formGroup.get(controlNameA); - const controlB = formGroup.get(controlNameB); - - if (!controlA || !controlB) { - return null; - } - - const controlThatShowsError = showErrorOn === "controlA" ? controlA : controlB; - - // Don't compare empty strings - if (controlA.value === "" && controlB.value === "") { - return pass(); - } - - const controlValuesMatch = controlA.value === controlB.value; - - if (validationGoal === ValidationGoal.InputsShouldMatch) { - if (controlValuesMatch) { - return pass(); - } else { - return fail(); - } - } - - if (validationGoal === ValidationGoal.InputsShouldNotMatch) { - if (!controlValuesMatch) { - return pass(); - } else { - return fail(); - } - } - - return null; // default return - - function fail() { - controlThatShowsError.setErrors({ - // Preserve any pre-existing errors - ...(controlThatShowsError.errors || {}), - // Add new compareInputsError - compareInputsError: { - message: errorMessage, - }, - }); - - return { - compareInputsError: { - message: errorMessage, - }, - }; - } - - function pass(): null { - // Get the current errors object - const errorsObj = controlThatShowsError?.errors; - - if (errorsObj != null) { - // Remove any compareInputsError if it exists, since that is the sole error we are targeting with this validator - if (errorsObj?.compareInputsError) { - delete errorsObj.compareInputsError; - } - - // Check if the errorsObj is now empty - const isEmptyObj = Object.keys(errorsObj).length === 0; - - // If the errorsObj is empty, set errors to null, otherwise set the errors to an object of pre-existing errors (other than compareInputsError) - controlThatShowsError.setErrors(isEmptyObj ? null : errorsObj); - } - - // Return null for this validator - return null; - } - }; -} From cf0e693caa94dee4c36601e05c530cf8dd262d45 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Tue, 8 Apr 2025 12:42:42 +0200 Subject: [PATCH 33/93] [PM-18697] Add new symmetric key runtime representation and move encrypt service to it (#13578) * Remove AES128CBC-HMAC encryption * Increase test coverage * Refactor symmetric keys and increase test coverage * Re-add type 0 encryption * Fix ts strict warning * Re-add support for encrypt hmac-less aes * Add comment about inner() * Update comment * Deduplicate encryption type check * Undo test changes * Lift out encryption type check to before splitting by encryption type * Change null to undefined * Fix test --- .../encrypt.service.implementation.ts | 246 ++++++++++-------- .../crypto/services/encrypt.service.spec.ts | 21 +- .../models/domain/encrypted-object.ts | 2 - .../domain/symmetric-crypto-key.spec.ts | 48 +++- .../models/domain/symmetric-crypto-key.ts | 115 ++++++-- 5 files changed, 283 insertions(+), 149 deletions(-) diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts index 7c5bc15a511..901e42d8f89 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.implementation.ts @@ -13,7 +13,11 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { EncryptedObject } from "@bitwarden/common/platform/models/domain/encrypted-object"; -import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { + Aes256CbcHmacKey, + Aes256CbcKey, + SymmetricCryptoKey, +} from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { ServerConfig } from "../../../platform/abstractions/config/server-config"; import { EncryptService } from "../abstractions/encrypt.service"; @@ -46,11 +50,19 @@ export class EncryptServiceImplementation implements EncryptService { plainBuf = plainValue; } - const encObj = await this.aesEncrypt(plainBuf, key); - const iv = Utils.fromBufferToB64(encObj.iv); - const data = Utils.fromBufferToB64(encObj.data); - const mac = encObj.mac != null ? Utils.fromBufferToB64(encObj.mac) : null; - return new EncString(encObj.key.encType, data, iv, mac); + const innerKey = key.inner(); + if (innerKey.type === EncryptionType.AesCbc256_HmacSha256_B64) { + const encObj = await this.aesEncrypt(plainBuf, innerKey); + const iv = Utils.fromBufferToB64(encObj.iv); + const data = Utils.fromBufferToB64(encObj.data); + const mac = Utils.fromBufferToB64(encObj.mac); + return new EncString(innerKey.type, data, iv, mac); + } else if (innerKey.type === EncryptionType.AesCbc256_B64) { + const encObj = await this.aesEncryptLegacy(plainBuf, innerKey); + const iv = Utils.fromBufferToB64(encObj.iv); + const data = Utils.fromBufferToB64(encObj.data); + return new EncString(innerKey.type, data, iv); + } } async encryptToBytes(plainValue: Uint8Array, key: SymmetricCryptoKey): Promise { @@ -58,21 +70,26 @@ export class EncryptServiceImplementation implements EncryptService { throw new Error("No encryption key provided."); } - const encValue = await this.aesEncrypt(plainValue, key); - let macLen = 0; - if (encValue.mac != null) { - macLen = encValue.mac.byteLength; - } - - const encBytes = new Uint8Array(1 + encValue.iv.byteLength + macLen + encValue.data.byteLength); - encBytes.set([encValue.key.encType]); - encBytes.set(new Uint8Array(encValue.iv), 1); - if (encValue.mac != null) { + const innerKey = key.inner(); + if (innerKey.type === EncryptionType.AesCbc256_HmacSha256_B64) { + const encValue = await this.aesEncrypt(plainValue, innerKey); + const macLen = encValue.mac.length; + const encBytes = new Uint8Array( + 1 + encValue.iv.byteLength + macLen + encValue.data.byteLength, + ); + encBytes.set([innerKey.type]); + encBytes.set(new Uint8Array(encValue.iv), 1); encBytes.set(new Uint8Array(encValue.mac), 1 + encValue.iv.byteLength); + encBytes.set(new Uint8Array(encValue.data), 1 + encValue.iv.byteLength + macLen); + return new EncArrayBuffer(encBytes); + } else if (innerKey.type === EncryptionType.AesCbc256_B64) { + const encValue = await this.aesEncryptLegacy(plainValue, innerKey); + const encBytes = new Uint8Array(1 + encValue.iv.byteLength + encValue.data.byteLength); + encBytes.set([innerKey.type]); + encBytes.set(new Uint8Array(encValue.iv), 1); + encBytes.set(new Uint8Array(encValue.data), 1 + encValue.iv.byteLength); + return new EncArrayBuffer(encBytes); } - - encBytes.set(new Uint8Array(encValue.data), 1 + encValue.iv.byteLength + macLen); - return new EncArrayBuffer(encBytes); } async decryptToUtf8( @@ -84,36 +101,25 @@ export class EncryptServiceImplementation implements EncryptService { throw new Error("No key provided for decryption."); } - // DO NOT REMOVE OR MOVE. This prevents downgrade to mac-less CBC, which would compromise integrity and confidentiality. - if (key.macKey != null && encString?.mac == null) { - this.logService.error( - "[Encrypt service] Key has mac key but payload is missing mac bytes. Key type " + - encryptionTypeName(key.encType) + - "Payload type " + - encryptionTypeName(encString.encryptionType), - "Decrypt context: " + decryptContext, + const innerKey = key.inner(); + if (encString.encryptionType !== innerKey.type) { + this.logDecryptError( + "Key encryption type does not match payload encryption type", + key.encType, + encString.encryptionType, + decryptContext, ); return null; } - if (key.encType !== encString.encryptionType) { - this.logService.error( - "[Encrypt service] Key encryption type does not match payload encryption type. Key type " + - encryptionTypeName(key.encType) + - "Payload type " + - encryptionTypeName(encString.encryptionType), - "Decrypt context: " + decryptContext, + if (innerKey.type === EncryptionType.AesCbc256_HmacSha256_B64) { + const fastParams = this.cryptoFunctionService.aesDecryptFastParameters( + encString.data, + encString.iv, + encString.mac, + key, ); - return null; - } - const fastParams = this.cryptoFunctionService.aesDecryptFastParameters( - encString.data, - encString.iv, - encString.mac, - key, - ); - if (fastParams.macKey != null && fastParams.mac != null) { const computedMac = await this.cryptoFunctionService.hmacFast( fastParams.macData, fastParams.macKey, @@ -122,18 +128,31 @@ export class EncryptServiceImplementation implements EncryptService { const macsEqual = await this.cryptoFunctionService.compareFast(fastParams.mac, computedMac); if (!macsEqual) { this.logMacFailed( - "[Encrypt service] decryptToUtf8 MAC comparison failed. Key or payload has changed. Key type " + - encryptionTypeName(key.encType) + - "Payload type " + - encryptionTypeName(encString.encryptionType) + - " Decrypt context: " + - decryptContext, + "decryptToUtf8 MAC comparison failed. Key or payload has changed.", + key.encType, + encString.encryptionType, + decryptContext, ); return null; } + return await this.cryptoFunctionService.aesDecryptFast({ + mode: "cbc", + parameters: fastParams, + }); + } else if (innerKey.type === EncryptionType.AesCbc256_B64) { + const fastParams = this.cryptoFunctionService.aesDecryptFastParameters( + encString.data, + encString.iv, + undefined, + key, + ); + return await this.cryptoFunctionService.aesDecryptFast({ + mode: "cbc", + parameters: fastParams, + }); + } else { + throw new Error(`Unsupported encryption type`); } - - return await this.cryptoFunctionService.aesDecryptFast({ mode: "cbc", parameters: fastParams }); } async decryptToBytes( @@ -149,72 +168,52 @@ export class EncryptServiceImplementation implements EncryptService { throw new Error("Nothing provided for decryption."); } - // DO NOT REMOVE OR MOVE. This prevents downgrade to mac-less CBC, which would compromise integrity and confidentiality. - if (key.macKey != null && encThing.macBytes == null) { - this.logService.error( - "[Encrypt service] Key has mac key but payload is missing mac bytes. Key type " + - encryptionTypeName(key.encType) + - " Payload type " + - encryptionTypeName(encThing.encryptionType) + - " Decrypt context: " + - decryptContext, + const inner = key.inner(); + if (encThing.encryptionType !== inner.type) { + this.logDecryptError( + "Encryption key type mismatch", + key.encType, + encThing.encryptionType, + decryptContext, ); return null; } - if (key.encType !== encThing.encryptionType) { - this.logService.error( - "[Encrypt service] Key encryption type does not match payload encryption type. Key type " + - encryptionTypeName(key.encType) + - " Payload type " + - encryptionTypeName(encThing.encryptionType) + - " Decrypt context: " + - decryptContext, - ); - return null; - } + if (inner.type === EncryptionType.AesCbc256_HmacSha256_B64) { + if (encThing.macBytes == null) { + this.logDecryptError("Mac missing", key.encType, encThing.encryptionType, decryptContext); + return null; + } - if (key.macKey != null && encThing.macBytes != null) { const macData = new Uint8Array(encThing.ivBytes.byteLength + encThing.dataBytes.byteLength); macData.set(new Uint8Array(encThing.ivBytes), 0); macData.set(new Uint8Array(encThing.dataBytes), encThing.ivBytes.byteLength); const computedMac = await this.cryptoFunctionService.hmac(macData, key.macKey, "sha256"); - if (computedMac === null) { - this.logMacFailed( - "[Encrypt service#decryptToBytes] Failed to compute MAC." + - " Key type " + - encryptionTypeName(key.encType) + - " Payload type " + - encryptionTypeName(encThing.encryptionType) + - " Decrypt context: " + - decryptContext, - ); - return null; - } - const macsMatch = await this.cryptoFunctionService.compare(encThing.macBytes, computedMac); if (!macsMatch) { this.logMacFailed( - "[Encrypt service#decryptToBytes]: MAC comparison failed. Key or payload has changed." + - " Key type " + - encryptionTypeName(key.encType) + - " Payload type " + - encryptionTypeName(encThing.encryptionType) + - " Decrypt context: " + - decryptContext, + "MAC comparison failed. Key or payload has changed.", + key.encType, + encThing.encryptionType, + decryptContext, ); return null; } + + return await this.cryptoFunctionService.aesDecrypt( + encThing.dataBytes, + encThing.ivBytes, + key.encKey, + "cbc", + ); + } else if (inner.type === EncryptionType.AesCbc256_B64) { + return await this.cryptoFunctionService.aesDecrypt( + encThing.dataBytes, + encThing.ivBytes, + key.encKey, + "cbc", + ); } - - const result = await this.cryptoFunctionService.aesDecrypt( - encThing.dataBytes, - encThing.ivBytes, - key.encKey, - "cbc", - ); - - return result ?? null; } async rsaEncrypt(data: Uint8Array, publicKey: Uint8Array): Promise { @@ -279,25 +278,48 @@ export class EncryptServiceImplementation implements EncryptService { return Utils.fromBufferToB64(hashArray); } - private async aesEncrypt(data: Uint8Array, key: SymmetricCryptoKey): Promise { + private async aesEncrypt(data: Uint8Array, key: Aes256CbcHmacKey): Promise { const obj = new EncryptedObject(); - obj.key = key; obj.iv = await this.cryptoFunctionService.randomBytes(16); - obj.data = await this.cryptoFunctionService.aesEncrypt(data, obj.iv, obj.key.encKey); + obj.data = await this.cryptoFunctionService.aesEncrypt(data, obj.iv, key.encryptionKey); - if (obj.key.macKey != null) { - const macData = new Uint8Array(obj.iv.byteLength + obj.data.byteLength); - macData.set(new Uint8Array(obj.iv), 0); - macData.set(new Uint8Array(obj.data), obj.iv.byteLength); - obj.mac = await this.cryptoFunctionService.hmac(macData, obj.key.macKey, "sha256"); - } + const macData = new Uint8Array(obj.iv.byteLength + obj.data.byteLength); + macData.set(new Uint8Array(obj.iv), 0); + macData.set(new Uint8Array(obj.data), obj.iv.byteLength); + obj.mac = await this.cryptoFunctionService.hmac(macData, key.authenticationKey, "sha256"); return obj; } - private logMacFailed(msg: string) { + /** + * @deprecated Removed once AesCbc256_B64 support is removed + */ + private async aesEncryptLegacy(data: Uint8Array, key: Aes256CbcKey): Promise { + const obj = new EncryptedObject(); + obj.iv = await this.cryptoFunctionService.randomBytes(16); + obj.data = await this.cryptoFunctionService.aesEncrypt(data, obj.iv, key.encryptionKey); + return obj; + } + + private logDecryptError( + msg: string, + keyEncType: EncryptionType, + dataEncType: EncryptionType, + decryptContext: string, + ) { + this.logService.error( + `[Encrypt service] ${msg} Key type ${encryptionTypeName(keyEncType)} Payload type ${encryptionTypeName(dataEncType)} Decrypt context: ${decryptContext}`, + ); + } + + private logMacFailed( + msg: string, + keyEncType: EncryptionType, + dataEncType: EncryptionType, + decryptContext: string, + ) { if (this.logMacFailures) { - this.logService.error(msg); + this.logDecryptError(msg, keyEncType, dataEncType, decryptContext); } } } diff --git a/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts index 3ce0d5883d2..7b173ab3eb2 100644 --- a/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts +++ b/libs/common/src/key-management/crypto/services/encrypt.service.spec.ts @@ -150,7 +150,7 @@ describe("EncryptService", () => { ); }); - it("decrypts data with provided key for Aes256Cbc", async () => { + it("decrypts data with provided key for Aes256CbcHmac", async () => { const decryptedBytes = makeStaticByteArray(10, 200); cryptoFunctionService.hmac.mockResolvedValue(makeStaticByteArray(1)); @@ -257,7 +257,7 @@ describe("EncryptService", () => { ); }); - it("decrypts data with provided key for Aes256Cbc_HmacSha256", async () => { + it("decrypts data with provided key for AesCbc256_HmacSha256", async () => { const key = new SymmetricCryptoKey(makeStaticByteArray(64, 0)); const encString = new EncString(EncryptionType.AesCbc256_HmacSha256_B64, "data", "iv", "mac"); cryptoFunctionService.aesDecryptFastParameters.mockReturnValue({ @@ -277,10 +277,14 @@ describe("EncryptService", () => { ); }); - it("decrypts data with provided key for Aes256Cbc", async () => { + it("decrypts data with provided key for AesCbc256", async () => { const key = new SymmetricCryptoKey(makeStaticByteArray(32, 0)); const encString = new EncString(EncryptionType.AesCbc256_B64, "data"); - cryptoFunctionService.aesDecryptFastParameters.mockReturnValue({} as any); + cryptoFunctionService.aesDecryptFastParameters.mockReturnValue({ + macData: makeStaticByteArray(32, 0), + macKey: makeStaticByteArray(32, 0), + mac: makeStaticByteArray(32, 0), + } as any); cryptoFunctionService.hmacFast.mockResolvedValue(makeStaticByteArray(32, 0)); cryptoFunctionService.compareFast.mockResolvedValue(true); cryptoFunctionService.aesDecryptFast.mockResolvedValue("data"); @@ -290,7 +294,7 @@ describe("EncryptService", () => { expect(cryptoFunctionService.compareFast).not.toHaveBeenCalled(); }); - it("returns null if key is Aes256Cbc_HmacSha256 but EncString is Aes256Cbc", async () => { + it("returns null if key is AesCbc256_HMAC but encstring is AesCbc256", async () => { const key = new SymmetricCryptoKey(makeStaticByteArray(64, 0)); const encString = new EncString(EncryptionType.AesCbc256_B64, "data"); @@ -299,7 +303,7 @@ describe("EncryptService", () => { expect(logService.error).toHaveBeenCalled(); }); - it("returns null if key is Aes256Cbc but encstring is AesCbc256_HmacSha256", async () => { + it("returns null if key is AesCbc256 but encstring is AesCbc256_HMAC", async () => { const key = new SymmetricCryptoKey(makeStaticByteArray(32, 0)); const encString = new EncString(EncryptionType.AesCbc256_HmacSha256_B64, "data", "iv", "mac"); @@ -332,10 +336,7 @@ describe("EncryptService", () => { ); }); it("returns null if key is mac key but encstring has no mac", async () => { - const key = new SymmetricCryptoKey( - makeStaticByteArray(64, 0), - EncryptionType.AesCbc256_HmacSha256_B64, - ); + const key = new SymmetricCryptoKey(makeStaticByteArray(64, 0)); const encString = new EncString(EncryptionType.AesCbc256_B64, "data"); const actual = await encryptService.decryptToUtf8(encString, key); diff --git a/libs/common/src/platform/models/domain/encrypted-object.ts b/libs/common/src/platform/models/domain/encrypted-object.ts index 92153b27636..3caa7ae68d1 100644 --- a/libs/common/src/platform/models/domain/encrypted-object.ts +++ b/libs/common/src/platform/models/domain/encrypted-object.ts @@ -1,10 +1,8 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; export class EncryptedObject { iv: Uint8Array; data: Uint8Array; mac: Uint8Array; - key: SymmetricCryptoKey; } diff --git a/libs/common/src/platform/models/domain/symmetric-crypto-key.spec.ts b/libs/common/src/platform/models/domain/symmetric-crypto-key.spec.ts index 58c902ebab6..cce99b847bb 100644 --- a/libs/common/src/platform/models/domain/symmetric-crypto-key.spec.ts +++ b/libs/common/src/platform/models/domain/symmetric-crypto-key.spec.ts @@ -1,5 +1,6 @@ import { makeStaticByteArray } from "../../../../spec"; import { EncryptionType } from "../../enums"; +import { Utils } from "../../misc/utils"; import { SymmetricCryptoKey } from "./symmetric-crypto-key"; @@ -24,6 +25,11 @@ describe("SymmetricCryptoKey", () => { key: key, keyB64: "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", macKey: null, + macKeyB64: undefined, + innerKey: { + type: EncryptionType.AesCbc256_B64, + encryptionKey: key, + }, }); }); @@ -40,6 +46,11 @@ describe("SymmetricCryptoKey", () => { "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+Pw==", macKey: key.slice(32, 64), macKeyB64: "ICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj8=", + innerKey: { + type: EncryptionType.AesCbc256_HmacSha256_B64, + encryptionKey: key.slice(0, 32), + authenticationKey: key.slice(32), + }, }); }); @@ -48,7 +59,7 @@ describe("SymmetricCryptoKey", () => { new SymmetricCryptoKey(makeStaticByteArray(30)); }; - expect(t).toThrowError("Unable to determine encType."); + expect(t).toThrowError(`Unsupported encType/key length 30`); }); }); @@ -69,6 +80,41 @@ describe("SymmetricCryptoKey", () => { expect(actual).toBeInstanceOf(SymmetricCryptoKey); }); + it("inner returns inner key", () => { + const key = new SymmetricCryptoKey(makeStaticByteArray(64)); + const actual = key.inner(); + + expect(actual).toEqual({ + type: EncryptionType.AesCbc256_HmacSha256_B64, + encryptionKey: key.encKey, + authenticationKey: key.macKey, + }); + }); + + it("toEncoded returns encoded key for AesCbc256_B64", () => { + const key = new SymmetricCryptoKey(makeStaticByteArray(32)); + const actual = key.toEncoded(); + + expect(actual).toEqual(key.encKey); + }); + + it("toEncoded returns encoded key for AesCbc256_HmacSha256_B64", () => { + const keyBytes = makeStaticByteArray(64); + const key = new SymmetricCryptoKey(keyBytes); + const actual = key.toEncoded(); + + expect(actual).toEqual(keyBytes); + }); + + it("toBase64 returns base64 encoded key", () => { + const keyBytes = makeStaticByteArray(64); + const keyB64 = Utils.fromBufferToB64(keyBytes); + const key = new SymmetricCryptoKey(keyBytes); + const actual = key.toBase64(); + + expect(actual).toEqual(keyB64); + }); + describe("fromString", () => { it("null string returns null", () => { const actual = SymmetricCryptoKey.fromString(null); diff --git a/libs/common/src/platform/models/domain/symmetric-crypto-key.ts b/libs/common/src/platform/models/domain/symmetric-crypto-key.ts index 372b869fd9c..45e15c1f602 100644 --- a/libs/common/src/platform/models/domain/symmetric-crypto-key.ts +++ b/libs/common/src/platform/models/domain/symmetric-crypto-key.ts @@ -5,7 +5,25 @@ import { Jsonify } from "type-fest"; import { Utils } from "../../../platform/misc/utils"; import { EncryptionType } from "../../enums"; +export type Aes256CbcHmacKey = { + type: EncryptionType.AesCbc256_HmacSha256_B64; + encryptionKey: Uint8Array; + authenticationKey: Uint8Array; +}; + +export type Aes256CbcKey = { + type: EncryptionType.AesCbc256_B64; + encryptionKey: Uint8Array; +}; + +/** + * A symmetric crypto key represents a symmetric key usable for symmetric encryption and decryption operations. + * The specific algorithm used is private to the key, and should only be exposed to encrypt service implementations. + * This can be done via `inner()`. + */ export class SymmetricCryptoKey { + private innerKey: Aes256CbcHmacKey | Aes256CbcKey; + key: Uint8Array; encKey: Uint8Array; macKey?: Uint8Array; @@ -17,38 +35,45 @@ export class SymmetricCryptoKey { meta: any; - constructor(key: Uint8Array, encType?: EncryptionType) { + /** + * @param key The key in one of the permitted serialization formats + */ + constructor(key: Uint8Array) { if (key == null) { throw new Error("Must provide key"); } - if (encType == null) { - if (key.byteLength === 32) { - encType = EncryptionType.AesCbc256_B64; - } else if (key.byteLength === 64) { - encType = EncryptionType.AesCbc256_HmacSha256_B64; - } else { - throw new Error("Unable to determine encType."); - } - } + if (key.byteLength === 32) { + this.innerKey = { + type: EncryptionType.AesCbc256_B64, + encryptionKey: key, + }; + this.encType = EncryptionType.AesCbc256_B64; + this.key = key; + this.keyB64 = Utils.fromBufferToB64(this.key); - this.key = key; - this.encType = encType; - - if (encType === EncryptionType.AesCbc256_B64 && key.byteLength === 32) { this.encKey = key; - this.macKey = null; - } else if (encType === EncryptionType.AesCbc256_HmacSha256_B64 && key.byteLength === 64) { - this.encKey = key.slice(0, 32); - this.macKey = key.slice(32, 64); - } else { - throw new Error("Unsupported encType/key length."); - } + this.encKeyB64 = Utils.fromBufferToB64(this.encKey); - this.keyB64 = Utils.fromBufferToB64(this.key); - this.encKeyB64 = Utils.fromBufferToB64(this.encKey); - if (this.macKey != null) { + this.macKey = null; + this.macKeyB64 = undefined; + } else if (key.byteLength === 64) { + this.innerKey = { + type: EncryptionType.AesCbc256_HmacSha256_B64, + encryptionKey: key.slice(0, 32), + authenticationKey: key.slice(32), + }; + this.encType = EncryptionType.AesCbc256_HmacSha256_B64; + this.key = key; + this.keyB64 = Utils.fromBufferToB64(this.key); + + this.encKey = key.slice(0, 32); + this.encKeyB64 = Utils.fromBufferToB64(this.encKey); + + this.macKey = key.slice(32); this.macKeyB64 = Utils.fromBufferToB64(this.macKey); + } else { + throw new Error(`Unsupported encType/key length ${key.byteLength}`); } } @@ -57,6 +82,48 @@ export class SymmetricCryptoKey { return { keyB64: this.keyB64 }; } + /** + * It is preferred not to work with the raw key where possible. + * Only use this method if absolutely necessary. + * + * @returns The inner key instance that can be directly used for encryption primitives + */ + inner(): Aes256CbcHmacKey | Aes256CbcKey { + return this.innerKey; + } + + /** + * @returns The serialized key in base64 format + */ + toBase64(): string { + return Utils.fromBufferToB64(this.toEncoded()); + } + + /** + * Serializes the key to a format that can be written to state or shared + * The currently permitted format is: + * - AesCbc256_B64: 32 bytes (the raw key) + * - AesCbc256_HmacSha256_B64: 64 bytes (32 bytes encryption key, 32 bytes authentication key, concatenated) + * + * @returns The serialized key that can be written to state or encrypted and then written to state / shared + */ + toEncoded(): Uint8Array { + if (this.innerKey.type === EncryptionType.AesCbc256_B64) { + return this.innerKey.encryptionKey; + } else if (this.innerKey.type === EncryptionType.AesCbc256_HmacSha256_B64) { + const encodedKey = new Uint8Array(64); + encodedKey.set(this.innerKey.encryptionKey, 0); + encodedKey.set(this.innerKey.authenticationKey, 32); + return encodedKey; + } else { + throw new Error("Unsupported encryption type."); + } + } + + /** + * @param s The serialized key in base64 format + * @returns A SymmetricCryptoKey instance + */ static fromString(s: string): SymmetricCryptoKey { if (s == null) { return null; From fa0ae2435a1b247571f101123bdf29653ab36efc Mon Sep 17 00:00:00 2001 From: Jared McCannon Date: Tue, 8 Apr 2025 07:17:53 -0500 Subject: [PATCH 34/93] Removed bootstrap classes from setup.component.html (#14166) --- .../admin-console/providers/setup/setup.component.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html index 74aa468c42e..38b4c3bc9de 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html @@ -1,18 +1,18 @@ {{ "loading" | i18n }} -
-