diff --git a/.eslintignore b/.eslintignore index b6c475d332..c9a25670a9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -8,7 +8,6 @@ storybook-static **/webpack.*.js **/jest.config.js -**/gulpfile.js apps/browser/config/config.js apps/browser/src/auth/scripts/duo.js diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c050ee1f6c..cf656967da 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -95,12 +95,14 @@ libs/common/src/autofill @bitwarden/team-autofill-dev apps/desktop/macos/autofill-extension @bitwarden/team-autofill-dev # DuckDuckGo integration apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-dev -apps/desktop/src/services/native-message-handler.service.ts @bitwarden/team-autofill-dev +apps/desktop/src/services/duckduckgo-message-handler.service.ts @bitwarden/team-autofill-dev + ## Component Library ## .storybook @bitwarden/team-design-system libs/components @bitwarden/team-design-system apps/browser/src/platform/popup/layout @bitwarden/team-design-system +apps/browser/src/popup/app-routing.animations.ts @bitwarden/team-design-system apps/web/src/app/layouts @bitwarden/team-design-system ## Desktop native module ## @@ -116,6 +118,7 @@ libs/key-management @bitwarden/team-key-management-dev apps/desktop/destkop_native/core/src/biometric/ @bitwarden/team-key-management-dev apps/desktop/src/services/native-messaging.service.ts @bitwarden/team-key-management-dev apps/browser/src/background/nativeMessaging.background.ts @bitwarden/team-key-management-dev +apps/desktop/src/services/biometric-message-handler.service.ts @bitwarden/team-key-management-dev ## Locales ## apps/browser/src/_locales/en/messages.json diff --git a/.github/renovate.json b/.github/renovate.json index 0172403f0f..9295ea5d61 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -39,6 +39,10 @@ "groupName": "macOS/iOS bindings", "matchPackageNames": ["core-foundation", "security-framework", "security-framework-sys"] }, + { + "groupName": "zbus", + "matchPackageNames": ["zbus", "zbus_polkit"] + }, { "matchPackageNames": [ "base64-loader", @@ -75,11 +79,6 @@ "concurrently", "cross-env", "del", - "gulp", - "gulp-if", - "gulp-json-editor", - "gulp-replace", - "gulp-zip", "nord", "patch-package", "prettier", diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index 350835d0ec..6e5e11c336 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -120,7 +120,6 @@ jobs: whoami node --version npm --version - gulp --version docker --version echo "GitHub ref: $GITHUB_REF" echo "GitHub event: $GITHUB_EVENT" diff --git a/apps/browser/package.json b/apps/browser/package.json index 53500a83d2..647847db45 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2024.11.2", + "version": "2024.12.0", "scripts": { "build": "npm run build:chrome", "build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 webpack", diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 45ff01b0b7..f98705ce1b 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -3,39 +3,39 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "مدير كلمات المرور Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "message": "في المنزل، في العمل، أو في أثناء التنقل، يقوم Bitwarden بتأمين جميع كلمات المرور والمعلومات الحساسة بسهولة", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { - "message": "قم بالتسجيل أو إنشاء حساب جديد للوصول إلى خزنتك الآمنة." + "message": "قم بالتسجيل أو إنشاء حساب جديد للوصول إلى خزانتك الآمنة." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "تم قَبُول الدعوة" }, "createAccount": { "message": "إنشاء حساب" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "هل أنت جديد على Bitwarden؟" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "تسجيل الدخول باستخدام مفتاح المرور" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "استخدام تسجيل الدخول الأحادي" }, "welcomeBack": { - "message": "Welcome back" + "message": "مرحبًا بعودتك" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "أنشئ كلمة مرور قوية" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "أكمل إنشاء حسابك عن طريق تعيين كلمة مرور" }, "enterpriseSingleSignOn": { "message": "تسجيل الدخول الأُحادي للمؤسسات – SSO" @@ -56,13 +56,13 @@ "message": "كلمة المرور الرئيسية" }, "masterPassDesc": { - "message": "كلمة المرور الرئيسية هي كلمة المرور التي تستخدمها للوصول إلى خزنتك. من المهم جدا ألا تنسى كلمة المرور الرئيسية. لا توجد طريقة لاسترداد كلمة المرور في حال نسيتها." + "message": "كلمة المرور الرئيسية هي كلمة المرور التي تستخدمها للوصول إلى خزانتك. من المهم جدا ألا تنسى كلمة المرور الرئيسية. لا توجد طريقة لاسترداد كلمة المرور في حال نسيتها." }, "masterPassHintDesc": { "message": "يمكن أن يساعدك تلميح كلمة المرور الرئيسية في تذكر كلمة المرور الخاصة بك في حال نسيتها." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "إذا نسيت كلمة المرور الخاصة بك، يمكن إرسال تلميح كلمة المرور إلى بريدك الإلكتروني. الحد الأقصى لعدد الأحرف هو $CURRENT$/$MAXIMUM$.", "placeholders": { "current": { "content": "$1", @@ -81,7 +81,7 @@ "message": "تلميح كلمة المرور الرئيسية (إختياري)" }, "joinOrganization": { - "message": "Join organization" + "message": "انضم إلى المنظمة" }, "joinOrganizationName": { "message": "Join $ORGANIZATIONNAME$", @@ -99,13 +99,13 @@ "message": "علامة تبويب" }, "vault": { - "message": "الخزنة" + "message": "الخزانة" }, "myVault": { - "message": "خزنتي" + "message": "خزانتي" }, "allVaults": { - "message": "جميع الخزنات" + "message": "جميع الخزانات" }, "tools": { "message": "الأدوات" @@ -217,10 +217,10 @@ "message": "إضافة هوية" }, "unlockVaultMenu": { - "message": "افتح خزنتك" + "message": "افتح خزانتك" }, "loginToVaultMenu": { - "message": "تسجيل الدخول إلى خزنتك" + "message": "تسجيل الدخول إلى خزانتك" }, "autoFillInfo": { "message": "لا توجد تسجيلات دخول متاحة للملء التلقائي في علامة تبويب المتصفح الحالية." @@ -408,7 +408,7 @@ "message": "المزامنة" }, "syncVaultNow": { - "message": "مزامنة الخزنة الآن" + "message": "مزامنة الخزانة الآن" }, "lastSync": { "message": "آخر مزامنة:" @@ -534,7 +534,7 @@ "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { - "message": "البحث في الخزنة" + "message": "البحث في الخزانة" }, "edit": { "message": "تعديل" @@ -651,7 +651,7 @@ "message": "قم بتأكيد هويتك" }, "yourVaultIsLocked": { - "message": "خزنتك مقفلة. قم بتأكيد هويتك للمتابعة." + "message": "خزانتك مقفلة. قم بتأكيد هويتك للمتابعة." }, "yourVaultIsLockedV2": { "message": "Your vault is locked" @@ -682,7 +682,7 @@ "message": "كلمة المرور الرئيسية غير صالحة" }, "vaultTimeout": { - "message": "نفذ وقت الخزنة" + "message": "نفذ وقت الخزانة" }, "vaultTimeout1": { "message": "Timeout" @@ -888,7 +888,7 @@ "message": "أُضيف المجلد" }, "twoStepLoginConfirmation": { - "message": "تسجيل الدخول بخطوتين يجعل حسابك أكثر أمنا من خلال مطالبتك بالتحقق من تسجيل الدخول باستخدام جهاز آخر مثل مفتاح الأمان، تطبيق المصادقة، الرسائل القصيرة، المكالمة الهاتفية، أو البريد الإلكتروني. يمكن تمكين تسجيل الدخول بخطوتين على خزنة الويب bitwarden.com. هل تريد زيارة الموقع الآن؟" + "message": "تسجيل الدخول بخطوتين يجعل حسابك أكثر أمنا من خلال مطالبتك بالتحقق من تسجيل الدخول باستخدام جهاز آخر مثل مفتاح الأمان، تطبيق المصادقة، الرسائل القصيرة، المكالمة الهاتفية، أو البريد الإلكتروني. يمكن تمكين تسجيل الدخول بخطوتين على خزانة الويب bitwarden.com. هل تريد زيارة الموقع الآن؟" }, "twoStepLoginConfirmationContent": { "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." @@ -984,7 +984,7 @@ "message": "Save to vault options" }, "addLoginNotificationDesc": { - "message": "اطلب إضافة عنصر إذا لم يُعثر عليه في خزنتك." + "message": "اطلب إضافة عنصر إذا لم يُعثر عليه في خزانتك." }, "addLoginNotificationDescAlt": { "message": "اطلب إضافة عنصر إذا لم يتم العثور على عنصر في المخزن الخاص بك. ينطبق على جميع حسابات تسجيل الدخول." @@ -1092,7 +1092,7 @@ "message": "Export from" }, "exportVault": { - "message": "تصدير الخزنة" + "message": "تصدير الخزانة" }, "fileFormat": { "message": "صيغة الملف" @@ -1125,11 +1125,15 @@ "message": "تحذير", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { - "message": "تأكيد تصدير الخزنة" + "message": "تأكيد تصدير الخزانة" }, "exportWarningDesc": { - "message": "يحتوي هذا التصدير على بيانات خزنتك بتنسيق غير مشفر. لا يجب عليك تخزين أو إرسال الملف الذي تم تصديره عبر قنوات غير آمنة (مثل البريد الإلكتروني). احذفه مباشرة بعد انتهائك من استخدامه." + "message": "يحتوي هذا التصدير على بيانات خزانتك بتنسيق غير مشفر. لا يجب عليك تخزين أو إرسال الملف الذي تم تصديره عبر قنوات غير آمنة (مثل البريد الإلكتروني). احذفه مباشرة بعد انتهائك من استخدامه." }, "encExportKeyWarningDesc": { "message": "يقوم هذا التصدير بتشفير بياناتك باستخدام مفتاح تشفير حسابك. إذا قمت بتدوير مفتاح تشفير حسابك يجب عليك التصدير مرة أخرى لأنك لن تتمكن من فك تشفير ملف التصدير هذا." @@ -1138,7 +1142,7 @@ "message": "مفاتيح تشفير الحساب فريدة من نوعها لكل حساب مستخدم Bitwarden، لذلك لا يمكنك استيراد تصدير مشفر إلى حساب آخر." }, "exportMasterPassword": { - "message": "أدخل كلمة المرور الرئيسية لتصدير بيانات خزنتك." + "message": "أدخل كلمة المرور الرئيسية لتصدير بيانات خزانتك." }, "shared": { "message": "مشترك" @@ -1247,10 +1251,10 @@ "message": "خيارات تسجيل الدخول بخطوتين المملوكة لجهات اخرى مثل YubiKey و Duo." }, "ppremiumSignUpReports": { - "message": "نظافة كلمة المرور، صحة الحساب، وتقارير تسريبات البيانات للحفاظ على سلامة خزنتك." + "message": "نظافة كلمة المرور، صحة الحساب، وتقارير تسريبات البيانات للحفاظ على سلامة خزانتك." }, "ppremiumSignUpTotp": { - "message": "مورد رمز التحقق (2FA) لتسجيل الدخول في خزنتك." + "message": "مورد رمز التحقق (2FA) لتسجيل الدخول في خزانتك." }, "ppremiumSignUpSupport": { "message": "أولوية دعم العملاء." @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "إذا تم اكتشاف نموذج تسجيل الدخول، يتم التعبئة التلقائية عند تحميل صفحة الويب." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "مواقع المساومة أو غير الموثوق بها يمكن أن تستغل الملء التلقائي في تحميل الصفحة." }, @@ -2108,7 +2099,7 @@ "message": "Already have an account?" }, "vaultTimeoutLogOutConfirmation": { - "message": "سيؤدي تسجيل الخروج إلى إزالة جميع إمكانية الوصول إلى خزنتك ويتطلب المصادقة عبر الإنترنت بعد انتهاء المهلة. هل أنت متأكد من أنك تريد استخدام هذا الإعداد؟" + "message": "سيؤدي تسجيل الخروج إلى إزالة جميع إمكانية الوصول إلى خزانتك ويتطلب المصادقة عبر الإنترنت بعد انتهاء المهلة. هل أنت متأكد من أنك تريد استخدام هذا الإعداد؟" }, "vaultTimeoutLogOutConfirmationTitle": { "message": "تأكيد إجراء المهلة" @@ -2686,7 +2677,7 @@ "message": "Email verified" }, "emailVerificationRequiredDesc": { - "message": "يجب عليك تأكيد بريدك الإلكتروني لاستخدام هذه الميزة. يمكنك تأكيد بريدك الإلكتروني في خزنة الويب." + "message": "يجب عليك تأكيد بريدك الإلكتروني لاستخدام هذه الميزة. يمكنك تأكيد بريدك الإلكتروني في خزانة الويب." }, "updatedMasterPassword": { "message": "Updated master password" @@ -2695,7 +2686,7 @@ "message": "تحديث كلمة المرور الرئيسية" }, "updateMasterPasswordWarning": { - "message": "تم تغيير كلمة المرور الرئيسية الخاصة بك مؤخرًا من قبل مسؤول في مؤسستك. من أجل الوصول إلى الخزنة، يجب عليك تحديثها الآن. سيتم تسجيل خروجك من الجلسة الحالية، مما يتطلب منك تسجيل الدخول مرة أخرى. قد تظل الجلسات النشطة على أجهزة أخرى نشطة لمدة تصل إلى ساعة واحدة." + "message": "تم تغيير كلمة المرور الرئيسية الخاصة بك مؤخرًا من قبل مسؤول في مؤسستك. من أجل الوصول إلى الخزانة، يجب عليك تحديثها الآن. سيتم تسجيل خروجك من الجلسة الحالية، مما يتطلب منك تسجيل الدخول مرة أخرى. قد تظل الجلسات النشطة على أجهزة أخرى نشطة لمدة تصل إلى ساعة واحدة." }, "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." @@ -2747,7 +2738,7 @@ "message": "Enterprise policy requirements have been applied to your timeout options" }, "vaultTimeoutPolicyInEffect": { - "message": "سياسات مؤسستك تؤثر على مهلة الخزنة الخاص بك. الحد الأقصى المسموح به لمهلة الخزنة هو $HOURS$ ساعة/ساعات و $MINUTES$ دقيقة/دقائق", + "message": "سياسات مؤسستك تؤثر على مهلة الخزانة الخاص بك. الحد الأقصى المسموح به لمهلة الخزانة هو $HOURS$ ساعة/ساعات و $MINUTES$ دقيقة/دقائق.", "placeholders": { "hours": { "content": "$1", @@ -2812,10 +2803,10 @@ } }, "vaultTimeoutTooLarge": { - "message": "مهلة خزنتك تتجاوز القيود التي تضعها مؤسستك." + "message": "مهلة خزانتك تتجاوز القيود التي تضعها مؤسستك." }, "vaultExportDisabled": { - "message": "تصدير الخزنة مُعطّل" + "message": "تصدير الخزانة مُعطّل" }, "personalVaultExportPolicyInEffect": { "message": "واحدة أو أكثر من سياسات المؤسسة تمنعك من تصدير خزانتك الشخصية." @@ -2857,7 +2848,7 @@ "message": "انتهت مدة جلستك. يرجى العودة ومحاولة تسجيل الدخول مرة أخرى." }, "exportingPersonalVaultTitle": { - "message": "جاري تصدير الخزنة الشخصية" + "message": "جاري تصدير الخزانة الشخصية" }, "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.", @@ -3168,7 +3159,7 @@ "message": "عبارة بصمة الإصبع" }, "fingerprintMatchInfo": { - "message": "الرجاء التأكد من أن الخزنة الخاصة بك غير مقفلة وأن عبارة بصمة الإصبع تتطابق على الجهاز الآخر." + "message": "الرجاء التأكد من أن الخزانة الخاصة بك غير مقفلة وأن عبارة بصمة الإصبع تتطابق على الجهاز الآخر." }, "resendNotification": { "message": "إعادة إرسال الإشعار" @@ -3794,7 +3785,7 @@ } }, "confirmVaultImport": { - "message": "تأكيد تصدير الخزنة" + "message": "تأكيد تصدير الخزانة" }, "confirmVaultImportDesc": { "message": "هذا الملف محمي بكلمة مرور. الرجاء إدخال كلمة مرور الملف لاستيراد البيانات." @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index a21a962693..63e0c367e8 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -1125,6 +1125,10 @@ "message": "XƏBƏRDARLIQ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Xəbərdarlıq", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Seyfi xaricə köçürməyi təsdiqlə" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Giriş formu aşkarlananda, səhifə yüklənən zaman formu avto-doldurma icra edilsin." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Xəbərdarlıq:$CLOSETAG$ Təhlükəsizliyi pozulmuş və ya güvənilməyən veb saytlar, səhifə yüklənəndə avto-doldurmanı istifadə edə bilər.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Təhlükəli və ya güvənilməyən veb saytlar, səhifə yüklənərkən avto-doldurmanı istifadə edə bilər." }, @@ -3288,16 +3279,16 @@ "message": "Yeni bir pəncərədə açılır" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Gələcək girişləri problemsiz etmək üçün bu cihazı xatırla" }, "deviceApprovalRequired": { "message": "Cihaz təsdiqi tələb olunur. Aşağıdan bir təsdiq variantı seçin:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Cihaz təsdiqi tələb olunur" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Aşağıdan bir təsdiq seçimi edin" }, "rememberThisDevice": { "message": "Bu cihazı xatırla" @@ -3373,7 +3364,7 @@ "message": "İstifadəçi e-poçtu əskikdir" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktiv istifadəçi e-poçtu tapılmadı. Hesabınızdan çıxış edilir." }, "deviceTrusted": { "message": "Cihaz güvənlidir" @@ -3812,7 +3803,7 @@ "message": "Müraciət edilir" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Giriş edildi!" }, "passkeyNotCopied": { "message": "Keçid açarı kopyalanmır" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Uzantı eni" + }, + "wide": { + "message": "Eni" + }, + "extraWide": { + "message": "Ekstra enli" } } diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 5ff88dce3a..b09e7374c6 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -20,16 +20,16 @@ "message": "Стварыць уліковы запіс" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Упершыню ў Bitwarden?" }, "logInWithPasskey": { "message": "Log in with passkey" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Выкарыстаць аднаразовы ўваход" }, "welcomeBack": { - "message": "Welcome back" + "message": "З вяртаннем" }, "setAStrongPassword": { "message": "Прызначыць надзейны пароль" @@ -120,7 +120,7 @@ "message": "Скапіяваць пароль" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "Скапіяваць парольную фразу" }, "copyNote": { "message": "Скапіяваць нататку" @@ -153,13 +153,13 @@ "message": "Скапіяваць нумар ліцэнзіі" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "Скапіяваць прыватны ключ" }, "copyPublicKey": { - "message": "Copy public key" + "message": "Скапіяваць публічны ключ" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "Скапіяваць адбітак пальца" }, "copyCustomField": { "message": "Скапіяваць $FIELD$", @@ -177,7 +177,7 @@ "message": "Скапіяваць нататкі" }, "fill": { - "message": "Fill", + "message": "Запоўніць", "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": { @@ -436,7 +436,7 @@ "message": "Генерыраваць пароль" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Згенерыраваць парольную фразу" }, "regeneratePassword": { "message": "Паўторна генерыраваць пароль" @@ -600,7 +600,7 @@ "message": "Адкрыць сайт" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Адкрыць сайт $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -855,7 +855,7 @@ "message": "Увайсці" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Увайсці ў Bitwarden" }, "restartRegistration": { "message": "Restart registration" @@ -1125,6 +1125,10 @@ "message": "ПАПЯРЭДЖАННЕ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Папярэджанне", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Пацвердзіць экспартаванне сховішча" }, @@ -1459,7 +1463,7 @@ "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "Прапановы аўтазапаўнення" }, "showInlineMenuLabel": { "message": "Show autofill suggestions on form fields" @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Калі выяўлена форма ўваходу, то будзе выканана яе аўтазапаўненне падчас загрузкі вэб-старонкі." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Скампраметаваныя або ненадзейныя вэб-сайты могуць задзейнічаць функцыю аўтазапаўнення падчас загрузкі старонкі." }, @@ -1774,7 +1765,7 @@ "message": "Пасведчанне" }, "typeSshKey": { - "message": "SSH key" + "message": "Ключ SSH" }, "newItemHeader": { "message": "Новы $TYPE$", @@ -1807,7 +1798,7 @@ "message": "Гісторыя пароляў" }, "generatorHistory": { - "message": "Generator history" + "message": "Гісторыя генератара" }, "clearGeneratorHistoryTitle": { "message": "Clear generator history" @@ -1852,7 +1843,7 @@ "message": "Абароненыя нататкі" }, "sshKeys": { - "message": "SSH Keys" + "message": "Ключы SSH" }, "clear": { "message": "Ачысціць", @@ -1935,7 +1926,7 @@ "message": "Ачысціць гісторыю" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Адсутнічаюць элементы для паказу" }, "nothingGeneratedRecently": { "message": "You haven't generated anything recently" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 752372210b..652129f692 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -1125,6 +1125,10 @@ "message": "ВНИМАНИЕ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Внимание", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Потвърждаване на изнасянето на трезора" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "При засичане на формуляр за вписване при зареждането на уеб страницата автоматично да се попълват данните на съответстващата регистрация." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Внимание:$CLOSETAG$ Опасните или компроментирани уеб сайтове могат да се възползват от функционалността за автоматично попълване при зареждане на страницата.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Компроментирани и измамни уеб сайтове могат да се възползват от автоматичното попълване при зареждане на страницата." }, @@ -3288,16 +3279,16 @@ "message": "Отваря се в нов прозорец" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Запомняне на това устройство, така че в бъдеще вписването да бъде по-лесно" }, "deviceApprovalRequired": { "message": "Изисква се одобрение на устройството. Изберете начин за одобрение по-долу:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Необходимо е одобрение на устройството" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Изберете начин за одобряване по-долу" }, "rememberThisDevice": { "message": "Запомняне на това устройство" @@ -3373,7 +3364,7 @@ "message": "Липсва е-поща на потребителя" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Не е намерена е-поща на активен потребител. Ще бъдете отписан(а)." }, "deviceTrusted": { "message": "Устройството е доверено" @@ -3812,7 +3803,7 @@ "message": "Използване на" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Вписахте се!" }, "passkeyNotCopied": { "message": "Секретният ключ няма да бъде копиран" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Ширина на разширението" + }, + "wide": { + "message": "Широко" + }, + "extraWide": { + "message": "Много широко" } } diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 18d214a37d..3b3b4cad43 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -1125,6 +1125,10 @@ "message": "সতর্কতা", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "ভল্ট রফতানির নিশ্চয়তা দিন" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "যদি কোনও লগইন ফর্ম সনাক্ত হয়, ওয়েব পৃষ্ঠাটি লোড হওয়ার পরে স্বয়ংক্রিয়ভাবে স্বতঃপূরণ করুন।" }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index a4a5f3b27e..a6e893887c 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index a1fc62182a..da8d7a3f8c 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -1125,6 +1125,10 @@ "message": "ADVERTIMENT", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirma l'exportació de la Caixa forta" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Si es detecta un formulari d'inici de sessió, es realitza automàticament un emplenament automàtic quan es carrega la pàgina web." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Els llocs web compromesos o no fiables poden aprofitar-se de l'emplenament automàtic en carregar de la pàgina." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index 03740f06ce..1984ba2700 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -1125,6 +1125,10 @@ "message": "VAROVÁNÍ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Varování", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Potvrdit export trezoru" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Pokud je zjištěn přihlašovací formulář, automaticky se při načítání webové stránky vyplní přihlašovací údaje." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Varování:$CLOSETAG$ Kompromitované nebo nedůvěryhodné webové stránky mohou využívat automatické vyplňování při načítání stránky.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Kompromitované nebo nedůvěryhodné webové stránky mohou zneužívat automatické vyplňování při načítání stránky." }, @@ -3288,16 +3279,16 @@ "message": "Otevře se v novém okně" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Zapamatovat si toto zařízení pro bezproblémové budoucí přihlášení" }, "deviceApprovalRequired": { "message": "Vyžaduje se schválení zařízení. Vyberte možnost schválení níže:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Vyžaduje se schválení zařízení" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Vyberte volbu schválení níže" }, "rememberThisDevice": { "message": "Zapamatovat toto zařízení" @@ -3373,7 +3364,7 @@ "message": "Chybí e-mail uživatele" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktivní uživatelský e-mail nebyl nalezen. Budete odhlášeni." }, "deviceTrusted": { "message": "Zařízení zařazeno mezi důvěryhodné" @@ -3812,7 +3803,7 @@ "message": "Přistupování" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Přihlášeno!" }, "passkeyNotCopied": { "message": "Přístupový klíč nebude zkopírován" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Šířka rozšíření" + }, + "wide": { + "message": "Šířka" + }, + "extraWide": { + "message": "Extra široký" } } diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index fa175cbd19..c57db3b62f 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -1125,6 +1125,10 @@ "message": "RHYBUDD", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Llenwi'n awtomatig wrth i dudalen lwytho os canfyddir ffurflen mewngofnodi." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 12076e2827..8c10608a29 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -1125,6 +1125,10 @@ "message": "ADVARSEL", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Advarsel", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Bekræft eksport af boks" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Registreres en loginformular, autoudfyld når websiden indlæses." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Advarsel:$CLOSETAG$ Kompromitterede eller ikke-betroede websteder kan misbruge autofyld ved sideindlæsning.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Kompromitterede eller ikke-betroede websteder kan misbruge autoudfyldning ved sideindlæsning." }, @@ -3288,16 +3279,16 @@ "message": "Åbnes i et nyt vindue" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Husk denne enhed for at gøre fremtidige indlogninger gnidningsløse" }, "deviceApprovalRequired": { "message": "Enhedsgodkendelse kræves. Vælg en godkendelsesmulighed nedenfor:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Enhedsgodkendelse kræves" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Vælg en godkendelsesmulighed nedenfor" }, "rememberThisDevice": { "message": "Husk denne enhed" @@ -3373,7 +3364,7 @@ "message": "Brugers e-mail mangler" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktiv bruger e-mail ikke fundet. Man logges ud." }, "deviceTrusted": { "message": "Enhed betroet" @@ -3812,7 +3803,7 @@ "message": "Tilgår" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Logget ind!" }, "passkeyNotCopied": { "message": "Adgangsnøglen kopieres ikke" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Udvidelsesbredde" + }, + "wide": { + "message": "Bred" + }, + "extraWide": { + "message": "Ekstra bred" } } diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 9113150ab2..b03f5a9757 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -1125,6 +1125,10 @@ "message": "ACHTUNG", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warnung", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Tresor-Export bestätigen" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Wenn eine Anmeldemaske erkannt wird, die Zugangsdaten automatisch ausfüllen während die Webseite lädt." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warnung:$CLOSETAG$ Kompromittierte oder nicht vertrauenswürdige Websites können Auto-Ausfüllen beim Laden einer Seite missbrauchen.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Kompromittierte oder nicht vertrauenswürdige Websites können Auto-Ausfüllen beim Laden der Seite ausnutzen." }, @@ -1852,7 +1843,7 @@ "message": "Sichere Notizen" }, "sshKeys": { - "message": "SSH Keys" + "message": "SSH-Schlüssel" }, "clear": { "message": "Löschen", @@ -2893,7 +2884,7 @@ "message": "E-Mail generieren" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Wert muss zwischen $MIN$ und $MAX$ liegen.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2907,7 +2898,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Verwende $RECOMMENDED$ oder mehr Zeichen, um ein starkes Passwort zu generieren.", "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": { @@ -2917,7 +2908,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Verwende $RECOMMENDED$ oder mehr Wörter, um eine starke Passphrase zu generieren.", "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": { @@ -3174,7 +3165,7 @@ "message": "Benachrichtigung erneut senden" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Alle Anmeldeoptionen anzeigen" }, "viewAllLoginOptions": { "message": "Alle Anmeldeoptionen anzeigen" @@ -3183,16 +3174,16 @@ "message": "Eine Benachrichtigung wurde an dein Gerät gesendet." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Eine Benachrichtigung wurde an dein Gerät gesendet" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Stelle sicher, dass dein Konto entsperrt ist und die Fingerabdruck-Phrase mit der vom anderen Gerät übereinstimmt" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Du wirst benachrichtigt, sobald die Anfrage genehmigt wurde" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Brauchst du eine andere Option?" }, "loginInitiated": { "message": "Anmeldung eingeleitet" @@ -3288,16 +3279,16 @@ "message": "Wird in einem neuen Fenster geöffnet" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Dieses Gerät merken, um zukünftige Anmeldungen reibungslos zu gestalten" }, "deviceApprovalRequired": { "message": "Geräte-Genehmigung erforderlich. Wähle unten eine Genehmigungsoption aus:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Geräte-Genehmigung erforderlich" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Wähle unten eine Genehmigungsoption aus" }, "rememberThisDevice": { "message": "Dieses Gerät merken" @@ -3373,7 +3364,7 @@ "message": "E-Mail-Adresse des Benutzers fehlt" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktive Benutzer-E-Mail-Adresse nicht gefunden. Du wirst abgemeldet." }, "deviceTrusted": { "message": "Gerät wird vertraut" @@ -3812,7 +3803,7 @@ "message": "Zugriff auf" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Angemeldet!" }, "passkeyNotCopied": { "message": "Passkey wird nicht kopiert" @@ -4306,13 +4297,13 @@ "message": "Filter" }, "filterVault": { - "message": "Filter vault" + "message": "Tresor filtern" }, "filterApplied": { - "message": "One filter applied" + "message": "Ein Filter angewendet" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "$COUNT$ Filter angewendet", "placeholders": { "count": { "content": "$1", @@ -4893,9 +4884,18 @@ "message": "Generiertes Passwort" }, "compactMode": { - "message": "Compact mode" + "message": "Kompaktmodus" }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Breite der Erweiterung" + }, + "wide": { + "message": "Breit" + }, + "extraWide": { + "message": "Extra breit" } } diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index c333bf24f6..f56db1424a 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -1125,6 +1125,10 @@ "message": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Επιβεβαίωση εξαγωγής θησαυ/κίου" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Εάν εντοπιστεί φόρμα σύνδεσης, θα συμπληρωθεί αυτόματα κατά τη φόρτωση της σελίδας." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Προειδοποίηση:$CLOSETAG$ Οι παραβιασμένες ή μη αξιόπιστες ιστοσελίδες μπορούν να εκμεταλλευτούν την αυτόματη συμπλήρωση κατά τη φόρτωση της σελίδας.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Παραβιασμένοι ή μη αξιόπιστοι ιστότοποι μπορούν να εκμεταλλευτούν την αυτόματη συμπλήρωση κατά τη φόρτωση της σελίδας." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 5200cf81d0..39bc6ed9b8 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1315,6 +1319,12 @@ "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": { @@ -1503,19 +1513,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4894,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 30b04e63dc..392c8ef7f8 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, auto-fill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit auto-fill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 56ed22bfd0..5299693987 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm Vault Export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, automatically perform an auto-fill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit auto-fill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 13e4d9b003..a7e7b8cebf 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -1125,6 +1125,10 @@ "message": "ADVERTENCIA", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Advertencia", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirma la exportación de la caja fuerte" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Si se detecta un formulario, realizar automáticamente un autorellenado cuando la web cargue." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Los sitios web vulnerados o no confiables pueden explotar el autorelleno al cargar la página." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index f7e3f7b135..020f282fb4 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -20,16 +20,16 @@ "message": "Konto loomine" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Esimene kord?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Logi sisse pääsuvõtmega" }, "useSingleSignOn": { "message": "Use single sign-on" }, "welcomeBack": { - "message": "Welcome back" + "message": "Tere tulemast tagasi" }, "setAStrongPassword": { "message": "Määra tugev parool" @@ -84,7 +84,7 @@ "message": "Liitu organisatsiooniga" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "Liitu $ORGANIZATIONNAME$ organisatsiooniga", "placeholders": { "organizationName": { "content": "$1", @@ -1125,6 +1125,10 @@ "message": "HOIATUS", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Hoidla eksportimise kinnitamine" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Sisselogimise vormi tuvastamisel sisestatakse sinna kontoandmed automaatselt." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Häkitud või ebausaldusväärsed veebilehed võivad lehe laadimisel automaatset sisestamist kuritarvitada." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index db86f97810..cf9054064d 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -1125,6 +1125,10 @@ "message": "KONTUZ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Baieztatu kutxa gotorra esportatzea" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Saio-hasierako formulario bat detektatzen bada, auto-bete webgunea kargatzen denean." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index b0ac5e86c3..9f7091b3ec 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -1125,6 +1125,10 @@ "message": "اخطار", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "برون ریزی گاوصندوق را تأیید کنید" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "اگر یک فرم ورودی شناسایی شد، وقتی صفحه وب بارگذاری شد، به صورت خودکار پر شود." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "وب‌سایت‌های در معرض خطر یا نامعتبر می‌توانند از پر کردن خودکار در بارگذاری صفحه سوء استفاده کنند." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 2a4edd9cd6..aa8adbb799 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -1125,6 +1125,10 @@ "message": "VAROITUS", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Varoitus", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Vahvista holvin vienti" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Automaattinen täyttö suoritetaan sivun avautuessa, jos sivulla havaitaan kirjautumislomake." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Varoitus:$CLOSETAG$ Vaarantuneet tai epäluotettavat sivustot voivat hyväksikäyttää sivun avautuessa suoritettavaa automaattista täyttöä.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Vaarantuneet tai epäluotettavat sivustot voivat hyväksikäyttää sivun avautuessa suoritettavaa automaattista täyttöä." }, @@ -1852,7 +1843,7 @@ "message": "Salatut muistiot" }, "sshKeys": { - "message": "SSH Keys" + "message": "SSH-avaimet" }, "clear": { "message": "Tyhjennä", @@ -3186,7 +3177,7 @@ "message": "Laitteeseesi lähetettiin ilmoitus" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Varmista, että vahvistavan laitteen holvi on avattu ja että se näyttää saman tunnistelausekkeen" }, "youWillBeNotifiedOnceTheRequestIsApproved": { "message": "Sinulle ilmoitetaan, kun pyyntö on hyväksytty" @@ -3288,16 +3279,16 @@ "message": "Avautuu uudessa ikkunassa" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Muista tämä laite tehdäksesi tulevista kirjautumisista saumattomia" }, "deviceApprovalRequired": { "message": "Laitehyväksyntä vaaditaan. Valitse hyväksyntätapa alta:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Laitteen hyväksyntä vaaditaan" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Valitse hyväksyntävaihtoehto alla" }, "rememberThisDevice": { "message": "Muista tämä laite" @@ -3373,7 +3364,7 @@ "message": "Käyttäjän sähköpostiosoite puuttuu" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktiivista käyttäjän sähköpostiosoitetta ei löytynyt. Kirjaudutaan ulos." }, "deviceTrusted": { "message": "Laitteeseen luotettu" @@ -3812,7 +3803,7 @@ "message": "Avataan" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Kirjautuminen onnistui!" }, "passkeyNotCopied": { "message": "Pääsyavainta ei kopioida" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index ab067bc9b8..fe3714b6d5 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -1125,6 +1125,10 @@ "message": "BABALA", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Tanggapin ang pag-export ng vault" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Kung natukoy ang isang form sa pag login, awtomatikong punan kapag naglo load ang web page." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Ang mga nakompromiso o hindi pinagkakatiwalaang mga website ay maaaring samantalahin ang awtomatikong pagpuno sa pag load ng pahina." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index f2e0658474..a4f238705a 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -1125,6 +1125,10 @@ "message": "AVERTISSEMENT", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Avertissement", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirmer l'export du coffre" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Si un formulaire de connexion est détecté, il sera saisi automatiquement lors du chargement de la page web." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Attention :$CLOSETAG$ Les sites web compromis ou non fiables peuvent exploiter la saisie automatique lors du chargement de la page.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "les sites web compromis ou non fiables peuvent exploiter la saisie automatique au chargement de la page." }, @@ -1852,7 +1843,7 @@ "message": "Notes sécurisées" }, "sshKeys": { - "message": "SSH Keys" + "message": "Clés SSH" }, "clear": { "message": "Effacer", @@ -3288,16 +3279,16 @@ "message": "S'ouvre dans une nouvelle fenêtre" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Mémorisez cet appareil pour faciliter les futures connexions" }, "deviceApprovalRequired": { "message": "L'approbation de l'appareil est requise. Sélectionnez une option d'approbation ci-dessous :" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Autorisation de l'appareil requise" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Sélectionnez une option d'approbation ci-dessous" }, "rememberThisDevice": { "message": "Se souvenir de cet appareil" @@ -3373,7 +3364,7 @@ "message": "Courriel de l'utilisateur manquant" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Courriel utilisateur actif introuvable. Déconnexion en cours." }, "deviceTrusted": { "message": "Appareil de confiance" @@ -3812,7 +3803,7 @@ "message": "Accès en cours" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Connecté !" }, "passkeyNotCopied": { "message": "La clé d'identification (passkey) ne sera pas copiée" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Largeur de l'extension" + }, + "wide": { + "message": "Large" + }, + "extraWide": { + "message": "Très large" } } diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index d1697b4dc5..845ddb08a9 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -1125,6 +1125,10 @@ "message": "ADVERTENCIA", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Advertencia", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 692d6f166d..88264c26e5 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -1125,6 +1125,10 @@ "message": "אזהרה", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "אישור ייצוא כספת" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "אם זוהה טופס כניסה, בצע אוטומטית מילוי-אוטומטי כשהעמוד נטען." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 050a4021a5..0d4cf1548d 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -1125,6 +1125,10 @@ "message": "चेतावनी", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "वॉल्ट निर्यात की पुष्टि करें" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "यदि लॉगिन फॉर्म का पता चलता है, तो वेब पेज लोड होने पर स्वचालित रूप से ऑटो-फिल करें।" }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index ec13925045..659a8d1b59 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -1125,6 +1125,10 @@ "message": "UPOZORENJE", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Potvrdi izvoz trezora" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Nakon učitavanja web stranice, ako je otkriven obrazac za prijavu, auto-ispuni." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Upozorenje:$CLOSETAG$ Ugrožene ili nepouzdane web stranice mogu iskoristiti auto-ispunu prilikom učitavanja stranice.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Ugrožene ili nepouzdane web stranice mogu iskoristiti auto-ispunu prilikom učitavanja stranice." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 4c42fc4f45..d11b62b6cb 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -1125,6 +1125,10 @@ "message": "FIGYELEM", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Figyelmeztetés", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Széf exportálás megerősítése" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Ha egy bejelentkezési űrlap észlelésre került, az adatok automatikus kitöltése az oldal betöltésekor." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Az oldalbetöltésnél automatikus kitöltést a feltört vagy nem megbízhatató weboldalak kihasználhatják." }, @@ -3288,16 +3279,16 @@ "message": "Megnyitás új ablakban" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Emlékezés az eszközre, hogy zökkenőmentes legyen a jövőbeni bejelentkezés" }, "deviceApprovalRequired": { "message": "Az eszköz jóváhagyása szükséges. Válasszunk egy jóváhagyási lehetőséget lentebb:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Eszköz jóváhagyás szükséges" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Válasszunk lentebb egy jóváhagyási lehetőséget." }, "rememberThisDevice": { "message": "Eszköz megjegyzése" @@ -3373,7 +3364,7 @@ "message": "A felhasználói email cím hiányzik." }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Az aktív felhasználói email cím nem található. Jelentkezzünk ki." }, "deviceTrusted": { "message": "Az eszköz megbízható." @@ -3812,7 +3803,7 @@ "message": "Elérés" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Megtörtént a bejelentkezés." }, "passkeyNotCopied": { "message": "A hozzáférési kulcs nem kerül másolásra." @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Béta" + }, + "extensionWidth": { + "message": "Kiterjesztés szélesség" + }, + "wide": { + "message": "Széles" + }, + "extraWide": { + "message": "Extra széles" } } diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 25d3e1cdd9..467492a2f7 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -20,16 +20,16 @@ "message": "Buat Akun" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Baru menggunakan Bitwarden?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Masuk dengan kunci sandi" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Gunakan masuk tunggal" }, "welcomeBack": { - "message": "Welcome back" + "message": "Selamat datang kembali" }, "setAStrongPassword": { "message": "Atur sebuah kata sandi yang kuat" @@ -120,7 +120,7 @@ "message": "Salin Kata Sandi" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "Salin frasa sandi" }, "copyNote": { "message": "Salin Catatan" @@ -153,13 +153,13 @@ "message": "Salin nomor lisensi" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "Salin kunci pribadi" }, "copyPublicKey": { - "message": "Copy public key" + "message": "Salin kunci publik" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "Salin sidik jari" }, "copyCustomField": { "message": "Salin $FIELD$", @@ -177,7 +177,7 @@ "message": "Salin catatan" }, "fill": { - "message": "Fill", + "message": "Isikan", "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": { @@ -436,7 +436,7 @@ "message": "Buat Kata Sandi" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Buat frasa sandi" }, "regeneratePassword": { "message": "Buat Ulang Kata Sandi" @@ -600,7 +600,7 @@ "message": "Buka situs web" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Buka situs web $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -855,7 +855,7 @@ "message": "Masuk" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Masuk ke Bitwarden" }, "restartRegistration": { "message": "Mulai ulang pendaftaran" @@ -1125,6 +1125,10 @@ "message": "PERINGATAN", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Peringatan", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Konfirmasi Ekspor Brankas" }, @@ -1433,7 +1437,7 @@ "message": "URL Server" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL server yang dihosting mandiri", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Jika formulir info masuk terdeteksi, secara otomatis melakukan pengisian otomatis ketika memuat laman web." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Peringatan:$CLOSETAG$ Situs web yang disusupi atau tidak terpercaya dapat memanfaatkan isi otomatis ketika halaman dimuat.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Situs web yang disusupi atau tidak terpercaya dapat memanfaatkan isi otomatis ketika halaman dimuat." }, @@ -1774,10 +1765,10 @@ "message": "Identitas" }, "typeSshKey": { - "message": "SSH key" + "message": "Kunci SSH" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "$TYPE$ baru", "placeholders": { "type": { "content": "$1", @@ -1786,7 +1777,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Sunting $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1795,7 +1786,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "Lihat $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1807,13 +1798,13 @@ "message": "Riwayat Kata Sandi" }, "generatorHistory": { - "message": "Generator history" + "message": "Riwayat penghasil" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Bersihkan riwayat penghasil" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Jika Anda melanjutkan, semua daftar akan dihapus selamanya dari riwayat penghasil. Apakah Anda yakin ingin melanjutkan?" }, "back": { "message": "Kembali" @@ -1822,7 +1813,7 @@ "message": "Koleksi" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ koleksi", "placeholders": { "count": { "content": "$1", @@ -1852,7 +1843,7 @@ "message": "Catatan Aman" }, "sshKeys": { - "message": "SSH Keys" + "message": "Kunci SSH" }, "clear": { "message": "Bersihkan", @@ -1878,7 +1869,7 @@ "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "Domain utama (disarankan)", "description": "Domain name. Ex. website.com" }, "domainName": { @@ -1932,13 +1923,13 @@ "message": "Tidak ada sandi yang dapat dicantumkan." }, "clearHistory": { - "message": "Clear history" + "message": "Bersihkan riwayat" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Tidak ada yang dapat ditampilkan" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Anda belum menghasilkan apapun akhir-akhir ini" }, "remove": { "message": "Hapus" @@ -1999,16 +1990,16 @@ "message": "Buka kunci dengan PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "Atur PIN" }, "setYourPinButton": { - "message": "Set PIN" + "message": "Atur PIN" }, "setYourPinCode": { "message": "Setel kode PIN Anda untuk membuka kunci Bitwarden. Pengaturan PIN Anda akan diatur ulang jika Anda pernah keluar sepenuhnya dari aplikasi." }, "setYourPinCode1": { - "message": "Your PIN will be used to unlock Bitwarden instead of your master password. Your PIN will reset if you ever fully log out of Bitwarden." + "message": "PIN Anda akan digunakan untuk membuka Bitwarden alih-alih dengan kata sandi utama Anda. PIN Anda akan diatur ulang apabila Anda pernah keluar sepenuhnya dari Bitwarden." }, "pinRequired": { "message": "Membutuhkan kode PIN." @@ -2017,13 +2008,13 @@ "message": "Kode PIN tidak valid." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "Terlalu banyak usaha memasukkan PIN yang gagal. Mengeluarkan dari sesi." }, "unlockWithBiometrics": { "message": "Buka kunci dengan biometrik" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "Buka dengan kata sandi utama" }, "awaitDesktop": { "message": "Menunggu konfirmasi dari desktop" @@ -2035,7 +2026,7 @@ "message": "Kunci dengan kata sandi utama saat peramban dimulai ulang" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Memerlukan kata sandi utama ketika mulai ulang peramban" }, "selectOneCollection": { "message": "Anda harus memilih setidaknya satu koleksi." @@ -2050,33 +2041,33 @@ "message": "Satu atau lebih kebijakan organisasi mempengaruhi pengaturan pembuat sandi Anda." }, "passwordGenerator": { - "message": "Password generator" + "message": "Pembuat kata sandi" }, "usernameGenerator": { - "message": "Username generator" + "message": "Pembuat nama pengguna" }, "useThisPassword": { - "message": "Use this password" + "message": "Gunakan kata sandi ini" }, "useThisUsername": { - "message": "Use this username" + "message": "Gunakan nama pengguna ini" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "Kata sandi aman berhasil dibuat! Jangan lupa untuk memperbarui kata sandi Anda di situs web." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Gunakan penghasil", "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": "untuk membuat sebuah kata sandi unit yang kuat", "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'" }, "vaultTimeoutAction": { "message": "Tindakan Batas Waktu Brankas" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Batas waktu tindakan" }, "lock": { "message": "Kunci", @@ -2105,7 +2096,7 @@ "message": "Item Yang Dipulihkan" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Sudah memiliki akun?" }, "vaultTimeoutLogOutConfirmation": { "message": "Keluar akan menghapus semua akses ke brankas Anda dan membutuhkan otentikasi daring setelah periode batas waktu tertentu. Apakah Anda yakin ingin menggunakan pengaturan ini?" @@ -2117,7 +2108,7 @@ "message": "Isi Otomatis dan Simpan" }, "fillAndSave": { - "message": "Fill and save" + "message": "Isikan dan simpan" }, "autoFillSuccessAndSavedUri": { "message": "Item yang Diisi Otomatis dan URI Tersimpan" @@ -2126,16 +2117,16 @@ "message": "Item Terisi Otomatis" }, "insecurePageWarning": { - "message": "Warning: This is an unsecured HTTP page, and any information you submit can potentially be seen and changed by others. This Login was originally saved on a secure (HTTPS) page." + "message": "Peringatan: Ini adalah halaman HTTP yang tidak aman, dan setiap informasi yang Anda kirim dapat berpotensi terlihat dan diubah oleh orang lain. Login ini awalnya disimpan di halaman aman (HTTPS) " }, "insecurePageWarningFillPrompt": { - "message": "Do you still wish to fill this login?" + "message": "Anda masih ingin mengisi login ini?" }, "autofillIframeWarning": { - "message": "The form is hosted by a different domain than the URI of your saved login. Choose OK to autofill anyway, or Cancel to stop." + "message": "Formulir dihosting oleh domain yang berbeda dari URI login yang telah Anda simpan. Pilih OK untuk tetap mengisi otomatis, atau Batalkan untuk menghentikan." }, "autofillIframeWarningTip": { - "message": "To prevent this warning in the future, save this URI, $HOSTNAME$, to your Bitwarden login item for this site.", + "message": "Untuk mencegah peringatan ini di masa depan, simpan URI ini, $HOSTNAME$, ke benda login Bitwarden untuk situs ini.", "placeholders": { "hostname": { "content": "$1", @@ -2147,10 +2138,10 @@ "message": "Atur Kata Sandi Utama" }, "currentMasterPass": { - "message": "Current master password" + "message": "Kata sandi utama saat ini" }, "newMasterPass": { - "message": "New master password" + "message": "Kata sandi utama baru" }, "confirmNewMasterPass": { "message": "Confirm new master password" @@ -3093,13 +3084,13 @@ "message": "Premium subscription required" }, "organizationIsDisabled": { - "message": "Organization suspended." + "message": "Organisasi ditangguhkan." }, "disabledOrganizationFilterError": { - "message": "Items in suspended Organizations cannot be accessed. Contact your Organization owner for assistance." + "message": "Benda-benda di Organisasi yang ditangguhkan tidak dapat diakses. Hubungi pemilik Organisasi Anda untuk mendapatkan panduan." }, "loggingInTo": { - "message": "Logging in to $DOMAIN$", + "message": "Sedang masuk ke $DOMAIN$", "placeholders": { "domain": { "content": "$1", @@ -3108,25 +3099,25 @@ } }, "settingsEdited": { - "message": "Settings have been edited" + "message": "Pengaturan telah disunting" }, "environmentEditedClick": { - "message": "Click here" + "message": "Tekan di sini" }, "environmentEditedReset": { - "message": "to reset to pre-configured settings" + "message": "untuk mengatur ulang ke pengaturan awal" }, "serverVersion": { - "message": "Server version" + "message": "Versi server" }, "selfHostedServer": { - "message": "self-hosted" + "message": "dihosting mandiri" }, "thirdParty": { - "message": "Third-party" + "message": "Pihak ketiga" }, "thirdPartyServerMessage": { - "message": "Connected to third-party server implementation, $SERVERNAME$. Please verify bugs using the official server, or report them to the third-party server.", + "message": "Tersambung ke penerapan server pihak ketiga, $SERVERNAME$. Mohon pastikan bug menggunakan server resmi, atau laporkan mereka ke server pihak ketiga.", "placeholders": { "servername": { "content": "$1", @@ -3135,7 +3126,7 @@ } }, "lastSeenOn": { - "message": "last seen on: $DATE$", + "message": "terakhir terlihat pada: $DATE$", "placeholders": { "date": { "content": "$1", @@ -3144,82 +3135,82 @@ } }, "loginWithMasterPassword": { - "message": "Log in with master password" + "message": "Masuk dengan kata sandi utama" }, "loggingInAs": { - "message": "Logging in as" + "message": "Masuk sebagai" }, "notYou": { - "message": "Not you?" + "message": "Bukan Anda?" }, "newAroundHere": { - "message": "New around here?" + "message": "Baru di sini?" }, "rememberEmail": { "message": "Ingat email" }, "loginWithDevice": { - "message": "Log in with device" + "message": "Masuk dengan perangkat" }, "loginWithDeviceEnabledInfo": { - "message": "Log in with device must be set up in the settings of the Bitwarden app. Need another option?" + "message": "Masuk dengan perangkat harus diatur di pengaturan aplikasi Bitwarden. Perlu pilihan lainnya?" }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "Frasa sidik jari" }, "fingerprintMatchInfo": { - "message": "Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device." + "message": "Pastikan brankas Anda terbuka dan frasa sidik jari cocok pada perangkat lainnya." }, "resendNotification": { - "message": "Resend notification" + "message": "Kirim ulang pemberitahuan" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Lihat semua pilihan masuk" }, "viewAllLoginOptions": { - "message": "View all log in options" + "message": "Lihat semua pilihan masuk" }, "notificationSentDevice": { - "message": "A notification has been sent to your device." + "message": "Sebuah pemberitahuan dikirim ke perangkat Anda." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Sebuah pemberitahuan telah dikirim ke perangkat Anda" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Pastikan akun Anda terbuka dan frasa sidik jari cocok pada perangkat lainnya" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Anda akan diberitahu setelah permintaan disetujui" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Perlu pilihan lainnya?" }, "loginInitiated": { - "message": "Login initiated" + "message": "Memulai login" }, "exposedMasterPassword": { - "message": "Exposed Master Password" + "message": "Kata Sandi Utama yang Terpapar" }, "exposedMasterPasswordDesc": { - "message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?" + "message": "Kata sandi ditemukan di pelanggaran data. Gunakan kata sandi unik untuk melindungi akun Anda. Apakah Anda yakin ingin menggunakan kata sandi yang terpapar?" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "Kata Sandi Utama yang Lemah dan Terpapar" }, "weakAndBreachedMasterPasswordDesc": { - "message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?" + "message": "Kata sandi lemah dikenali dan ditemukan di pelanggaran data. Gunakan kata sandi unik untuk melindungi akun Anda. Apakah Anda yakin ingin menggunakan kata sandi ini?" }, "checkForBreaches": { - "message": "Check known data breaches for this password" + "message": "Periksa pelanggaran data yang diketahui untuk kata sandi ini" }, "important": { - "message": "Important:" + "message": "Penting:" }, "masterPasswordHint": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "Kata sandi utama Anda tidak dapat dipulihkan jika Anda melupakannya!" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "Minimal $LENGTH$ karakter", "placeholders": { "length": { "content": "$1", @@ -3228,13 +3219,13 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Your organization policies have turned on autofill on page load." + "message": "Kebijakan organisasi Anda telah menyalakan isi otomatis ketika halaman dimuat." }, "howToAutofill": { - "message": "How to autofill" + "message": "Bagaimana cara mengisi otomatis" }, "autofillSelectInfoWithCommand": { - "message": "Select an item from this screen, use the shortcut $COMMAND$, or explore other options in settings.", + "message": "Pilih sebuah benda dari layar ini, gunakan pintasan $COMMAND$, atau jelajahi pilihan lainnya di pengaturan.", "placeholders": { "command": { "content": "$1", @@ -3243,31 +3234,31 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "Pilih sebuah benda dari layar ini, atau jelajahi pilihan lainnya di pengaturan." }, "gotIt": { - "message": "Got it" + "message": "Dimengerti" }, "autofillSettings": { - "message": "Autofill settings" + "message": "Pengaturan isi otomatis" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Pintasan isi otomatis" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Ubah pintasan" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "Kelola pintasan" }, "autofillShortcut": { - "message": "Autofill keyboard shortcut" + "message": "Pintasan papan ketik isi otomatis" }, "autofillLoginShortcutNotSet": { - "message": "The autofill login shortcut is not set. Change this in the browser's settings." + "message": "Pintasan isi otomatis login belum diatur. Ubah ini di pengaturan peramban." }, "autofillLoginShortcutText": { - "message": "The autofill login shortcut is $COMMAND$. Manage all shortcuts in the browser's settings.", + "message": "Pintasan isi otomatis login adalah $COMMAND$. Kelola semua pintasan di pengaturan peramban.", "placeholders": { "command": { "content": "$1", @@ -3276,7 +3267,7 @@ } }, "autofillShortcutTextSafari": { - "message": "Default autofill shortcut: $COMMAND$.", + "message": "Pintasan isi otomatis bawaan: $COMMAND$.", "placeholders": { "command": { "content": "$1", @@ -3285,7 +3276,7 @@ } }, "opensInANewWindow": { - "message": "Opens in a new window" + "message": "Buka di jendela baru" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { "message": "Remember this device to make future logins seamless" @@ -3478,16 +3469,16 @@ "message": "-- Type to filter --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "Mengambil pilihan..." }, "multiSelectNotFound": { - "message": "No items found" + "message": "Tidak ada benda yang ditemukan" }, "multiSelectClearAll": { - "message": "Clear all" + "message": "Bersihkan semua" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ $QUANTITY$ lagi", "placeholders": { "quantity": { "content": "$1", @@ -3499,165 +3490,165 @@ "message": "Submenu" }, "toggleCollapse": { - "message": "Toggle collapse", + "message": "Saklar lipat", "description": "Toggling an expand/collapse state." }, "filelessImport": { - "message": "Import your data to Bitwarden?", + "message": "Impor data Anda ke Bitwarden?", "description": "Default notification title for triggering a fileless import." }, "lpFilelessImport": { - "message": "Protect your LastPass data and import to Bitwarden?", + "message": "Lindungi data LastPass Anda dan impor ke Bitwarden?", "description": "LastPass specific notification title for triggering a fileless import." }, "lpCancelFilelessImport": { - "message": "Save as unencrypted file", + "message": "Simpan sebagai berkas yang tidak dienkripsi", "description": "LastPass specific notification button text for cancelling a fileless import." }, "startFilelessImport": { - "message": "Import to Bitwarden", + "message": "Impor ke Bitwarden", "description": "Notification button text for starting a fileless import." }, "importing": { - "message": "Importing...", + "message": "Mengimpor...", "description": "Notification message for when an import is in progress." }, "dataSuccessfullyImported": { - "message": "Data successfully imported!", + "message": "Data berhasil diimpor!", "description": "Notification message for when an import has completed successfully." }, "dataImportFailed": { - "message": "Error importing. Check console for details.", + "message": "Gagal mengimpor. Periksa konsol untuk rinciannya.", "description": "Notification message for when an import has failed." }, "importNetworkError": { - "message": "Network error encountered during import.", + "message": "Kesalahan jaringan ditemui ketika mengimpor.", "description": "Notification message for when an import has failed due to a network error." }, "aliasDomain": { - "message": "Alias domain" + "message": "Domain alias" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Items with master password re-prompt cannot be autofilled on page load. Autofill on page load turned off.", + "message": "Benda dengan meminta ulang kata sandi utama tidak dapat diisikan otomatis ketika halaman dimuat. Isi otomatis ketika halaman dimuat dimatikan.", "description": "Toast message for describing that master password re-prompt cannot be autofilled on page load." }, "autofillOnPageLoadSetToDefault": { - "message": "Autofill on page load set to use default setting.", + "message": "Isi otomatis ketika halaman dimuat telah diatur untuk menggunakan pengaturan bawaan.", "description": "Toast message for informing the user that autofill on page load has been set to the default setting." }, "turnOffMasterPasswordPromptToEditField": { - "message": "Turn off master password re-prompt to edit this field", + "message": "Matikan minta ulang kata sandi utama untuk menyunting kolom ini", "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { - "message": "Toggle side navigation" + "message": "Saklar bilah isi navigasi" }, "skipToContent": { - "message": "Skip to content" + "message": "Loncat ke konten" }, "bitwardenOverlayButton": { - "message": "Bitwarden autofill menu button", + "message": "Tombol menu isi otomatis Bitwarden", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden autofill menu", + "message": "Saklar menu isi otomatis Bitwarden", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden autofill menu", + "message": "Menu isi otomatis Bitwarden", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "Buka akun Anda untuk melihat login yang cocok", "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Buka akun Anda untuk melihat saran isi otomatis", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "Buka akun", "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Buka akun Anda, membukanya di jendela baru", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "Isi tanda pengenal untuk", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { - "message": "Partial username", + "message": "Nama pengguna sebagian", "description": "Screen reader text for when a login item is focused where a partial username is displayed. SR will announce this phrase before reading the text of the partial username" }, "noItemsToShow": { - "message": "No items to show", + "message": "Tidak ada benda untuk ditampilkan", "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "Benda baru", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { - "message": "Add new vault item", + "message": "Tambah benda brankas baru", "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Login baru", "description": "Button text to display within inline menu when there are no matching items on a login field" }, "addNewLoginItemAria": { - "message": "Add new vault login item, opens in a new window", + "message": "Tambah baru untuk benda login, membukanya di jendela baru", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Kartu baru", "description": "Button text to display within inline menu when there are no matching items on a credit card field" }, "addNewCardItemAria": { - "message": "Add new vault card item, opens in a new window", + "message": "Tambah brankas baru untuk benda kartu, membukanya di jendela baru", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Pengenal baru", "description": "Button text to display within inline menu when there are no matching items on an identity field" }, "addNewIdentityItemAria": { - "message": "Add new vault identity item, opens in a new window", + "message": "Tambah brankas baru untuk benda pengenal, membukanya di jendela baru", "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden autofill menu available. Press the down arrow key to select.", + "message": "Menu isi otomatis Bitwarden tersedia. Tekan tombol panah ke bawah untuk memilih.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { - "message": "Turn on" + "message": "Nyalakan" }, "ignore": { - "message": "Ignore" + "message": "Abaikan" }, "importData": { - "message": "Import data", + "message": "Impor data", "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" }, "importError": { - "message": "Import error" + "message": "Kesalahan impor" }, "importErrorDesc": { - "message": "There was a problem with the data you tried to import. Please resolve the errors listed below in your source file and try again." + "message": "Ada masalah dengan data yang Anda coba impor. Harap selesaikan kesalahan yang tercantum di bawah ini pada berkas sumber Anda dan coba lagi." }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "Selesaikan masalah berikut dan coba lagi." }, "description": { - "message": "Description" + "message": "Keterangan" }, "importSuccess": { - "message": "Data successfully imported" + "message": "Data berhasil diimpor" }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "Sejumlah $AMOUNT$ benda telah diimpor.", "placeholders": { "amount": { "content": "$1", @@ -3666,10 +3657,10 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Coba lagi" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Diperlukan verifikasi untuk tindakan ini. Atur PIN untuk melanjutkan." }, "setPin": { "message": "Set PIN" @@ -3842,152 +3833,152 @@ "message": "Search or save passkey as new login" }, "confirm": { - "message": "Confirm" + "message": "Konfirmasi" }, "savePasskey": { - "message": "Save passkey" + "message": "Simpan kunci sandi" }, "savePasskeyNewLogin": { - "message": "Save passkey as new login" + "message": "Simpan kunci sandi sebagai login baru" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "Pilih sebuah login untuk menyimpan kunci sandi ini" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "Pilih sebuah kunci sandi untuk masuk" }, "passkeyItem": { - "message": "Passkey Item" + "message": "Benda kunci sandi" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "Timpa kunci sandi?" }, "overwritePasskeyAlert": { - "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + "message": "Benda ini telah memiliki kunci sandi. Apakah Anda yakin ingin menimpa kunci sandi yang sekarang?" }, "featureNotSupported": { - "message": "Feature not yet supported" + "message": "Kemampuan belum didukung" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "message": "Otentikasi diperlukan untuk menggunakan kunci sandi. Verifikasikan diri Anda untuk melanjutkan." }, "multifactorAuthenticationCancelled": { - "message": "Multifactor authentication cancelled" + "message": "Otentikasi multifaktor dibatalkan" }, "noLastPassDataFound": { - "message": "No LastPass data found" + "message": "Tidak ada data LastPass yang ditemukan" }, "incorrectUsernameOrPassword": { - "message": "Incorrect username or password" + "message": "Nama pengguna atau kata sandi salah" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Kata sandi salah" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Kode salah" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "PIN salah" }, "multifactorAuthenticationFailed": { - "message": "Multifactor authentication failed" + "message": "Otentikasi multifaktor gagal" }, "includeSharedFolders": { - "message": "Include shared folders" + "message": "Sertakan folder yang dibagikan" }, "lastPassEmail": { - "message": "LastPass Email" + "message": "Surel LastPass" }, "importingYourAccount": { - "message": "Importing your account..." + "message": "Mengimpor akun Anda..." }, "lastPassMFARequired": { - "message": "LastPass multifactor authentication required" + "message": "Otentikasi multifaktor LastPass diperlukan" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "Masukkan kode sandi sekali-waktu dari aplikasi otentikator Anda" }, "lastPassOOBDesc": { - "message": "Approve the login request in your authentication app or enter a one-time passcode." + "message": "Setujui permintaan masuk di aplikasi otentikasi Anda atau masukkan kode sandi sekali-waktu." }, "passcode": { - "message": "Passcode" + "message": "Kode sandi" }, "lastPassMasterPassword": { - "message": "LastPass master password" + "message": "Kata sandi utama LastPass" }, "lastPassAuthRequired": { - "message": "LastPass authentication required" + "message": "Otentikasi LastPass diperlukan" }, "awaitingSSO": { - "message": "Awaiting SSO authentication" + "message": "Menunggu otentikasi SSO" }, "awaitingSSODesc": { - "message": "Please continue to log in using your company credentials." + "message": "Harap lanjutkan masuk menggunakan tanda pengenal perusahaan Anda." }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "Lihat petunjuk lengkap pada situs bantuan kami di", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { - "message": "Import directly from LastPass" + "message": "Impor langsung dari LastPass" }, "importFromCSV": { - "message": "Import from CSV" + "message": "Impor dari CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Try again or look for an email from LastPass to verify it's you." + "message": "Coba lagi atau cari surel dari LastPass untuk memverifikasi bahwa ini adalah Anda." }, "collection": { - "message": "Collection" + "message": "Koleksi" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "Masukkan YubiKey yang ditautkan dengan akun LastPass Anda ke port USB komputer Anda, kemudian sentuh tombolnya." }, "switchAccount": { - "message": "Switch account" + "message": "Ganti akun" }, "switchAccounts": { - "message": "Switch accounts" + "message": "Ganti akun" }, "switchToAccount": { - "message": "Switch to account" + "message": "Ganti ke akun" }, "activeAccount": { - "message": "Active account" + "message": "Akun aktif" }, "availableAccounts": { - "message": "Available accounts" + "message": "Akun yang tersedia" }, "accountLimitReached": { - "message": "Account limit reached. Log out of an account to add another." + "message": "Batas akun tercapai. Keluar dari akun untuk menambahkan akun lain." }, "active": { - "message": "active" + "message": "aktif" }, "locked": { - "message": "locked" + "message": "terkunci" }, "unlocked": { - "message": "unlocked" + "message": "terbuka" }, "server": { "message": "server" }, "hostedAt": { - "message": "hosted at" + "message": "dihost di" }, "useDeviceOrHardwareKey": { - "message": "Use your device or hardware key" + "message": "Gunakan perangkat Anda atau kunci perangkat keras" }, "justOnce": { - "message": "Just once" + "message": "Hanya sekali" }, "alwaysForThisSite": { - "message": "Always for this site" + "message": "Selalu untuk situs ini" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "$DOMAIN$ ditambahkan ke domain yang dikecualikan.", "placeholders": { "domain": { "content": "$1", @@ -3996,7 +3987,7 @@ } }, "commonImportFormats": { - "message": "Common formats", + "message": "Format umum", "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index fe3f7467b2..e11b793399 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -1125,6 +1125,10 @@ "message": "ATTENZIONE", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Conferma esportazione della cassaforte" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Se sono rilevati campi di login, riempili automaticamente quando la pagina si carica." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Attenzione:$CLOSETAG$ Siti Web compromessi o non attendibili possono sfruttare il riempimento automatico al caricamento della pagina.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Siti compromessi potrebbero sfruttare il riempimento automatico al caricamento della pagina." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index a1cb2877d8..d9908835c8 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1125,6 +1125,10 @@ "message": "警告", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "保管庫のエクスポートの確認" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "ページ読み込み時にログインフォームを検出したとき、ログイン情報を自動入力します。" }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$警告:$CLOSETAG$ 侵害された、または信頼できないウェブサイトは、ページ読み込み時の自動入力を悪用する可能性があります。", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "ウイルス感染したり信頼できないウェブサイトは、ページの読み込み時の自動入力を悪用できてしまいます。" }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 5a0dbf4f9e..8b92a9ff34 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -1125,6 +1125,10 @@ "message": "გაფრთხილება", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 0ae9d0617f..6f26673abc 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 660c8cac25..6d15ddc906 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -1125,6 +1125,10 @@ "message": "ಎಚ್ಚರಿಕೆ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "ವಾಲ್ಟ್ ರಫ್ತು ಖಚಿತಪಡಿಸಿ" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "ಲಾಗಿನ್ ಫಾರ್ಮ್ ಪತ್ತೆಯಾದಲ್ಲಿ, ವೆಬ್ ಪುಟ ಲೋಡ್ ಆಗುವಾಗ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸ್ವಯಂ ಭರ್ತಿ ಮಾಡಿ." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index e058e32efa..0b527149d1 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -1125,6 +1125,10 @@ "message": "경고", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "보관함 내보내기 확인" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "로그인 양식을 감지하면 웹 페이지 로드 시 자동 완성을 자동으로 수행합니다." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "취약하거나 신뢰할 수 없는 웹사이트 페이지 로드 시 자동 완성이 악용될 수 있습니다." }, @@ -4423,7 +4414,7 @@ } }, "enableAnimations": { - "message": "Enable animations" + "message": "애니메이션 활성화" }, "showAnimations": { "message": "Show animations" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index f1e8d4f223..3318bd8df1 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -1125,6 +1125,10 @@ "message": "ĮSPĖJIMAS", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Patvirtinti saugyklos eksportą" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Jei aptikta prisijungimo forma, automatiškai užpildyti, kai kraunamas tinklalapis." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Pažeistos arba nepatikimos svetainės gali išnaudoti automatinį užpildymą įkeliant puslapį." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 0ce6bf97a2..cb0f299dcb 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -1125,6 +1125,10 @@ "message": "UZMANĪBU", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Brīdinājums", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Apstiprināt glabātavas satura izgūšanu" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Ja tiek noteikta pieteikšanās veidne, tā tiks aizpildīta lapas ielādes brīdī." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Brīdinājums:$CLOSETAG$ pārveidotās vai neuzticamās tīmekļvietnēs automātiskā aizpilde lapas ielādes laikā var tikt ļaunprātīgi izmantota.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Pārveidotās vai neuzticamās tīmekļvietnēs automātiskā aizpilde lapas ielādes laikā var tikt ļaunprātīgi izmantota." }, @@ -1852,7 +1843,7 @@ "message": "Drošās piezīmes" }, "sshKeys": { - "message": "SSH Keys" + "message": "SSH atslēgas" }, "clear": { "message": "Notīrīt", @@ -2917,7 +2908,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Jāizmanto $RECOMMENDED$ vai vairāk vārdu, lai aizveidotu spēcīgu parles vārdkopu.", + "message": " Jāizmanto $RECOMMENDED$ vai vairāk vārdu, lai aizveidotu spēcīgu paroles vārdkopu.", "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": { @@ -3288,16 +3279,16 @@ "message": "Atver jaunā logā" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Atcerēties šo ierīci, lai nākotnes pieteikšanos padarītu plūdenāku" }, "deviceApprovalRequired": { "message": "Nepieciešams ierīces apstiprinājums. Zemāk jāatlasa apstiprinājuma iespēja:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Nepieciešama ierīces apstiprināšana" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Zemāk jāatlasa apstiprināšnas iespēja" }, "rememberThisDevice": { "message": "Atcerēties šo ierīci" @@ -3373,7 +3364,7 @@ "message": "Trūkst lietotāja e-pasta adreses" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktīva lietotāja e-pasta adrese netika atrasta. Notiek atteikšanās." }, "deviceTrusted": { "message": "Ierīce ir uzticama" @@ -3812,7 +3803,7 @@ "message": "Piekļūst" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Pieteicies." }, "passkeyNotCopied": { "message": "Piekļuves atslēga netiks ievietota starpliktuvē" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Paplašinājuma platums" + }, + "wide": { + "message": "Plats" + }, + "extraWide": { + "message": "Ļoti plats" } } diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index ba6a3cc9f2..f5a2e244fc 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -1125,6 +1125,10 @@ "message": "മുന്നറിയിപ്പ്", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "ഒരു ലോഗിൻ ഫോം കണ്ടെത്തിയാൽ, വെബ് പേജ് ലോഡുചെയ്യുമ്പോൾ യാന്ത്രികമായി ഒരു സ്വയം പൂരിപ്പിക്കൽ നടത്തുക." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 02e1fa16b7..bd7a1c755e 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 0ae9d0617f..6f26673abc 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index bf1312feb2..027923d050 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -1125,6 +1125,10 @@ "message": "ADVARSEL", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Bekreft eksport av hvelvet" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Dersom et innloggingskjema blir oppdaget, utfør automatisk en auto-utfylling når nettstedet lastes inn." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Kompromitterte eller upålitelige nettsider kan utnytte auto-utfylling når du laster inn siden." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 0ae9d0617f..6f26673abc 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 5fddc8f069..6ed6627330 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -1125,6 +1125,10 @@ "message": "WAARSCHUWING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Waarschuwing", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Kluisexport bevestigen" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Als een inlogformulier wordt gedetecteerd, dan worden de inloggegevens automatisch ingevuld." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Waarschuwing:$CLOSETAG$ Geconpromitteerde of niet-vertrouwde websites kunnen het automatische invullen bij het laden van de pagina misbruiken.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Gehackte of onbetrouwbare websites kunnen auto-invullen tijdens het laden van de pagina misbruiken." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extensiebreedte" + }, + "wide": { + "message": "Breed" + }, + "extraWide": { + "message": "Extra breed" } } diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 0ae9d0617f..6f26673abc 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 0ae9d0617f..6f26673abc 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index bdfad0f7a7..dc5b84eb6e 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1125,6 +1125,10 @@ "message": "UWAGA", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Potwierdź eksportowanie sejfu" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Jeśli zostanie wykryty formularz logowania, automatycznie uzupełnij dane logowania po załadowaniu strony." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Ostrzeżenie:$CLOSETAG$ Niebezpieczne witryny są w stanie wykorzystać autouzupełnianie przy wczytywaniu strony.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Zaatakowane lub niezaufane witryny internetowe mogą wykorzystać funkcję autouzupełniania podczas wczytywania strony, aby wyrządzić szkody." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index d9ee8086a5..79c87bbda0 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -1125,6 +1125,10 @@ "message": "AVISO", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirmar Exportação do Cofre" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Se um formulário de login for detectado, realizar automaticamente um auto-preenchimento quando a página web carregar." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Aviso:$CLOSETAG$ Comprometido ou sites não confiáveis podem explorar o autopreenchimento ao carregar a página.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Sites comprometidos ou não confiáveis podem tomar vantagem do autopreenchimento ao carregar a página." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index f2498bdfff..46d0fee21c 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -1125,6 +1125,10 @@ "message": "AVISO", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Aviso", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirmar a exportação do cofre" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Se for detetado um formulário de início de sessão, o preenchimento automático é efetuado quando a página Web é carregada." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Aviso:$CLOSETAG$ Aviso: Os sites comprometidos ou não confiáveis podem explorar o preenchimento automático ao carregar a página.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Os sites comprometidos ou não confiáveis podem explorar o preenchimento automático ao carregar a página." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Largura da extensão" + }, + "wide": { + "message": "Ampla" + }, + "extraWide": { + "message": "Muito ampla" } } diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 980341b49f..c2f145087c 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -1125,6 +1125,10 @@ "message": "AVERTISMENT", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirmare export seif" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Dacă se detectează un formular de autentificare, completați-l automat la încărcarea paginii web." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Site-urile web compromise sau nesigure pot profita de auto-completarea la încărcare." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 87b523cd89..7eb6d55cf5 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -1125,6 +1125,10 @@ "message": "ВНИМАНИЕ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Предупреждение", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Подтвердить экспорт хранилища" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Если обнаружена форма входа, автозаполнение выполняется при загрузке веб-страницы." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Предупреждение:$CLOSETAG$ взломанные или недоверенные сайты могут использовать автозаполнение при загрузке страницы.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Взломанные или недоверенные сайты могут внедрить вредоносный код во время автозаполнения при загрузке страницы." }, @@ -3288,16 +3279,16 @@ "message": "Откроется в новом окне" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Запомнить это устройство, чтобы в будущем авторизовываться быстрее" }, "deviceApprovalRequired": { "message": "Требуется одобрение устройства. Выберите вариант ниже:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Требуется подтверждение устройства" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Выберите вариант подтверждения ниже" }, "rememberThisDevice": { "message": "Запомнить это устройство" @@ -3373,7 +3364,7 @@ "message": "Отсутствует email пользователя" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Email активного пользователя не найден. Разлогиниваем." }, "deviceTrusted": { "message": "Доверенное устройство" @@ -3812,7 +3803,7 @@ "message": "Доступ" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Выполнен вход!" }, "passkeyNotCopied": { "message": "Passkey не будет скопирован" @@ -4662,7 +4653,7 @@ "message": "Теперь автозаполнение и поиск на вкладке Хранилище стали проще и интуитивно понятнее, чем когда-либо. Осмотритесь!" }, "accountActions": { - "message": "Действия с аккаунтом" + "message": "Действия аккаунта" }, "showNumberOfAutofillSuggestions": { "message": "Показывать количество вариантов автозаполнения логина на значке расширения" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Ширина расширения" + }, + "wide": { + "message": "Широкое" + }, + "extraWide": { + "message": "Очень широкое" } } diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 4d1eeebc1f..42be772294 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -1125,6 +1125,10 @@ "message": "අවවාදයයි", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "සුරක්ෂිතාගාරය අපනයන තහවුරු" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "පිවිසුම් පෝරමයක් අනාවරණය කර ඇත්නම්, වෙබ් පිටුව පැටවුම් කරන විට ස්වයංක්රීයව ස්වයංක්රීයව පිරවීම සිදු කරන්න." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index d44be0f59c..9a720ea289 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -1125,6 +1125,10 @@ "message": "UPOZORNENIE", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Upozornenie", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Potvrdiť export trezoru" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Ak je detekovaný prihlasovací formulár, automaticky vykonať vypĺňanie pri načítaní stránky." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Upozornenie:$CLOSETAG$ Kompromitované alebo nedôveryhodné webové stránky môžu využívať automatické vypĺňanie pri načítaní stránky.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Skompromitované alebo nedôveryhodné stránky môžu pri svojom načítaní zneužiť automatické dopĺňanie." }, @@ -3288,16 +3279,16 @@ "message": "Otvárať v novom okne" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Zapamätať si toto zariadenie, pre budúce bezproblémové prihlásenie" }, "deviceApprovalRequired": { "message": "Vyžaduje sa schválenie zariadenia. Vyberte možnosť schválenia nižšie:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Vyžaduje sa schválenie zariadenia" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Vyberte možnosť schválenia nižšie" }, "rememberThisDevice": { "message": "Zapamätať si toto zariadenie" @@ -3373,7 +3364,7 @@ "message": "Chýba e-mail používateľa" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "E-mail aktívneho používateľa sa nenašiel. Odhlasuje sa." }, "deviceTrusted": { "message": "Dôveryhodné zariadenie" @@ -3812,7 +3803,7 @@ "message": "Pristupovanie" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Prihlásený!" }, "passkeyNotCopied": { "message": "Prístupový kód sa neskopíruje" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Šírka rozšírenia" + }, + "wide": { + "message": "Široké" + }, + "extraWide": { + "message": "Extra široké" } } diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 2ec14a1c5a..b5dadd4340 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -1125,6 +1125,10 @@ "message": "OPOZORILO", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Potrdite izvoz trezorja" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Če Bitwarden na strani zazna prijavni obrazec, ga samodejno izpolni takoj, ko se stran naloži." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Spletne strani, ki jim ne zaupate ali v katere so vdrli, lahko zlorabijo samodejno izpolnjevanje ob naložitvi strani." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 112ba3ca3f..e7759897a8 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -1125,6 +1125,10 @@ "message": "УПОЗОРЕЊЕ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Потврдите извоз сефа" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Ако се открије образац за пријаву, извршите аутоматско попуњавање када се веб страница учита." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Пажња:$CLOSETAG$ Компромитоване или непоуздане веб локације могу да искористе ауто-попуњавање при учитавању странице.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Компромитоване или непоуздане веб локације могу да искористе ауто-пуњење при учитавању странице." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 96bcac046f..2bbf1e133e 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -1125,6 +1125,10 @@ "message": "VARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Bekräfta export av valv" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Utför automatisk ifyllnad om ett inloggningsformulär upptäcks när webbsidan laddas." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Komprometterade eller ej betrodda webbplatser kan utnyttja automatisk ifyllnad vid sidladdning." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 0ae9d0617f..6f26673abc 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -1125,6 +1125,10 @@ "message": "WARNING", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Confirm vault export" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 540513662f..76d3e0cf54 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -1125,6 +1125,10 @@ "message": "คำเตือน", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "ยืนยันการส่งออกตู้นิรภัย" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "If a login form is detected, autofill when the web page loads." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Compromised or untrusted websites can exploit autofill on page load." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index eebefd2bd2..1d54e9865b 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -1125,6 +1125,10 @@ "message": "UYARI", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Uyarı", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Kasayı dışa aktarmayı onaylayın" }, @@ -1274,7 +1278,7 @@ "message": "Bitwarden'ı desteklediğiniz için teşekkür ederiz." }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "Premium'a yükseltin ve şunları alın:" }, "premiumPrice": { "message": "Bunların hepsi sadece yılda $PRICE$!", @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Sayfa yüklendiğinde giriş formu tespit edilirse otomatik olarak formu doldur." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Uyarı:$CLOSETAG$ Ele geçirilmiş veya güvenilmeyen web siteleri sayfa yüklenirken otomatik doldurmayı suistimal edebilir.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Ele geçirilmiş veya güvenilmeyen web siteleri sayfa yüklenirken otomatik doldurmayı suistimal edebilir." }, @@ -3288,16 +3279,16 @@ "message": "Yeni pencerede açılır" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Sonraki girişleri kolaylaştırmak için bu cihazı hatırla" }, "deviceApprovalRequired": { "message": "Cihaz onayı gerekiyor. Lütfen onay yönteminizi seçin:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Cihazı onaylamanız gerekiyor" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Aşağıdan bir onay yöntemi seçin" }, "rememberThisDevice": { "message": "Bu cihazı hatırla" @@ -3373,7 +3364,7 @@ "message": "Kullanıcının e-postası eksik" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktif kullanıcı e-postası bulunamadı. Çıkış yapılıyor." }, "deviceTrusted": { "message": "Cihaza güvenildi" @@ -3809,10 +3800,10 @@ "message": "Geçiş anahtarı" }, "accessing": { - "message": "Accessing" + "message": "Erişim" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Giriş yapıldı!" }, "passkeyNotCopied": { "message": "Geçiş anahtarı kopyalanmayacak" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Uzantı genişliği" + }, + "wide": { + "message": "Geniş" + }, + "extraWide": { + "message": "Ekstra geniş" } } diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index 914541bb4a..3ffc1f375f 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -1125,6 +1125,10 @@ "message": "ПОПЕРЕДЖЕННЯ", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Підтвердити експорт сховища" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Якщо виявлено форму входу, автоматично заповнювати її під час завантаження вебсторінки." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Обережно!$CLOSETAG$ Скомпрометовані або ненадійні вебсайти можуть використати функцію автозаповнення під час завантаження сторінки для завдання шкоди.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Скомпрометовані або ненадійні вебсайти можуть використати функцію автозаповнення під час завантаження сторінки для завдання шкоди." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Бета" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index 16120158b0..88adbc3a53 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -1125,6 +1125,10 @@ "message": "CẢNH BÁO", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "Warning", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "Xác nhận xuất kho" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "Nếu phát hiện biểu mẫu đăng nhập, thực hiện tự động điền khi trang web tải xong." }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Cảnh báo:$CLOSETAG$ Các trang web bị xâm phạm hoặc không đáng tin cậy có thể lợi dụng tính năng tự động điền khi trang web được tải.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "Các trang web bị xâm phạm hoặc không đáng tin cậy có thể khai thác tính năng tự động điền khi tải trang." }, @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 67211476ae..05b71990c1 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -1125,6 +1125,10 @@ "message": "警告", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "警告", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "确认密码库导出" }, @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "网页加载时如果检测到登录表单,则执行自动填充。" }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$警告:$CLOSETAG$不完整或不信任的网站可以利用页面加载时的自动填充功能。", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "不完整或不信任的网站可以利用页面加载时的自动填充功能。" }, @@ -1852,7 +1843,7 @@ "message": "安全笔记" }, "sshKeys": { - "message": "SSH Keys" + "message": "SSH 密钥" }, "clear": { "message": "清除", @@ -3288,16 +3279,16 @@ "message": "在新窗口中打开" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "记住此设备以便将来无缝登录" }, "deviceApprovalRequired": { "message": "需要设备批准。请在下面选择一个批准选项:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "需要设备批准" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "在下方选择一个批准选项" }, "rememberThisDevice": { "message": "记住此设备" @@ -3373,7 +3364,7 @@ "message": "缺少用户电子邮件" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "未找到活动的用户电子邮件。您将被注销。" }, "deviceTrusted": { "message": "设备已信任" @@ -3812,7 +3803,7 @@ "message": "正在访问" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "已登录!" }, "passkeyNotCopied": { "message": "通行密钥不会被复制" @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta 版" + }, + "extensionWidth": { + "message": "扩展宽度" + }, + "wide": { + "message": "宽" + }, + "extraWide": { + "message": "超宽" } } diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index db169e503b..fd71e2de56 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -23,10 +23,10 @@ "message": "New to Bitwarden?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "使用密碼金鑰登入" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "使用單一登入" }, "welcomeBack": { "message": "Welcome back" @@ -241,7 +241,7 @@ "message": "請求密碼提示" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "輸入您的帳號電子郵件,您的密碼提示會傳送給您" + "message": "輸入您帳戶的電子郵件,您的密碼提示會傳送給您" }, "passwordHint": { "message": "密碼提示" @@ -274,7 +274,7 @@ "message": "變更主密碼" }, "continueToWebApp": { - "message": "接下來造訪 Web App 嗎?" + "message": "接下來造訪網頁 App 嗎?" }, "continueToWebAppDesc": { "message": "在 Web 應用程式上探索 Bitwarden 帳戶的更多功能。" @@ -327,7 +327,7 @@ "message": "Bitwarden 驗證器" }, "continueToAuthenticatorPageDesc": { - "message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website" + "message": "您可以使用 Bitwarden 驗證器儲存驗證器金鑰,並為兩步驟驗證流程產生 TOTP 代碼。前往 bitwarden.com 網站以了解更多資訊。" }, "bitwardenSecretsManager": { "message": "Bitwarden Secrets Manager" @@ -828,13 +828,13 @@ "message": "從目前網頁掃描驗證器二維碼" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "無縫兩步驟驗證" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden 可以儲存並填入兩步驟驗證碼。複製金鑰並貼上到此欄位。" }, "totpHelperWithCapture": { - "message": "Bitwarden can store and fill 2-step verification codes. Select the camera icon to take a screenshot of this website's authenticator QR code, or copy and paste the key into this field." + "message": "Bitwarden 可以儲存並填入兩步驟驗證碼。選擇相機圖示來截取此網站的驗證器QR code,或手動複製金鑰並貼上到此欄位。" }, "learnMoreAboutAuthenticators": { "message": "Learn more about authenticators" @@ -894,7 +894,7 @@ "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "前往網頁 App 嗎?" }, "editedFolder": { "message": "資料夾已儲存" @@ -990,7 +990,7 @@ "message": "如果在您的密碼庫中找不到項目,則詢問是否新增項目。適用於所有已登入的帳戶。" }, "showCardsInVaultView": { - "message": "Show cards as Autofill suggestions on Vault view" + "message": "在密碼庫介面中顯示支付卡自動填入建議" }, "showCardsCurrentTab": { "message": "於分頁頁面顯示支付卡" @@ -999,7 +999,7 @@ "message": "於分頁頁面顯示信用卡以便於自動填入。" }, "showIdentitiesInVaultView": { - "message": "Show identities as Autofill suggestions on Vault view" + "message": "在密碼庫介面中顯示身分自動填入建議" }, "showIdentitiesCurrentTab": { "message": "於分頁頁面顯示身分" @@ -1089,7 +1089,7 @@ "description": "'Solarized' is a noun and the name of a color scheme. It should not be translated." }, "exportFrom": { - "message": "Export from" + "message": "匯出自" }, "exportVault": { "message": "匯出密碼庫" @@ -1098,7 +1098,7 @@ "message": "檔案格式" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "此檔案匯出將受密碼保護,需要檔案密碼才能解密。" }, "filePassword": { "message": "檔案密碼" @@ -1107,24 +1107,28 @@ "message": "此密碼將用於匯出和匯入此檔案" }, "accountRestrictedOptionDescription": { - "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account." + "message": "使用衍生自您帳戶的使用者名稱與主密碼的加密金鑰,加密此匯出檔案,並限制只能匯入到目前的 Bitwarden 帳戶。" }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "設定一組檔案密碼來加密匯出的資料,並使用此密碼解密以匯入至任意 Bitwarden 帳戶。" }, "exportTypeHeading": { "message": "匯出類型" }, "accountRestricted": { - "message": "Account restricted" + "message": "帳號已受限制" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "「檔案密碼」與「確認檔案密碼」不一致。" }, "warning": { "message": "警告", "description": "WARNING (should stay in capitalized letters if the language permits)" }, + "warningCapitalized": { + "message": "警告", + "description": "Warning (should maintain locale-relevant capitalization)" + }, "confirmVaultExport": { "message": "確認匯出密碼庫" }, @@ -1144,7 +1148,7 @@ "message": "已共用" }, "bitwardenForBusinessPageDesc": { - "message": "Bitwarden for Business allows you to share your vault items with others by using an organization. Learn more on the bitwarden.com website." + "message": "Bitwarden 可讓您透過組織與其他人共用您的密碼庫項目。請造訪 bitwarden.com 網站以了解更多資訊。" }, "moveToOrganization": { "message": "移動至組織 " @@ -1205,7 +1209,7 @@ "message": "檔案" }, "fileToShare": { - "message": "File to share" + "message": "要分享的文件" }, "selectFile": { "message": "選取檔案" @@ -1241,7 +1245,7 @@ "message": "用於檔案附件的 1 GB 加密儲存空間。" }, "premiumSignUpEmergency": { - "message": "Emergency access." + "message": "緊急存取" }, "premiumSignUpTwoStepOptions": { "message": "專有的兩步驟登入選項,例如 YubiKey 和 Duo。" @@ -1265,7 +1269,7 @@ "message": "您可以在 bitwarden.com 網頁版密碼庫購買進階會員資格。現在要前往嗎?" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "您可以在 Bitwarden 網頁 App 的帳號設定中購買進階版。" }, "premiumCurrentMember": { "message": "您目前為進階會員!" @@ -1274,7 +1278,7 @@ "message": "感謝您支持 Bitwarden 。" }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "升級到進階版並接收:" }, "premiumPrice": { "message": "每年只需 $PRICE$!", @@ -1286,7 +1290,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "每年只需 $PRICE$!", "placeholders": { "price": { "content": "$1", @@ -1503,19 +1507,6 @@ "enableAutoFillOnPageLoadDesc": { "message": "網頁載入時如果偵測到登入表單,則執行自動填入。" }, - "autofillOnPageLoadWarning": { - "message": "$OPENTAG$Warning:$CLOSETAG$ Compromised or untrusted websites can exploit autofill on page load.", - "placeholders": { - "openTag": { - "content": "$1", - "example": "" - }, - "closeTag": { - "content": "$2", - "example": "" - } - } - }, "experimentalFeature": { "message": "被入侵或不被信任的網站,可能會濫用頁面載入的自動填入功能。" }, @@ -2297,7 +2288,7 @@ "message": "Please unlock this user in the desktop application and try again." }, "biometricsNotAvailableTitle": { - "message": "Biometric unlock unavailable" + "message": "生物辨識解鎖不可用" }, "biometricsNotAvailableDesc": { "message": "Biometric unlock is currently unavailable. Please try again later." @@ -2330,7 +2321,7 @@ "message": "某個組織原則已禁止您將項目匯入至您的個人密碼庫。" }, "domainsTitle": { - "message": "Domains", + "message": "網域", "description": "A category title describing the concept of web domains" }, "excludedDomains": { @@ -2343,7 +2334,7 @@ "message": "對於所有已登入的帳戶,Bitwarden 不會詢問是否儲存這些網域的登入資訊。您必須重新整理頁面變更才會生效。" }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "網站 $number$ (URI)", "placeholders": { "number": { "content": "$1", @@ -2361,17 +2352,17 @@ } }, "excludedDomainsSavedSuccess": { - "message": "Excluded domain changes saved" + "message": "例外網域更改已儲存" }, "limitSendViews": { - "message": "Limit views" + "message": "限制查看" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "在達到限額後,沒有人能查看此 Send。", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "剩餘 $ACCESSCOUNT$ 次查看次數", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2385,7 +2376,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDetails": { - "message": "Send details", + "message": "Send 詳細資訊", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "searchSends": { @@ -2400,7 +2391,7 @@ "message": "文字" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "要分享的文字" }, "sendTypeFile": { "message": "檔案" @@ -2410,7 +2401,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "默認隱藏文字" }, "maxAccessCountReached": { "message": "已達最大存取次數", @@ -2426,7 +2417,7 @@ "message": "密碼保護" }, "copyLink": { - "message": "Copy link" + "message": "複製連結" }, "copySendLink": { "message": "複製 Send 連結", @@ -2464,7 +2455,7 @@ "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": "您確定要永久刪除此 Send 嗎?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { @@ -2490,7 +2481,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "此 Send 將在指定的日期後被永久刪除。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -2527,7 +2518,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "新增一個用於收件人存取此 Send 的可選密碼。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendNotesDesc": { @@ -2572,15 +2563,15 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSendSuccessfully": { - "message": "Send created successfully!", + "message": "Send 創建成功!", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHoursSingle": { - "message": "The Send will be available to anyone with the link for the next 1 hour.", + "message": "在接下來的 1 小時內,任何人都可以透過連結訪問此 Send。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInHours": { - "message": "The Send will be available to anyone with the link for the next $HOURS$ hours.", + "message": "在接下來的 $HOURS$ 小時內,任何人都可以透過連結訪問此 Send。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "hours": { @@ -2590,11 +2581,11 @@ } }, "sendExpiresInDaysSingle": { - "message": "The Send will be available to anyone with the link for the next 1 day.", + "message": "在接下來的 1 天內,任何人都可以透過連結訪問此 Send。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendExpiresInDays": { - "message": "The Send will be available to anyone with the link for the next $DAYS$ days.", + "message": "在接下來的 $DAYS$ 天內,任何人都可以透過連結訪問此 Send。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "days": { @@ -2604,7 +2595,7 @@ } }, "sendLinkCopied": { - "message": "Send link copied", + "message": "已複製 Send 連結", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { @@ -2612,11 +2603,11 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogText": { - "message": "Pop out extension?", + "message": "彈出擴充程式?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendFilePopoutDialogDesc": { - "message": "To create a file Send, you need to pop out the extension to a new window.", + "message": "要建立檔案 Send,您需要彈出擴充程式到新視窗。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -2629,7 +2620,7 @@ "message": "要使用 Safari 來選擇檔案,請點選此橫幅彈出至新視窗。" }, "popOut": { - "message": "Pop out" + "message": "彈出" }, "sendFileCalloutHeader": { "message": "在開始之前" @@ -2665,7 +2656,7 @@ "message": "對收件人隱藏我的電子郵件地址。" }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "對查看者隱藏您的電子郵件地址。" }, "sendOptionsPolicyInEffect": { "message": "一個或多個組織原則正影響您的 Send 選項。" @@ -2683,7 +2674,7 @@ "message": "需要驗證電子郵件" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "電子郵件已驗證" }, "emailVerificationRequiredDesc": { "message": "您必須驗證您的電子郵件才能使用此功能。您可以在網頁密碼庫裡驗證您的電子郵件。" @@ -2701,7 +2692,7 @@ "message": "您的主密碼不符合一個或多個組織政策規定。您必須立即更新您的主密碼才能存取密碼庫。進行此動作將登出您目前的工作階段,需要您重新登入。其他裝置上的工作階段可能持續長達一小時。" }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "您的組織停用了信任裝置加密。若要存取您的密碼庫,請設定主密碼。" }, "resetPasswordPolicyAutoEnroll": { "message": "自動註冊" @@ -2725,7 +2716,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { - "message": "out of $TOTAL$", + "message": "$TOTAL$ 不足", "placeholders": { "total": { "content": "$1", @@ -2744,7 +2735,7 @@ "message": "分鐘" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "企業政策已套用至您的逾時選項中" }, "vaultTimeoutPolicyInEffect": { "message": "您的組織政策已限定您密碼庫逾時的時間長度。密碼庫逾時時間最高可以設定到 $HOURS$ 小時 $MINUTES$ 分鐘。", @@ -2760,7 +2751,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "最多 $HOURS$ 小時 $MINUTES$ 分鐘", "placeholders": { "hours": { "content": "$1", @@ -2773,7 +2764,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Timeout exceeds the restriction set by your organization: $HOURS$ hour(s) and $MINUTES$ minute(s) maximum", + "message": "逾時時間超出了您組織設定的此限制:最多 $HOURS$ 小時 $MINUTES$ 分鐘", "placeholders": { "hours": { "content": "$1", @@ -2869,10 +2860,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "正在匯出組織密碼庫" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "只會匯出與 $ORGANIZATION$ 相關的組織密碼庫資料。不包括個人密碼庫和其他組織中的項目。", "placeholders": { "organization": { "content": "$1", @@ -2890,10 +2881,10 @@ "message": "產生使用者名稱" }, "generateEmail": { - "message": "Generate email" + "message": "生成電子郵件" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "數值必須在 $MIN$ 和 $MAX$ 之間。", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2907,7 +2898,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " 使用 $RECOMMENDED$ 或更多個字元產生更強的密碼。", "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": { @@ -2917,7 +2908,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " 使用 $RECOMMENDED$ 或更多個單字產生強的密碼短語。", "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": { @@ -2967,15 +2958,15 @@ "message": "使用外部轉寄服務產生一個電子郵件別名。" }, "forwarderDomainName": { - "message": "Email domain", + "message": "電子郵件網域", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "選擇一個所選服務支援的網域", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "$SERVICENAME$ 錯誤:$ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -2989,7 +2980,7 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "由 Bitwarden 生成。", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { @@ -3824,7 +3815,7 @@ "message": "發起站點需要驗證。沒有主密碼的帳戶尚未開通此功能。" }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "使用密碼金鑰登入?" }, "passkeyAlreadyExists": { "message": "用於這個應用程式的密碼金鑰已經存在。" @@ -3839,7 +3830,7 @@ "message": "No matching logins for this site" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "搜尋或將密碼金鑰儲存為新的登入資訊" }, "confirm": { "message": "確認" @@ -3851,10 +3842,10 @@ "message": "將密碼金鑰儲存為新的登入資訊" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "選擇一個用於儲存此密碼金鑰的登入資訊" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "選擇一個用於登入的密碼金鑰" }, "passkeyItem": { "message": "密碼金鑰項目" @@ -4064,17 +4055,17 @@ "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "保存憑證時發生錯誤。檢查控制台以了解詳細資訊。", "description": "Notification message for when saving credentials has failed." }, "success": { "message": "Success" }, "removePasskey": { - "message": "Remove passkey" + "message": "移除密碼金鑰" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "密碼金鑰已移除" }, "autofillSuggestions": { "message": "Autofill suggestions" @@ -4221,7 +4212,7 @@ "message": "Items with no folder" }, "itemDetails": { - "message": "Item details" + "message": "項目詳細資訊" }, "itemName": { "message": "Item name" @@ -4297,7 +4288,7 @@ "message": "Are you sure you want to permanently delete this attachment?" }, "premium": { - "message": "Premium" + "message": "進階版" }, "freeOrgsCannotUseAttachments": { "message": "Free organizations cannot use attachments" @@ -4321,7 +4312,7 @@ } }, "personalDetails": { - "message": "Personal details" + "message": "個人資訊" }, "identification": { "message": "Identification" @@ -4411,10 +4402,10 @@ "message": "If you've renewed it, update the card's information" }, "cardDetails": { - "message": "Card details" + "message": "信用卡詳細資料" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "$BRAND$ 詳細資訊", "placeholders": { "brand": { "content": "$1", @@ -4438,7 +4429,7 @@ "message": "Data" }, "passkeys": { - "message": "Passkeys", + "message": "密碼金鑰", "description": "A section header for a list of passkeys." }, "passwords": { @@ -4446,7 +4437,7 @@ "description": "A section header for a list of passwords." }, "logInWithPasskeyAriaLabel": { - "message": "Log in with passkey", + "message": "使用密碼金鑰登入", "description": "ARIA label for the inline menu button that logs in with a passkey." }, "assign": { @@ -4897,5 +4888,14 @@ }, "beta": { "message": "Beta" + }, + "extensionWidth": { + "message": "Extension width" + }, + "wide": { + "message": "Wide" + }, + "extraWide": { + "message": "Extra wide" } } diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html index e9c9fd9c75..18c6f51533 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill.component.html @@ -160,7 +160,10 @@ {{ "enableAutoFillOnPageLoadDesc" | i18n }} - + {{ "warningCapitalized" | i18n }}: {{ "experimentalFeature" | i18n }} { }); describe("collectPageDetailsFromTab$", () => { - const tab = mock({ id: 1 }); + const tab = mock({ id: 1, url: "https://www.example.com" }); const messages = new Subject(); function mockCollectPageDetailsResponseMessage( @@ -165,11 +165,16 @@ describe("AutofillService", () => { it("sends a `collectPageDetails` message to the passed tab", () => { autofillService.collectPageDetailsFromTab$(tab); - expect(BrowserApi.tabSendMessage).toHaveBeenCalledWith(tab, { - command: AutofillMessageCommand.collectPageDetails, - sender: AutofillMessageSender.collectPageDetailsFromTabObservable, + expect(BrowserApi.tabSendMessage).toHaveBeenCalledWith( tab, - }); + { + command: AutofillMessageCommand.collectPageDetails, + sender: AutofillMessageSender.collectPageDetailsFromTabObservable, + tab, + }, + null, + true, + ); }); it("builds an array of page details from received `collectPageDetailsResponse` messages", async () => { @@ -218,6 +223,41 @@ describe("AutofillService", () => { expect(tracker.emissions[1]).toBeUndefined(); }); + + it("returns an empty array when the tab.url is empty", async () => { + const tracker = subscribeTo(autofillService.collectPageDetailsFromTab$({ ...tab, url: "" })); + + await tracker.pauseUntilReceived(1); + + expect(tracker.emissions[0]).toEqual([]); + }); + + it("returns an empty array when the `BrowserApi.tabSendMessage` throws an error", async () => { + (BrowserApi.tabSendMessage as jest.Mock).mockRejectedValueOnce(undefined); + + const tracker = subscribeTo(autofillService.collectPageDetailsFromTab$(tab)); + + await tracker.pauseUntilReceived(1); + + expect(tracker.emissions[0]).toEqual([]); + }); + + ["moz-extension://", "chrome-extension://", "safari-web-extension://"].forEach( + (extensionPrefix) => { + it(`returns an empty array when the tab.url starts with ${extensionPrefix}`, async () => { + const tracker = subscribeTo( + autofillService.collectPageDetailsFromTab$({ + ...tab, + url: `${extensionPrefix}/3e42342/popup/index.html`, + }), + ); + + await tracker.pauseUntilReceived(1); + + expect(tracker.emissions[0]).toEqual([]); + }); + }, + ); }); describe("loadAutofillScriptsOnInstall", () => { diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index 24054794b6..eaaf23ca84 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -1,4 +1,4 @@ -import { filter, firstValueFrom, Observable, scan, startWith } from "rxjs"; +import { filter, firstValueFrom, merge, Observable, ReplaySubject, scan, startWith } from "rxjs"; import { pairwise } from "rxjs/operators"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; @@ -91,6 +91,9 @@ export default class AutofillService implements AutofillServiceInterface { * @param tab The tab to collect page details from */ collectPageDetailsFromTab$(tab: chrome.tabs.Tab): Observable { + /** Replay Subject that can be utilized when `messages$` may not emit the page details. */ + const pageDetailsFallback$ = new ReplaySubject<[]>(1); + const pageDetailsFromTab$ = this.messageListener .messages$(COLLECT_PAGE_DETAILS_RESPONSE_COMMAND) .pipe( @@ -112,13 +115,35 @@ export default class AutofillService implements AutofillServiceInterface { ), ); - void BrowserApi.tabSendMessage(tab, { - tab: tab, - command: AutofillMessageCommand.collectPageDetails, - sender: AutofillMessageSender.collectPageDetailsFromTabObservable, + void BrowserApi.tabSendMessage( + tab, + { + tab: tab, + command: AutofillMessageCommand.collectPageDetails, + sender: AutofillMessageSender.collectPageDetailsFromTabObservable, + }, + null, + true, + ).catch(() => { + // When `tabSendMessage` throws an error the `pageDetailsFromTab$` will not emit, + // fallback to an empty array + pageDetailsFallback$.next([]); }); - return pageDetailsFromTab$; + // Fallback to empty array when: + // - In Safari, `tabSendMessage` doesn't throw an error for this case. + // - When opening the extension directly via the URL, `tabSendMessage` doesn't always respond nor throw an error in FireFox. + // Adding checks for the major 3 browsers here to be safe. + const urlHasBrowserProtocol = [ + "moz-extension://", + "chrome-extension://", + "safari-web-extension://", + ].some((protocol) => tab.url.startsWith(protocol)); + if (!tab.url || urlHasBrowserProtocol) { + pageDetailsFallback$.next([]); + } + + return merge(pageDetailsFromTab$, pageDetailsFallback$); } /** diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 764304f4ff..b66f2457b2 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -725,7 +725,7 @@ export default class MainBackground { ); const sdkClientFactory = flagEnabled("sdk") - ? new BrowserSdkClientFactory() + ? new BrowserSdkClientFactory(this.logService) : new NoopSdkClientFactory(); this.sdkService = new DefaultSdkService( sdkClientFactory, diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index e81409e6e2..0ccc75cd5d 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.11.2", + "version": "2024.12.0", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index 1ece562622..32f58b0cc5 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -3,7 +3,7 @@ "minimum_chrome_version": "102.0", "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.11.2", + "version": "2024.12.0", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/browser/src/platform/browser/browser-api.ts b/apps/browser/src/platform/browser/browser-api.ts index 072ef74004..850e14302d 100644 --- a/apps/browser/src/platform/browser/browser-api.ts +++ b/apps/browser/src/platform/browser/browser-api.ts @@ -200,15 +200,17 @@ export class BrowserApi { tab: chrome.tabs.Tab, obj: T, options: chrome.tabs.MessageSendOptions = null, + rejectOnError = false, ): Promise { if (!tab || !tab.id) { return; } - return new Promise((resolve) => { + return new Promise((resolve, reject) => { chrome.tabs.sendMessage(tab.id, obj, options, (response) => { - if (chrome.runtime.lastError) { + if (chrome.runtime.lastError && rejectOnError) { // Some error happened + reject(); } resolve(response); }); diff --git a/apps/browser/src/platform/popup/browser-popup-utils.ts b/apps/browser/src/platform/popup/browser-popup-utils.ts index fb53d3451f..5459c0e220 100644 --- a/apps/browser/src/platform/popup/browser-popup-utils.ts +++ b/apps/browser/src/platform/popup/browser-popup-utils.ts @@ -1,6 +1,7 @@ import { BrowserApi } from "../browser/browser-api"; import { ScrollOptions } from "./abstractions/browser-popup-utils.abstractions"; +import { PopupWidthOptions } from "./layout/popup-width.service"; class BrowserPopupUtils { /** @@ -108,7 +109,10 @@ class BrowserPopupUtils { const defaultPopoutWindowOptions: chrome.windows.CreateData = { type: "popup", focused: true, - width: 380, + width: Math.max( + PopupWidthOptions.default, + typeof document === "undefined" ? PopupWidthOptions.default : document.body.clientWidth, + ), height: 630, }; const offsetRight = 15; diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index e80ac249ac..1aaea85e4a 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -514,3 +514,25 @@ export const TransparentHeader: Story = { `, }), }; + +export const WidthOptions: Story = { + render: (args) => ({ + props: args, + template: /* HTML */ ` +
+
Default:
+
+ +
+
Wide:
+
+ +
+
Extra wide:
+
+ +
+
+ `, + }), +}; diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html index 78b859f33b..a4ae3161b4 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html @@ -9,7 +9,7 @@
- + {{ "typeLogin" | i18n }} - + {{ "typeCard" | i18n }} - + {{ "typeIdentity" | i18n }} - + {{ "note" | i18n }} diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts index 6842f35ea6..b5dc2a2f03 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.spec.ts @@ -1,141 +1,163 @@ import { CommonModule } from "@angular/common"; import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { Router } from "@angular/router"; +import { ActivatedRoute, RouterLink } from "@angular/router"; +import { mock } from "jest-mock-extended"; -import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction"; +import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; -import { ButtonModule, DialogService, MenuModule } from "@bitwarden/components"; +import { ButtonModule, DialogService, MenuModule, NoItemsModule } from "@bitwarden/components"; import { BrowserApi } from "../../../../../platform/browser/browser-api"; import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; -import { AddEditQueryParams } from "../add-edit/add-edit-v2.component"; -import { AddEditFolderDialogComponent } from "../add-edit-folder-dialog/add-edit-folder-dialog.component"; import { NewItemDropdownV2Component, NewItemInitialValues } from "./new-item-dropdown-v2.component"; describe("NewItemDropdownV2Component", () => { let component: NewItemDropdownV2Component; let fixture: ComponentFixture; - const open = jest.fn(); - const navigate = jest.fn(); + let dialogServiceMock: jest.Mocked; + let browserApiMock: jest.Mocked; - jest - .spyOn(BrowserApi, "getTabFromCurrentWindow") - .mockResolvedValue({ url: "https://example.com" } as chrome.tabs.Tab); + const mockTab = { url: "https://example.com" }; + + beforeAll(() => { + jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(mockTab as chrome.tabs.Tab); + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(false); + jest.spyOn(Utils, "getHostname").mockReturnValue("example.com"); + }); beforeEach(async () => { - open.mockClear(); - navigate.mockClear(); + dialogServiceMock = mock(); + dialogServiceMock.open.mockClear(); + + const activatedRouteMock = { + snapshot: { paramMap: { get: jest.fn() } }, + }; + + const i18nServiceMock = mock(); + const folderServiceMock = mock(); + const folderApiServiceAbstractionMock = mock(); + const accountServiceMock = mock(); await TestBed.configureTestingModule({ - imports: [NewItemDropdownV2Component, MenuModule, ButtonModule, JslibModule, CommonModule], - providers: [ - { provide: I18nService, useValue: { t: (key: string) => key } }, - { provide: Router, useValue: { navigate } }, + imports: [ + CommonModule, + RouterLink, + ButtonModule, + MenuModule, + NoItemsModule, + NewItemDropdownV2Component, ], - }) - .overrideProvider(DialogService, { useValue: { open } }) - .compileComponents(); + providers: [ + { provide: DialogService, useValue: dialogServiceMock }, + { provide: I18nService, useValue: i18nServiceMock }, + { provide: ActivatedRoute, useValue: activatedRouteMock }, + { provide: BrowserApi, useValue: browserApiMock }, + { provide: FolderService, useValue: folderServiceMock }, + { provide: FolderApiServiceAbstraction, useValue: folderApiServiceAbstractionMock }, + { provide: AccountService, useValue: accountServiceMock }, + ], + }).compileComponents(); + }); + beforeEach(() => { fixture = TestBed.createComponent(NewItemDropdownV2Component); component = fixture.componentInstance; fixture.detectChanges(); }); - it("opens new folder dialog", () => { - component.openFolderDialog(); - - expect(open).toHaveBeenCalledWith(AddEditFolderDialogComponent); - }); - - describe("new item", () => { - const emptyParams: AddEditQueryParams = { - collectionId: undefined, - organizationId: undefined, - folderId: undefined, - }; - - beforeEach(() => { - jest.spyOn(component, "newItemNavigate"); - }); - - it("navigates to new login", async () => { - await component.newItemNavigate(CipherType.Login); - - expect(navigate).toHaveBeenCalledWith(["/add-cipher"], { - queryParams: { - type: CipherType.Login.toString(), - name: "example.com", - uri: "https://example.com", - ...emptyParams, - }, - }); - }); - - it("navigates to new card", async () => { - await component.newItemNavigate(CipherType.Card); - - expect(navigate).toHaveBeenCalledWith(["/add-cipher"], { - queryParams: { type: CipherType.Card.toString(), ...emptyParams }, - }); - }); - - it("navigates to new identity", async () => { - await component.newItemNavigate(CipherType.Identity); - - expect(navigate).toHaveBeenCalledWith(["/add-cipher"], { - queryParams: { type: CipherType.Identity.toString(), ...emptyParams }, - }); - }); - - it("navigates to new note", async () => { - await component.newItemNavigate(CipherType.SecureNote); - - expect(navigate).toHaveBeenCalledWith(["/add-cipher"], { - queryParams: { type: CipherType.SecureNote.toString(), ...emptyParams }, - }); - }); - - it("includes initial values", async () => { + describe("buildQueryParams", () => { + it("should build query params for a Login cipher when not popped out", async () => { + await component.ngOnInit(); component.initialValues = { folderId: "222-333-444", organizationId: "444-555-666", collectionId: "777-888-999", } as NewItemInitialValues; - await component.newItemNavigate(CipherType.Login); + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(false); + jest.spyOn(Utils, "getHostname").mockReturnValue("example.com"); - expect(navigate).toHaveBeenCalledWith(["/add-cipher"], { - queryParams: { - type: CipherType.Login.toString(), - folderId: "222-333-444", - organizationId: "444-555-666", - collectionId: "777-888-999", - uri: "https://example.com", - name: "example.com", - }, + const params = component.buildQueryParams(CipherType.Login); + + expect(params).toEqual({ + type: CipherType.Login.toString(), + collectionId: "777-888-999", + organizationId: "444-555-666", + folderId: "222-333-444", + uri: "https://example.com", + name: "example.com", }); }); - it("does not include name or uri when the extension is popped out", async () => { + it("should build query params for a Login cipher when popped out", () => { + component.initialValues = { + collectionId: "777-888-999", + } as NewItemInitialValues; + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(true); + const params = component.buildQueryParams(CipherType.Login); + + expect(params).toEqual({ + type: CipherType.Login.toString(), + collectionId: "777-888-999", + }); + }); + + it("should build query params for a secure note", () => { component.initialValues = { - folderId: "222-333-444", - organizationId: "444-555-666", collectionId: "777-888-999", } as NewItemInitialValues; - await component.newItemNavigate(CipherType.Login); + const params = component.buildQueryParams(CipherType.SecureNote); - expect(navigate).toHaveBeenCalledWith(["/add-cipher"], { - queryParams: { - type: CipherType.Login.toString(), - folderId: "222-333-444", - organizationId: "444-555-666", - collectionId: "777-888-999", - }, + expect(params).toEqual({ + type: CipherType.SecureNote.toString(), + collectionId: "777-888-999", + }); + }); + + it("should build query params for an Identity", () => { + component.initialValues = { + collectionId: "777-888-999", + } as NewItemInitialValues; + + const params = component.buildQueryParams(CipherType.Identity); + + expect(params).toEqual({ + type: CipherType.Identity.toString(), + collectionId: "777-888-999", + }); + }); + + it("should build query params for a Card", () => { + component.initialValues = { + collectionId: "777-888-999", + } as NewItemInitialValues; + + const params = component.buildQueryParams(CipherType.Card); + + expect(params).toEqual({ + type: CipherType.Card.toString(), + collectionId: "777-888-999", + }); + }); + + it("should build query params for a SshKey", () => { + component.initialValues = { + collectionId: "777-888-999", + } as NewItemInitialValues; + + const params = component.buildQueryParams(CipherType.SshKey); + + expect(params).toEqual({ + type: CipherType.SshKey.toString(), + collectionId: "777-888-999", }); }); }); diff --git a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts index a1d5cbd332..e2062101e1 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/new-item-dropdown/new-item-dropdown-v2.component.ts @@ -1,6 +1,6 @@ import { CommonModule } from "@angular/common"; -import { Component, Input } from "@angular/core"; -import { Router, RouterLink } from "@angular/router"; +import { Component, Input, OnInit } from "@angular/core"; +import { RouterLink } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -25,31 +25,31 @@ export interface NewItemInitialValues { standalone: true, imports: [NoItemsModule, JslibModule, CommonModule, ButtonModule, RouterLink, MenuModule], }) -export class NewItemDropdownV2Component { +export class NewItemDropdownV2Component implements OnInit { cipherType = CipherType; - + private tab?: chrome.tabs.Tab; /** * Optional initial values to pass to the add cipher form */ @Input() initialValues: NewItemInitialValues; - constructor( - private router: Router, - private dialogService: DialogService, - ) {} + constructor(private dialogService: DialogService) {} - private async buildQueryParams(type: CipherType): Promise { - const tab = await BrowserApi.getTabFromCurrentWindow(); + async ngOnInit() { + this.tab = await BrowserApi.getTabFromCurrentWindow(); + } + + buildQueryParams(type: CipherType): AddEditQueryParams { const poppedOut = BrowserPopupUtils.inPopout(window); const loginDetails: { uri?: string; name?: string } = {}; // When a Login Cipher is created and the extension is not popped out, // pass along the uri and name - if (!poppedOut && type === CipherType.Login && tab) { - loginDetails.uri = tab.url; - loginDetails.name = Utils.getHostname(tab.url); + if (!poppedOut && type === CipherType.Login && this.tab) { + loginDetails.uri = this.tab.url; + loginDetails.name = Utils.getHostname(this.tab.url); } return { @@ -61,10 +61,6 @@ export class NewItemDropdownV2Component { }; } - async newItemNavigate(type: CipherType) { - await this.router.navigate(["/add-cipher"], { queryParams: await this.buildQueryParams(type) }); - } - openFolderDialog() { this.dialogService.open(AddEditFolderDialogComponent); } diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html index 05deeec0d3..5f958433c6 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-header/vault-header-v2.component.html @@ -32,7 +32,5 @@ [open]="initialDisclosureVisibility$ | async" (openChange)="toggleFilters($event)" > -
- -
+ diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts index 36343d3a66..bc84dd337c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.spec.ts @@ -5,7 +5,12 @@ import { Subject } from "rxjs"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { AUTOFILL_ID } from "@bitwarden/common/autofill/constants"; +import { + AUTOFILL_ID, + COPY_PASSWORD_ID, + COPY_USERNAME_ID, + COPY_VERIFICATION_CODE_ID, +} from "@bitwarden/common/autofill/constants"; import { EventType } from "@bitwarden/common/enums"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -17,7 +22,10 @@ import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; +import { CopyCipherFieldService } from "@bitwarden/vault"; +import { BrowserApi } from "../../../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { PopupRouterCacheService } from "../../../../../platform/popup/view-cache/popup-router-cache.service"; import { VaultPopupAutofillService } from "./../../../services/vault-popup-autofill.service"; @@ -34,17 +42,26 @@ describe("ViewV2Component", () => { const params$ = new Subject(); const mockNavigate = jest.fn(); const collect = jest.fn().mockResolvedValue(null); - const doAutofill = jest.fn(); + const doAutofill = jest.fn().mockResolvedValue(true); + const copy = jest.fn().mockResolvedValue(true); const mockCipher = { id: "122-333-444", type: CipherType.Login, orgId: "222-444-555", + login: { + username: "test-username", + password: "test-password", + totp: "123", + }, }; const mockVaultPopupAutofillService = { doAutofill, }; + const mockCopyCipherFieldService = { + copy, + }; const mockUserId = Utils.newGuid() as UserId; const accountService: FakeAccountService = mockAccountServiceWith(mockUserId); @@ -57,6 +74,7 @@ describe("ViewV2Component", () => { mockNavigate.mockClear(); collect.mockClear(); doAutofill.mockClear(); + copy.mockClear(); await TestBed.configureTestingModule({ imports: [ViewV2Component], @@ -91,6 +109,10 @@ describe("ViewV2Component", () => { canDeleteCipher$: jest.fn().mockReturnValue(true), }, }, + { + provide: CopyCipherFieldService, + useValue: mockCopyCipherFieldService, + }, ], }).compileComponents(); @@ -159,5 +181,46 @@ describe("ViewV2Component", () => { expect(doAutofill).toHaveBeenCalledOnce(); })); + + it('invokes `copy` when action="copy-username"', fakeAsync(() => { + params$.next({ action: COPY_USERNAME_ID }); + + flush(); // Resolve all promises + + expect(copy).toHaveBeenCalledOnce(); + })); + + it('invokes `copy` when action="copy-password"', fakeAsync(() => { + params$.next({ action: COPY_PASSWORD_ID }); + + flush(); // Resolve all promises + + expect(copy).toHaveBeenCalledOnce(); + })); + + it('invokes `copy` when action="copy-totp"', fakeAsync(() => { + params$.next({ action: COPY_VERIFICATION_CODE_ID }); + + flush(); // Resolve all promises + + expect(copy).toHaveBeenCalledOnce(); + })); + + it("closes the popout after a load action", fakeAsync(() => { + jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValueOnce(true); + jest.spyOn(BrowserPopupUtils, "inSingleActionPopout").mockReturnValueOnce(true); + const closeSpy = jest.spyOn(BrowserPopupUtils, "closeSingleActionPopout"); + const focusSpy = jest + .spyOn(BrowserApi, "focusTab") + .mockImplementation(() => Promise.resolve()); + + params$.next({ action: AUTOFILL_ID, senderTabId: 99 }); + + flush(); // Resolve all promises + + expect(doAutofill).toHaveBeenCalledOnce(); + expect(focusSpy).toHaveBeenCalledWith(99); + expect(closeSpy).toHaveBeenCalledOnce(); + })); }); }); diff --git a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts index 8242fd8747..f739c0ce82 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/view-v2/view-v2.component.ts @@ -10,7 +10,13 @@ import { JslibModule } from "@bitwarden/angular/jslib.module"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { AUTOFILL_ID, SHOW_AUTOFILL_BUTTON } from "@bitwarden/common/autofill/constants"; +import { + AUTOFILL_ID, + COPY_PASSWORD_ID, + COPY_USERNAME_ID, + COPY_VERIFICATION_CODE_ID, + SHOW_AUTOFILL_BUTTON, +} from "@bitwarden/common/autofill/constants"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -18,7 +24,6 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; import { AsyncActionsModule, @@ -28,19 +33,34 @@ import { SearchModule, ToastService, } from "@bitwarden/components"; +import { CopyCipherFieldService } from "@bitwarden/vault"; import { PremiumUpgradePromptService } from "../../../../../../../../libs/common/src/vault/abstractions/premium-upgrade-prompt.service"; import { CipherViewComponent } from "../../../../../../../../libs/vault/src/cipher-view"; +import { BrowserApi } from "../../../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../../../platform/popup/components/pop-out.component"; import { PopupRouterCacheService } from "../../../../../platform/popup/view-cache/popup-router-cache.service"; import { BrowserPremiumUpgradePromptService } from "../../../services/browser-premium-upgrade-prompt.service"; import { BrowserViewPasswordHistoryService } from "../../../services/browser-view-password-history.service"; +import { closeViewVaultItemPopout, VaultPopoutType } from "../../../utils/vault-popout-window"; import { PopupFooterComponent } from "./../../../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "./../../../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "./../../../../../platform/popup/layout/popup-page.component"; import { VaultPopupAutofillService } from "./../../../services/vault-popup-autofill.service"; +/** + * The types of actions that can be triggered when loading the view vault item popout via the + * extension ContextMenu. See context-menu-clicked-handler.ts for more information. + */ +type LoadAction = + | typeof AUTOFILL_ID + | typeof SHOW_AUTOFILL_BUTTON + | typeof COPY_USERNAME_ID + | typeof COPY_PASSWORD_ID + | typeof COPY_VERIFICATION_CODE_ID; + @Component({ selector: "app-view-v2", templateUrl: "view-v2.component.html", @@ -68,10 +88,10 @@ export class ViewV2Component { headerText: string; cipher: CipherView; organization$: Observable; - folder$: Observable; canDeleteCipher$: Observable; collections$: Observable; - loadAction: typeof AUTOFILL_ID | typeof SHOW_AUTOFILL_BUTTON; + loadAction: LoadAction; + senderTabId?: number; constructor( private route: ActivatedRoute, @@ -86,6 +106,7 @@ export class ViewV2Component { private eventCollectionService: EventCollectionService, private popupRouterCacheService: PopupRouterCacheService, protected cipherAuthorizationService: CipherAuthorizationService, + private copyCipherFieldService: CopyCipherFieldService, ) { this.subscribeToParams(); } @@ -95,13 +116,15 @@ export class ViewV2Component { .pipe( switchMap(async (params): Promise => { this.loadAction = params.action; + this.senderTabId = params.senderTabId ? parseInt(params.senderTabId, 10) : undefined; return await this.getCipherData(params.cipherId); }), switchMap(async (cipher) => { this.cipher = cipher; this.headerText = this.setHeader(cipher.type); - if (this.loadAction === AUTOFILL_ID) { - await this.vaultPopupAutofillService.doAutofill(this.cipher); + + if (this.loadAction) { + await this._handleLoadAction(this.loadAction, this.senderTabId); } this.canDeleteCipher$ = this.cipherAuthorizationService.canDeleteCipher$(cipher); @@ -211,4 +234,65 @@ export class ViewV2Component { protected showFooter(): boolean { return this.cipher && (!this.cipher.isDeleted || (this.cipher.isDeleted && this.cipher.edit)); } + + /** + * Handles the load action for the view vault item popout. These actions are typically triggered + * via the extension context menu. It is necessary to render the view for items that have password + * reprompt enabled. + * @param loadAction + * @param senderTabId + * @private + */ + private async _handleLoadAction(loadAction: LoadAction, senderTabId?: number): Promise { + let actionSuccess = false; + + // Both vaultPopupAutofillService and copyCipherFieldService will perform password re-prompting internally. + + switch (loadAction) { + case "show-autofill-button": + // This action simply shows the cipher view, no need to do anything. + return; + case "autofill": + actionSuccess = await this.vaultPopupAutofillService.doAutofill(this.cipher, false); + break; + case "copy-username": + actionSuccess = await this.copyCipherFieldService.copy( + this.cipher.login.username, + "username", + this.cipher, + ); + break; + case "copy-password": + actionSuccess = await this.copyCipherFieldService.copy( + this.cipher.login.password, + "password", + this.cipher, + ); + break; + case "copy-totp": + actionSuccess = await this.copyCipherFieldService.copy( + this.cipher.login.totp, + "totp", + this.cipher, + ); + break; + } + + if (BrowserPopupUtils.inPopout(window)) { + setTimeout( + async () => { + if ( + BrowserPopupUtils.inSingleActionPopout(window, VaultPopoutType.viewVaultItem) && + senderTabId + ) { + await BrowserApi.focusTab(senderTabId); + await closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`); + } else { + await this.popupRouterCacheService.back(); + } + }, + actionSuccess ? 1000 : 0, + ); + } + } } diff --git a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts index 0f76c2f2cd..7620bd4950 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-autofill.service.ts @@ -10,7 +10,6 @@ import { startWith, Subject, switchMap, - timeout, } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -75,9 +74,7 @@ export class VaultPopupAutofillService { if (!tab) { return of([]); } - return this.autofillService - .collectPageDetailsFromTab$(tab) - .pipe(timeout({ first: 1500, with: () => of([]) })); + return this.autofillService.collectPageDetailsFromTab$(tab); }), shareReplay({ refCount: false, bufferSize: 1 }), ); diff --git a/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts b/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts index 151f8517d5..2b37b26b9c 100644 --- a/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts +++ b/apps/browser/src/vault/popup/services/vault-ui-onboarding.service.ts @@ -24,8 +24,7 @@ export const GLOBAL_VAULT_UI_ONBOARDING = new KeyDefinition( @Injectable() export class VaultUiOnboardingService { - // TODO: Update this date to the release date of the new Browser UI - private onboardingUiReleaseDate = new Date("2024-07-25"); + private onboardingUiReleaseDate = new Date("2024-12-10"); private vaultUiOnboardingState: GlobalState = this.stateProvider.getGlobal( GLOBAL_VAULT_UI_ONBOARDING, diff --git a/apps/browser/src/vault/popup/settings/appearance-v2.component.html b/apps/browser/src/vault/popup/settings/appearance-v2.component.html index 466cffa216..0fc6297b50 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.html +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.html @@ -18,6 +18,11 @@ + + {{ "extensionWidth" | i18n }} + + + { const setEnableRoutingAnimation = jest.fn().mockResolvedValue(undefined); const setEnableCompactMode = jest.fn().mockResolvedValue(undefined); + const mockWidthService: Partial = { + width$: new BehaviorSubject("default"), + setWidth: jest.fn().mockResolvedValue(undefined), + }; + beforeEach(async () => { setSelectedTheme.mockClear(); setShowFavicons.mockClear(); @@ -78,6 +84,10 @@ describe("AppearanceV2Component", () => { provide: PopupCompactModeService, useValue: { enabled$: enableCompactMode$, setEnabled: setEnableCompactMode }, }, + { + provide: PopupWidthService, + useValue: mockWidthService, + }, ], }) .overrideComponent(AppearanceV2Component, { @@ -102,6 +112,7 @@ describe("AppearanceV2Component", () => { enableBadgeCounter: true, theme: ThemeType.Nord, enableCompactMode: false, + width: "default", }); }); diff --git a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts index c20bc48bfe..31f7f31148 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts @@ -12,7 +12,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; -import { BadgeModule, CheckboxModule } from "@bitwarden/components"; +import { BadgeModule, CheckboxModule, Option } from "@bitwarden/components"; import { CardComponent } from "../../../../../../libs/components/src/card/card.component"; import { FormFieldModule } from "../../../../../../libs/components/src/form-field/form-field.module"; @@ -21,6 +21,10 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp import { PopupCompactModeService } from "../../../platform/popup/layout/popup-compact-mode.service"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; +import { + PopupWidthOption, + PopupWidthService, +} from "../../../platform/popup/layout/popup-width.service"; @Component({ standalone: true, @@ -41,6 +45,8 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co }) export class AppearanceV2Component implements OnInit { private compactModeService = inject(PopupCompactModeService); + private popupWidthService = inject(PopupWidthService); + private i18nService = inject(I18nService); appearanceForm = this.formBuilder.group({ enableFavicon: false, @@ -48,6 +54,7 @@ export class AppearanceV2Component implements OnInit { theme: ThemeType.System, enableAnimations: true, enableCompactMode: false, + width: "default" as PopupWidthOption, }); /** To avoid flashes of inaccurate values, only show the form after the entire form is populated. */ @@ -56,6 +63,13 @@ export class AppearanceV2Component implements OnInit { /** Available theme options */ themeOptions: { name: string; value: ThemeType }[]; + /** Available width options */ + protected readonly widthOptions: Option[] = [ + { label: this.i18nService.t("default"), value: "default" }, + { label: this.i18nService.t("wide"), value: "wide" }, + { label: this.i18nService.t("extraWide"), value: "extra-wide" }, + ]; + constructor( private messagingService: MessagingService, private domainSettingsService: DomainSettingsService, @@ -81,6 +95,7 @@ export class AppearanceV2Component implements OnInit { this.animationControlService.enableRoutingAnimation$, ); const enableCompactMode = await firstValueFrom(this.compactModeService.enabled$); + const width = await firstValueFrom(this.popupWidthService.width$); // Set initial values for the form this.appearanceForm.setValue({ @@ -89,6 +104,7 @@ export class AppearanceV2Component implements OnInit { theme, enableAnimations, enableCompactMode, + width, }); this.formLoading = false; @@ -122,6 +138,12 @@ export class AppearanceV2Component implements OnInit { .subscribe((enableCompactMode) => { void this.updateCompactMode(enableCompactMode); }); + + this.appearanceForm.controls.width.valueChanges + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((width) => { + void this.updateWidth(width); + }); } async updateFavicon(enableFavicon: boolean) { @@ -144,4 +166,8 @@ export class AppearanceV2Component implements OnInit { async updateCompactMode(enableCompactMode: boolean) { await this.compactModeService.setEnabled(enableCompactMode); } + + async updateWidth(width: PopupWidthOption) { + await this.popupWidthService.setWidth(width); + } } diff --git a/apps/browser/store/locales/ar/copy.resx b/apps/browser/store/locales/ar/copy.resx index e1bfa48b44..9fdfb94210 100644 --- a/apps/browser/store/locales/ar/copy.resx +++ b/apps/browser/store/locales/ar/copy.resx @@ -172,16 +172,16 @@ 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. - مزامنة خزنتك والوصول إليها من عدة أجهزة + مزامنة خزانتك والوصول إليها من عدة أجهزة - إدارة جميع تسجيلات الدخول وكلمات المرور الخاصة بك من خزنة آمنة + إدارة جميع تسجيلات الدخول وكلمات المرور الخاصة بك من خزانة آمنة قم بملء بيانات تسجيل الدخول تلقائياً وبسرعة في أي موقع تزوره - يمكنك الوصول الى خزنتك بسهولة من قائمة النقر بالزر الأيمن + يمكنك الوصول الى خزانتك بسهولة من قائمة النقر بالزر الأيمن إنشاء كلمات مرور قوية، وعشوائية، وآمنة، تلقائيًا diff --git a/apps/cli/package.json b/apps/cli/package.json index 8be8f9ca34..16ad1c8519 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/cli", "description": "A secure and free password manager for all of your devices.", - "version": "2024.11.1", + "version": "2024.12.0", "keywords": [ "bitwarden", "password", @@ -80,7 +80,7 @@ "papaparse": "5.4.1", "proper-lockfile": "4.1.2", "rxjs": "7.8.1", - "tldts": "6.1.61", + "tldts": "6.1.64", "zxcvbn": "4.4.2" } } diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index fc014534e0..3f8702d000 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -21,7 +21,6 @@ import { LoginExport } from "@bitwarden/common/models/export/login.export"; import { SecureNoteExport } from "@bitwarden/common/models/export/secure-note.export"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; @@ -58,7 +57,6 @@ export class GetCommand extends DownloadCommand { private auditService: AuditService, private keyService: KeyService, encryptService: EncryptService, - private stateService: StateService, private searchService: SearchService, private apiService: ApiService, private organizationService: OrganizationService, diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index a25357f6f6..0614aa05e1 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -58,7 +58,6 @@ export class OssServeConfigurator { this.serviceContainer.auditService, this.serviceContainer.keyService, this.serviceContainer.encryptService, - this.serviceContainer.stateService, this.serviceContainer.searchService, this.serviceContainer.apiService, this.serviceContainer.organizationService, diff --git a/apps/cli/src/tools/generate.command.ts b/apps/cli/src/tools/generate.command.ts index 2829bc5141..0a17e4843b 100644 --- a/apps/cli/src/tools/generate.command.ts +++ b/apps/cli/src/tools/generate.command.ts @@ -33,7 +33,7 @@ export class GenerateCommand { includeNumber: normalizedOptions.includeNumber, minNumber: normalizedOptions.minNumber, minSpecial: normalizedOptions.minSpecial, - ambiguous: normalizedOptions.ambiguous, + ambiguous: !normalizedOptions.ambiguous, }; const enforcedOptions = (await this.stateService.getIsAuthenticated()) diff --git a/apps/cli/src/tools/send/send.program.ts b/apps/cli/src/tools/send/send.program.ts index 60e78137e7..d70b810221 100644 --- a/apps/cli/src/tools/send/send.program.ts +++ b/apps/cli/src/tools/send/send.program.ts @@ -144,7 +144,6 @@ export class SendProgram extends BaseProgram { this.serviceContainer.auditService, this.serviceContainer.keyService, this.serviceContainer.encryptService, - this.serviceContainer.stateService, this.serviceContainer.searchService, this.serviceContainer.apiService, this.serviceContainer.organizationService, diff --git a/apps/cli/src/vault.program.ts b/apps/cli/src/vault.program.ts index 4d3215944e..252818c2f2 100644 --- a/apps/cli/src/vault.program.ts +++ b/apps/cli/src/vault.program.ts @@ -179,7 +179,6 @@ export class VaultProgram extends BaseProgram { this.serviceContainer.auditService, this.serviceContainer.keyService, this.serviceContainer.encryptService, - this.serviceContainer.stateService, this.serviceContainer.searchService, this.serviceContainer.apiService, this.serviceContainer.organizationService, diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 53d151397f..16a5a48cd0 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -211,9 +211,9 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", @@ -298,12 +298,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.6.0" @@ -313,7 +307,7 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitwarden-russh" version = "0.1.0" -source = "git+https://github.com/bitwarden/bitwarden-russh.git?branch=km/pm-10098/clean-russh-implementation#86ff1bf2f4620a3ae5684adee31abdbee33c6f07" +source = "git+https://github.com/bitwarden/bitwarden-russh.git?rev=b4e7f2fedbe3df8c35545feb000176d3e7b2bc32#b4e7f2fedbe3df8c35545feb000176d3e7b2bc32" dependencies = [ "anyhow", "byteorder", @@ -701,7 +695,7 @@ dependencies = [ "tokio-util", "typenum", "widestring", - "windows", + "windows 0.58.0", "zbus", "zbus_polkit", ] @@ -1099,7 +1093,7 @@ version = "0.19.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39650279f135469465018daae0ba53357942a5212137515777d5fdca74984a44" dependencies = [ - "bitflags 2.6.0", + "bitflags", "futures-channel", "futures-core", "futures-executor", @@ -1190,14 +1184,14 @@ dependencies = [ [[package]] name = "homedir" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bed305c13ce3829a09d627f5d43ff738482a09361ae4eb8039993b55fb10e5e" +checksum = "5bdbbd5bc8c5749697ccaa352fa45aff8730cf21c68029c0eef1ffed7c3d6ba2" dependencies = [ "cfg-if", - "nix 0.26.4", + "nix 0.29.0", "widestring", - "windows", + "windows 0.57.0", ] [[package]] @@ -1299,7 +1293,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", ] @@ -1366,15 +1360,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.9.1" @@ -1417,7 +1402,7 @@ version = "2.16.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "214f07a80874bb96a8433b3cdfc84980d56c7b02e1a0d7ba4ba0db5cef785e2b" dependencies = [ - "bitflags 2.6.0", + "bitflags", "ctor", "napi-derive", "napi-sys", @@ -1469,26 +1454,13 @@ dependencies = [ "libloading", ] -[[package]] -name = "nix" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset 0.7.1", - "pin-utils", -] - [[package]] name = "nix" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "cfg_aliases 0.1.1", "libc", @@ -1500,11 +1472,11 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cfg-if", "cfg_aliases 0.2.1", "libc", - "memoffset 0.9.1", + "memoffset", ] [[package]] @@ -1601,7 +1573,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.6.0", + "bitflags", "block2", "libc", "objc2", @@ -1617,7 +1589,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.6.0", + "bitflags", "block2", "objc2", "objc2-foundation", @@ -1647,7 +1619,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.6.0", + "bitflags", "block2", "libc", "objc2", @@ -1659,7 +1631,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.6.0", + "bitflags", "block2", "objc2", "objc2-foundation", @@ -1671,7 +1643,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.6.0", + "bitflags", "block2", "objc2", "objc2-foundation", @@ -1785,18 +1757,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", @@ -2001,7 +1973,7 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -2105,7 +2077,7 @@ version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -2156,7 +2128,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d0283c0a4a22a0f1b0e4edca251aa20b92fc96eaa09b84bec052f9415e9d71" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -2348,9 +2320,9 @@ dependencies = [ [[package]] name = "ssh-key" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca9b366a80cf18bb6406f4cf4d10aebfb46140a8c0c33f666a144c5c76ecbafc" +checksum = "3b86f5297f0f04d08cabaa0f6bff7cb6aec4d9c3b49d87990d63da9d9156a8c3" dependencies = [ "bcrypt-pbkdf", "ed25519-dalek", @@ -2484,9 +2456,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -2623,7 +2595,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" dependencies = [ - "memoffset 0.9.1", + "memoffset", "tempfile", "winapi", ] @@ -2694,7 +2666,7 @@ version = "0.31.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" dependencies = [ - "bitflags 2.6.0", + "bitflags", "rustix", "wayland-backend", "wayland-scanner", @@ -2706,7 +2678,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.6.0", + "bitflags", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2718,7 +2690,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.6.0", + "bitflags", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2790,7 +2762,17 @@ version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ - "windows-core", + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", "windows-targets 0.52.6", ] @@ -2800,12 +2782,25 @@ version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.57.0", + "windows-interface 0.57.0", "windows-result 0.1.2", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-implement" version = "0.57.0" @@ -2817,6 +2812,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-interface" version = "0.57.0" @@ -2828,6 +2834,17 @@ dependencies = [ "syn", ] +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-registry" version = "0.3.0" @@ -2835,7 +2852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bafa604f2104cf5ae2cc2db1dee84b7e6a5d11b05f737b60def0ffdc398cbc0a" dependencies = [ "windows-result 0.2.0", - "windows-strings", + "windows-strings 0.2.0", "windows-targets 0.52.6", ] @@ -2857,6 +2874,16 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-strings" version = "0.2.0" diff --git a/apps/desktop/desktop_native/core/Cargo.toml b/apps/desktop/desktop_native/core/Cargo.toml index 039cd19c6a..6abf7fbb0a 100644 --- a/apps/desktop/desktop_native/core/Cargo.toml +++ b/apps/desktop/desktop_native/core/Cargo.toml @@ -10,30 +10,30 @@ default = ["sys"] manual_test = [] sys = [ - "dep:widestring", - "dep:windows", - "dep:core-foundation", - "dep:security-framework", - "dep:security-framework-sys", - "dep:gio", - "dep:libsecret", - "dep:zbus", - "dep:zbus_polkit", + "dep:widestring", + "dep:windows", + "dep:core-foundation", + "dep:security-framework", + "dep:security-framework-sys", + "dep:gio", + "dep:libsecret", + "dep:zbus", + "dep:zbus_polkit", ] [dependencies] aes = "=0.8.4" anyhow = "=1.0.93" arboard = { version = "=3.4.1", default-features = false, features = [ - "wayland-data-control", + "wayland-data-control", ] } -async-stream = "=0.3.5" +async-stream = "=0.3.6" base64 = "=0.22.1" byteorder = "=1.5.0" cbc = { version = "=0.1.2", features = ["alloc"] } -homedir = "=0.3.3" +homedir = "=0.3.4" libc = "=0.2.162" -pin-project = "=1.1.5" +pin-project = "=1.1.7" dirs = "=5.0.1" futures = "=0.3.31" interprocess = { version = "=2.2.1", features = ["tokio"] } @@ -44,16 +44,16 @@ russh-cryptovec = "=0.7.3" scopeguard = "=1.2.0" sha2 = "=0.10.8" ssh-encoding = "=0.2.0" -ssh-key = { version = "=0.6.6", default-features = false, features = [ +ssh-key = { version = "=0.6.7", default-features = false, features = [ "encryption", "ed25519", "rsa", "getrandom", ] } -bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", branch = "km/pm-10098/clean-russh-implementation" } -tokio = { version = "=1.40.0", features = ["io-util", "sync", "macros", "net"] } +bitwarden-russh = { git = "https://github.com/bitwarden/bitwarden-russh.git", rev = "b4e7f2fedbe3df8c35545feb000176d3e7b2bc32" } +tokio = { version = "=1.41.1", features = ["io-util", "sync", "macros", "net"] } tokio-stream = { version = "=0.1.15", features = ["net"] } -tokio-util = { version = "0.7.11", features = ["codec"] } +tokio-util = { version = "=0.7.12", features = ["codec"] } thiserror = "=1.0.69" typenum = "=1.17.0" rand_chacha = "=0.3.1" @@ -63,7 +63,7 @@ ed25519 = { version = "=2.2.3", features = ["pkcs8"] } [target.'cfg(windows)'.dependencies] widestring = { version = "=1.1.0", optional = true } -windows = { version = "=0.57.0", features = [ +windows = { version = "=0.58.0", features = [ "Foundation", "Security_Credentials_UI", "Security_Cryptography", diff --git a/apps/desktop/desktop_native/core/src/biometric/windows.rs b/apps/desktop/desktop_native/core/src/biometric/windows.rs index d5e8b6dc91..c951e42e26 100644 --- a/apps/desktop/desktop_native/core/src/biometric/windows.rs +++ b/apps/desktop/desktop_native/core/src/biometric/windows.rs @@ -1,4 +1,4 @@ -use std::str::FromStr; +use std::{ffi::c_void, str::FromStr}; use anyhow::{anyhow, Result}; use base64::{engine::general_purpose::STANDARD as base64_engine, Engine}; @@ -40,6 +40,8 @@ pub struct Biometric {} impl super::BiometricTrait for Biometric { async fn prompt(hwnd: Vec, message: String) -> Result { let h = isize::from_le_bytes(hwnd.clone().try_into().unwrap()); + + let h = h as *mut c_void; let window = HWND(h); // The Windows Hello prompt is displayed inside the application window. For best result we @@ -174,7 +176,7 @@ fn focus_security_prompt() -> Result<()> { class_name: windows::core::PCSTR, ) -> retry::OperationResult<(), ()> { let hwnd = unsafe { FindWindowA(class_name, None) }; - if hwnd.0 != 0 { + if let Ok(hwnd) = hwnd { set_focus(hwnd); return retry::OperationResult::Ok(()); } diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs index 8cbcd97d91..9d04ea87cc 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/mod.rs @@ -17,9 +17,11 @@ pub mod importer; pub struct BitwardenDesktopAgent { keystore: ssh_agent::KeyStore, cancellation_token: CancellationToken, - show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, String)>, + show_ui_request_tx: tokio::sync::mpsc::Sender<(u32, (String, bool))>, get_ui_response_rx: Arc>>, request_id: Arc>, + /// before first unlock, or after account switching, listing keys should require an unlock to get a list of public keys + needs_unlock: Arc>, is_running: Arc>, } @@ -33,8 +35,30 @@ impl ssh_agent::Agent for BitwardenDesktopAgent { let request_id = self.get_request_id().await; let mut rx_channel = self.get_ui_response_rx.lock().await.resubscribe(); + let message = (request_id, (ssh_key.cipher_uuid.clone(), false)); self.show_ui_request_tx - .send((request_id, ssh_key.cipher_uuid.clone())) + .send(message) + .await + .expect("Should send request to ui"); + while let Ok((id, response)) = rx_channel.recv().await { + if id == request_id { + return response; + } + } + false + } + + async fn can_list(&self) -> bool { + if !*self.needs_unlock.lock().await{ + return true; + } + + let request_id = self.get_request_id().await; + + let mut rx_channel = self.get_ui_response_rx.lock().await.resubscribe(); + let message = (request_id, ("".to_string(), true)); + self.show_ui_request_tx + .send(message) .await .expect("Should send request to ui"); while let Ok((id, response)) = rx_channel.recv().await { @@ -75,6 +99,8 @@ impl BitwardenDesktopAgent { let keystore = &mut self.keystore; keystore.0.write().expect("RwLock is not poisoned").clear(); + *self.needs_unlock.blocking_lock() = false; + for (key, name, cipher_id) in new_keys.iter() { match parse_key_safe(&key) { Ok(private_key) => { @@ -119,6 +145,14 @@ impl BitwardenDesktopAgent { Ok(()) } + pub fn clear_keys(&mut self) -> Result<(), anyhow::Error> { + let keystore = &mut self.keystore; + keystore.0.write().expect("RwLock is not poisoned").clear(); + *self.needs_unlock.blocking_lock() = true; + + Ok(()) + } + async fn get_request_id(&self) -> u32 { if !*self.is_running.lock().await { println!("[BitwardenDesktopAgent] Agent is not running, but tried to get request id"); diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs b/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs index 27f27998ce..ed2fe9ffab 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/unix.rs @@ -14,7 +14,7 @@ use super::BitwardenDesktopAgent; impl BitwardenDesktopAgent { pub async fn start_server( - auth_request_tx: tokio::sync::mpsc::Sender<(u32, String)>, + auth_request_tx: tokio::sync::mpsc::Sender<(u32, (String, bool))>, auth_response_rx: Arc>>, ) -> Result { let agent = BitwardenDesktopAgent { @@ -23,6 +23,7 @@ impl BitwardenDesktopAgent { show_ui_request_tx: auth_request_tx, get_ui_response_rx: auth_response_rx, request_id: Arc::new(tokio::sync::Mutex::new(0)), + needs_unlock: Arc::new(tokio::sync::Mutex::new(true)), is_running: Arc::new(tokio::sync::Mutex::new(false)), }; let cloned_agent_state = agent.clone(); diff --git a/apps/desktop/desktop_native/core/src/ssh_agent/windows.rs b/apps/desktop/desktop_native/core/src/ssh_agent/windows.rs index 9ccae7af67..6a99b7cfb0 100644 --- a/apps/desktop/desktop_native/core/src/ssh_agent/windows.rs +++ b/apps/desktop/desktop_native/core/src/ssh_agent/windows.rs @@ -12,7 +12,7 @@ use super::BitwardenDesktopAgent; impl BitwardenDesktopAgent { pub async fn start_server( - auth_request_tx: tokio::sync::mpsc::Sender<(u32, String)>, + auth_request_tx: tokio::sync::mpsc::Sender<(u32, (String, bool))>, auth_response_rx: Arc>>, ) -> Result { let agent_state = BitwardenDesktopAgent { @@ -21,6 +21,7 @@ impl BitwardenDesktopAgent { get_ui_response_rx: auth_response_rx, cancellation_token: CancellationToken::new(), request_id: Arc::new(tokio::sync::Mutex::new(0)), + needs_unlock: Arc::new(tokio::sync::Mutex::new(true)), is_running: Arc::new(tokio::sync::Mutex::new(true)), }; let stream = named_pipe_listener_stream::NamedPipeServerStream::new( diff --git a/apps/desktop/desktop_native/napi/Cargo.toml b/apps/desktop/desktop_native/napi/Cargo.toml index bf7701a656..644ff8a51d 100644 --- a/apps/desktop/desktop_native/napi/Cargo.toml +++ b/apps/desktop/desktop_native/napi/Cargo.toml @@ -20,7 +20,7 @@ anyhow = "=1.0.93" desktop_core = { path = "../core" } napi = { version = "=2.16.13", features = ["async"] } napi-derive = "=2.16.12" -tokio = { version = "=1.40.0" } +tokio = { version = "=1.41.1" } tokio-util = "=0.7.12" tokio-stream = "=0.1.15" diff --git a/apps/desktop/desktop_native/napi/index.d.ts b/apps/desktop/desktop_native/napi/index.d.ts index 62e448d480..956b2d726d 100644 --- a/apps/desktop/desktop_native/napi/index.d.ts +++ b/apps/desktop/desktop_native/napi/index.d.ts @@ -69,12 +69,13 @@ export declare namespace sshagent { status: SshKeyImportStatus sshKey?: SshKey } - export function serve(callback: (err: Error | null, arg: string) => any): Promise + export function serve(callback: (err: Error | null, arg0: string, arg1: boolean) => any): Promise export function stop(agentState: SshAgentState): void export function isRunning(agentState: SshAgentState): boolean export function setKeys(agentState: SshAgentState, newKeys: Array): void export function lock(agentState: SshAgentState): void export function importKey(encodedKey: string, password: string): SshKeyImportResult + export function clearKeys(agentState: SshAgentState): void export function generateKeypair(keyAlgorithm: string): Promise export class SshAgentState { } } diff --git a/apps/desktop/desktop_native/napi/src/lib.rs b/apps/desktop/desktop_native/napi/src/lib.rs index 8e156eb3ef..4c7bc8eaa9 100644 --- a/apps/desktop/desktop_native/napi/src/lib.rs +++ b/apps/desktop/desktop_native/napi/src/lib.rs @@ -247,15 +247,15 @@ pub mod sshagent { #[napi] pub async fn serve( - callback: ThreadsafeFunction, + callback: ThreadsafeFunction<(String, bool), CalleeHandled>, ) -> napi::Result { - let (auth_request_tx, mut auth_request_rx) = tokio::sync::mpsc::channel::<(u32, String)>(32); + let (auth_request_tx, mut auth_request_rx) = tokio::sync::mpsc::channel::<(u32, (String, bool))>(32); let (auth_response_tx, auth_response_rx) = tokio::sync::broadcast::channel::<(u32, bool)>(32); let auth_response_tx_arc = Arc::new(Mutex::new(auth_response_tx)); tokio::spawn(async move { let _ = auth_response_rx; - while let Some((request_id, cipher_uuid)) = auth_request_rx.recv().await { + while let Some((request_id, (cipher_uuid, is_list_request))) = auth_request_rx.recv().await { let cloned_request_id = request_id.clone(); let cloned_cipher_uuid = cipher_uuid.clone(); let cloned_response_tx_arc = auth_response_tx_arc.clone(); @@ -266,7 +266,7 @@ pub mod sshagent { let auth_response_tx_arc = cloned_response_tx_arc; let callback = cloned_callback; let promise_result: Result, napi::Error> = - callback.call_async(Ok(cipher_uuid)).await; + callback.call_async(Ok((cipher_uuid, is_list_request))).await; match promise_result { Ok(promise_result) => match promise_result.await { Ok(result) => { @@ -345,6 +345,12 @@ pub mod sshagent { Ok(result.into()) } + #[napi] + pub fn clear_keys(agent_state: &mut SshAgentState) -> napi::Result<()> { + let bitwarden_agent_state = &mut agent_state.state; + bitwarden_agent_state.clear_keys().map_err(|e| napi::Error::from_reason(e.to_string())) + } + #[napi] pub async fn generate_keypair(key_algorithm: String) -> napi::Result { desktop_core::ssh_agent::generator::generate_keypair(key_algorithm) diff --git a/apps/desktop/desktop_native/proxy/Cargo.toml b/apps/desktop/desktop_native/proxy/Cargo.toml index 0208b2f033..0511f583c1 100644 --- a/apps/desktop/desktop_native/proxy/Cargo.toml +++ b/apps/desktop/desktop_native/proxy/Cargo.toml @@ -12,7 +12,7 @@ desktop_core = { path = "../core", default-features = false } futures = "=0.3.31" log = "=0.4.22" simplelog = "=0.12.2" -tokio = { version = "=1.40.0", features = ["io-std", "io-util", "macros", "rt"] } +tokio = { version = "=1.41.1", features = ["io-std", "io-util", "macros", "rt"] } tokio-util = { version = "=0.7.12", features = ["codec"] } [target.'cfg(target_os = "macos")'.dependencies] diff --git a/apps/desktop/native-messaging-test-runner/package-lock.json b/apps/desktop/native-messaging-test-runner/package-lock.json index f51c0a32d9..8dd8204b69 100644 --- a/apps/desktop/native-messaging-test-runner/package-lock.json +++ b/apps/desktop/native-messaging-test-runner/package-lock.json @@ -18,7 +18,7 @@ "yargs": "17.7.2" }, "devDependencies": { - "@types/node": "22.9.0", + "@types/node": "22.9.3", "@types/node-ipc": "9.2.3", "typescript": "4.7.4" } @@ -106,9 +106,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.9.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.3.tgz", + "integrity": "sha512-F3u1fs/fce3FFk+DAxbxc78DF8x0cY09RRL8GnXLmkJ1jvx3TtPdWoTT5/NiYfI5ASqXBmfqJi9dZ3gxMx4lzw==", "license": "MIT", "dependencies": { "undici-types": "~6.19.8" diff --git a/apps/desktop/native-messaging-test-runner/package.json b/apps/desktop/native-messaging-test-runner/package.json index 23b1dbdafb..d2da248522 100644 --- a/apps/desktop/native-messaging-test-runner/package.json +++ b/apps/desktop/native-messaging-test-runner/package.json @@ -23,7 +23,7 @@ "yargs": "17.7.2" }, "devDependencies": { - "@types/node": "22.9.0", + "@types/node": "22.9.3", "@types/node-ipc": "9.2.3", "typescript": "4.7.4" }, diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 7b41f87ffb..54feb7df9e 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.11.3", + "version": "2024.12.0", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index 3ef2dde2e8..1f181f4828 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -5,6 +5,7 @@ import { DesktopDefaultOverlayPosition, EnvironmentSelectorComponent, } from "@bitwarden/angular/auth/components/environment-selector.component"; +import { TwoFactorTimeoutComponent } from "@bitwarden/angular/auth/components/two-factor-auth/two-factor-auth-expired.component"; import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap"; import { authGuard, @@ -35,6 +36,7 @@ import { VaultIcon, LoginDecryptionOptionsComponent, DevicesIcon, + TwoFactorTimeoutIcon, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -103,6 +105,22 @@ const routes: Routes = [ ], }, ), + { + path: "2fa-timeout", + component: AnonLayoutWrapperComponent, + children: [ + { + path: "", + component: TwoFactorTimeoutComponent, + }, + ], + data: { + pageIcon: TwoFactorTimeoutIcon, + pageTitle: { + key: "authenticationTimeout", + }, + } satisfies RouteDataProperties & AnonLayoutWrapperData, + }, { path: "register", component: RegisterComponent }, { path: "vault", diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts index e8a9e96924..7840c1dd40 100644 --- a/apps/desktop/src/app/app.component.ts +++ b/apps/desktop/src/app/app.component.ts @@ -25,7 +25,7 @@ import { import { CollectionService } from "@bitwarden/admin-console/common"; import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; import { ModalService } from "@bitwarden/angular/services/modal.service"; -import { FingerprintDialogComponent } from "@bitwarden/auth/angular"; +import { FingerprintDialogComponent, LoginApprovalComponent } from "@bitwarden/auth/angular"; import { LogoutReason } from "@bitwarden/auth/common"; import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service"; import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service"; @@ -67,7 +67,6 @@ import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legac import { KeyService, BiometricStateService } from "@bitwarden/key-management"; import { DeleteAccountComponent } from "../auth/delete-account.component"; -import { LoginApprovalComponent } from "../auth/login/login-approval.component"; import { MenuAccount, MenuUpdateRequest } from "../main/menu/menu.updater"; import { flagEnabled } from "../platform/flags"; import { PremiumComponent } from "../vault/app/accounts/premium.component"; diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 2a11c78a57..040102d039 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -26,6 +26,7 @@ import { } from "@bitwarden/auth/angular"; import { InternalUserDecryptionOptionsServiceAbstraction, + LoginApprovalComponentServiceAbstraction, LoginEmailService, PinServiceAbstraction, } from "@bitwarden/auth/common"; @@ -87,6 +88,7 @@ import { BiometricsService, } from "@bitwarden/key-management"; +import { DesktopLoginApprovalComponentService } from "../../auth/login/desktop-login-approval-component.service"; import { DesktopLoginComponentService } from "../../auth/login/desktop-login-component.service"; import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service"; import { ElectronBiometricsService } from "../../key-management/biometrics/electron-biometrics.service"; @@ -104,9 +106,10 @@ import { ElectronRendererStorageService } from "../../platform/services/electron import { I18nRendererService } from "../../platform/services/i18n.renderer.service"; import { fromIpcMessaging } from "../../platform/utils/from-ipc-messaging"; import { fromIpcSystemTheme } from "../../platform/utils/from-ipc-system-theme"; +import { BiometricMessageHandlerService } from "../../services/biometric-message-handler.service"; import { DesktopLockComponentService } from "../../services/desktop-lock-component.service"; +import { DuckDuckGoMessageHandlerService } from "../../services/duckduckgo-message-handler.service"; import { EncryptedMessageHandlerService } from "../../services/encrypted-message-handler.service"; -import { NativeMessageHandlerService } from "../../services/native-message-handler.service"; import { NativeMessagingService } from "../../services/native-messaging.service"; import { SearchBarService } from "../layout/search/search-bar.service"; @@ -132,6 +135,7 @@ const safeProviders: SafeProvider[] = [ deps: [], }), safeProvider(NativeMessagingService), + safeProvider(BiometricMessageHandlerService), safeProvider(SearchBarService), safeProvider(DialogService), safeProvider({ @@ -255,7 +259,7 @@ const safeProviders: SafeProvider[] = [ ], }), safeProvider({ - provide: NativeMessageHandlerService, + provide: DuckDuckGoMessageHandlerService, deps: [ StateServiceAbstraction, EncryptService, @@ -349,6 +353,11 @@ const safeProviders: SafeProvider[] = [ useClass: LoginEmailService, deps: [AccountService, AuthService, StateProvider], }), + safeProvider({ + provide: LoginApprovalComponentServiceAbstraction, + useClass: DesktopLoginApprovalComponentService, + deps: [I18nServiceAbstraction], + }), ]; @NgModule({ diff --git a/apps/desktop/src/app/tools/generator/credential-generator.component.html b/apps/desktop/src/app/tools/generator/credential-generator.component.html index 37d677472d..66b0de13df 100644 --- a/apps/desktop/src/app/tools/generator/credential-generator.component.html +++ b/apps/desktop/src/app/tools/generator/credential-generator.component.html @@ -6,6 +6,7 @@
- {{ "accountIsManagedMessage" | i18n: managingOrganization?.name }} + {{ "accountIsOwnedMessage" | i18n: managingOrganization?.name }} 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 new file mode 100644 index 0000000000..cc53e0a32b --- /dev/null +++ b/apps/web/src/app/billing/services/free-families-policy.service.ts @@ -0,0 +1,125 @@ +import { Injectable } from "@angular/core"; +import { combineLatest, filter, from, map, Observable, of, switchMap } from "rxjs"; + +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; + +interface EnterpriseOrgStatus { + isFreeFamilyPolicyEnabled: boolean; + belongToOneEnterpriseOrgs: boolean; + belongToMultipleEnterpriseOrgs: boolean; +} + +@Injectable({ providedIn: "root" }) +export class FreeFamiliesPolicyService { + protected enterpriseOrgStatus: EnterpriseOrgStatus = { + isFreeFamilyPolicyEnabled: false, + belongToOneEnterpriseOrgs: false, + belongToMultipleEnterpriseOrgs: false, + }; + + constructor( + private policyService: PolicyService, + private organizationService: OrganizationService, + private configService: ConfigService, + ) {} + + get showFreeFamilies$(): Observable { + return this.isFreeFamilyFlagEnabled$.pipe( + switchMap((isFreeFamilyFlagEnabled) => + isFreeFamilyFlagEnabled + ? this.getFreeFamiliesVisibility$() + : this.organizationService.canManageSponsorships$, + ), + ); + } + + private getFreeFamiliesVisibility$(): Observable { + return combineLatest([ + this.checkEnterpriseOrganizationsAndFetchPolicy(), + this.organizationService.canManageSponsorships$, + ]).pipe( + map(([orgStatus, canManageSponsorships]) => + this.shouldShowFreeFamilyLink(orgStatus, canManageSponsorships), + ), + ); + } + + private shouldShowFreeFamilyLink( + orgStatus: EnterpriseOrgStatus | null, + canManageSponsorships: boolean, + ): boolean { + if (!orgStatus) { + return false; + } + const { belongToOneEnterpriseOrgs, isFreeFamilyPolicyEnabled } = orgStatus; + return canManageSponsorships && !(belongToOneEnterpriseOrgs && isFreeFamilyPolicyEnabled); + } + + checkEnterpriseOrganizationsAndFetchPolicy(): Observable { + return this.organizationService.organizations$.pipe( + filter((organizations) => Array.isArray(organizations) && organizations.length > 0), + switchMap((organizations) => this.fetchEnterpriseOrganizationPolicy(organizations)), + ); + } + + private fetchEnterpriseOrganizationPolicy( + organizations: Organization[], + ): Observable { + const { belongToOneEnterpriseOrgs, belongToMultipleEnterpriseOrgs } = + this.evaluateEnterpriseOrganizations(organizations); + + if (!belongToOneEnterpriseOrgs) { + return of({ + isFreeFamilyPolicyEnabled: false, + belongToOneEnterpriseOrgs, + belongToMultipleEnterpriseOrgs, + }); + } + + const organizationId = this.getOrganizationIdForOneEnterprise(organizations); + if (!organizationId) { + return of({ + isFreeFamilyPolicyEnabled: false, + belongToOneEnterpriseOrgs, + belongToMultipleEnterpriseOrgs, + }); + } + + return this.policyService.getAll$(PolicyType.FreeFamiliesSponsorshipPolicy).pipe( + map((policies) => ({ + isFreeFamilyPolicyEnabled: policies.some( + (policy) => policy.organizationId === organizationId && policy.enabled, + ), + belongToOneEnterpriseOrgs, + belongToMultipleEnterpriseOrgs, + })), + ); + } + + private evaluateEnterpriseOrganizations(organizations: any[]): { + belongToOneEnterpriseOrgs: boolean; + belongToMultipleEnterpriseOrgs: boolean; + } { + const enterpriseOrganizations = organizations.filter((org) => org.canManageSponsorships); + const count = enterpriseOrganizations.length; + + return { + belongToOneEnterpriseOrgs: count === 1, + belongToMultipleEnterpriseOrgs: count > 1, + }; + } + + private getOrganizationIdForOneEnterprise(organizations: any[]): string | null { + const enterpriseOrganizations = organizations.filter((org) => org.canManageSponsorships); + return enterpriseOrganizations.length === 1 ? enterpriseOrganizations[0].id : null; + } + + private get isFreeFamilyFlagEnabled$(): Observable { + return from(this.configService.getFeatureFlag(FeatureFlag.DisableFreeFamiliesSponsorship)); + } +} diff --git a/apps/web/src/app/billing/settings/sponsored-families.component.ts b/apps/web/src/app/billing/settings/sponsored-families.component.ts index c098b6044c..f49e7acce2 100644 --- a/apps/web/src/app/billing/settings/sponsored-families.component.ts +++ b/apps/web/src/app/billing/settings/sponsored-families.component.ts @@ -8,13 +8,17 @@ import { AsyncValidatorFn, ValidationErrors, } from "@angular/forms"; -import { firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs"; +import { combineLatest, firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { PlanSponsorshipType } from "@bitwarden/common/billing/enums"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; @@ -31,6 +35,7 @@ interface RequestSponsorshipForm { }) export class SponsoredFamiliesComponent implements OnInit, OnDestroy { loading = false; + isFreeFamilyFlagEnabled: boolean; availableSponsorshipOrgs$: Observable; activeSponsorshipOrgs$: Observable; @@ -53,6 +58,8 @@ export class SponsoredFamiliesComponent implements OnInit, OnDestroy { private formBuilder: FormBuilder, private accountService: AccountService, private toastService: ToastService, + private configService: ConfigService, + private policyService: PolicyService, ) { this.sponsorshipForm = this.formBuilder.group({ selectedSponsorshipOrgId: new FormControl("", { @@ -72,10 +79,34 @@ export class SponsoredFamiliesComponent implements OnInit, OnDestroy { } async ngOnInit() { - this.availableSponsorshipOrgs$ = this.organizationService.organizations$.pipe( - map((orgs) => orgs.filter((o) => o.familySponsorshipAvailable)), + this.isFreeFamilyFlagEnabled = await this.configService.getFeatureFlag( + FeatureFlag.DisableFreeFamiliesSponsorship, ); + if (this.isFreeFamilyFlagEnabled) { + this.availableSponsorshipOrgs$ = combineLatest([ + this.organizationService.organizations$, + this.policyService.getAll$(PolicyType.FreeFamiliesSponsorshipPolicy), + ]).pipe( + map(([organizations, policies]) => + organizations + .filter((org) => org.familySponsorshipAvailable) + .map((org) => ({ + organization: org, + isPolicyEnabled: policies.some( + (policy) => policy.organizationId === org.id && policy.enabled, + ), + })) + .filter(({ isPolicyEnabled }) => !isPolicyEnabled) + .map(({ organization }) => organization), + ), + ); + } else { + this.availableSponsorshipOrgs$ = this.organizationService.organizations$.pipe( + map((orgs) => orgs.filter((o) => o.familySponsorshipAvailable)), + ); + } + this.availableSponsorshipOrgs$.pipe(takeUntil(this._destroy)).subscribe((orgs) => { if (orgs.length === 1) { this.sponsorshipForm.patchValue({ diff --git a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html index b07cbbfad1..eeeaa25604 100644 --- a/apps/web/src/app/billing/settings/sponsoring-org-row.component.html +++ b/apps/web/src/app/billing/settings/sponsoring-org-row.component.html @@ -18,7 +18,11 @@ - + diff --git a/apps/web/src/app/tools/credential-generator/credential-generator.component.ts b/apps/web/src/app/tools/credential-generator/credential-generator.component.ts index f252796d06..8d7b56a09a 100644 --- a/apps/web/src/app/tools/credential-generator/credential-generator.component.ts +++ b/apps/web/src/app/tools/credential-generator/credential-generator.component.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; -import { ButtonModule, DialogService, ItemModule, LinkModule } from "@bitwarden/components"; +import { ButtonModule, DialogService, LinkModule } from "@bitwarden/components"; import { CredentialGeneratorHistoryDialogComponent, GeneratorModule, @@ -13,7 +13,7 @@ import { SharedModule } from "../../shared"; standalone: true, selector: "credential-generator", templateUrl: "credential-generator.component.html", - imports: [SharedModule, HeaderModule, GeneratorModule, ItemModule, ButtonModule, LinkModule], + imports: [SharedModule, HeaderModule, GeneratorModule, ButtonModule, LinkModule], }) export class CredentialGeneratorComponent { constructor(private dialogService: DialogService) {} diff --git a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts index 85faac0c08..527f00d58f 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts +++ b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.ts @@ -130,6 +130,8 @@ export class AddEditComponentV2 implements OnInit { return this.i18nService.t(partOne, this.i18nService.t("typeIdentity").toLowerCase()); case CipherType.SecureNote: return this.i18nService.t(partOne, this.i18nService.t("note").toLowerCase()); + case CipherType.SshKey: + return this.i18nService.t(partOne, this.i18nService.t("typeSshKey").toLowerCase()); } } diff --git a/apps/web/src/app/vault/individual-vault/add-edit.component.ts b/apps/web/src/app/vault/individual-vault/add-edit.component.ts index b4bd42a389..8f8c477951 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit.component.ts +++ b/apps/web/src/app/vault/individual-vault/add-edit.component.ts @@ -100,6 +100,14 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On async ngOnInit() { await super.ngOnInit(); await this.load(); + + // https://bitwarden.atlassian.net/browse/PM-10413 + // cannot generate ssh keys so block creation + if (this.type === CipherType.SshKey && this.cipherId == null) { + this.type = CipherType.Login; + this.cipher.type = CipherType.Login; + } + this.viewOnly = !this.cipher.edit && this.editMode; // remove when all the title for all clients are updated to New Item if (this.cloneMode || !this.editMode) { diff --git a/apps/web/src/app/vault/individual-vault/vault.component.html b/apps/web/src/app/vault/individual-vault/vault.component.html index 679d2ce6f7..75332dcf72 100644 --- a/apps/web/src/app/vault/individual-vault/vault.component.html +++ b/apps/web/src/app/vault/individual-vault/vault.component.html @@ -1,4 +1,6 @@ - + ; private activeUserId: UserId; - protected organizationsPaymentStatus: FreeTrial[] = []; private searchText$ = new Subject(); private refresh$ = new BehaviorSubject(null); private destroy$ = new Subject(); @@ -208,6 +208,37 @@ export class VaultComponent implements OnInit, OnDestroy { ), ); + protected organizationsPaymentStatus$: Observable = combineLatest([ + this.organizationService.organizations$.pipe( + map((organizations) => organizations?.filter((org) => org.isOwner) ?? []), + ), + this.hasSubscription$, + ]).pipe( + switchMap(([ownerOrgs, hasSubscription]) => { + if (!ownerOrgs || ownerOrgs.length === 0 || !hasSubscription) { + return of([]); + } + return combineLatest( + ownerOrgs.map((org) => + combineLatest([ + this.organizationApiService.getSubscription(org.id), + this.organizationBillingService.getPaymentSource(org.id), + ]).pipe( + map(([subscription, paymentSource]) => { + return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues( + org, + subscription, + paymentSource, + ); + }), + ), + ), + ); + }), + map((results) => results.filter((result) => result.shownBanner)), + shareReplay({ refCount: false, bufferSize: 1 }), + ); + constructor( private syncService: SyncService, private route: ActivatedRoute, @@ -241,6 +272,7 @@ export class VaultComponent implements OnInit, OnDestroy { private organizationApiService: OrganizationApiServiceAbstraction, protected billingApiService: BillingApiServiceAbstraction, private trialFlowService: TrialFlowService, + private organizationBillingService: OrganizationBillingServiceAbstraction, ) {} async ngOnInit() { @@ -423,36 +455,6 @@ export class VaultComponent implements OnInit, OnDestroy { this.unpaidSubscriptionDialog$.pipe(takeUntil(this.destroy$)).subscribe(); - const organizationsPaymentStatus$ = combineLatest([ - this.organizationService.organizations$, - this.hasSubscription$, - ]).pipe( - switchMap(([allOrganizations, hasSubscription]) => { - if (!allOrganizations || allOrganizations.length === 0 || !hasSubscription) { - return of([]); - } - return combineLatest( - allOrganizations - .filter((org) => org.isOwner && hasSubscription) - .map((org) => - combineLatest([ - this.organizationApiService.getSubscription(org.id), - this.organizationApiService.getBilling(org.id), - ]).pipe( - map(([subscription, billing]) => { - return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues( - org, - subscription, - billing?.paymentSource, - ); - }), - ), - ), - ); - }), - map((results) => results.filter((result) => result.shownBanner)), - ); - firstSetup$ .pipe( switchMap(() => this.refresh$), @@ -466,7 +468,6 @@ export class VaultComponent implements OnInit, OnDestroy { ciphers$, collections$, selectedCollection$, - organizationsPaymentStatus$, ]), ), takeUntil(this.destroy$), @@ -480,7 +481,6 @@ export class VaultComponent implements OnInit, OnDestroy { ciphers, collections, selectedCollection, - organizationsPaymentStatus, ]) => { this.filter = filter; this.canAccessPremium = canAccessPremium; @@ -496,7 +496,6 @@ export class VaultComponent implements OnInit, OnDestroy { this.showBulkMove = filter.type !== "trash"; this.isEmpty = collections?.length === 0 && ciphers?.length === 0; - this.organizationsPaymentStatus = organizationsPaymentStatus; this.performingInitialLoad = false; this.refreshing = false; }, diff --git a/apps/web/src/app/vault/org-vault/vault.component.ts b/apps/web/src/app/vault/org-vault/vault.component.ts index 64318047b9..18cc6e49ab 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -48,6 +48,7 @@ import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { OrganizationBillingServiceAbstraction } from "@bitwarden/common/billing/abstractions"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billing-api.service.abstraction"; import { EventType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -252,6 +253,7 @@ export class VaultComponent implements OnInit, OnDestroy { private organizationApiService: OrganizationApiServiceAbstraction, private trialFlowService: TrialFlowService, protected billingApiService: BillingApiServiceAbstraction, + private organizationBillingService: OrganizationBillingServiceAbstraction, ) {} async ngOnInit() { @@ -595,15 +597,11 @@ export class VaultComponent implements OnInit, OnDestroy { combineLatest([ of(org), this.organizationApiService.getSubscription(org.id), - this.organizationApiService.getBilling(org.id), + this.organizationBillingService.getPaymentSource(org.id), ]), ), - map(([org, sub, billing]) => { - return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues( - org, - sub, - billing?.paymentSource, - ); + map(([org, sub, paymentSource]) => { + return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues(org, sub, paymentSource); }), ); diff --git a/apps/web/src/connectors/duo-redirect.ts b/apps/web/src/connectors/duo-redirect.ts index 2b8a3de4de..a113c6b975 100644 --- a/apps/web/src/connectors/duo-redirect.ts +++ b/apps/web/src/connectors/duo-redirect.ts @@ -51,14 +51,12 @@ window.addEventListener("load", async () => { */ function redirectToDuoFrameless(redirectUrl: string) { const validateUrl = new URL(redirectUrl); + const validDuoUrl = + validateUrl.protocol === "https:" && + (validateUrl.hostname.endsWith(".duosecurity.com") || + validateUrl.hostname.endsWith(".duofederal.com")); - if ( - validateUrl.protocol !== "https:" || - !( - validateUrl.hostname.endsWith("duosecurity.com") || - validateUrl.hostname.endsWith("duofederal.com") - ) - ) { + if (!validDuoUrl) { throw new Error("Invalid redirect URL"); } diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 0930f9b0e7..d6fe5401d4 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Wagwoordgeskiedenis" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Daar is geen wagwoorde om te lys nie." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Wis", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 7a5e63d9b8..407ed12cca 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -527,10 +527,10 @@ "description": "Search Secure Note type" }, "searchVault": { - "message": "البحث في الخزنة" + "message": "البحث في الخزانة" }, "searchMyVault": { - "message": "البحث في خزنتي" + "message": "البحث في خزانتي" }, "searchOrganization": { "message": "البحث عن المؤسسة" @@ -789,19 +789,19 @@ "message": "أنا" }, "myVault": { - "message": "خزنتي" + "message": "خزانتي" }, "allVaults": { - "message": "جميع الخزنات" + "message": "جميع الخزانات" }, "vault": { - "message": "الخزنة" + "message": "الخزانة" }, "vaults": { - "message": "الخزنات" + "message": "الخزانات" }, "vaultItems": { - "message": "عناصر الخزنة" + "message": "عناصر الخزانة" }, "filter": { "message": "تصفية" @@ -976,7 +976,7 @@ "message": "لا" }, "loginOrCreateNewAccount": { - "message": "قم بتسجيل الدخول أو أنشئ حساباً جديداً لتتمكن من الوصول إلى خزنتك السرية." + "message": "قم بتسجيل الدخول أو أنشئ حساباً جديداً لتتمكن من الوصول إلى خزانتك السرية." }, "loginWithDevice": { "message": "تسجيل الدخول باستخدام جهاز" @@ -1132,7 +1132,7 @@ "message": "كلمة المرور الرئيسية" }, "masterPassDesc": { - "message": "كلمة المرور الرئيسية هي كلمة المرور التي تستخدمها للوصول إلى خزنتك. من المهم جدا ألا تنسى كلمة المرور الرئيسية. لا توجد طريقة لاسترداد كلمة المرور في حال نسيتها." + "message": "كلمة المرور الرئيسية هي كلمة المرور التي تستخدمها للوصول إلى خزانتك. من المهم جدا ألا تنسى كلمة المرور الرئيسية. لا توجد طريقة لاسترداد كلمة المرور في حال نسيتها." }, "masterPassImportant": { "message": "لا يمكن استعادة كلمة المرور الرئيسية إذا نسيتها!" @@ -1500,7 +1500,7 @@ "message": "تحذير" }, "confirmVaultExport": { - "message": "تأكيد تصدير الخزنة" + "message": "تأكيد تصدير الخزانة" }, "confirmSecretsExport": { "message": "Confirm secrets export" @@ -1524,7 +1524,7 @@ "message": "Export from" }, "exportVault": { - "message": "تصدير الخزنة" + "message": "تصدير الخزانة" }, "exportSecrets": { "message": "Export secrets" @@ -1575,7 +1575,7 @@ "message": "This file is password-protected. Please enter the file password to import data." }, "exportSuccess": { - "message": "تم تصدير بيانات الخزنة الخاصة بك." + "message": "تم تصدير بيانات الخزانة الخاصة بك" }, "passwordGenerator": { "message": "مولّد كلمات المرور" @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "سجل كلمات المرور" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "مسح", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -1777,7 +1795,7 @@ } }, "purgeVault": { - "message": "مسح الخزنة" + "message": "مسح الخزانة" }, "purgedOrganizationVault": { "message": "Purged organization vault." @@ -1940,7 +1958,7 @@ "message": "التفضيلات" }, "preferencesDesc": { - "message": "تخصيص تجرِبة خزنة الويب الخاصة بك." + "message": "تخصيص تجرِبة خزانة الويب الخاصة بك." }, "preferencesUpdated": { "message": "Preferences saved" @@ -1949,7 +1967,7 @@ "message": "اللّغة" }, "languageDesc": { - "message": "تغيير اللغة المستخدمة في خزنة الويب." + "message": "تغيير اللغة المستخدمة في خزانة الويب." }, "enableFavicon": { "message": "إظهار أيقونات الموقع" @@ -4313,7 +4331,7 @@ "message": "عوامل التصفية" }, "vaultTimeout": { - "message": "مهلة الخزنة" + "message": "مهلة الخزانة" }, "vaultTimeout1": { "message": "Timeout" @@ -4446,7 +4464,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." }, "fingerprintMatchInfo": { - "message": "الرجاء التأكد من أن الخزنة الخاصة بك غير مقفلة وأن بصمة الإصبع تتطابق مع الجهاز الآخر." + "message": "الرجاء التأكد من أن الخزانة الخاصة بك غير مقفلة وأن بصمة الإصبع تتطابق مع الجهاز الآخر." }, "fingerprintPhraseHeader": { "message": "بصمة الإصبع" @@ -4579,13 +4597,13 @@ "message": "User preference" }, "vaultTimeoutAction": { - "message": "إجراء مهلة الخزنة" + "message": "إجراء مهلة الخزانة" }, "vaultTimeoutActionLockDesc": { - "message": "الخزنة المقفلة تتطلب إعادة إدخال كلمة المرور الرئيسية الخاصة بك للوصول إليها مرة أخرى." + "message": "الخزانة المقفلة تتطلب إعادة إدخال كلمة المرور الرئيسية الخاصة بك للوصول إليها مرة أخرى." }, "vaultTimeoutActionLogOutDesc": { - "message": "تسجيل الخروج من الخزنة يتطلب إعادة المصادقة للوصول إليها مرة أخرى." + "message": "تسجيل الخروج من الخزانة يتطلب إعادة المصادقة للوصول إليها مرة أخرى." }, "lock": { "message": "قفل", @@ -5557,7 +5575,7 @@ "message": "المظهر" }, "themeDesc": { - "message": "اختر مظهر خزنة الويب خاصتك." + "message": "اختر مظهر خزانة الويب خاصتك." }, "themeSystem": { "message": "تلقائي" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 47b0ee377e..5f9a8fda09 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Parol tarixçəsi" }, + "generatorHistory": { + "message": "Yaradıcı tarixçəsi" + }, + "clearGeneratorHistoryTitle": { + "message": "Yaradıcı tarixçəsini təmizlə" + }, + "cleargGeneratorHistoryDescription": { + "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." }, + "clearHistory": { + "message": "Tarixçəni təmizlə" + }, + "nothingToShow": { + "message": "Göstəriləcək heç nə yoxdur" + }, + "nothingGeneratedRecently": { + "message": "Təzəlikcə heç nə yaratmamısınız" + }, "clear": { "message": "Təmizlə", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Bütün seansların səlahiyyəti götürüldü" }, - "accountIsManagedMessage": { - "message": "Bu hesab $ORGANIZATIONNAME$ tərəfindən idarə olunur", + "accountIsOwnedMessage": { + "message": "$ORGANIZATIONNAME$ bu hesabın sahibidir", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Giriş başladıldı" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Gələcək girişləri problemsiz etmək üçün bu cihazı xatırla" }, "deviceApprovalRequired": { "message": "Cihaz təsdiqi tələb olunur. Aşağıdan bir təsdiq variantı seçin:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Cihaz təsdiqi tələb olunur" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Aşağıdan bir təsdiq seçimi edin" }, "rememberThisDevice": { "message": "Bu cihazı xatırla" @@ -8293,7 +8311,7 @@ "message": "İstifadəçi e-poçtu əskikdir" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktiv istifadəçi e-poçtu tapılmadı. Hesabınızdan çıxış edilir." }, "deviceTrusted": { "message": "Cihaz güvənlidir" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Təşkilat üçün kolleksiya davranışını idarə et" }, - "limitCollectionCreationDeletionDesc": { - "message": "Kolleksiya yaradılmasını və silinməsini sahibləri və adminləri ilə məhdudlaşdır" - }, "limitCollectionCreationDesc": { "message": "Kolleksiya yaradılmasını sahibləri və adminləri ilə məhdudlaşdır" }, diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 0e709bc33c..ff1d68e970 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Гісторыя пароляў" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "У спісе адсутнічаюць паролі." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Ачысціць", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Аўтарызацыя ўсіх сеансаў скасавана" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index bbdb722984..6df82896f9 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Хронология на паролата" }, + "generatorHistory": { + "message": "История на генерирането" + }, + "clearGeneratorHistoryTitle": { + "message": "Изчистване на историята на генериране" + }, + "cleargGeneratorHistoryDescription": { + "message": "Ако продължите, всички записи в историята на генериране ще бъдат изтрити завинаги. Наистина ли искате това?" + }, "noPasswordsInList": { "message": "Няма пароли за показване." }, + "clearHistory": { + "message": "Изчистване на историята" + }, + "nothingToShow": { + "message": "Няма нищо за показване" + }, + "nothingGeneratedRecently": { + "message": "Скоро не сте генерирали нищо" + }, "clear": { "message": "Изчистване", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Всички сесии са прекратени" }, - "accountIsManagedMessage": { - "message": "Тази регистрация се управлява от $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Тази регистрация е притежание на $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Вписването е стартирано" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Запомняне на това устройство, така че в бъдеще вписването да бъде по-лесно" }, "deviceApprovalRequired": { "message": "Изисква се одобрение на устройството. Изберете начин за одобрение по-долу:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Необходимо е одобрение на устройството" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Изберете начин за одобряване по-долу" }, "rememberThisDevice": { "message": "Запомняне на това устройство" @@ -8293,7 +8311,7 @@ "message": "Липсва е-поща на потребителя" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Не е намерена е-поща на активен потребител. Ще бъдете отписан(а)." }, "deviceTrusted": { "message": "Устройството е доверено" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Управление на поведението на колекциите за организацията" }, - "limitCollectionCreationDeletionDesc": { - "message": "Ограничаване на създаването и изтриването на колекции, така че да може да се извършва само от собствениците и администраторите" - }, "limitCollectionCreationDesc": { "message": "Ограничаване на създаването на колекции, така че да може да се извършва само от собствениците и администраторите" }, diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 6cf67fcee6..1e2fb12f3b 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 9e221e721f..5acd4aa9d6 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 4e5e78f3c5..a1b591f8df 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Historial de les contrasenyes" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "No hi ha cap contrasenya a llistar." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Esborra", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Totes les sessions estan desautoritzades" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Administra el comportament de col·lecció per a l'organització" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limita la creació i la supressió de col·leccions als propietaris i administradors" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 2135f0e01a..147af1e94a 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Historie hesel" }, + "generatorHistory": { + "message": "Historie generátoru" + }, + "clearGeneratorHistoryTitle": { + "message": "Vymazat historii generátoru" + }, + "cleargGeneratorHistoryDescription": { + "message": "Pokud budete pokračovat, všechny položky budou trvale smazány z historie generátoru. Jste si jisti, že chcete pokračovat?" + }, "noPasswordsInList": { "message": "Nejsou k dispozici žádná hesla." }, + "clearHistory": { + "message": "Vymazat historii" + }, + "nothingToShow": { + "message": "Nic k zobrazení" + }, + "nothingGeneratedRecently": { + "message": "Nedávno jste nic nevygenerovali" + }, "clear": { "message": "Vymazat", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Všechny relace byly zrušeny" }, - "accountIsManagedMessage": { - "message": "Tento účet je spravován: $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Tento účet je vlastněn: $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Bylo zahájeno přihlášení" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Zapamatovat si toto zařízení pro bezproblémové budoucí přihlášení" }, "deviceApprovalRequired": { "message": "Vyžaduje se schválení zařízení. Vyberte možnost schválení níže:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Vyžaduje se schválení zařízení" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Vyberte volbu schválení níže" }, "rememberThisDevice": { "message": "Zapamatovat toto zařízení" @@ -8293,7 +8311,7 @@ "message": "Chybí e-mail uživatele" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktivní uživatelský e-mail nebyl nalezen. Budete odhlášeni." }, "deviceTrusted": { "message": "Zařízení zařazeno mezi důvěryhodné" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Spravuje chování kolekce pro organizaci" }, - "limitCollectionCreationDeletionDesc": { - "message": "Omezí vytváření a mazání kolekce na vlastníky a správce" - }, "limitCollectionCreationDesc": { "message": "Omezí vytváření kolekce na vlastníky a správce" }, diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 0839ac7f9f..91d6f860aa 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index e1cb4d28f2..eeb2d86c9f 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Adgangskodehistorik" }, + "generatorHistory": { + "message": "Generatorhistorik" + }, + "clearGeneratorHistoryTitle": { + "message": "Ryd generatorhistorik" + }, + "cleargGeneratorHistoryDescription": { + "message": "Fortsætter man, slettes alle poster permanent fra generatorhistorikken. Sikker på, at handlingen skal udføres?" + }, "noPasswordsInList": { "message": "Der er ingen adgangskoder at vise." }, + "clearHistory": { + "message": "Ryd historik" + }, + "nothingToShow": { + "message": "Intet at vise" + }, + "nothingGeneratedRecently": { + "message": "Intet genereret for nylig" + }, "clear": { "message": "Ryd", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Godkendelser for alle sessioner fjernet" }, - "accountIsManagedMessage": { - "message": "Denne konto håndteres af $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Denne konto ejes af $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Indlogning påbegyndt" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Husk denne enhed for at gøre fremtidige indlogninger gnidningsløse" }, "deviceApprovalRequired": { "message": "Enhedsgodkendelse kræves. Vælg en godkendelsesmulighed nedenfor:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Enhedsgodkendelse kræves" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Vælg en godkendelsesmulighed nedenfor" }, "rememberThisDevice": { "message": "Husk denne enhed" @@ -8293,7 +8311,7 @@ "message": "Brugers e-mail mangler" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktiv bruger e-mail ikke fundet. Man logges ud." }, "deviceTrusted": { "message": "Enhed betroet" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Håndtér samlingsadfærden for organisationen" }, - "limitCollectionCreationDeletionDesc": { - "message": "Begræns samlingsoprettelse og -sletning til ejere og admins" - }, "limitCollectionCreationDesc": { "message": "Begræns samlingsoprettelse til ejere og admins" }, diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 7e79831c54..59fd62a30e 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -985,7 +985,7 @@ "message": "Die Anmeldung über ein Gerät muss in den Einstellungen der Bitwarden App eingerichtet werden. Benötigst du eine andere Option?" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Brauchst du eine andere Option?" }, "loginWithMasterPassword": { "message": "Mit Master-Passwort anmelden" @@ -1309,7 +1309,7 @@ "message": "Eine Benachrichtigung wurde an dein Gerät gesendet" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Stelle sicher, dass dein Konto entsperrt ist und die Fingerabdruck-Phrase mit der vom anderen Gerät übereinstimmt" }, "versionNumber": { "message": "Version $VERSION_NUMBER$", @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Passwortverlauf" }, + "generatorHistory": { + "message": "Generator-Verlauf" + }, + "clearGeneratorHistoryTitle": { + "message": "Generator-Verlauf löschen" + }, + "cleargGeneratorHistoryDescription": { + "message": "Wenn du fortfährst, werden alle Einträge dauerhaft aus dem Generator-Verlauf gelöscht. Bist du sicher, dass du fortfahren möchtest?" + }, "noPasswordsInList": { "message": "Keine Passwörter vorhanden." }, + "clearHistory": { + "message": "Verlauf löschen" + }, + "nothingToShow": { + "message": "Nichts anzuzeigen" + }, + "nothingGeneratedRecently": { + "message": "Du hast in letzter Zeit nichts generiert" + }, "clear": { "message": "Löschen", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Alle Sitzungen wurden abgemeldet" }, - "accountIsManagedMessage": { - "message": "Dieses Konto wird von $ORGANIZATIONNAME$ verwaltet", + "accountIsOwnedMessage": { + "message": "Dieses Konto ist im Besitz von $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -3397,7 +3415,7 @@ } }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Alle Anmeldeoptionen anzeigen" }, "viewAllLoginOptions": { "message": "Alle Anmeldeoptionen anzeigen" @@ -4456,7 +4474,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." }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Du wirst benachrichtigt, sobald die Anfrage genehmigt wurde" }, "free": { "message": "Free", @@ -6392,7 +6410,7 @@ "message": "Erforderlich, wenn die Entitäts-ID keine URL ist." }, "offerNoLongerValid": { - "message": "This offer is no longer valid. Contact your organization administrators for more information." + "message": "Dieses Angebot ist nicht mehr gültig. Kontaktiere die Administratoren deiner Organisation für weitere Informationen." }, "openIdOptionalCustomizations": { "message": "Optionale Anpassungen" @@ -6501,7 +6519,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Benutze $RECOMMENDED$ oder mehr Zeichen um ein starkes Passwort zu generieren.", + "message": " Verwende $RECOMMENDED$ oder mehr Zeichen, um ein starkes Passwort zu generieren.", "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": { @@ -6511,7 +6529,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Verwende $RECOMMENDED$ oder mehr Wörter, um eine starke Passphrase zu generieren.", "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": { @@ -8052,16 +8070,16 @@ "message": "Anmeldung eingeleitet" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Dieses Gerät merken, um zukünftige Anmeldungen reibungslos zu gestalten" }, "deviceApprovalRequired": { "message": "Geräte-Genehmigung erforderlich. Wähle unten eine Genehmigungsoption aus:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Geräte-Genehmigung erforderlich" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Wähle unten eine Genehmigungsoption aus" }, "rememberThisDevice": { "message": "Dieses Gerät merken" @@ -8293,7 +8311,7 @@ "message": "E-Mail-Adresse des Benutzers fehlt" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktive Benutzer-E-Mail-Adresse nicht gefunden. Du wirst abgemeldet." }, "deviceTrusted": { "message": "Gerät wird vertraut" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Verwalte das Sammlungsverhalten für die Organisation" }, - "limitCollectionCreationDeletionDesc": { - "message": "Sammlungserstellung und -löschung auf Eigentümer und Administratoren beschränken" - }, "limitCollectionCreationDesc": { "message": "Das Erstellen von Sammlungen auf Eigentümer und Administratoren beschränken" }, @@ -9675,7 +9690,7 @@ "message": "Bist du sicher, dass du diesen Anhang dauerhaft löschen möchtest?" }, "manageSubscriptionFromThe": { - "message": "verwalten", + "message": "Verwalte das Abonnement von", "description": "This represents the beginning of a sentence. The full sentence will be 'Manage subscription from the Provider Portal', but 'Provider Portal' will be a link and thus cannot be included in the translation file." }, "toHostBitwardenOnYourOwnServer": { @@ -9759,18 +9774,18 @@ "message": "Erfolgreich gelöscht" }, "freeFamiliesSponsorship": { - "message": "Remove Free Bitwarden Families sponsorship" + "message": "Kostenloses Bitwarden Families-Sponsoring entfernen" }, "freeFamiliesSponsorshipPolicyDesc": { - "message": "Do not allow members to redeem a Families plan through this organization." + "message": "Erlaube Mitgliedern nicht, einen Families-Tarif über diese Organisation einzulösen." }, "verifyBankAccountWithStatementDescriptorWarning": { - "message": "Payment with a bank account is only available to customers in the United States. You will be required to verify your bank account. We will make a micro-deposit within the next 1-2 business days. Enter the statement descriptor code from this deposit on the organization's billing page to verify the bank account. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + "message": "Die Zahlung mit einem Bankkonto ist nur für Kunden in den Vereinigten Staaten möglich. Du musst dein Bankkonto verifizieren. Wir werden innerhalb der nächsten 1-2 Werktage eine Mikro-Einzahlung vornehmen. Gib den Code aus der Beschreibung dieser Einzahlung auf der Rechnungsseite der Organisation ein, um das Bankkonto zu verifizieren. Schlägt die Verifizierung des Bankkontos fehl, wird dies als versäumte Zahlung gewertet und dein Abonnement gesperrt." }, "verifyBankAccountWithStatementDescriptorInstructions": { - "message": "We have made a micro-deposit to your bank account (this may take 1-2 business days). Enter the six-digit code starting with 'SM' found on the deposit description. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + "message": "Wir haben eine Mikro-Einzahlung auf dein Bankkonto vorgenommen (dies kann 1-2 Werktage dauern). Gib den sechsstelligen Code ein, der mit \"SM\" beginnt und in der Einzahlungsbeschreibung steht. Schlägt die Verifizierung des Bankkontos fehl, wird dies als versäumte Zahlung gewertet und dein Abonnement gesperrt." }, "descriptorCode": { - "message": "Descriptor code" + "message": "Beschreibungscode" } } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index aa9cb47b13..110286543c 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Ιστορικό Κωδικού" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Δεν υπάρχουν κωδικοί στη λίστα." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Εκκαθάριση", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Η Ανακληθεί η Πρόσβαση από Όλες τις Συνεδρίες" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 0c1558a35d..cab0e703a7 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -29,6 +29,33 @@ "notifiedMembers": { "message": "Notified members" }, + "revokeMembers": { + "message": "Revoke members" + }, + "restoreMembers": { + "message": "Restore members" + }, + "revokeMembersWarning":{ + "message": "Members with claimed and unclaimed accounts will have different results when revoked:" + }, + "claimedAccountRevoke": { + "message": "Claimed account: Revoke access to Bitwarden account" + }, + "unclaimedAccountRevoke": { + "message": "Unclaimed account: Revoke access to organization data" + }, + "claimedAccount": { + "message": "Claimed account" + }, + "unclaimedAccount": { + "message": "Unclaimed account" + }, + "restoreMembersInstructions": { + "message": "To restore a member's account, go to the Revoked tab. The process may take a few seconds to complete and cannot be interrupted or canceled." + }, + "cannotRestoreAccessError":{ + "message": "Cannot restore organization access" + }, "allApplicationsWithCount": { "message": "All applications ($COUNT$)", "placeholders": { @@ -1110,6 +1137,12 @@ "logInToBitwarden": { "message": "Log in to Bitwarden" }, + "authenticationTimeout": { + "message": "Authentication timeout" + }, + "authenticationSessionTimedOut": { + "message": "The authentication session timed out. Please restart the login process." + }, "verifyIdentity": { "message": "Verify your Identity" }, @@ -1785,8 +1818,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -5610,6 +5643,12 @@ "bulkFilteredMessage": { "message": "Excluded, not applicable for this action" }, + "nonCompliantMembersTitle":{ + "message": "Non-compliant members" + }, + "nonCompliantMembersError":{ + "message": "Members that are non-compliant with the Single organization or Two-step login policy cannot be restored until they adhere to the policy requirements" + }, "fingerprint": { "message": "Fingerprint" }, @@ -9715,9 +9754,19 @@ "description": "Title for the delete organization user dialog" } }, - "deleteOrganizationUserWarning": { - "message": "When a member is deleted, their Bitwarden account and individual vault data will be permanently deleted. Collection data will remain in the organization. To reinstate them they must create an account and be onboarded again.", - "description": "Warning for the delete organization user dialog" + "deleteOrganizationUserWarningDesc": { + "message": "This will permanently delete all items owned by $NAME$. Collection items are not impacted.", + "description": "Warning description for the delete organization user dialog", + "placeholders": { + "name": { + "content": "$1", + "example": "John Doe" + } + } + }, + "deleteManyOrganizationUsersWarningDesc": { + "message": "This will permanently delete all items owned by the following members. Collection items are not impacted.", + "description": "Warning description for the bulk delete organization users dialog" }, "organizationUserDeleted": { "message": "Deleted $NAME$", @@ -9787,5 +9836,8 @@ }, "descriptorCode": { "message": "Descriptor code" + }, + "removeMembers": { + "message": "Remove members" } } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 9039334134..beadcfc710 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorised" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behaviour for the organisation" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index ba89bea21c..1ca16a1704 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorised" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behaviour for the organisation" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index eab492710a..7c4061ad35 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Pasvorta Historio" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Ne estas listigitaj pasvortoj." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Malplenigi", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Ĉiuj Sesioj Neaŭtorizitaj" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 1a51107dfe..ef1152c04b 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -27,10 +27,10 @@ } }, "notifiedMembers": { - "message": "Notified members" + "message": "Miembros notificados" }, "allApplicationsWithCount": { - "message": "All applications ($COUNT$)", + "message": "Todas las aplicaciones ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -42,7 +42,7 @@ "message": "Create new login item" }, "criticalApplicationsWithCount": { - "message": "Critical applications ($COUNT$)", + "message": "Aplicaciones críticas ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -51,7 +51,7 @@ } }, "notifiedMembersWithCount": { - "message": "Notified members ($COUNT$)", + "message": "Miembros notificados ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -87,7 +87,7 @@ "message": "Apps marked as critical" }, "application": { - "message": "Application" + "message": "Aplicación" }, "atRiskPasswords": { "message": "At-risk passwords" @@ -759,31 +759,31 @@ "message": "Copy website" }, "copyNotes": { - "message": "Copy notes" + "message": "Copiar notas" }, "copyAddress": { - "message": "Copy address" + "message": "Copiar dirección" }, "copyPhone": { - "message": "Copy phone" + "message": "Copiar teléfono" }, "copyEmail": { - "message": "Copy email" + "message": "Copiar correo electrónico" }, "copyCompany": { "message": "Copy company" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Copiar número de seguro social" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "Copiar número de pasaporte" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "Copiar número de licencia" }, "copyName": { - "message": "Copy name" + "message": "Copiar nombre" }, "me": { "message": "Yo" @@ -952,7 +952,7 @@ "message": "Restart registration" }, "expiredLink": { - "message": "Expired link" + "message": "Enlace expirado" }, "pleaseRestartRegistrationOrTryLoggingIn": { "message": "Please restart registration or try logging in." @@ -1169,10 +1169,10 @@ "message": "Configuración" }, "accountEmail": { - "message": "Account email" + "message": "Correo electrónico de la cuenta" }, "requestHint": { - "message": "Request hint" + "message": "Solicitar pista" }, "requestPasswordHint": { "message": "Request password hint" @@ -1221,7 +1221,7 @@ "message": "Your new account has been created!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "¡Has iniciado sesión!" }, "trialAccountCreated": { "message": "Cuenta creada con éxito." @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Historial de contraseñas" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "No hay contraseñas que listar." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Limpiar", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Desautorizadas todas las sesiones" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Administrar el comportamiento de la colección para la organización" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, @@ -8654,16 +8669,16 @@ } }, "addField": { - "message": "Add field" + "message": "Añadir campo" }, "editField": { - "message": "Edit field" + "message": "Editar campo" }, "items": { "message": "Elementos" }, "assignedSeats": { - "message": "Assigned seats" + "message": "Asientos asignados" }, "assigned": { "message": "Asignado" @@ -8678,16 +8693,16 @@ "message": "Desvincular organización" }, "manageSeats": { - "message": "MANAGE SEATS" + "message": "GESTIONAR ASIENTOS" }, "manageSeatsDescription": { "message": "Adjustments to seats will be reflected in the next billing cycle." }, "unassignedSeatsDescription": { - "message": "Unassigned seats" + "message": "Asientos no asignados" }, "purchaseSeatDescription": { - "message": "Additional seats purchased" + "message": "Asientos adicionales comprados" }, "assignedSeatCannotUpdate": { "message": "Assigned Seats can not be updated. Please contact your organization owner for assistance." diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index 01b64364ea..b82a600afa 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Paroolide ajalugu" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Puuduvad paroolid, mida kuvada." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Tühjenda", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Kõikidest seadmetest on välja logitud" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index 158233471d..bd8e1febd5 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Pasahitz historia" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Ez dago erakusteko pasahitzik." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Ezabatu", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Saio guztiei baimena kendua" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index 870ffb1f8e..beb39cd47a 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "تاریخچه کلمه عبور" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "هیچ کلمه عبوری برای فهرست کردن وجود ندارد." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "پاک کردن", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "همه نشست‌ها غیرمجاز است" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 95aa99cdb7..4a27d1b5f5 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Salasanahistoria" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Näytettäviä salasanoja ei ole." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Tyhjennä", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Kaikki istunnot mitätöitiin" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Voi hallita organisaation kokoelmien toimintaa." }, - "limitCollectionCreationDeletionDesc": { - "message": "Rajoita kokoelmien luonti ja poisto omistajille ja ylläpitäjille" - }, "limitCollectionCreationDesc": { "message": "Rajoita kokoelmien luonti omistajille ja ylläpitäjille" }, diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 44ecebc6e6..536dbeaebc 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Kasaysayan ng password" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Walang maililistang password." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Burahin", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Na-deauthorize lahat ng mga sesyon" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index fe0e9dc0e5..3bbed3aba4 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Historique des mots de passe" }, + "generatorHistory": { + "message": "Historique du générateur" + }, + "clearGeneratorHistoryTitle": { + "message": "Effacer l'historique du générateur" + }, + "cleargGeneratorHistoryDescription": { + "message": "Si vous continuez, toutes les entrées seront définitivement supprimées de l'historique du générateur. Êtes-vous sûr de vouloir continuer?" + }, "noPasswordsInList": { "message": "Aucun mot de passe à afficher." }, + "clearHistory": { + "message": "Effacer l'historique" + }, + "nothingToShow": { + "message": "Rien à afficher" + }, + "nothingGeneratedRecently": { + "message": "Vous n'avez rien généré récemment" + }, "clear": { "message": "Effacer", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Toutes les sessions ont été révoquées" }, - "accountIsManagedMessage": { - "message": "Ce compte est géré par $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Ce compte appartient à $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Connexion initiée" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Se souvenir de cet appareil pour rendre les connexions futures transparentes" }, "deviceApprovalRequired": { "message": "L'approbation de l'appareil est requise. Sélectionnez une option d'approbation ci-dessous:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Autorisation de l'appareil requise" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Sélectionnez une option d'approbation ci-dessous" }, "rememberThisDevice": { "message": "Se souvenir de cet appareil" @@ -8293,7 +8311,7 @@ "message": "Courriel de l'utilisateur manquant" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Courriel de l'utilisateur actif introuvable. Vous allez être déconnecté." }, "deviceTrusted": { "message": "Appareil de confiance" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Gérer le comportement de la collection pour l'organisation" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limiter la création et la suppression de la collection aux propriétaires et administrateurs" - }, "limitCollectionCreationDesc": { "message": "Limiter la création de collections aux propriétaires et administrateurs" }, diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index a492300c13..ceda4ca59d 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 411ef267e4..9da5dfe492 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "היסטוריית סיסמאות" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "אין סיסמאות להצגה ברשימה." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "נקה", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "הוסרה ההרשאה מכל הסשנים" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 2cd148e301..7c8ecd4473 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 2fc33c3b34..5a5ca9b979 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Povijest" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Nema lozinki na popisu." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Očisti", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Sve sesije deautorizirane" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Upravljaj ponašanjem zbirki za organizaciju" }, - "limitCollectionCreationDeletionDesc": { - "message": "Ograniči kreiranje i brisanje zbirki vlasnicima i adminima" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 2ae6a5f699..7042ac1f6a 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Jelszóelőzmények" }, + "generatorHistory": { + "message": "Generátor előzmények" + }, + "clearGeneratorHistoryTitle": { + "message": "Generátor előzmények kiürítése" + }, + "cleargGeneratorHistoryDescription": { + "message": "Ha folytatjuk, az összes bejegyzés véglegesen törlődik a generátor előzményeiből. Biztosan folytatjuk?" + }, "noPasswordsInList": { "message": "Nincsenek listázható jelszavak." }, + "clearHistory": { + "message": "Előzmények törlése" + }, + "nothingToShow": { + "message": "Nincs megjeleníthető elem" + }, + "nothingGeneratedRecently": { + "message": "Mostanában nem lett semmi generálva." + }, "clear": { "message": "Kiürítés", "description": "To clear something out. Example: To clear browser history." @@ -1767,7 +1785,7 @@ "sessionsDeauthorized": { "message": "Az összes munkamenet hitelesítése eldobásra került." }, - "accountIsManagedMessage": { + "accountIsOwnedMessage": { "message": "Ezt a fiókot $ORGANIZATIONNAME$ kezeli.", "placeholders": { "organizationName": { @@ -8052,16 +8070,16 @@ "message": "A bejelentkezés elindításra került." }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Emlékezés az eszközre, hogy zökkenőmentes legyen a jövőbeni bejelentkezés" }, "deviceApprovalRequired": { "message": "Az eszköz jóváhagyása szükséges. Válasszunk egy jóváhagyási lehetőséget lentebb:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Eszköz jóváhagyás szükséges" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Válasszunk lentebb egy jóváhagyási lehetőséget." }, "rememberThisDevice": { "message": "Eszköz megjegyzése" @@ -8293,7 +8311,7 @@ "message": "A felhasználói email cím hiányzik." }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "" }, "deviceTrusted": { "message": "Az eszköz megbízható." @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Gyűjtési viselkedést kezelhet a szervezetnek" }, - "limitCollectionCreationDeletionDesc": { - "message": "A gyűjtemény létrehozásának és törlésének korlátozása tulajdonosokra és adminisztrátorokra" - }, "limitCollectionCreationDesc": { "message": "A gyűjtemény létrehozásának korlátozása tulajdonosokra és adminisztrátorokra" }, diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 9bc97de8a3..53b7fb2714 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Riwayat Kata Sandi" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Tidak ada sandi yang dapat dicantumkan." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Bersihkan", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Semua Sesi Dicabut Izinnya" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 321e52e4b1..e37992b812 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Cronologia delle password" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Non ci sono password da mostrare." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Cancella", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Tutte le sessioni revocate" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Gestisci il comportamento delle raccolte per l'organizzazione" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limita la creazione e l'eliminazione delle raccolte a proprietari e amministratori" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 429727af20..c212cb6f93 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "パスワードの履歴" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "表示するパスワードがありません" }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "消去する", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "全てのセッションを無効化" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "組織のコレクションに関する挙動を管理します" }, - "limitCollectionCreationDeletionDesc": { - "message": "コレクションの作成・削除を所有者と管理者のみに制限" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index d03ea96816..a3a7d9157e 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index 24d2cfb901..1ad5f52a94 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index cc80dfcbd4..1eb0012ccc 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "ಪಾಸ್ವರ್ಡ್ ಇತಿಹಾಸ" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "ಪಟ್ಟಿ ಮಾಡಲು ಯಾವುದೇ ಪಾಸ್ವರ್ಡ್ಗಳು ಇಲ್ಲ." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "ಕ್ಲಿಯರ್‌", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "ಎಲ್ಲಾ ಸೆಷನ್‌ಗಳು ಅನಧಿಕೃತವಾಗಿವೆ" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 5ccd3e177a..264e6cf7d3 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "비밀번호 변경 기록" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "비밀번호가 없습니다." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "삭제", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "모든 세션 해제 됨" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index af4908ab00..81d0dde4e6 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Paroles izmaiņu vēsture" }, + "generatorHistory": { + "message": "Veidotāja vēsture" + }, + "clearGeneratorHistoryTitle": { + "message": "Iztīrīt veidotāja vēsturi" + }, + "cleargGeneratorHistoryDescription": { + "message": "Turpinot visi veidotāja vēstures ieraksti tiks neatgrieziniski izdzēsti. Vai tiešām turpināt?" + }, "noPasswordsInList": { "message": "Nav paroļu, ko parādīt." }, + "clearHistory": { + "message": "Iztīrīt vēsturi" + }, + "nothingToShow": { + "message": "Nav nekā, ko parādīt" + }, + "nothingGeneratedRecently": { + "message": "Pēdējā laikā nav nekas izveidots" + }, "clear": { "message": "Notīrīt", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Visu sesiju darbība ir atsaukta" }, - "accountIsManagedMessage": { - "message": "Šo kontu pārvalda $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Šis konts pieder $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -6511,7 +6529,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Jāizmanto $RECOMMENDED$ vai vairāk vārdu, lai aizveidotu spēcīgu parles vārdkopu.", + "message": " Jāizmanto $RECOMMENDED$ vai vairāk vārdu, lai aizveidotu spēcīgu paroles vārdkopu.", "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": { @@ -8052,16 +8070,16 @@ "message": "Uzsākta pieteikšanās" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Atcerēties šo ierīci, lai nākotnes pieteikšanos padarītu plūdenāku" }, "deviceApprovalRequired": { "message": "Nepieciešams ierīces apstiprinājums. Zemāk jāatlasa apstiprinājuma iespēja:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Nepieciešama ierīces apstiprināšana" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Zemāk jāatlasa apstiprināšnas iespēja" }, "rememberThisDevice": { "message": "Atcerēties šo ierīci" @@ -8293,7 +8311,7 @@ "message": "Trūkst lietotāja e-pasta adreses" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktīva lietotāja e-pasta adrese netika atrasta. Notiek atteikšanās." }, "deviceTrusted": { "message": "Ierīce ir uzticama" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Krājumu uzvedības pārvaldība apvienībā" }, - "limitCollectionCreationDeletionDesc": { - "message": "Ļaut krājumu izveidošanu un izdzēšanu tikai īpašniekiem un pārvaldniekiem" - }, "limitCollectionCreationDesc": { "message": "Ļaut krājumu izveidošanu tikai īpašniekiem un pārvaldītājiem" }, diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index 51d65c719c..559c1e4768 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "പാസ്സ്‌വേഡ് ചരിത്രം" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "പ്രദർശിപ്പിക്കാൻ പാസ്സ്‌വേഡുകൾ ഒന്നും ഇല്ല." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "മായ്ക്കുക", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "എല്ലാ സെഷനും നിരസിച്ചു." }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index 24d2cfb901..1ad5f52a94 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index 24d2cfb901..1ad5f52a94 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index 43ba5fea30..5145af4cc1 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Passordhistorikk" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Det er ingen passord å liste opp." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Tøm", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Fjernet autoriseringen fra alle økter" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index 079a4217a0..068f477149 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 460fc01add..0f1025abd7 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Geschiedenis" }, + "generatorHistory": { + "message": "Generatorgeschiedenis" + }, + "clearGeneratorHistoryTitle": { + "message": "Generatorgeschiedenis wissen" + }, + "cleargGeneratorHistoryDescription": { + "message": "Als je doorgaat, wis je definitief de geschiedenis van de generator. Weet je zeker dat je wilt doorgaan?" + }, "noPasswordsInList": { "message": "Er zijn geen wachtwoorden om weer te geven." }, + "clearHistory": { + "message": "Geschiedenis wissen" + }, + "nothingToShow": { + "message": "Niets weer te geven" + }, + "nothingGeneratedRecently": { + "message": "Je hebt de laatste tijd niets gegenereerd" + }, "clear": { "message": "Wissen", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Autorisatie van alle sessies ingetrokken" }, - "accountIsManagedMessage": { - "message": "Dit account wordt beheerd door $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Dit account is eigendom van $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Het gedrag van de collectie beheren voor de organisatie" }, - "limitCollectionCreationDeletionDesc": { - "message": "Aanmaken en verwijderen van collecties tot eigenaren en managers beperken" - }, "limitCollectionCreationDesc": { "message": "Aanmaken van collecties beperken tot eigenaren en managers" }, diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index b47839aa8e..eb9058d8d3 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Passordoversyn" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Det er ingen passord å syna." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Tøm", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index 24d2cfb901..1ad5f52a94 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 6cabe22b90..e02e23842c 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Historia hasła" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Brak haseł." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Wyczyść", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Wszystkie sesje zostały zakończone" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Zarządzaj zachowaniami kolekcji w organizacji" }, - "limitCollectionCreationDeletionDesc": { - "message": "Ogranicz tworzenie i usuwanie kolekcji dla właścicieli i administratorów" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, @@ -9138,7 +9153,7 @@ } }, "lowKDFIterationsBanner": { - "message": "Niska liczba itracjia KDF. Zwiększ liczbę iteracji, aby zwiększyć bezpieczeństwo Twojego konta." + "message": "Niska liczba iteracji KDF. Zwiększ liczbę iteracji, aby zwiększyć bezpieczeństwo Twojego konta." }, "changeKDFSettings": { "message": "Zmień ustawienia KDF" diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 4f86642b05..5df8556ae6 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Histórico de Senha" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Não existem senhas para listar." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Limpar", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Todas as Sessões Desautorizadas" }, - "accountIsManagedMessage": { - "message": "Esta conta é gerenciada por $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Gerenciar o comportamento da coleção para a organização" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limitar criação de coleção e exclusão a proprietários e administradores" - }, "limitCollectionCreationDesc": { "message": "Limitar criação de coleção e exclusão a proprietários e administradores" }, diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 92e5c0c88e..06d56cb2f7 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Histórico de palavras-passe" }, + "generatorHistory": { + "message": "Histórico do gerador" + }, + "clearGeneratorHistoryTitle": { + "message": "Limpar o histórico do gerador" + }, + "cleargGeneratorHistoryDescription": { + "message": "Se continuar, todas as entradas serão permanentemente eliminadas do histórico do gerador. Tem a certeza de que pretende continuar?" + }, "noPasswordsInList": { "message": "Não existem palavras-passe para listar." }, + "clearHistory": { + "message": "Limpar histórico" + }, + "nothingToShow": { + "message": "Nada a mostrar" + }, + "nothingGeneratedRecently": { + "message": "Não gerou nada recentemente" + }, "clear": { "message": "Limpar", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Todas as sessões desautorizadas" }, - "accountIsManagedMessage": { - "message": "Esta conta é gerida por $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Esta conta é propriedade de $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Gerir o comportamento da coleção da organização" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limitar a criação e eliminação de coleções aos proprietários e administradores" - }, "limitCollectionCreationDesc": { "message": "Limitar a criação de coleções aos proprietários e administradores" }, diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index e8e76e800e..c5c4d7b93a 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Istoric parole" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Nicio parolă de afișat." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Ștergere", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Toate sesiunile au fost dezautorizate" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index e560c4d7be..6d86d11431 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -6,7 +6,7 @@ "message": "Критичные приложения" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "Управление доступом" }, "riskInsights": { "message": "Информация о рисках" @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "История паролей" }, + "generatorHistory": { + "message": "История генератора" + }, + "clearGeneratorHistoryTitle": { + "message": "Очистить историю генератора" + }, + "cleargGeneratorHistoryDescription": { + "message": "Если вы продолжите, все записи будут навсегда удалены из истории генератора. Вы уверены, что хотите продолжить?" + }, "noPasswordsInList": { "message": "Нет паролей для отображения." }, + "clearHistory": { + "message": "Очистить историю" + }, + "nothingToShow": { + "message": "Нечего показать" + }, + "nothingGeneratedRecently": { + "message": "Вы ничего не создавали в последнее время" + }, "clear": { "message": "Очистить", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Все сессии деавторизованы" }, - "accountIsManagedMessage": { - "message": "Управление этим аккаунтом осуществляет $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Этот аккаунт принадлежит $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Вход инициирован" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Запомнить это устройство, чтобы в будущем авторизовываться быстрее" }, "deviceApprovalRequired": { "message": "Требуется одобрение устройства. Выберите вариант ниже:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Требуется подтверждение устройства" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Выберите вариант подтверждения ниже" }, "rememberThisDevice": { "message": "Запомнить это устройство" @@ -8293,7 +8311,7 @@ "message": "Отсутствует email пользователя" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Email активного пользователя не найден. Разлогиниваем." }, "deviceTrusted": { "message": "Доверенное устройство" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Управление настройками коллекций для организации" }, - "limitCollectionCreationDeletionDesc": { - "message": "Ограничить создание и удаление коллекций владельцам и администраторам" - }, "limitCollectionCreationDesc": { "message": "Ограничить создание коллекций владельцам и администраторам" }, @@ -8430,7 +8445,7 @@ "message": "Максимальная потенциальная стоимость сервисного аккаунта" }, "loggedInExclamation": { - "message": "Вход выполнен!" + "message": "Выполнен вход!" }, "beta": { "message": "Beta" diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index ce6b049315..fd6077f5f1 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 839bc75a87..54b03ab3e4 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "História hesla" }, + "generatorHistory": { + "message": "História generátora" + }, + "clearGeneratorHistoryTitle": { + "message": "Vymazať históriu generátora" + }, + "cleargGeneratorHistoryDescription": { + "message": "Ak budete pokračovať, všetky položky z histórie generátora budu natrvalo vymazané. Naozaj chcete pokračovať?" + }, "noPasswordsInList": { "message": "Neboli nájdené žiadne heslá." }, + "clearHistory": { + "message": "Vymazať históriu" + }, + "nothingToShow": { + "message": "Nie je čo zobraziť" + }, + "nothingGeneratedRecently": { + "message": "V poslednej dobe ste nič negenerovali" + }, "clear": { "message": "Vyčistiť", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Všetky sedenia odhlásené" }, - "accountIsManagedMessage": { - "message": "Tento účet spravuje $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Tento účet vlastní $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Iniciované prihlásenie" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Zapamätať si toto zariadenie, pre budúce bezproblémové prihlásenie" }, "deviceApprovalRequired": { "message": "Vyžaduje sa schválenie zariadenia. Vyberte možnosť schválenia nižšie:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Vyžaduje sa schválenie zariadenia" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Vyberte možnosť schválenia nižšie" }, "rememberThisDevice": { "message": "Zapamätať si toto zariadenie" @@ -8293,7 +8311,7 @@ "message": "Chýba e-mail používateľa" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "E-mail aktívneho používateľa sa nenašiel. Odhlasuje sa." }, "deviceTrusted": { "message": "Dôveryhodné zariadenie" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Spravovať správanie zbierky pre organizáciu" }, - "limitCollectionCreationDeletionDesc": { - "message": "Obmedziť vytváranie a vymazávanie zbierky len pre vlastníkov a administrátorov" - }, "limitCollectionCreationDesc": { "message": "Obmedziť vytváranie zbierky len pre vlastníkov a administrátorov" }, diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 9258380508..07f6dc1b91 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Zgodovina gesel" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Ni gesel za prikaz." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Počisti", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Vse seje prekinjene" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 7966b20f89..6d2b8a18cf 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Историја Лозинке" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Нама лозинке у листи." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Очисти", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Одузето овлашћење свих сесија" }, - "accountIsManagedMessage": { - "message": "Овим налогом управља $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Управљајте понашањем збирке за организацију" }, - "limitCollectionCreationDeletionDesc": { - "message": "Ограничите креирање и брисање збирке на власнике и администраторе" - }, "limitCollectionCreationDesc": { "message": "Ограничите креирање збирке на власнике и администраторе" }, diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index fa98bbe6d5..4a9125537c 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Istorija lozinki" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Očisti", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index 16ee1126c0..bd67758aaa 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Lösenordshistorik" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Det finns inga lösenord att visa." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Rensa", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Alla sessioner avauktoriserades" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index 24d2cfb901..1ad5f52a94 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index bb0351a930..6744d955ca 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Password history" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "There are no passwords to list." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Clear", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "All sessions deauthorized" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index d8741205c1..e83bd6667d 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Parola geçmişi" }, + "generatorHistory": { + "message": "Üreteç geçmişi" + }, + "clearGeneratorHistoryTitle": { + "message": "Üreteç geçmişini temizle" + }, + "cleargGeneratorHistoryDescription": { + "message": "Devam ederseniz üreteç geçmişindeki tüm kayıtlar kalıcı olarak silinecektir. Devam etmek istediğinizden emin misiniz?" + }, "noPasswordsInList": { "message": "Listelenecek parola yok." }, + "clearHistory": { + "message": "Geçmişi temizle" + }, + "nothingToShow": { + "message": "Gösterilecek bir şey yok" + }, + "nothingGeneratedRecently": { + "message": "Yakın zamanda herhangi bir şey üretmediniz" + }, "clear": { "message": "Temizle", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Tüm oturumlar kapatıldı" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "Bu hesap $ORGANIZATIONNAME$ kuruluşuna aittir", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "Giriş başlatıldı" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Sonraki girişleri kolaylaştırmak için bu cihazı hatırla" }, "deviceApprovalRequired": { "message": "Cihaz onayı gerekiyor. Lütfen onay yönteminizi seçin:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Cihazı onaylamanız gerekiyor" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Aşağıdan bir onay yöntemi seçin" }, "rememberThisDevice": { "message": "Bu cihazı hatırla" @@ -8293,7 +8311,7 @@ "message": "Kullanıcının e-postası eksik" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Aktif kullanıcı e-postası bulunamadı. Çıkış yapılıyor." }, "deviceTrusted": { "message": "Cihaza güvenildi" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Kuruluş için toplama davranışını yönetin" }, - "limitCollectionCreationDeletionDesc": { - "message": "Koleksiyon oluşturma ve silme işlemlerini sahipler ve yöneticilerle sınırlandırın" - }, "limitCollectionCreationDesc": { "message": "Koleksiyon oluşturmayı sahipler ve yöneticilerle sınırlandırın" }, diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 2a438a711d..bde7ab4dbe 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Історія паролів" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Немає паролів." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Стерти", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Усі сеанси завершено" }, - "accountIsManagedMessage": { - "message": "Цим обліковим записом керує $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Керувати налаштуваннями збірок для організації" }, - "limitCollectionCreationDeletionDesc": { - "message": "Дозволити створення та видалення збірок лише власникам та адміністраторам" - }, "limitCollectionCreationDesc": { "message": "Дозволити створення збірок лише власникам та адміністраторам" }, diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index cccc634d9e..d6701a713e 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "Lịch sử mật khẩu" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "Chưa có mật khẩu." }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "Xóa", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "Tất cả phiên đăng nhập đã bị gỡ" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "Manage the collection behavior for the organization" }, - "limitCollectionCreationDeletionDesc": { - "message": "Limit collection creation and deletion to owners and admins" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 188c464314..c3b1c6a5ef 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "密码历史记录" }, + "generatorHistory": { + "message": "生成器历史记录" + }, + "clearGeneratorHistoryTitle": { + "message": "清除生成器历史记录" + }, + "cleargGeneratorHistoryDescription": { + "message": "若继续,所有条目将从生成器历史记录中永久删除。确定要继续吗?" + }, "noPasswordsInList": { "message": "没有可列出的密码。" }, + "clearHistory": { + "message": "清除历史记录" + }, + "nothingToShow": { + "message": "没有可显示的内容" + }, + "nothingGeneratedRecently": { + "message": "您最近没有生成任何内容" + }, "clear": { "message": "清除", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "已取消所有会话授权" }, - "accountIsManagedMessage": { - "message": "此账户由 $ORGANIZATIONNAME$ 管理", + "accountIsOwnedMessage": { + "message": "此账户由 $ORGANIZATIONNAME$ 拥有", "placeholders": { "organizationName": { "content": "$1", @@ -8052,16 +8070,16 @@ "message": "登录已发起" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "记住此设备以便将来无缝登录" }, "deviceApprovalRequired": { "message": "需要设备批准。请在下面选择一个批准选项:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "需要设备批准" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "在下方选择一个批准选项" }, "rememberThisDevice": { "message": "记住此设备" @@ -8293,7 +8311,7 @@ "message": "缺少用户电子邮件" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "未找到活动的用户电子邮件。您将被注销。" }, "deviceTrusted": { "message": "设备已信任" @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "管理组织的集合行为" }, - "limitCollectionCreationDeletionDesc": { - "message": "限制为仅所有者和管理员可以创建和删除集合" - }, "limitCollectionCreationDesc": { "message": "限制为仅所有者和管理员可以创建集合" }, @@ -9759,18 +9774,18 @@ "message": "删除成功" }, "freeFamiliesSponsorship": { - "message": "删除免费的 Bitwarden 家庭赞助" + "message": "移除免费的 Bitwarden 家庭赞助" }, "freeFamiliesSponsorshipPolicyDesc": { "message": "不允许成员通过此组织兑换家庭计划。" }, "verifyBankAccountWithStatementDescriptorWarning": { - "message": "Payment with a bank account is only available to customers in the United States. You will be required to verify your bank account. We will make a micro-deposit within the next 1-2 business days. Enter the statement descriptor code from this deposit on the organization's billing page to verify the bank account. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + "message": "使用银行账户付款仅对美国用户开放。您将被要求验证您的银行账户。我们将在 1-2 个工作日内进行一笔小额转账,请在组织的计费页面输入该转账的语句描述符代码以验证银行账户。验证银行账户失败将会错过支付,您的订阅将失效。" }, "verifyBankAccountWithStatementDescriptorInstructions": { - "message": "We have made a micro-deposit to your bank account (this may take 1-2 business days). Enter the six-digit code starting with 'SM' found on the deposit description. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + "message": "我们已向您的银行账户存入了一笔小额转账(可能需要 1-2 个工作日到账)。请输入转账说明中以 \"SM\" 开头的六位数代码。验证银行账户失败将会错过支付,您的订阅将失效。" }, "descriptorCode": { - "message": "Descriptor code" + "message": "描述符代码" } } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index d1a83596a2..2d39d982fc 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -1642,9 +1642,27 @@ "passwordHistory": { "message": "密碼歷史記錄" }, + "generatorHistory": { + "message": "Generator history" + }, + "clearGeneratorHistoryTitle": { + "message": "Clear generator history" + }, + "cleargGeneratorHistoryDescription": { + "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + }, "noPasswordsInList": { "message": "沒有可列出的密碼。" }, + "clearHistory": { + "message": "Clear history" + }, + "nothingToShow": { + "message": "Nothing to show" + }, + "nothingGeneratedRecently": { + "message": "You haven't generated anything recently" + }, "clear": { "message": "清除", "description": "To clear something out. Example: To clear browser history." @@ -1767,8 +1785,8 @@ "sessionsDeauthorized": { "message": "已取消所有工作階段授權" }, - "accountIsManagedMessage": { - "message": "This account is managed by $ORGANIZATIONNAME$", + "accountIsOwnedMessage": { + "message": "This account is owned by $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -8390,9 +8408,6 @@ "collectionManagementDesc": { "message": "管理組織分類的行為" }, - "limitCollectionCreationDeletionDesc": { - "message": "對擁有者和管理員限制集合的建立和刪除" - }, "limitCollectionCreationDesc": { "message": "Limit collection creation to owners and admins" }, diff --git a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/domain-verification/domain-verification.component.ts b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/domain-verification/domain-verification.component.ts index 987888741a..9c0bae1052 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/domain-verification/domain-verification.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/organizations/manage/domain-verification/domain-verification.component.ts @@ -14,6 +14,8 @@ import { import { OrgDomainApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain-api.service.abstraction"; import { OrgDomainServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization-domain/org-domain.service.abstraction"; import { OrganizationDomainResponse } from "@bitwarden/common/admin-console/abstractions/organization-domain/responses/organization-domain.response"; +import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { HttpStatusCode } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; @@ -33,6 +35,7 @@ import { }) export class DomainVerificationComponent implements OnInit, OnDestroy { private componentDestroyed$ = new Subject(); + private singleOrgPolicyEnabled = false; loading = true; @@ -48,6 +51,7 @@ export class DomainVerificationComponent implements OnInit, OnDestroy { private validationService: ValidationService, private toastService: ToastService, private configService: ConfigService, + private policyApiService: PolicyApiServiceAbstraction, ) {} // eslint-disable-next-line @typescript-eslint/no-empty-function @@ -71,6 +75,14 @@ export class DomainVerificationComponent implements OnInit, OnDestroy { async load() { await this.orgDomainApiService.getAllByOrgId(this.organizationId); + if (await this.configService.getFeatureFlag(FeatureFlag.AccountDeprovisioning)) { + const singleOrgPolicy = await this.policyApiService.getPolicy( + this.organizationId, + PolicyType.SingleOrg, + ); + this.singleOrgPolicyEnabled = singleOrgPolicy?.enabled ?? false; + } + this.loading = false; } @@ -87,6 +99,7 @@ export class DomainVerificationComponent implements OnInit, OnDestroy { map(async ([accountDeprovisioningEnabled, organizationDomains]) => { if ( accountDeprovisioningEnabled && + !this.singleOrgPolicyEnabled && organizationDomains.every((domain) => domain.verifiedDate === null) ) { await this.dialogService.openSimpleDialog({ diff --git a/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts b/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts index 8e5860833c..3a76b92ced 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/organizations/organizations-routing.module.ts @@ -76,6 +76,13 @@ const routes: Routes = [ }, ], }, + { + path: "access-intelligence", + loadChildren: () => + import("../../tools/access-intelligence/access-intelligence.module").then( + (m) => m.AccessIntelligenceModule, + ), + }, ], }, ]; diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/verify-recover-delete-provider.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/verify-recover-delete-provider.component.ts index a4461b3e11..68264593b8 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/verify-recover-delete-provider.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/verify-recover-delete-provider.component.ts @@ -1,4 +1,5 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, OnInit, SecurityContext } from "@angular/core"; +import { DomSanitizer } from "@angular/platform-browser"; import { ActivatedRoute, Router } from "@angular/router"; import { firstValueFrom } from "rxjs"; @@ -24,6 +25,7 @@ export class VerifyRecoverDeleteProviderComponent implements OnInit { private i18nService: I18nService, private route: ActivatedRoute, private toastService: ToastService, + private sanitizer: DomSanitizer, ) {} async ngOnInit() { @@ -31,7 +33,10 @@ export class VerifyRecoverDeleteProviderComponent implements OnInit { if (qParams.providerId != null && qParams.token != null && qParams.name != null) { this.providerId = qParams.providerId; this.token = qParams.token; - this.name = qParams.name; + this.name = + qParams.name && typeof qParams.name === "string" + ? this.sanitizer.sanitize(SecurityContext.HTML, qParams.name) || "" + : ""; } else { await this.router.navigate(["/"]); } diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/overview/overview.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/overview/overview.component.ts index bf2dbb76ad..3585f09faf 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/overview/overview.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/overview/overview.component.ts @@ -20,6 +20,7 @@ import { I18nPipe } from "@bitwarden/angular/platform/pipes/i18n.pipe"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { OrganizationBillingServiceAbstraction } from "@bitwarden/common/billing/abstractions"; 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"; @@ -114,9 +115,9 @@ export class OverviewComponent implements OnInit, OnDestroy { private smOnboardingTasksService: SMOnboardingTasksService, private logService: LogService, private router: Router, - private organizationApiService: OrganizationApiServiceAbstraction, private trialFlowService: TrialFlowService, + private organizationBillingService: OrganizationBillingServiceAbstraction, ) {} ngOnInit() { @@ -144,15 +145,11 @@ export class OverviewComponent implements OnInit, OnDestroy { combineLatest([ of(org), this.organizationApiService.getSubscription(org.id), - this.organizationApiService.getBilling(org.id), + this.organizationBillingService.getPaymentSource(org.id), ]), ), - map(([org, sub, billing]) => { - return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues( - org, - sub, - billing?.paymentSource, - ); + map(([org, sub, paymentSource]) => { + return this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues(org, sub, paymentSource); }), takeUntil(this.destroy$), ); diff --git a/apps/web/src/app/tools/access-intelligence/access-intelligence-routing.module.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence-routing.module.ts similarity index 100% rename from apps/web/src/app/tools/access-intelligence/access-intelligence-routing.module.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence-routing.module.ts diff --git a/apps/web/src/app/tools/access-intelligence/access-intelligence.module.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence.module.ts similarity index 100% rename from apps/web/src/app/tools/access-intelligence/access-intelligence.module.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/access-intelligence.module.ts diff --git a/apps/web/src/app/tools/access-intelligence/all-applications.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.html similarity index 100% rename from apps/web/src/app/tools/access-intelligence/all-applications.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.html diff --git a/apps/web/src/app/tools/access-intelligence/all-applications.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.ts similarity index 94% rename from apps/web/src/app/tools/access-intelligence/all-applications.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.ts index 5d76403f46..c755aa7259 100644 --- a/apps/web/src/app/tools/access-intelligence/all-applications.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/all-applications.component.ts @@ -21,10 +21,9 @@ import { ToastService, } from "@bitwarden/components"; import { CardComponent } from "@bitwarden/tools-card"; - -import { HeaderModule } from "../../layouts/header/header.module"; -import { SharedModule } from "../../shared"; -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; +import { SharedModule } from "@bitwarden/web-vault/app/shared"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; import { applicationTableMockData } from "./application-table.mock"; diff --git a/apps/web/src/app/tools/access-intelligence/application-table.mock.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/application-table.mock.ts similarity index 100% rename from apps/web/src/app/tools/access-intelligence/application-table.mock.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/application-table.mock.ts diff --git a/apps/web/src/app/tools/access-intelligence/critical-applications.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.html similarity index 100% rename from apps/web/src/app/tools/access-intelligence/critical-applications.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.html diff --git a/apps/web/src/app/tools/access-intelligence/critical-applications.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts similarity index 90% rename from apps/web/src/app/tools/access-intelligence/critical-applications.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts index 0779b2977e..43ff3d458b 100644 --- a/apps/web/src/app/tools/access-intelligence/critical-applications.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/critical-applications.component.ts @@ -7,10 +7,9 @@ import { debounceTime, map } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { SearchModule, TableDataSource, NoItemsModule, Icons } from "@bitwarden/components"; import { CardComponent } from "@bitwarden/tools-card"; - -import { HeaderModule } from "../../layouts/header/header.module"; -import { SharedModule } from "../../shared"; -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; +import { SharedModule } from "@bitwarden/web-vault/app/shared"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; import { applicationTableMockData } from "./application-table.mock"; import { RiskInsightsTabType } from "./risk-insights.component"; diff --git a/apps/web/src/app/tools/access-intelligence/notified-members-table.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/notified-members-table.component.html similarity index 100% rename from apps/web/src/app/tools/access-intelligence/notified-members-table.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/notified-members-table.component.html diff --git a/apps/web/src/app/tools/access-intelligence/notified-members-table.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/notified-members-table.component.ts similarity index 100% rename from apps/web/src/app/tools/access-intelligence/notified-members-table.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/notified-members-table.component.ts diff --git a/apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.html similarity index 100% rename from apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.html diff --git a/apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts similarity index 93% rename from apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts index e3011604a4..1e9e4171bc 100644 --- a/apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.spec.ts @@ -3,7 +3,6 @@ import { ActivatedRoute, convertToParamMap } from "@angular/router"; import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; -// eslint-disable-next-line no-restricted-imports import { MemberCipherDetailsApiService, PasswordHealthService, @@ -15,9 +14,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { TableModule } from "@bitwarden/components"; - -import { LooseComponentsModule } from "../../shared"; -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { LooseComponentsModule } from "@bitwarden/web-vault/app/shared"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; import { PasswordHealthMembersURIComponent } from "./password-health-members-uri.component"; diff --git a/apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.ts similarity index 92% rename from apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.ts index c8aea97ef7..ffc9a7911e 100644 --- a/apps/web/src/app/tools/access-intelligence/password-health-members-uri.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members-uri.component.ts @@ -5,7 +5,6 @@ import { ActivatedRoute } from "@angular/router"; import { map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -// eslint-disable-next-line no-restricted-imports import { MemberCipherDetailsApiService, PasswordHealthService, @@ -24,11 +23,8 @@ import { TableDataSource, TableModule, } from "@bitwarden/components"; - -// eslint-disable-next-line no-restricted-imports -import { HeaderModule } from "../../layouts/header/header.module"; -// eslint-disable-next-line no-restricted-imports -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; @Component({ standalone: true, diff --git a/apps/web/src/app/tools/access-intelligence/password-health-members.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members.component.html similarity index 100% rename from apps/web/src/app/tools/access-intelligence/password-health-members.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members.component.html diff --git a/apps/web/src/app/tools/access-intelligence/password-health-members.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members.component.ts similarity index 92% rename from apps/web/src/app/tools/access-intelligence/password-health-members.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members.component.ts index 66ff348e9f..19eded0de6 100644 --- a/apps/web/src/app/tools/access-intelligence/password-health-members.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health-members.component.ts @@ -4,7 +4,6 @@ import { FormControl, FormsModule } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { debounceTime, map } from "rxjs"; -// eslint-disable-next-line no-restricted-imports import { MemberCipherDetailsApiService, PasswordHealthService, @@ -21,12 +20,9 @@ import { TableModule, ToastService, } from "@bitwarden/components"; - -import { HeaderModule } from "../../layouts/header/header.module"; -// eslint-disable-next-line no-restricted-imports -import { SharedModule } from "../../shared"; -// eslint-disable-next-line no-restricted-imports -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; +import { SharedModule } from "@bitwarden/web-vault/app/shared"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; @Component({ standalone: true, diff --git a/apps/web/src/app/tools/access-intelligence/password-health.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.html similarity index 100% rename from apps/web/src/app/tools/access-intelligence/password-health.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.html diff --git a/apps/web/src/app/tools/access-intelligence/password-health.component.spec.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.spec.ts similarity index 93% rename from apps/web/src/app/tools/access-intelligence/password-health.component.spec.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.spec.ts index 5e934e3edf..98637d0dec 100644 --- a/apps/web/src/app/tools/access-intelligence/password-health.component.spec.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.spec.ts @@ -3,7 +3,6 @@ import { ActivatedRoute, convertToParamMap } from "@angular/router"; import { mock } from "jest-mock-extended"; import { of } from "rxjs"; -// eslint-disable-next-line no-restricted-imports import { MemberCipherDetailsApiService, PasswordHealthService, @@ -15,9 +14,8 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { TableModule } from "@bitwarden/components"; import { TableBodyDirective } from "@bitwarden/components/src/table/table.component"; - -import { LooseComponentsModule } from "../../shared"; -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { LooseComponentsModule } from "@bitwarden/web-vault/app/shared"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; import { PasswordHealthComponent } from "./password-health.component"; diff --git a/apps/web/src/app/tools/access-intelligence/password-health.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.ts similarity index 86% rename from apps/web/src/app/tools/access-intelligence/password-health.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.ts index 058cfb86da..8ae14562f3 100644 --- a/apps/web/src/app/tools/access-intelligence/password-health.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/password-health.component.ts @@ -5,7 +5,6 @@ import { ActivatedRoute } from "@angular/router"; import { map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -// eslint-disable-next-line no-restricted-imports import { MemberCipherDetailsApiService, PasswordHealthService, @@ -22,13 +21,9 @@ import { TableDataSource, TableModule, } from "@bitwarden/components"; - -// eslint-disable-next-line no-restricted-imports -import { HeaderModule } from "../../layouts/header/header.module"; -// eslint-disable-next-line no-restricted-imports -import { OrganizationBadgeModule } from "../../vault/individual-vault/organization-badge/organization-badge.module"; -// eslint-disable-next-line no-restricted-imports -import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module"; +import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; +import { OrganizationBadgeModule } from "@bitwarden/web-vault/app/vault/individual-vault/organization-badge/organization-badge.module"; +import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; @Component({ standalone: true, diff --git a/apps/web/src/app/tools/access-intelligence/risk-insights.component.html b/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html similarity index 95% rename from apps/web/src/app/tools/access-intelligence/risk-insights.component.html rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html index 067207160d..6df47e3c46 100644 --- a/apps/web/src/app/tools/access-intelligence/risk-insights.component.html +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.html @@ -4,7 +4,7 @@ {{ "reviewAtRiskPasswords" | i18n }}  {{ "learnMore" | i18n }}
-
+
{{ "dataLastUpdated" | i18n: (dataLastUpdated | date: "MMMM d, y 'at' h:mm a") diff --git a/apps/web/src/app/tools/access-intelligence/risk-insights.component.ts b/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.ts similarity index 96% rename from apps/web/src/app/tools/access-intelligence/risk-insights.component.ts rename to bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.ts index 1c6a36b445..2308de2873 100644 --- a/apps/web/src/app/tools/access-intelligence/risk-insights.component.ts +++ b/bitwarden_license/bit-web/src/app/tools/access-intelligence/risk-insights.component.ts @@ -7,8 +7,7 @@ import { JslibModule } from "@bitwarden/angular/jslib.module"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { AsyncActionsModule, ButtonModule, TabsModule } from "@bitwarden/components"; - -import { HeaderModule } from "../../layouts/header/header.module"; +import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; import { AllApplicationsComponent } from "./all-applications.component"; import { CriticalApplicationsComponent } from "./critical-applications.component"; diff --git a/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-expired.component.ts b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-expired.component.ts new file mode 100644 index 0000000000..faa08cf073 --- /dev/null +++ b/libs/angular/src/auth/components/two-factor-auth/two-factor-auth-expired.component.ts @@ -0,0 +1,25 @@ +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; +import { RouterModule } from "@angular/router"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { ButtonModule } from "@bitwarden/components"; + +/** + * This component is used to display a message to the user that their authentication session has expired. + * It provides a button to navigate to the login page. + */ +@Component({ + selector: "app-two-factor-expired", + standalone: true, + imports: [CommonModule, JslibModule, ButtonModule, RouterModule], + template: ` +

+ {{ "authenticationSessionTimedOut" | i18n }} +

+ + {{ "logIn" | i18n }} + + `, +}) +export class TwoFactorTimeoutComponent {} diff --git a/libs/angular/src/auth/components/two-factor-v1.component.spec.ts b/libs/angular/src/auth/components/two-factor-v1.component.spec.ts index 55be60aafd..10d227c2fe 100644 --- a/libs/angular/src/auth/components/two-factor-v1.component.spec.ts +++ b/libs/angular/src/auth/components/two-factor-v1.component.spec.ts @@ -86,9 +86,12 @@ describe("TwoFactorComponent", () => { }; let selectedUserDecryptionOptions: BehaviorSubject; + let twoFactorTimeoutSubject: BehaviorSubject; beforeEach(() => { + twoFactorTimeoutSubject = new BehaviorSubject(false); mockLoginStrategyService = mock(); + mockLoginStrategyService.twoFactorTimeout$ = twoFactorTimeoutSubject; mockRouter = mock(); mockI18nService = mock(); mockApiService = mock(); @@ -492,4 +495,10 @@ describe("TwoFactorComponent", () => { }); }); }); + + it("navigates to the timeout route when timeout expires", async () => { + twoFactorTimeoutSubject.next(true); + + expect(mockRouter.navigate).toHaveBeenCalledWith(["2fa-timeout"]); + }); }); diff --git a/libs/angular/src/auth/components/two-factor-v1.component.ts b/libs/angular/src/auth/components/two-factor-v1.component.ts index 70de10c19c..1717397164 100644 --- a/libs/angular/src/auth/components/two-factor-v1.component.ts +++ b/libs/angular/src/auth/components/two-factor-v1.component.ts @@ -1,4 +1,5 @@ -import { Directive, Inject, OnDestroy, OnInit } from "@angular/core"; +import { Directive, Inject, OnInit, OnDestroy } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute, NavigationExtras, Router } from "@angular/router"; import { firstValueFrom } from "rxjs"; import { first } from "rxjs/operators"; @@ -68,6 +69,7 @@ export class TwoFactorComponentV1 extends CaptchaProtectedComponent implements O protected changePasswordRoute = "set-password"; protected forcePasswordResetRoute = "update-temp-password"; protected successRoute = "vault"; + protected twoFactorTimeoutRoute = "2fa-timeout"; get isDuoProvider(): boolean { return ( @@ -99,6 +101,21 @@ export class TwoFactorComponentV1 extends CaptchaProtectedComponent implements O ) { super(environmentService, i18nService, platformUtilsService, toastService); this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win); + + // Add subscription to twoFactorTimeout$ and navigate to twoFactorTimeoutRoute if expired + this.loginStrategyService.twoFactorTimeout$ + .pipe(takeUntilDestroyed()) + .subscribe(async (expired) => { + if (!expired) { + return; + } + + try { + await this.router.navigate([this.twoFactorTimeoutRoute]); + } catch (err) { + this.logService.error(`Failed to navigate to ${this.twoFactorTimeoutRoute} route`, err); + } + }); } async ngOnInit() { diff --git a/libs/angular/src/scss/bwicons/fonts/bwi-font.svg b/libs/angular/src/scss/bwicons/fonts/bwi-font.svg index 606f39e116..c8535bebef 100644 --- a/libs/angular/src/scss/bwicons/fonts/bwi-font.svg +++ b/libs/angular/src/scss/bwicons/fonts/bwi-font.svg @@ -119,7 +119,7 @@ - + diff --git a/libs/angular/src/scss/bwicons/fonts/bwi-font.ttf b/libs/angular/src/scss/bwicons/fonts/bwi-font.ttf index 523c5233e0..9696152a49 100644 Binary files a/libs/angular/src/scss/bwicons/fonts/bwi-font.ttf and b/libs/angular/src/scss/bwicons/fonts/bwi-font.ttf differ diff --git a/libs/angular/src/scss/bwicons/fonts/bwi-font.woff b/libs/angular/src/scss/bwicons/fonts/bwi-font.woff index 4eef2c8603..554375a1ce 100644 Binary files a/libs/angular/src/scss/bwicons/fonts/bwi-font.woff and b/libs/angular/src/scss/bwicons/fonts/bwi-font.woff differ diff --git a/libs/angular/src/scss/bwicons/fonts/bwi-font.woff2 b/libs/angular/src/scss/bwicons/fonts/bwi-font.woff2 index 7353bb99ef..80544871f3 100644 Binary files a/libs/angular/src/scss/bwicons/fonts/bwi-font.woff2 and b/libs/angular/src/scss/bwicons/fonts/bwi-font.woff2 differ diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 0208a3cdc7..a43f1fa07a 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1213,6 +1213,8 @@ const safeProviders: SafeProvider[] = [ useClass: OrganizationBillingService, deps: [ ApiServiceAbstraction, + BillingApiServiceAbstraction, + ConfigService, KeyServiceAbstraction, EncryptService, I18nServiceAbstraction, diff --git a/libs/auth/src/angular/icons/index.ts b/libs/auth/src/angular/icons/index.ts index 9c444df570..05bb630fcb 100644 --- a/libs/auth/src/angular/icons/index.ts +++ b/libs/auth/src/angular/icons/index.ts @@ -10,3 +10,4 @@ export * from "./vault.icon"; export * from "./registration-user-add.icon"; export * from "./registration-lock-alt.icon"; export * from "./registration-expired-link.icon"; +export * from "./two-factor-timeout.icon"; diff --git a/libs/auth/src/angular/icons/two-factor-timeout.icon.ts b/libs/auth/src/angular/icons/two-factor-timeout.icon.ts new file mode 100644 index 0000000000..71d0aa549d --- /dev/null +++ b/libs/auth/src/angular/icons/two-factor-timeout.icon.ts @@ -0,0 +1,8 @@ +import { svgIcon } from "@bitwarden/components"; + +export const TwoFactorTimeoutIcon = svgIcon` + + + + +`; diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index 16ae77e937..a01b8849c8 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -66,3 +66,7 @@ export * from "./vault-timeout-input/vault-timeout-input.component"; // self hosted environment configuration dialog export * from "./self-hosted-env-config-dialog/self-hosted-env-config-dialog.component"; + +// login approval +export * from "./login-approval/login-approval.component"; +export * from "./login-approval/default-login-approval-component.service"; diff --git a/libs/auth/src/angular/lock/lock.component.ts b/libs/auth/src/angular/lock/lock.component.ts index 94c226f3f6..d8a2853a04 100644 --- a/libs/auth/src/angular/lock/lock.component.ts +++ b/libs/auth/src/angular/lock/lock.component.ts @@ -228,6 +228,7 @@ export class LockV2Component implements OnInit, OnDestroy { this.unlockOptions = null; this.activeUnlockOption = null; this.formGroup = null; // new form group will be created based on new active unlock option + this.isInitialLockScreen = true; // Desktop properties: this.biometricAsked = false; diff --git a/libs/auth/src/angular/login-approval/default-login-approval-component.service.spec.ts b/libs/auth/src/angular/login-approval/default-login-approval-component.service.spec.ts new file mode 100644 index 0000000000..ec274fac8b --- /dev/null +++ b/libs/auth/src/angular/login-approval/default-login-approval-component.service.spec.ts @@ -0,0 +1,25 @@ +import { TestBed } from "@angular/core/testing"; + +import { DefaultLoginApprovalComponentService } from "./default-login-approval-component.service"; +import { LoginApprovalComponent } from "./login-approval.component"; + +describe("DefaultLoginApprovalComponentService", () => { + let service: DefaultLoginApprovalComponentService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [DefaultLoginApprovalComponentService], + }); + + service = TestBed.inject(DefaultLoginApprovalComponentService); + }); + + it("is created successfully", () => { + expect(service).toBeTruthy(); + }); + + it("has showLoginRequestedAlertIfWindowNotVisible method that is a no-op", async () => { + const loginApprovalComponent = {} as LoginApprovalComponent; + await service.showLoginRequestedAlertIfWindowNotVisible(loginApprovalComponent.email); + }); +}); diff --git a/libs/auth/src/angular/login-approval/default-login-approval-component.service.ts b/libs/auth/src/angular/login-approval/default-login-approval-component.service.ts new file mode 100644 index 0000000000..8b0463be6c --- /dev/null +++ b/libs/auth/src/angular/login-approval/default-login-approval-component.service.ts @@ -0,0 +1,16 @@ +import { LoginApprovalComponentServiceAbstraction } from "../../common/abstractions/login-approval-component.service.abstraction"; + +/** + * Default implementation of the LoginApprovalComponentServiceAbstraction. + */ +export class DefaultLoginApprovalComponentService + implements LoginApprovalComponentServiceAbstraction +{ + /** + * No-op implementation of the showLoginRequestedAlertIfWindowNotVisible method. + * @returns + */ + async showLoginRequestedAlertIfWindowNotVisible(email?: string): Promise { + return; + } +} diff --git a/apps/desktop/src/auth/login/login-approval.component.html b/libs/auth/src/angular/login-approval/login-approval.component.html similarity index 93% rename from apps/desktop/src/auth/login/login-approval.component.html rename to libs/auth/src/angular/login-approval/login-approval.component.html index cc2c0536c9..ddbc48d71a 100644 --- a/apps/desktop/src/auth/login/login-approval.component.html +++ b/libs/auth/src/angular/login-approval/login-approval.component.html @@ -1,7 +1,7 @@ {{ "areYouTryingtoLogin" | i18n }} -

{{ "logInAttemptBy" | i18n: email }}

+

{{ "logInAttemptBy" | i18n: email }}

{{ "fingerprintPhraseHeader" | i18n }}

{{ fingerprintPhrase }}

diff --git a/libs/auth/src/angular/login-approval/login-approval.component.spec.ts b/libs/auth/src/angular/login-approval/login-approval.component.spec.ts new file mode 100644 index 0000000000..ff598bdeb9 --- /dev/null +++ b/libs/auth/src/angular/login-approval/login-approval.component.spec.ts @@ -0,0 +1,122 @@ +import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; + +import { + AuthRequestServiceAbstraction, + LoginApprovalComponentServiceAbstraction, +} from "@bitwarden/auth/common"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; +import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { ToastService } from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; + +import { LoginApprovalComponent } from "./login-approval.component"; + +describe("LoginApprovalComponent", () => { + let component: LoginApprovalComponent; + let fixture: ComponentFixture; + + let authRequestService: MockProxy; + let accountService: MockProxy; + let apiService: MockProxy; + let i18nService: MockProxy; + let dialogRef: MockProxy; + let toastService: MockProxy; + + const testNotificationId = "test-notification-id"; + const testEmail = "test@bitwarden.com"; + const testPublicKey = "test-public-key"; + + beforeEach(async () => { + authRequestService = mock(); + accountService = mock(); + apiService = mock(); + i18nService = mock(); + dialogRef = mock(); + toastService = mock(); + + accountService.activeAccount$ = of({ + email: testEmail, + id: "test-user-id" as UserId, + emailVerified: true, + name: null, + }); + + await TestBed.configureTestingModule({ + imports: [LoginApprovalComponent], + providers: [ + { provide: DIALOG_DATA, useValue: { notificationId: testNotificationId } }, + { provide: AuthRequestServiceAbstraction, useValue: authRequestService }, + { provide: AccountService, useValue: accountService }, + { provide: PlatformUtilsService, useValue: mock() }, + { provide: I18nService, useValue: i18nService }, + { provide: ApiService, useValue: apiService }, + { provide: AppIdService, useValue: mock() }, + { provide: KeyService, useValue: mock() }, + { provide: DialogRef, useValue: dialogRef }, + { provide: ToastService, useValue: toastService }, + { + provide: LoginApprovalComponentServiceAbstraction, + useValue: mock(), + }, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(LoginApprovalComponent); + component = fixture.componentInstance; + }); + + it("creates successfully", () => { + expect(component).toBeTruthy(); + }); + + describe("ngOnInit", () => { + beforeEach(() => { + apiService.getAuthRequest.mockResolvedValue({ + publicKey: testPublicKey, + creationDate: new Date().toISOString(), + } as AuthRequestResponse); + authRequestService.getFingerprintPhrase.mockResolvedValue("test-phrase"); + }); + + it("retrieves and sets auth request data", async () => { + await component.ngOnInit(); + + expect(apiService.getAuthRequest).toHaveBeenCalledWith(testNotificationId); + expect(component.email).toBe(testEmail); + expect(component.fingerprintPhrase).toBeDefined(); + }); + + it("updates time text initially", async () => { + i18nService.t.mockReturnValue("justNow"); + + await component.ngOnInit(); + expect(component.requestTimeText).toBe("justNow"); + }); + }); + + describe("denyLogin", () => { + it("denies auth request and shows info toast", async () => { + const response = { requestApproved: false } as AuthRequestResponse; + apiService.getAuthRequest.mockResolvedValue(response); + authRequestService.approveOrDenyAuthRequest.mockResolvedValue(response); + i18nService.t.mockReturnValue("denied message"); + + await component.denyLogin(); + + expect(authRequestService.approveOrDenyAuthRequest).toHaveBeenCalledWith(false, response); + expect(toastService.showToast).toHaveBeenCalledWith({ + variant: "info", + title: null, + message: "denied message", + }); + }); + }); +}); diff --git a/apps/desktop/src/auth/login/login-approval.component.ts b/libs/auth/src/angular/login-approval/login-approval.component.ts similarity index 94% rename from apps/desktop/src/auth/login/login-approval.component.ts rename to libs/auth/src/angular/login-approval/login-approval.component.ts index e6428e0020..9dff4d3e27 100644 --- a/apps/desktop/src/auth/login/login-approval.component.ts +++ b/libs/auth/src/angular/login-approval/login-approval.component.ts @@ -4,7 +4,10 @@ import { Component, OnInit, OnDestroy, Inject } from "@angular/core"; import { Subject, firstValueFrom, map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common"; +import { + AuthRequestServiceAbstraction, + LoginApprovalComponentServiceAbstraction as LoginApprovalComponentService, +} from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; @@ -56,6 +59,7 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { protected keyService: KeyService, private dialogRef: DialogRef, private toastService: ToastService, + private loginApprovalComponentService: LoginApprovalComponentService, ) { this.notificationId = params.notificationId; } @@ -89,14 +93,7 @@ export class LoginApprovalComponent implements OnInit, OnDestroy { this.updateTimeText(); }, RequestTimeUpdate); - const isVisible = await ipc.platform.isWindowVisible(); - if (!isVisible) { - await ipc.auth.loginRequest( - this.i18nService.t("logInRequested"), - this.i18nService.t("confirmLoginAtemptForMail", this.email), - this.i18nService.t("close"), - ); - } + this.loginApprovalComponentService.showLoginRequestedAlertIfWindowNotVisible(this.email); } } diff --git a/libs/auth/src/angular/login/login.component.html b/libs/auth/src/angular/login/login.component.html index 0629e70a6a..efea291752 100644 --- a/libs/auth/src/angular/login/login.component.html +++ b/libs/auth/src/angular/login/login.component.html @@ -97,14 +97,6 @@ {{ "getMasterPasswordHint" | i18n }} - - -
+ +
+ + + + + + + diff --git a/libs/importer/src/components/dialog/sshkey-password-prompt.component.ts b/libs/importer/src/components/dialog/sshkey-password-prompt.component.ts new file mode 100644 index 0000000000..527dfec6e8 --- /dev/null +++ b/libs/importer/src/components/dialog/sshkey-password-prompt.component.ts @@ -0,0 +1,46 @@ +import { DialogRef } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component } from "@angular/core"; +import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + AsyncActionsModule, + ButtonModule, + DialogModule, + FormFieldModule, + IconButtonModule, +} from "@bitwarden/components"; + +@Component({ + templateUrl: "sshkey-password-prompt.component.html", + standalone: true, + imports: [ + CommonModule, + JslibModule, + DialogModule, + FormFieldModule, + AsyncActionsModule, + ButtonModule, + IconButtonModule, + ReactiveFormsModule, + ], +}) +export class SshKeyPasswordPromptComponent { + protected formGroup = this.formBuilder.group({ + sshKeyPassword: ["", Validators.required], + }); + + constructor( + public dialogRef: DialogRef, + protected formBuilder: FormBuilder, + ) {} + + submit = () => { + this.formGroup.markAsTouched(); + if (!this.formGroup.valid) { + return; + } + this.dialogRef.close(this.formGroup.value.sshKeyPassword); + }; +} diff --git a/libs/tools/generator/components/src/forwarder-settings.component.html b/libs/tools/generator/components/src/forwarder-settings.component.html index 0e15c2e89a..d610f53d59 100644 --- a/libs/tools/generator/components/src/forwarder-settings.component.html +++ b/libs/tools/generator/components/src/forwarder-settings.component.html @@ -12,7 +12,7 @@ {{ "apiKey" | i18n }} - + - + {{ "sendTypeText" | i18n }} - + {{ "sendTypeFile" | i18n }}