From 30b4c891df420162deea1323cb8135be9decc700 Mon Sep 17 00:00:00 2001 From: Vince Grassia <593223+vgrassia@users.noreply.github.com> Date: Mon, 30 Dec 2024 12:46:07 -0500 Subject: [PATCH 01/65] Change logic for workflow (#12626) --- .github/workflows/crowdin-pull.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/crowdin-pull.yml b/.github/workflows/crowdin-pull.yml index f99cecf91d6..1ac6dd9113f 100644 --- a/.github/workflows/crowdin-pull.yml +++ b/.github/workflows/crowdin-pull.yml @@ -21,8 +21,17 @@ jobs: - app_name: web crowdin_project_id: "308189" steps: + - name: Generate GH App token + uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + id: app-token + with: + app-id: ${{ secrets.BW_GHAPP_ID }} + private-key: ${{ secrets.BW_GHAPP_KEY }} + - name: Checkout repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + token: ${{ steps.app-token.outputs.token }} - name: Login to Azure uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0 @@ -35,13 +44,6 @@ jobs: with: keyvault: "bitwarden-ci" secrets: "crowdin-api-token, github-gpg-private-key, github-gpg-private-key-passphrase" - - - name: Generate GH App token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 - id: app-token - with: - app-id: ${{ secrets.BW_GHAPP_ID }} - private-key: ${{ secrets.BW_GHAPP_KEY }} - name: Download translations uses: bitwarden/gh-actions/crowdin@main From 160506c708a41719a39099bfa132772a1378f423 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:56:09 +0000 Subject: [PATCH 02/65] Autosync the updated translations (#12627) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 359 +-- apps/browser/src/_locales/az/messages.json | 115 +- apps/browser/src/_locales/be/messages.json | 113 +- apps/browser/src/_locales/bg/messages.json | 113 +- apps/browser/src/_locales/bn/messages.json | 113 +- apps/browser/src/_locales/bs/messages.json | 113 +- apps/browser/src/_locales/ca/messages.json | 113 +- apps/browser/src/_locales/cs/messages.json | 113 +- apps/browser/src/_locales/cy/messages.json | 113 +- apps/browser/src/_locales/da/messages.json | 113 +- apps/browser/src/_locales/de/messages.json | 127 +- apps/browser/src/_locales/el/messages.json | 331 +-- apps/browser/src/_locales/en_GB/messages.json | 113 +- apps/browser/src/_locales/en_IN/messages.json | 113 +- apps/browser/src/_locales/es/messages.json | 113 +- apps/browser/src/_locales/et/messages.json | 113 +- apps/browser/src/_locales/eu/messages.json | 113 +- apps/browser/src/_locales/fa/messages.json | 113 +- apps/browser/src/_locales/fi/messages.json | 131 +- apps/browser/src/_locales/fil/messages.json | 113 +- apps/browser/src/_locales/fr/messages.json | 133 +- apps/browser/src/_locales/gl/messages.json | 2115 ++++++++--------- apps/browser/src/_locales/he/messages.json | 113 +- apps/browser/src/_locales/hi/messages.json | 137 +- apps/browser/src/_locales/hr/messages.json | 133 +- apps/browser/src/_locales/hu/messages.json | 113 +- apps/browser/src/_locales/id/messages.json | 113 +- apps/browser/src/_locales/it/messages.json | 113 +- apps/browser/src/_locales/ja/messages.json | 123 +- apps/browser/src/_locales/ka/messages.json | 113 +- apps/browser/src/_locales/km/messages.json | 113 +- apps/browser/src/_locales/kn/messages.json | 113 +- apps/browser/src/_locales/ko/messages.json | 113 +- apps/browser/src/_locales/lt/messages.json | 113 +- apps/browser/src/_locales/lv/messages.json | 113 +- apps/browser/src/_locales/ml/messages.json | 113 +- apps/browser/src/_locales/mr/messages.json | 113 +- apps/browser/src/_locales/my/messages.json | 113 +- apps/browser/src/_locales/nb/messages.json | 113 +- apps/browser/src/_locales/ne/messages.json | 113 +- apps/browser/src/_locales/nl/messages.json | 113 +- apps/browser/src/_locales/nn/messages.json | 113 +- apps/browser/src/_locales/or/messages.json | 113 +- apps/browser/src/_locales/pl/messages.json | 119 +- apps/browser/src/_locales/pt_BR/messages.json | 205 +- apps/browser/src/_locales/pt_PT/messages.json | 115 +- apps/browser/src/_locales/ro/messages.json | 113 +- apps/browser/src/_locales/ru/messages.json | 113 +- apps/browser/src/_locales/si/messages.json | 113 +- apps/browser/src/_locales/sk/messages.json | 113 +- apps/browser/src/_locales/sl/messages.json | 113 +- apps/browser/src/_locales/sr/messages.json | 113 +- apps/browser/src/_locales/sv/messages.json | 113 +- apps/browser/src/_locales/te/messages.json | 113 +- apps/browser/src/_locales/th/messages.json | 113 +- apps/browser/src/_locales/tr/messages.json | 113 +- apps/browser/src/_locales/uk/messages.json | 113 +- apps/browser/src/_locales/vi/messages.json | 125 +- apps/browser/src/_locales/zh_CN/messages.json | 199 +- apps/browser/src/_locales/zh_TW/messages.json | 113 +- apps/browser/store/locales/gl/copy.resx | 6 +- apps/browser/store/locales/pt_BR/copy.resx | 32 +- 62 files changed, 1586 insertions(+), 8004 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 7ba554b13b7..46f119bdafe 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -84,7 +84,7 @@ "message": "انضم إلى المنظمة" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "انضم إلى $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -93,7 +93,7 @@ } }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "أنهي الانضمام إلى هذه المؤسسة عن طريق تعيين كلمة مرور رئيسية." }, "tab": { "message": "علامة تبويب" @@ -120,7 +120,7 @@ "message": "نسخ كلمة المرور" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "انسخ عبارة المرور" }, "copyNote": { "message": "نسخ الملاحظة" @@ -138,31 +138,31 @@ "message": "نسخ رمز الأمان" }, "copyName": { - "message": "Copy name" + "message": "انسخ الاسم" }, "copyCompany": { - "message": "Copy company" + "message": "انسخ الشركة" }, "copySSN": { - "message": "Copy Social Security number" + "message": "انسخ رَقْم الضمان الاجتماعي" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "نسخ رَقْم جواز السفر" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "نسخ رَقْم الترخيص" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "نسخ المفتاح الخاص" }, "copyPublicKey": { - "message": "Copy public key" + "message": "نسخ المفتاح العام" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "نسخ البصمة" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "نسخ $FIELD$", "placeholders": { "field": { "content": "$1", @@ -171,13 +171,13 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "نسخ الموقع الإلكتروني" }, "copyNotes": { - "message": "Copy notes" + "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": { @@ -193,10 +193,10 @@ "message": "هوية التعبئة التلقائية" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "ملء رمز التحقق" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "ملء رمز التحقق", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -239,16 +239,16 @@ "message": "إضافة عنصر" }, "accountEmail": { - "message": "Account email" + "message": "البريد الإلكتروني للحساب" }, "requestHint": { - "message": "Request hint" + "message": "طلب تلميح" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "طلب تلميح كلمة المرور" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "أدخل عنوان البريد الإلكتروني لحسابك وسيُرسل تلميح كلمة المرور الخاصة بك إليك" }, "passwordHint": { "message": "تلميح كلمة المرور" @@ -281,25 +281,25 @@ "message": "تغيير كلمة المرور الرئيسية" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "هل تريد المتابعة إلى تطبيق الويب؟" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "استكشف المزيد من الميزات لحساب Bitwarden الخاص بك على تطبيق الويب." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "هل تريد المتابعة إلى مركز المساعدة؟" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "تعرف على المزيد حول كيفية استخدام Bitwarden في مركز المساعدة." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "هل تريد المتابعة إلى متجر إضافات المتصفح؟" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "ساعد الآخرين في معرفة ما إذا كان Bitwarden مناسب لهم. قم بزيارة متجر إضافات المتصفح الخاص بك واترك تقييمًا الآن." }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "يمكنك تغيير كلمة المرور الرئيسية الخاصة بك على تطبيق ويب الخاص ب Bitwarden." }, "fingerprintPhrase": { "message": "عبارة بصمة الإصبع", @@ -316,43 +316,43 @@ "message": "تسجيل الخروج" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "حول Bitwarden" }, "about": { "message": "عن التطبيق" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "المزيد من Bitwarden" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "هل تريد المتابعة إلى bitwarden.com؟" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden للأعمال التجارية" }, "bitwardenAuthenticator": { - "message": "Bitwarden Authenticator" + "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 يسمح لك بتخزين مفاتيح المصادقة وإنشاء رموز لمرة واحدة المستندة إلى الوقت لعمليات المصادقة الثنائية. تعرف على المزيد على موقع bitwarden.com" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "مدير الأسرار من Bitwarden" }, "continueToSecretsManagerPageDesc": { - "message": "Securely store, manage, and share developer secrets with Bitwarden Secrets Manager. Learn more on the bitwarden.com website." + "message": "قم بتخزين وإدارة ومشاركة أسرار التطوير مع مدير الأسرار من Bitwarden. تعرف على المزيد في موقع bitwarden.com." }, "passwordlessDotDev": { "message": "Passwordless.dev" }, "continueToPasswordlessDotDevPageDesc": { - "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." + "message": "أنشئ تجارِب تسجيل دخول سلسة وآمنة خالية من كلمات المرور التقليدية مع Passwordless.dev. تعلم المزيد على موقع bitwarden.com." }, "freeBitwardenFamilies": { - "message": "Free Bitwarden Families" + "message": "Bitwarden للعائلات المجاني" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "أنت مؤهل للحصول على Bitwarden للعائلات المجاني. أحصل على هذا العرض اليوم عبر تطبيق الويب." }, "version": { "message": "الإصدار" @@ -373,22 +373,22 @@ "message": "تحرير المجلّد" }, "newFolder": { - "message": "New folder" + "message": "مجلد جديد" }, "folderName": { - "message": "Folder name" + "message": "أسم المجلد" }, "folderHintText": { "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" }, "noFoldersAdded": { - "message": "No folders added" + "message": "لا توجد مجلدات مضافة" }, "createFoldersToOrganize": { - "message": "Create folders to organize your vault items" + "message": "أنشئ مجلدات لتنظيم عناصر المخزن الخاصة بك" }, "deleteFolderPermanently": { - "message": "Are you sure you want to permanently delete this folder?" + "message": "هل أنت متأكد أنك تريد حذف هذا المجلد نهائيًا؟" }, "deleteFolder": { "message": "حذف المجلّد" @@ -431,7 +431,7 @@ "message": "قم بإنشاء كلمات مرور قوية وفريدة لتسجيلات الدخول الخاصة بك." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "تطبيق ويب Bitwarden" }, "importItems": { "message": "استيراد العناصر" @@ -443,7 +443,7 @@ "message": "توليد كلمة مرور" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "توليد عبارة المرور" }, "regeneratePassword": { "message": "إعادة توليد كلمة المرور" @@ -454,9 +454,6 @@ "length": { "message": "الطول" }, - "passwordMinLength": { - "message": "الحد الأدنى لطول كلمة السر" - }, "uppercase": { "message": "أحرف كبيرة (من A إلى Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -474,11 +471,11 @@ "description": "deprecated. Use specialCharactersLabel instead." }, "include": { - "message": "Include", + "message": "تضمين", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "تضمين أحرف ذات نسق كبير", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -486,7 +483,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "تضمين أحرف ذات نسق صغير", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -494,7 +491,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "تضمين أرقام", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -502,7 +499,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "تضمين أحرف خاصة", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { @@ -528,16 +525,12 @@ "minSpecial": { "message": "الحد الأدنى من الأحرف الخاصة" }, - "avoidAmbChar": { - "message": "تجنب الأحرف الغامضة", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "تجنب الأحرف المبهمة", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "طُبقت متطلبات سياسة المؤسسة على خيارات المولد الخاصة بك.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -571,19 +564,19 @@ "message": "المفضلات" }, "unfavorite": { - "message": "Unfavorite" + "message": "إزالة من المفضلة" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "تم إضافة العنصر إلى المفضلات" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "تم إزالة العنصر من المفضلات" }, "notes": { "message": "الملاحظات" }, "privateNote": { - "message": "Private note" + "message": "ملاحظة سرية" }, "note": { "message": "الملاحظة" @@ -604,10 +597,10 @@ "message": "بدء" }, "launchWebsite": { - "message": "Launch website" + "message": "تشغيل الموقع" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "تشغيل الموقع $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -628,7 +621,7 @@ "message": "الأخرى" }, "unlockMethods": { - "message": "Unlock options" + "message": "فتح الخيارات" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "أعدنّ طريقة إلغاء القُفْل لتغيير إجراء مهلة المخزن الخاص بك." @@ -637,13 +630,13 @@ "message": "إعداد طريقة إلغاء القفل في الإعدادات" }, "sessionTimeoutHeader": { - "message": "Session timeout" + "message": "مهلة الجَلسة" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "مهلة الخزنة" }, "otherOptions": { - "message": "Other options" + "message": "خيارات أخرى" }, "rateExtension": { "message": "قيِّم هذه الإضافة" @@ -658,13 +651,13 @@ "message": "خزانتك مقفلة. قم بتأكيد هويتك للمتابعة." }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "المخزن الخاص بك مقفل" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "حسابك مقفل" }, "or": { - "message": "or" + "message": "أو" }, "unlock": { "message": "إلغاء القفل" @@ -689,7 +682,7 @@ "message": "نفذ وقت الخزانة" }, "vaultTimeout1": { - "message": "Timeout" + "message": "المهلة" }, "lockNow": { "message": "إقفل الآن" @@ -743,16 +736,16 @@ "message": "الأمان" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "تأكيد كلمة المرور الرئيسية" }, "masterPassword": { - "message": "Master password" + "message": "كلمة المرور الرئيسية" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "لا يمكن استعادة كلمة المرور الرئيسية إذا نسيتها!" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "تلميح كلمة المرور الرئيسية" }, "errorOccurred": { "message": "لقد حدث خطأ ما" @@ -786,10 +779,10 @@ "message": "تم إنشاء حسابك الجديد! يمكنك الآن تسجيل الدخول." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "تم إنشاء حسابك الجديد!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "لقد قمت بتسجيل الدخول!" }, "youSuccessfullyLoggedIn": { "message": "سجلتَ الدخول بنجاح" @@ -804,7 +797,7 @@ "message": "رمز التحقق مطلوب." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "تم إلغاء المصادقة أو استغرقت وقتا طويلا. الرجاء المحاولة مرة أخرى." }, "invalidVerificationCode": { "message": "رمز التحقق غير صالح" @@ -832,16 +825,16 @@ "message": "مسح رمز QR للمصادقة من صفحة الويب الحالية" }, "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 المصادق لهذا الموقع، أو أنسخ وألصق المفتاح في هذا الحقل." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "تعرف على المزيد عن المصادقين" }, "copyTOTP": { "message": "نسخ مفتاح المصادقة (TOTP)" @@ -850,28 +843,28 @@ "message": "تم تسجيل الخروج" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "لقد تم تسجيل خروجك من حسابك." }, "loginExpired": { "message": "انتهت صلاحية جلسة تسجيل الدخول الخاصة بك." }, "logIn": { - "message": "Log in" + "message": "تسجيل الدخول" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "تسجيل الدخول إلى Bitwarden" }, "restartRegistration": { - "message": "Restart registration" + "message": "إعادة التسجيل" }, "expiredLink": { - "message": "Expired link" + "message": "رابط منتهي الصَّلاحِيَة" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "الرجاء إعادة التسجيل أو حاول تسجيل الدخول." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "قد يكون لديك حساب بالفعل" }, "logOutConfirmation": { "message": "هل أنت متأكد من أنك تريد تسجيل الخروج؟" @@ -895,10 +888,10 @@ "message": "تسجيل الدخول بخطوتين يجعل حسابك أكثر أمنا من خلال مطالبتك بالتحقق من تسجيل الدخول باستخدام جهاز آخر مثل مفتاح الأمان، تطبيق المصادقة، الرسائل القصيرة، المكالمة الهاتفية، أو البريد الإلكتروني. يمكن تمكين تسجيل الدخول بخطوتين على خزانة الويب bitwarden.com. هل تريد زيارة الموقع الآن؟" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "اجعل حسابك أكثر أمنا من خلال إعداد تسجيل الدخول بخطوتين في تطبيق Bitwarden على الويب." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "هل تريد المتابعة إلى تطبيق الويب؟" }, "editedFolder": { "message": "حُفظ المجلد" @@ -941,7 +934,7 @@ "message": "رابط جديد" }, "addDomain": { - "message": "Add domain", + "message": "أضف نطاق", "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." }, "addedItem": { @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "قائمة عناصر الهوية في صفحة التبويب لسهولة الملء التلقائي." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "مسح الحافظة", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1053,7 +1049,7 @@ "message": "إلغاء القفل" }, "additionalOptions": { - "message": "Additional options" + "message": "خيارات إضافية" }, "enableContextMenuItem": { "message": "إظهار خيارات قائمة السياق" @@ -1093,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": "تصدير الخزانة" @@ -1102,13 +1098,13 @@ "message": "صيغة الملف" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "سيكون المِلَفّ المُصدر محميًا بكلمة مرور وسيتطلب كلمة مرور المِلَفّ لفك تشفيره." }, "filePassword": { - "message": "File password" + "message": "كلمة مرور الملف" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "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." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "الانتقال إلى مؤسسة" }, - "share": { - "message": "مشاركة" - }, "movedItemToOrg": { "message": "$ITEMNAME$ انتقل إلى $ORGNAME$", "placeholders": { @@ -1936,10 +1929,10 @@ "message": "Clear history" }, "nothingToShow": { - "message": "Nothing to show" + "message": "لا يوجد شيء لعرضه" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "لم تقم بتوليد أي شيء مؤخرًا" }, "remove": { "message": "إزالة" @@ -2000,16 +1993,16 @@ "message": "فتح باستخدام رمز PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "تعيين رَقَم التعريف الشخصي" }, "setYourPinButton": { - "message": "Set PIN" + "message": "تعيين رَقَم التعريف الشخصي" }, "setYourPinCode": { "message": "تعيين رمز PIN الخاص بك لإلغاء قفل Bitwarden. سيتم إعادة تعيين إعدادات PIN الخاصة بك إذا قمت بتسجيل الخروج بالكامل من التطبيق." }, "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": "سيتم استخدام رَقَم التعريف الشخصي الخاص بك لفتح Bitwarden بدلاً من كلمة المرور الرئيسية. سيتم حذف رَقَم التعريف الشخصي الخاص بك إذا قمت بتسجيل الخروج بالكامل من Bitwarden." }, "pinRequired": { "message": "رمز PIN مطلوب." @@ -2024,7 +2017,7 @@ "message": "فتح باستخدام القياسات الحيوية" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "فتح بكلمة المرور الرئيسية" }, "awaitDesktop": { "message": "في انتظار التأكيد من سطح المكتب" @@ -2036,7 +2029,7 @@ "message": "قفل مع كلمة المرور الرئيسية عند إعادة تشغيل المتصفح" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "أطلب كلمة المرور الرئيسية عند إعادة تشغيل المتصفح" }, "selectOneCollection": { "message": "يجب عليك تحديد مجموعة واحدة على الأقل." @@ -2047,30 +2040,27 @@ "clone": { "message": "استنساخ" }, - "passwordGeneratorPolicyInEffect": { - "message": "واحدة أو أكثر من سياسات المؤسسة تؤثر على إعدادات المولدات الخاصة بك." - }, "passwordGenerator": { - "message": "Password generator" + "message": "مولد كلمة المرور" }, "usernameGenerator": { - "message": "Username generator" + "message": "مولد اسم المستخدم" }, "useThisPassword": { - "message": "Use this password" + "message": "استخدم كلمة المرور هذه" }, "useThisUsername": { - "message": "Use this username" + "message": "استخدم اسم المستخدم هذا" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "تم توليد كلمة مرور آمنة! لا تنس أن تقوم أيضا بتحديث كلمة المرور الخاصة بك على الموقع." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "استخدام المولد", "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": "لإنشاء كلمة مرور فريدة قوية", "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": { @@ -2106,7 +2096,7 @@ "message": "تم استعادة العنصر" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "لديك حساب بالفعل؟" }, "vaultTimeoutLogOutConfirmation": { "message": "سيؤدي تسجيل الخروج إلى إزالة جميع إمكانية الوصول إلى خزانتك ويتطلب المصادقة عبر الإنترنت بعد انتهاء المهلة. هل أنت متأكد من أنك تريد استخدام هذا الإعداد؟" @@ -2118,7 +2108,7 @@ "message": "التعبئة التلقائية والحفظ" }, "fillAndSave": { - "message": "Fill and save" + "message": "عبء ثم احفظ" }, "autoFillSuccessAndSavedUri": { "message": "تم تعبئة العنصر تلقائياً وحفظ عنوان URI" @@ -2199,19 +2189,19 @@ "message": "كلمة المرور الرئيسية الجديدة لا تفي بمتطلبات السياسة العامة." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "احصل على النصائح والإعلانات وفرص البحوث من Bitwarden في صندوق الوارد الخاص بك." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "إلغاء الاشتراك" }, "atAnyTime": { - "message": "at any time." + "message": "في أي وقت." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "عن طريق المتابعة، أنت توافق على" }, "and": { - "message": "and" + "message": "و" }, "acceptPolicies": { "message": "من خلال تحديد هذا المربع فإنك توافق على ما يلي:" @@ -2274,7 +2264,7 @@ "message": "عدم تطابق الحساب" }, "nativeMessagingWrongUserKeyTitle": { - "message": "Biometric key missmatch" + "message": "عدم تطابق المفتاح الحيوي" }, "nativeMessagingWrongUserKeyDesc": { "message": "Biometric unlock failed. The biometric secret key failed to unlock the vault. Please try to set up biometrics again." @@ -2331,7 +2321,7 @@ "message": "An organization policy has blocked importing items into your individual vault." }, "domainsTitle": { - "message": "Domains", + "message": "النطاقات", "description": "A category title describing the concept of web domains" }, "excludedDomains": { @@ -2341,10 +2331,10 @@ "message": "Bitwarden لن يطلب حفظ تفاصيل تسجيل الدخول لهذه النطاقات. يجب عليك تحديث الصفحة حتى تصبح التغييرات سارية المفعول." }, "excludedDomainsDescAlt": { - "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." + "message": "Bitwarden لن يطلب حفظ تفاصيل تسجيل الدخول لهذه النطافات لجميع الحسابات مسجلة الدخول. يجب عليك تحديث الصفحة لكي تصبح التغييرات نافذة المفعول." }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "الموقع $number$ (URI)", "placeholders": { "number": { "content": "$1", @@ -2362,17 +2352,17 @@ } }, "excludedDomainsSavedSuccess": { - "message": "Excluded domain changes saved" + "message": "تم حفظ تغييرات استبعاد النطاقات" }, "limitSendViews": { "message": "Limit views" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "لا يمكن لأحد عرض هذا الإرسال بعد الوصول إلى الحد الأقصى.", "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": { @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "نص" }, @@ -2407,22 +2389,15 @@ "message": "ملف" }, "allSends": { - "message": "All Sends", + "message": "كل الإرسالات", "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" - }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + "message": "إخفاء النص بشكل افتراضي" }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "تاريخ الحذف" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "تاريخ انتهاء الصلاحية" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "يوم واحد" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "مُخصّص" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "قبل أن تبدأ" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "لاستخدام منتقي التاريخ على نمط التقويم", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "انقر هنا", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "أن يخرج من النافذة.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "صلاحية تاريخ الانتهاء المقدّم غير صحيح." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "خطأ" }, - "regenerateUsername": { - "message": "إعادة إنشاء اسم المستخدم" - }, "generateUsername": { "message": "إنشاء اسم المستخدم" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "نوع اسم المستخدم" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "اسم الموقع الإلكتروني" }, - "whatWouldYouLikeToGenerate": { - "message": "ما الذي ترغب في توليده؟" - }, - "passwordType": { - "message": "نوع كلمة المرور" - }, "service": { "message": "الخدمة" }, diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index aea4e46abeb..51bfe95a48a 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Uzunluq" }, - "passwordMinLength": { - "message": "Minimal parol uzunluğu" - }, "uppercase": { "message": "Böyük hərf (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum simvol" }, - "avoidAmbChar": { - "message": "Anlaşılmaz simvollardan çəkinin", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Anlaşılmaz xarakterlərdən çəkin", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Asan avto-doldurma üçün Vərəq səhifəsində kimlik elementlərini sadalayın." }, + "clickToAutofillOnVault": { + "message": "Seyf görünüşündə avto-doldurmaq üçün elementlərə klikləyin" + }, "clearClipboard": { "message": "Lövhəni təmizlə", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Təşkilata daşı" }, - "share": { - "message": "Paylaş" - }, "movedItemToOrg": { "message": "$ITEMNAME$, $ORGNAME$ şirkətinə daşındı", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klonla" }, - "passwordGeneratorPolicyInEffect": { - "message": "Bir və ya daha çox təşkilat siyasəti yaradıcı ayarlarınıza təsir edir." - }, "passwordGenerator": { "message": "Parol yaradıcı" }, @@ -2389,14 +2379,6 @@ "message": "Send detalları", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "\"Send\"ləri axtar", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "\"Send\" əlavə et", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Mətn" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Mətni ilkin olaraq gizlət" }, - "maxAccessCountReached": { - "message": "Maksimal müraciət sayına çatıldı", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Müddəti bitib" }, - "pendingDeletion": { - "message": "Silinməsi gözlənilir" - }, "passwordProtected": { "message": "Parolla qorunan" }, @@ -2472,24 +2447,9 @@ "message": "\"Send\"ə düzəliş et", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "\"Send\"in növü nədir?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Bu \"Send\"i açıqlayan bir ad.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Göndərmək istədiyiniz fayl." - }, "deletionDate": { "message": "Silinmə tarixi" }, - "deletionDateDesc": { - "message": "\"Send\" göstərilən tarix və saatda birdəfəlik silinəcək.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send, bu tarixdə həmişəlik silinəcək.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Bitmə tarixi" }, - "expirationDateDesc": { - "message": "Əgər ayarlanıbsa, göstərilən tarix və vaxtda \"Send\"ə müraciət başa çatacaq.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 gün" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Özəl" }, - "maximumAccessCount": { - "message": "Maksimal müraciət sayı" - }, - "maximumAccessCountDesc": { - "message": "Əgər ayarlanıbsa, istifadəçilər maksimal müraciət sayına çatdıqdan sonra bu \"Send\"ə müraciət edə bilməyəcək.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "İstəyinizə görə istifadəçilərdən bu \"Send\"ə müraciət edərkən parol tələb edə bilərsiniz.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Alıcıların bu \"Send\"ə müraciət etməsi üçün ixtiyari bir parol əlavə edin.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Bu \"Send\" ilə bağlı gizli notlar.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Heç kimin müraciət edə bilməməsi üçün bu \"Send\"i deaktiv et.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Saxladıqdan sonra \"Send\"in keçidini lövhəyə kopyala.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Göndərmək istədiyiniz mətn" - }, - "sendHideText": { - "message": "Bu \"Send\"in mətnini ilkin olaraq gizlət", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Hazırkı müraciət sayı" - }, "createSend": { "message": "Yeni \"Send\"", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Başlamazdan əvvəl" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Təqvim stilində tarix seçici istifadə etmək üçün", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "bura klikləyin", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "yeni bir pəncərə açın.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Göstərilən son istifadə tarixi yararsızdır." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Silinmə və son istifadə tarixlərini saxlayarkən xəta baş verdi." }, - "hideEmail": { - "message": "E-poçt ünvanımı alıcılardan gizlət." - }, "hideYourEmail": { "message": "E-poçt ünvanınız baxanlardan gizlədilsin." }, - "sendOptionsPolicyInEffect": { - "message": "Bir və ya daha çox təşkilat siyasətləri \"Send\" seçimlərinizə təsir edir." - }, "passwordPrompt": { "message": "Ana parolu təkrar soruş" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Xəta" }, - "regenerateUsername": { - "message": "İstifadəçi adını yenidən yarat" - }, "generateUsername": { "message": "İstifadəçi adı yarat" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "İstifadəçi adı növü" - }, "plusAddressedEmail": { "message": "Üstəgəl ünvanlı e-poçt", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Veb sayt adı" }, - "whatWouldYouLikeToGenerate": { - "message": "Nə yaratmaq istəyirsiniz?" - }, - "passwordType": { - "message": "Parol növü" - }, "service": { "message": "Xidmət" }, @@ -4677,7 +4570,7 @@ "message": "Uzantı ikonunda giriş üçün avto-doldurma təklif sayını göstər" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Seyfdə cəld kopyalama fəaliyyətlərini göstər" }, "systemDefault": { "message": "İlkin sistem" diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 37b234105c3..46c804d27d9 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Даўжыня" }, - "passwordMinLength": { - "message": "Мінімальная даўжыня пароля" - }, "uppercase": { "message": "Вялікія літары (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Мінімум спецыяльных сімвалаў" }, - "avoidAmbChar": { - "message": "Пазбягаць неадназначных сімвалаў", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Пазбягаць неадназначных сімвалаў", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Спіс элементаў пасведчання на старонцы з укладкамі для лёгкага аўтазапаўнення." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Ачыстка буфера абмену", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Перамясціць у арганізацыю" }, - "share": { - "message": "Абагуліць" - }, "movedItemToOrg": { "message": "$ITEMNAME$ перамешчана ў $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Кланіраваць" }, - "passwordGeneratorPolicyInEffect": { - "message": "Адна або больш палітык арганізацыі ўплывае на налады генератара." - }, "passwordGenerator": { "message": "Генератар пароляў" }, @@ -2389,14 +2379,6 @@ "message": "Падрабязнасці Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Пошук у Send'ах", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Дадаць Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Тэкст" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Дасягнута максімальная колькасць доступаў", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Пратэрмінавана" }, - "pendingDeletion": { - "message": "Чакаецца выдаленне" - }, "passwordProtected": { "message": "Абаронена паролем" }, @@ -2472,24 +2447,9 @@ "message": "Рэдагаваць Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Які гэта тып Send'a?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Зразумелая назва для апісання гэтага Send'a.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Файл, які вы хочаце адправіць." - }, "deletionDate": { "message": "Дата выдалення" }, - "deletionDateDesc": { - "message": "Send будзе незваротна выдалены ў азначаныя дату і час.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Дата завяршэння" }, - "expirationDateDesc": { - "message": "Калі зададзена, то доступ да гэтага Send міне ў азначаную дату і час.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 дзень" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Карыстальніцкі" }, - "maximumAccessCount": { - "message": "Максімальная колькасць доступаў" - }, - "maximumAccessCountDesc": { - "message": "Калі прызначана, то карыстальнікі больш не змогуць атрымаць доступ да гэтага Send пасля таго, як будзе дасягнута максімальная колькасць зваротаў.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Па магчымасці запытваць у карыстальнікаў пароль для доступу да гэтага Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Прыватныя нататкі пра гэты Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Адключыць гэты Send, каб ніхто не змог атрымаць да яго доступ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Скапіяваць спасылку на гэты Send у буфер абмену пасля захавання.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Тэкст, які вы хочаце адправіць." - }, - "sendHideText": { - "message": "Прадвызначана хаваць тэкст гэтага Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Бягучая колькасць доступаў" - }, "createSend": { "message": "Стварыць новы Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Перад тым, як пачаць" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Для выкарыстання каляндарнага стылю выбару даты", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "націсніце тут", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "для адкрыцця ў новым акне.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Азначаная дата завяршэння тэрміну дзеяння з'яўляецца няправільнай." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Адбылася памылка пры захаванні дат выдалення і завяршэння тэрміну дзеяння." }, - "hideEmail": { - "message": "Схаваць мой адрас электроннай пошты ад атрымальнікаў." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Адна або больш палітык арганізацыі ўплываюць на параметры Send." - }, "passwordPrompt": { "message": "Паўторны запыт асноўнага пароля" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Памылка" }, - "regenerateUsername": { - "message": "Паўторна генерыраваць імя карыстальніка" - }, "generateUsername": { "message": "Генерыраваць імя карыстальніка" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Тып імя карыстальніка" - }, "plusAddressedEmail": { "message": "Адрасы электроннай пошты з плюсам", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Назва вэб-сайта" }, - "whatWouldYouLikeToGenerate": { - "message": "Што вы хочаце генерыраваць?" - }, - "passwordType": { - "message": "Тып пароля" - }, "service": { "message": "Сэрвіс" }, diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 554650d5800..7cbbdc07be4 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Дължина" }, - "passwordMinLength": { - "message": "Минимална дължина на паролата" - }, "uppercase": { "message": "Главни букви (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Минимален брой специални знаци" }, - "avoidAmbChar": { - "message": "Без нееднозначни знаци", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Без нееднозначни знаци", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Показване на самоличностите в страницата с разделите, за лесно автоматично попълване." }, + "clickToAutofillOnVault": { + "message": "Щракнете върху елементите в трезора за автоматично попълване" + }, "clearClipboard": { "message": "Изчистване на буфера", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Преместване в организация" }, - "share": { - "message": "Споделяне" - }, "movedItemToOrg": { "message": "$ITEMNAME$ се премести в $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Клониране" }, - "passwordGeneratorPolicyInEffect": { - "message": "Поне една политика на организация влияе на настройките на генерирането на паролите." - }, "passwordGenerator": { "message": "Генератор на пароли" }, @@ -2389,14 +2379,6 @@ "message": "Подробности за Изпращането", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Търсене в изпратените", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Добавяне на изпращане", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Текст" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Скриване на текста по подразбиране" }, - "maxAccessCountReached": { - "message": "Достигнат е максималният брой достъпвания", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Изтекъл" }, - "pendingDeletion": { - "message": "Предстои изтриване" - }, "passwordProtected": { "message": "Защита с парола" }, @@ -2472,24 +2447,9 @@ "message": "Редактиране на изпращане", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Вид на изпратеното", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Описателно име за това изпращане.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Файл за изпращане." - }, "deletionDate": { "message": "Дата на изтриване" }, - "deletionDateDesc": { - "message": "Изпращането ще бъде окончателно изтрито на зададената дата и време.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Изпращането ще бъде окончателно изтрито на тази дата.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Срок на валидност" }, - "expirationDateDesc": { - "message": "При задаване — това изпращане ще се изключи на зададената дата и време.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 ден" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "По избор" }, - "maximumAccessCount": { - "message": "Максимален брой достъпвания." - }, - "maximumAccessCountDesc": { - "message": "При задаване — това изпращане ще се изключи след определен брой достъпвания.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Изискване на парола за достъп до това изпращане.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Добавете незадължителна парола, с която получателите да имат достъп до това Изпращане.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Скрити бележки за това изпращане.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Пълно спиране на това изпращане — никой няма да има достъп.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Копиране на връзката към това изпращане при запазването му.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Текст за изпращане." - }, - "sendHideText": { - "message": "Стандартно текстът на това изпращане да се крие.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Текущ брой на достъпванията" - }, "createSend": { "message": "Създаване на изпращане", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Преди да почнете" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "За избор на дата от каландар", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "натиснете тук", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "за изскачащ прозорец.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Неправилна дата на валидност." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Грешка при запазване на датата на валидност и изтриване." }, - "hideEmail": { - "message": "Скриване на е-пощата ми от получателите." - }, "hideYourEmail": { "message": "Скриване на Вашата е-поща от получателите." }, - "sendOptionsPolicyInEffect": { - "message": "Поне една политика на организация влияе на настройките за изпращане." - }, "passwordPrompt": { "message": "Повторно запитване за главната парола" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Грешка" }, - "regenerateUsername": { - "message": "Повторно генериране на потр. име" - }, "generateUsername": { "message": "Генериране на потр. име" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Тип потребителско име" - }, "plusAddressedEmail": { "message": "Адрес на е-поща с плюс", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Име на уеб сайт" }, - "whatWouldYouLikeToGenerate": { - "message": "Какво бихте искали да генерирате?" - }, - "passwordType": { - "message": "Тип парола" - }, "service": { "message": "Услуга" }, diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index c31f3511a5f..2da7b40554c 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -454,9 +454,6 @@ "length": { "message": "দৈর্ঘ্য" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "ন্যূনতম বিশেষ" }, - "avoidAmbChar": { - "message": "অস্পষ্ট বর্ণগুলি এড়িয়ে চলুন", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "ক্লিপবোর্ড পরিষ্কার", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "ভাগ করুন" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "নকল" }, - "passwordGeneratorPolicyInEffect": { - "message": "এক বা একাধিক সংস্থার নীতিগুলি আপনার উৎপাদকের সেটিংসকে প্রভাবিত করছে।" - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "অবসায়িত" }, - "pendingDeletion": { - "message": "মুছে ফেলার জন্য অপেক্ষমান" - }, "passwordProtected": { "message": "পাসওয়ার্ড সুরক্ষিত" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index d6cb591a524..9f5a610c351 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Isteklo" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dan" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index e405a18f885..b38783abc82 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Longitud" }, - "passwordMinLength": { - "message": "Longitud mínima de la contrasenya" - }, "uppercase": { "message": "Majúscula (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mínim de caràcters especials" }, - "avoidAmbChar": { - "message": "Eviteu caràcters ambigus", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Eviteu caràcters ambigus", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Llista els elements d'identitat de la pestanya de la pàgina per facilitar l'autoemplenat." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Buida el porta-retalls", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Desplaça a l'organització" }, - "share": { - "message": "Comparteix" - }, "movedItemToOrg": { "message": "$ITEMNAME$ desplaçat a $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clona" }, - "passwordGeneratorPolicyInEffect": { - "message": "Una o més polítiques d’organització afecten la configuració del generador." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Detalls de l'enviament", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Cerca Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Afig Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Ocultar el text per defecte" }, - "maxAccessCountReached": { - "message": "S'ha assolit el recompte màxim d'accesos", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Caducat" }, - "pendingDeletion": { - "message": "Pendent de supressió" - }, "passwordProtected": { "message": "Protegit amb contrasenya" }, @@ -2472,24 +2447,9 @@ "message": "Edita Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Quin tipus de Send és aquest?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Un nom apropiat per descriure aquest Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "El fitxer que voleu enviar." - }, "deletionDate": { "message": "Data de supressió" }, - "deletionDateDesc": { - "message": "L'enviament se suprimirà permanentment a la data i hora especificades.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "L'enviament s'esborrarà permanentment en aquesta data.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Data de caducitat" }, - "expirationDateDesc": { - "message": "Si s'estableix, l'accés a aquest enviament caducarà en la data i hora especificades.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dia" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalitzat" }, - "maximumAccessCount": { - "message": "Recompte màxim d'accessos" - }, - "maximumAccessCountDesc": { - "message": "Si s’estableix, els usuaris ja no podran accedir a aquest Send una vegada s’assolisca el nombre màxim d’accessos.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Opcionalment, necessiteu una contrasenya perquè els usuaris accedisquen a aquest Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Notes privades sobre aquest Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Desactiveu aquest Send perquè ningú no hi puga accedir.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copieu l'enllaç d'aquest Send al porta-retalls després de guardar-lo.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "El text que voleu enviar." - }, - "sendHideText": { - "message": "Amaga el text d'aquest Send per defecte.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Recompte d’accessos actual" - }, "createSend": { "message": "Crea un nou Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Abans de començar" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Per utilitzar un selector de dates d'estil calendari", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "feu clic ací", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "per eixir de la finestra.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "La data de caducitat proporcionada no és vàlida." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "S'ha produït un error en guardar les dates de supressió i caducitat." }, - "hideEmail": { - "message": "Amagueu la meua adreça de correu electrònic als destinataris." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Una o més polítiques d'organització afecten les vostres opcions del Send." - }, "passwordPrompt": { "message": "Sol·licitud de la contrasenya mestra" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenera el nom d'usuari" - }, "generateUsername": { "message": "Genera un nom d'usuari" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tipus de nom d'usuari" - }, "plusAddressedEmail": { "message": "Adreça amb sufix", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nom del lloc web" }, - "whatWouldYouLikeToGenerate": { - "message": "Què voleu generar?" - }, - "passwordType": { - "message": "Tipus de contrasenya" - }, "service": { "message": "Servei" }, diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index cf3ae3e2fd0..bcc7020ffb3 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Délka" }, - "passwordMinLength": { - "message": "Minimální délka hesla" - }, "uppercase": { "message": "Velká písmena (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimální počet speciálních znaků" }, - "avoidAmbChar": { - "message": "Nepoužívat zaměnitelné znaky", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Nepoužívat zaměnitelné znaky", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Pro snadné vyplnění zobrazí položky identit na obrazovce Karta." }, + "clickToAutofillOnVault": { + "message": "Klepněte na položky pro automatické vyplnění v zobrazení trezoru" + }, "clearClipboard": { "message": "Vymazat schránku", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Přesunout do organizace" }, - "share": { - "message": "Sdílet" - }, "movedItemToOrg": { "message": "$ITEMNAME$ přesunut do $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Duplikovat" }, - "passwordGeneratorPolicyInEffect": { - "message": "Jedna nebo více zásad organizace ovlivňují nastavení generátoru." - }, "passwordGenerator": { "message": "Generátor hesla" }, @@ -2389,14 +2379,6 @@ "message": "Podrobnosti Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Prohledat Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Přidat Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Ve výchozím nastavení skrýt text" }, - "maxAccessCountReached": { - "message": "Dosažen maximální počet přístupů", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Vypršela platnost" }, - "pendingDeletion": { - "message": "Čekání na smazání" - }, "passwordProtected": { "message": "Chráněno heslem" }, @@ -2472,24 +2447,9 @@ "message": "Upravit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Jakého typu je tento Send?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Přátelský název pro popis tohoto Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Soubor, který chcete odeslat." - }, "deletionDate": { "message": "Datum smazání" }, - "deletionDateDesc": { - "message": "Tento Send bude trvale smazán v určený datum a čas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Tento Send bude trvale smazán v určené datum.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Datum vypršení platnosti" }, - "expirationDateDesc": { - "message": "Je-li nastaveno, přístup k tomuto Send vyprší v daný datum a čas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 den" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Vlastní" }, - "maximumAccessCount": { - "message": "Maximální počet přístupů" - }, - "maximumAccessCountDesc": { - "message": "Je-li nastaveno, uživatelé již nebudou mít přístup k tomuto Send, jakmile bude dosaženo maximálního počtu přístupů.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Volitelně vyžadovat heslo pro přístup k tomuto Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Přidá volitelné heslo pro příjemce pro přístup k tomuto Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Soukromé poznámky o tomto Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deaktivuje tento Send, díky čemuž k němu nebude moci nikdo přistoupit.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Zkopíruje odkaz pro sdílení tohoto Send po uložení.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Text, který chcete odeslat." - }, - "sendHideText": { - "message": "Skrýt ve výchozím stavu text tohoto Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Aktuální počet přístupů" - }, "createSend": { "message": "Nový Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Než začnete" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Chcete-li použít k výběru data styl kalendáře", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klepněte zde", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "pro zobrazení okna.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Uvedené datum vypršení platnosti není platné." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Došlo k chybě při ukládání datumu smzání a vypršení platnosti." }, - "hideEmail": { - "message": "Skrýt mou e-mailovou adresu před příjemci." - }, "hideYourEmail": { "message": "Skryje Vaši e-mailovou adresu před zobrazením." }, - "sendOptionsPolicyInEffect": { - "message": "Jedna nebo více zásad organizace ovlivňuje nastavení Send." - }, "passwordPrompt": { "message": "Zeptat se znovu na hlavní heslo" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Chyba" }, - "regenerateUsername": { - "message": "Znovu vygenerovat uživatelské jméno" - }, "generateUsername": { "message": "Vygenerovat uživatelské jméno" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Typ uživatelského jména" - }, "plusAddressedEmail": { "message": "E-mailová adresa s plusem", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Název webu" }, - "whatWouldYouLikeToGenerate": { - "message": "Co chcete vygenerovat?" - }, - "passwordType": { - "message": "Typ hesla" - }, "service": { "message": "Služba" }, diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 3d4f1c73c02..3bc85b10fb5 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Hyd" }, - "passwordMinLength": { - "message": "Hyd lleiaf cyfrineiriau" - }, "uppercase": { "message": "Priflythrennau (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Isafswm nodau arbennig" }, - "avoidAmbChar": { - "message": "Osgoi nodau amwys", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clirio'r clipfwrdd", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Rhannu" - }, "movedItemToOrg": { "message": "Symudwyd $ITEMNAME$ i $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Chwilio drwy Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Ychwanegu Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Testun" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Wedi dod i ben" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Dyddiad dileu" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Dyddiad dod i ben" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 diwrnod" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Addasedig" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Cyn i chi ddechrau" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "cliciwch yma", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Dyw'r dyddiad dod i ben a roddwyd ddim yn ddilys." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Cuddio fy nghyfeiriad ebost rhag derbynwyr." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Ailofyn am y prif gyfrinair" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Gwall" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Cynhyrchu enw defnyddiwr" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Math o enw defnyddiwr" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "Beth hoffech chi ei gynhyrchu?" - }, - "passwordType": { - "message": "Math o gyfrinair" - }, "service": { "message": "Gwasanaeth" }, diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 207f409378e..433cdebbb17 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Længde" }, - "passwordMinLength": { - "message": "Minimumslængde på adgangskode" - }, "uppercase": { "message": "Store bogstaver (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mindste antal specialtegn" }, - "avoidAmbChar": { - "message": "Undgå tvetydige tegn", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Undgå tvetydige tegn", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Vis identitetsemner på siden Fane for nem autoudfyldning." }, + "clickToAutofillOnVault": { + "message": "Klik på emner for at autoudfylde i Boks-visning" + }, "clearClipboard": { "message": "Ryd udklipsholder", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Flyt til organisation" }, - "share": { - "message": "Del" - }, "movedItemToOrg": { "message": "$ITEMNAME$ flyttet til $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klon" }, - "passwordGeneratorPolicyInEffect": { - "message": "Én eller flere organisationspolitikker påvirker dine generatorindstillinger." - }, "passwordGenerator": { "message": "Adgangskodegenerator" }, @@ -2389,14 +2379,6 @@ "message": "Send-detaljer", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Søg i Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Tilføj Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Skjul tekst som standard" }, - "maxAccessCountReached": { - "message": "Maksimalt adgangsantal nået", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Udløbet" }, - "pendingDeletion": { - "message": "Afventer sletning" - }, "passwordProtected": { "message": "Kodeordsbeskyttet" }, @@ -2472,24 +2447,9 @@ "message": "Redigér Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Hvilken type Send er denne?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Et venligt navn til at beskrive denne Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Den fil, du vil sende." - }, "deletionDate": { "message": "Sletningsdato" }, - "deletionDateDesc": { - "message": "Send'en slettes permanent på den angivne dato og tid.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Denne Send slettes permanent på denne dato.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Udløbsdato" }, - "expirationDateDesc": { - "message": "Hvis angivet, vil adgangen til denne Send udløbe på den angivne dato og tidspunkt.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dag" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Tilpasset" }, - "maximumAccessCount": { - "message": "Maksimalt antal tilgange" - }, - "maximumAccessCountDesc": { - "message": "Hvis opsat, vil brugere ikke længere kunne tilgå denne Send, når det maksimale adgangsantal er nået.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Valgfrit brugeradgangskodekrav for at tilgå denne Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Tilføj en valgfri adgangskode til modtagere for adgang til denne Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notater om denne Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deaktivér denne Send, så ingen kan tilgå den.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopiér denne Sends link til udklipsholderen når du gemmer.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Den tekst, du vil sende." - }, - "sendHideText": { - "message": "Skjul denne Sends tekst som standard.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Aktuelt antal tilgange" - }, "createSend": { "message": "Ny Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Før du starter" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "For at bruge en datovælger i kalenderstil skal du", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klikke her", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "for at åbne dit vindue.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Den angivne udløbsdato er ikke gyldig." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Der opstod en fejl under forsøget på at gemme dine sletnings- og udløbsdatoer." }, - "hideEmail": { - "message": "Skjul min e-mailadresse for modtagere." - }, "hideYourEmail": { "message": "Skjul e-mailadressen for modtagere." }, - "sendOptionsPolicyInEffect": { - "message": "Én eller flere organisationspolitikker påvirker dine Send-valgmuligheder." - }, "passwordPrompt": { "message": "Genanmodning om hovedadgangskode" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Fejl" }, - "regenerateUsername": { - "message": "Regenerér brugernavn" - }, "generateUsername": { "message": "Generér brugernavn" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Brugernavnstype" - }, "plusAddressedEmail": { "message": "Plus-adresseret e-mail", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Hjemmeside navn" }, - "whatWouldYouLikeToGenerate": { - "message": "Hvad vil du gerne generere?" - }, - "passwordType": { - "message": "Adgangskodetype" - }, "service": { "message": "Tjeneste" }, diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 169cdf6aa78..2fc5297205a 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -193,10 +193,10 @@ "message": "Identität automatisch ausfüllen" }, "fillVerificationCode": { - "message": "Verifizierungscode eingeben" + "message": "Verifizierungscode ausfüllen" }, "fillVerificationCodeAria": { - "message": "Verifizierungscode eingeben", + "message": "Verifizierungscode ausfüllen", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -454,9 +454,6 @@ "length": { "message": "Länge" }, - "passwordMinLength": { - "message": "Minimale Passwortlänge" - }, "uppercase": { "message": "Großbuchstaben (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mindestanzahl Sonderzeichen" }, - "avoidAmbChar": { - "message": "Mehrdeutige Zeichen vermeiden", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Mehrdeutige Zeichen vermeiden", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Identitäten-Einträge auf der Tab Seite anzeigen, um das Auto-Ausfüllen zu vereinfachen." }, + "clickToAutofillOnVault": { + "message": "Klicke auf Einträge zum automatischen Ausfüllen in der Tresor-Ansicht" + }, "clearClipboard": { "message": "Zwischenablage leeren", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "In Organisation verschieben" }, - "share": { - "message": "Teilen" - }, "movedItemToOrg": { "message": "$ITEMNAME$ verschoben nach $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Duplizieren" }, - "passwordGeneratorPolicyInEffect": { - "message": "Eine oder mehrere Organisationsrichtlinien beeinflussen deine Generator-Einstellungen." - }, "passwordGenerator": { "message": "Passwort-Generator" }, @@ -2389,14 +2379,6 @@ "message": "Send-Details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Sends suchen", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Send hinzufügen", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Text standardmäßig ausblenden" }, - "maxAccessCountReached": { - "message": "Maximale Zugriffsanzahl erreicht", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Abgelaufen" }, - "pendingDeletion": { - "message": "Ausstehende Löschung" - }, "passwordProtected": { "message": "Passwortgeschützt" }, @@ -2472,24 +2447,9 @@ "message": "Send bearbeiten", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Welche Art von Send ist das?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Ein eigener Name, um dieses Send zu beschreiben.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Die Datei, die du senden möchtest." - }, "deletionDate": { "message": "Löschdatum" }, - "deletionDateDesc": { - "message": "Das Send wird am angegebenen Datum zur angegebenen Uhrzeit dauerhaft gelöscht.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Das Send wird an diesem Datum dauerhaft gelöscht.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Ablaufdatum" }, - "expirationDateDesc": { - "message": "Falls aktiviert, verfällt der Zugriff auf dieses Send am angegebenen Datum zur angegebenen Uhrzeit.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 Tag" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Benutzerdefiniert" }, - "maximumAccessCount": { - "message": "Maximale Zugriffsanzahl" - }, - "maximumAccessCountDesc": { - "message": "Falls aktiviert, können Benutzer nicht mehr auf dieses Send zugreifen, sobald die maximale Zugriffsanzahl erreicht ist.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optional ein Passwort verlangen, damit Benutzer auf dieses Send zugreifen können.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Füge ein optionales Passwort hinzu, mit dem Empfänger auf dieses Send zugreifen können.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private Notizen zu diesem Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Dieses Send deaktivieren, damit niemand darauf zugreifen kann.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopiere den Send-Link beim Speichern in die Zwischenablage.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Der Text, den du senden möchtest." - }, - "sendHideText": { - "message": "Send-Text standardmäßig ausblenden.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Aktuelle Zugriffsanzahl" - }, "createSend": { "message": "Neues Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Bevor du beginnst" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Um einen Kalender-Datumsauswahl zu verwenden", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "hier klicken", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "zum Öffnen in einem neuen Fenster.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Das angegebene Verfallsdatum ist nicht gültig." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Es gab einen Fehler beim Speichern deiner Lösch- und Verfallsdaten." }, - "hideEmail": { - "message": "Meine E-Mail-Adresse vor den Empfängern ausblenden." - }, "hideYourEmail": { "message": "Verberge deine E-Mail-Adresse vor Betrachtern." }, - "sendOptionsPolicyInEffect": { - "message": "Eine oder mehrere Organisationsrichtlinien beeinflussen deine Send Einstellungen." - }, "passwordPrompt": { "message": "Master-Passwort erneut abfragen" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Fehler" }, - "regenerateUsername": { - "message": "Benutzername neu generieren" - }, "generateUsername": { "message": "Benutzername generieren" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Benutzernamenstyp" - }, "plusAddressedEmail": { "message": "Plus-adressierte E-Mail-Adresse", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Websitename" }, - "whatWouldYouLikeToGenerate": { - "message": "Was möchtest du generieren?" - }, - "passwordType": { - "message": "Passworttyp" - }, "service": { "message": "Dienst" }, @@ -4914,13 +4807,13 @@ "message": "Wichtiger Hinweis" }, "setupTwoStepLogin": { - "message": "Richte die zweistufige Anmeldung ein" + "message": "Zwei-Faktor-Authentifizierung einrichten" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden wird einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten ab Februar 2025 zu überprüfen." + "message": "Ab Februar 2025 wird Bitwarden einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten zu verifizieren." }, "newDeviceVerificationNoticeContentPage2": { - "message": "Du kannst die zweistufige Anmeldung als eine alternative Methode einrichten, um deinen Account zu schützen, oder ändere deine E-Mail-Adresse zu einer, auf die du zugreifen kannst." + "message": "Du kannst die Zwei-Faktor-Authentifizierung als eine alternative Methode einrichten, um dein Konto zu schützen, oder deine E-Mail-Adresse zu einer anderen ändern, auf die du zugreifen kannst." }, "remindMeLater": { "message": "Erinnere mich später" @@ -4941,10 +4834,10 @@ "message": "Ja, ich kann zuverlässig auf meine E-Mails zugreifen" }, "turnOnTwoStepLogin": { - "message": "Aktiviere die zweistufige Anmeldung" + "message": "Zwei-Faktor-Authentifizierung aktivieren" }, "changeAcctEmail": { - "message": "Ändere die E-Mail-Adresse des Kontos" + "message": "E-Mail-Adresse des Kontos ändern" }, "extensionWidth": { "message": "Breite der Erweiterung" diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index d6ae3c52333..a33bc4d0e20 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -20,16 +20,16 @@ "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": "Ορίστε έναν ισχυρό κωδικό πρόσβασης" @@ -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": { @@ -193,10 +193,10 @@ "message": "Αυτόματη συμπλήρωση ταυτότητας" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Συμπλήρωση κωδικού επαλήθευσης" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "Συμπλήρωση Κωδικού Επαλήθευσης", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -443,7 +443,7 @@ "message": "Δημιουργία κωδικού πρόσβασης" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Δημιουργία φράσης πρόσβασης" }, "regeneratePassword": { "message": "Επαναδημιουργία κωδικού πρόσβασης" @@ -454,9 +454,6 @@ "length": { "message": "Μήκος" }, - "passwordMinLength": { - "message": "Ελάχιστο μήκος κωδικού πρόσβασης" - }, "uppercase": { "message": "Κεφαλαία (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Ελάχιστοι ειδικοί χαρακτήρες" }, - "avoidAmbChar": { - "message": "Αποφυγή αμφιλεγόμενων χαρακτήρων", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Αποφυγή αμφιλεγόμενων χαρακτήρων", "description": "Label for the avoid ambiguous characters checkbox." @@ -607,7 +600,7 @@ "message": "Εκκίνηση ιστοσελίδας" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Εκκίνηση ιστοσελίδας $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -859,7 +852,7 @@ "message": "Σύνδεση" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Σύνδεση στο Bitwarden" }, "restartRegistration": { "message": "Επανεκκίνηση εγγραφής" @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Λίστα στοιχείων ταυτότητας στη σελίδα Καρτέλας για εύκολη αυτόματη συμπλήρωση." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Εκκαθάριση Πρόχειρου", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1130,7 +1126,7 @@ "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "Προειδοποίηση", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Μετακίνηση σε οργανισμό" }, - "share": { - "message": "Κοινοποίηση" - }, "movedItemToOrg": { "message": "$ITEMNAME$ μετακινήθηκε στο $ORGNAME$", "placeholders": { @@ -1324,10 +1317,10 @@ "message": "Εισάγετε τον 6ψήφιο κωδικό από την εφαρμογή επαλήθευσης." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Χρονικό όριο επαλήθευσης" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "Λήξη χρονικού ορίου συνεδρίας επαλήθευσης. Παρακαλώ επανεκκινήστε τη διαδικασία σύνδεσης." }, "enterVerificationCodeEmail": { "message": "Εισάγετε τον 6ψήφιο κωδικό επαλήθευσης τον οποίο λάβατε στο $EMAIL$.", @@ -1447,7 +1440,7 @@ "message": "URL Διακομιστή" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "Διεύθυνση URL διακομιστή αυτοεξυπηρετητή", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1775,7 +1768,7 @@ "message": "Ταυτότητα" }, "typeSshKey": { - "message": "SSH key" + "message": "Κλειδί SSH" }, "newItemHeader": { "message": "Νέα $TYPE$", @@ -1808,13 +1801,13 @@ "message": "Ιστορικό κωδικού πρόσβασης" }, "generatorHistory": { - "message": "Generator history" + "message": "Ιστορικό γεννήτριας" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Εκκαθάριση ιστορικού γεννήτριας" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Αν συνεχίσετε, όλες οι καταχωρήσεις θα διαγραφούν οριστικά από το ιστορικό της γεννήτριας. Είστε σίγουροι ότι θέλετε να συνεχίσετε;" }, "back": { "message": "Πίσω" @@ -1853,7 +1846,7 @@ "message": "Ασφαλείς σημειώσεις" }, "sshKeys": { - "message": "SSH Keys" + "message": "Κλειδιά SSH" }, "clear": { "message": "Εκκαθάριση", @@ -1936,10 +1929,10 @@ "message": "Διαγραφή ιστορικού" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Τίποτα για προβολή" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Δεν έχετε δημιουργήσει τίποτα πρόσφατα" }, "remove": { "message": "Αφαίρεση" @@ -2047,9 +2040,6 @@ "clone": { "message": "Κλώνος" }, - "passwordGeneratorPolicyInEffect": { - "message": "Μία ή περισσότερες πολιτικές του οργανισμού επηρεάζουν τις ρυθμίσεις της γεννήτριας." - }, "passwordGenerator": { "message": "Γεννήτρια κωδικού πρόσβασης" }, @@ -2389,14 +2379,6 @@ "message": "Στοιχεία Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Αναζήτηση Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Προσθήκη Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Κείμενο" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Απόκρυψη κειμένου από προεπιλογή" }, - "maxAccessCountReached": { - "message": "Φτάσατε στον μέγιστο αριθμό πρόσβασης", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Έληξε" }, - "pendingDeletion": { - "message": "Εκκρεμεί διαγραφή" - }, "passwordProtected": { "message": "Προστατευμένο με κωδικό" }, @@ -2472,24 +2447,9 @@ "message": "Επεξεργασία Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Τι είδους Send είναι αυτό;", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Ένα φιλικό όνομα για την περιγραφή αυτού του Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Το αρχείο που θέλετε να στείλετε." - }, "deletionDate": { "message": "Ημερομηνία διαγραφής" }, - "deletionDateDesc": { - "message": "Το Send θα διαγραφεί οριστικά την καθορισμένη ημερομηνία και ώρα.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Το Send θα διαγραφεί οριστικά σε αυτήν την ημερομηνία.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Ημερομηνία λήξης" }, - "expirationDateDesc": { - "message": "Εάν οριστεί, η πρόσβαση σε αυτό το Send θα λήξει την καθορισμένη ημερομηνία και ώρα.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 ημέρα" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Προσαρμοσμένο" }, - "maximumAccessCount": { - "message": "Μέγιστος Αριθμός Πρόσβασης" - }, - "maximumAccessCountDesc": { - "message": "Εάν οριστεί, οι χρήστες δεν θα μπορούν πλέον να έχουν πρόσβαση σε αυτό το send μόλις επιτευχθεί ο μέγιστος αριθμός πρόσβασης.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Προαιρετικά απαιτείται κωδικός πρόσβασης για τους χρήστες για να έχουν πρόσβαση σε αυτό το Send.", - "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.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNotesDesc": { - "message": "Ιδιωτικές σημειώσεις σχετικά με αυτό το Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Απενεργοποιήστε αυτό το Send έτσι ώστε κανείς να μην μπορεί να έχει πρόσβαση σε αυτό.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Αντιγραφή του συνδέσμου για αυτό το Send στο πρόχειρο κατά την αποθήκευση.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Το κείμενο που θέλετε να στείλετε." - }, - "sendHideText": { - "message": "Απόκρυψη του κειμένου αυτού του Send από προεπιλογή.", + "message": "Προσθέστε έναν προαιρετικό κωδικό πρόσβασης για τους παραλήπτες για πρόσβαση σε αυτήν την αποστολή.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "currentAccessCount": { - "message": "Τρέχων αριθμός πρόσβασης" - }, "createSend": { "message": "Νέο Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Πριν ξεκινήσετε" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Για να χρησιμοποιήσετε έναν επιλογέα ημερομηνίας στυλ ημερολογίου", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "κάντε κλικ εδώ", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "για να βγεις από το παράθυρο.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Η ημερομηνία λήξης που δόθηκε δεν είναι έγκυρη." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Παρουσιάστηκε σφάλμα κατά την αποθήκευση των ημερομηνιών διαγραφής και λήξης." }, - "hideEmail": { - "message": "Απόκρυψη της διεύθυνσης email μου από τους παραλήπτες." - }, "hideYourEmail": { "message": "Απόκρυψη της διεύθυνσης email σας από τους θεατές." }, - "sendOptionsPolicyInEffect": { - "message": "Μία ή περισσότερες οργανωτικές πολιτικές επηρεάζουν τις επιλογές send σας." - }, "passwordPrompt": { "message": "Προτροπή νέου κωδικού πρόσβασης" }, @@ -2884,17 +2789,14 @@ "error": { "message": "Σφάλμα" }, - "regenerateUsername": { - "message": "Επαναδημιουργία ονόματος χρήστη" - }, "generateUsername": { "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": { @@ -2908,7 +2810,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": { @@ -2918,7 +2820,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": { @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Τύπος ονόματος χρήστη" - }, "plusAddressedEmail": { "message": "Συν διεύθυνση ηλ. ταχυδρομείου", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Όνομα ιστοσελίδας" }, - "whatWouldYouLikeToGenerate": { - "message": "Τι θα θέλατε να δημιουργήσετε?" - }, - "passwordType": { - "message": "Τύπος κωδικού πρόσβασης" - }, "service": { "message": "Υπηρεσία" }, @@ -2968,11 +2861,11 @@ "message": "Δημιουργήστε ένα alias email με μια εξωτερική υπηρεσία προώθησης." }, "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": { @@ -3175,25 +3068,25 @@ "message": "Επαναποστολή ειδοποίησης" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Δείτε όλες τις επιλογές σύνδεσης" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "Δείτε όλες τις επιλογές σύνδεσης" }, "notificationSentDevice": { "message": "Μια ειδοποίηση έχει σταλεί στη συσκευή σας." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Μια ειδοποίηση στάλθηκε στη συσκευή σας" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Βεβαιωθείτε ότι ο λογαριασμός σας είναι ξεκλείδωτος και ότι η φράση δακτυλικού αποτυπώματος ταιριάζει στην άλλη συσκευή" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Θα ειδοποιηθείτε μόλις εγκριθεί η αίτηση" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Χρειάζεστε μια άλλη επιλογή;" }, "loginInitiated": { "message": "Η σύνδεση ξεκίνησε" @@ -3289,16 +3182,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": "Απομνημόνευση αυτής της συσκευής" @@ -3374,7 +3267,7 @@ "message": "Η διεύθυνση ηλ. ταχυδρομείου του χρήστη λείπει" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Το ηλ. ταχυδρομείο χρήστη δεν βρέθηκε. Αποσυνδεθήκατε." }, "deviceTrusted": { "message": "Αξιόπιστη συσκευή" @@ -3585,11 +3478,11 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Κωδικός Επαλήθευσης Κωδικού Πρόσβασης μιας φοράς", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "Χρόνος που απομένει πριν λήξει του τρέχον ΚΕΚΠ", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { @@ -3821,7 +3714,7 @@ "message": "Πρόσβαση" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Έχετε συνδεθεί!" }, "passkeyNotCopied": { "message": "Το κλειδί πρόσβασης δε θα αντιγραφεί" @@ -4315,13 +4208,13 @@ "message": "Φίλτρα" }, "filterVault": { - "message": "Filter vault" + "message": "Φίλτρο θησαυ/κιου" }, "filterApplied": { - "message": "One filter applied" + "message": "Ένα φίλτρο εφαρμόστηκε" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "$COUNT$ φίλτρα εφαρμόστηκαν", "placeholders": { "count": { "content": "$1", @@ -4653,13 +4546,13 @@ "message": "Τοποθεσία Αντικειμένου" }, "fileSend": { - "message": "File Send" + "message": "Δημιουργία Αποστολής" }, "fileSends": { "message": "Send αρχείων" }, "textSend": { - "message": "Text Send" + "message": "Κείμενο Αποστολής" }, "textSends": { "message": "Send κειμένων" @@ -4677,7 +4570,7 @@ "message": "Εμφάνιση αριθμού προτάσεων αυτόματης συμπλήρωσης σύνδεσης στο εικονίδιο επέκτασης" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Εμφάνιση ενεργειών γρήγορης αντιγραφής στο Θησαυ/κιο" }, "systemDefault": { "message": "Προεπιλογή συστήματος" @@ -4686,16 +4579,16 @@ "message": "Οι απαιτήσεις της πολιτικής για επιχειρήσεις έχουν εφαρμοστεί σε αυτήν τη ρύθμιση" }, "sshPrivateKey": { - "message": "Private key" + "message": "Ιδιωτικό κλειδί" }, "sshPublicKey": { - "message": "Public key" + "message": "Δημόσιο κλειδί" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Δακτυλικό αποτύπωμα" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Τύπος κλειδιού" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -4752,181 +4645,181 @@ "message": "Ταυτοποίηση" }, "fillGeneratedPassword": { - "message": "Fill generated password", + "message": "Συμπληρώση του δημιουργημένου κωδικού πρόσβασης", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "Ο κωδικός επαναδημιουργήθηκε", "description": "Notification message for when a password has been regenerated" }, "saveLoginToBitwarden": { - "message": "Save login to Bitwarden?", + "message": "Αποθήκευση σύνδεσης στο Bitwarden;", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "Κενό", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { - "message": "Tilde", + "message": "Περισπωμένη", "description": "Represents the ~ key in screen reader content as a readable word" }, "backtickCharacterDescriptor": { - "message": "Backtick", + "message": "Ανάποδη απόστροφος", "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "Θαυμαστικό", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { - "message": "At sign", + "message": "Παπάκι", "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "Δίεση", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { - "message": "Dollar sign", + "message": "Δολάριο", "description": "Represents the $ key in screen reader content as a readable word" }, "percentSignCharacterDescriptor": { - "message": "Percent sign", + "message": "Τοις εκατό", "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "Εκθέτης", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { - "message": "Ampersand", + "message": "Και", "description": "Represents the & key in screen reader content as a readable word" }, "asteriskCharacterDescriptor": { - "message": "Asterisk", + "message": "Πολλαπλασιασμός", "description": "Represents the * key in screen reader content as a readable word" }, "parenLeftCharacterDescriptor": { - "message": "Left parenthesis", + "message": "Αριστερή παρένθεση", "description": "Represents the ( key in screen reader content as a readable word" }, "parenRightCharacterDescriptor": { - "message": "Right parenthesis", + "message": "Δεξιά παρένθεση", "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "Κάτω παύλα", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "Παύλα", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { - "message": "Plus", + "message": "Συν", "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "Ίσον", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "Αριστερό άγκιστρο", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "Δεξί άγκιστρο", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "Αριστερή αγκύλη", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "Δεξιά αγκύλη", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "Κάθετος γραμμή", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "Πίσω κάθετος", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { - "message": "Colon", + "message": "Άνω κάτω τελεία", "description": "Represents the : key in screen reader content as a readable word" }, "semicolonCharacterDescriptor": { - "message": "Semicolon", + "message": "Ερωτηματικό", "description": "Represents the ; key in screen reader content as a readable word" }, "doubleQuoteCharacterDescriptor": { - "message": "Double quote", + "message": "Διπλά εισαγωγικά", "description": "Represents the double quote key in screen reader content as a readable word" }, "singleQuoteCharacterDescriptor": { - "message": "Single quote", + "message": "Μονά εισαγωγικά", "description": "Represents the ' key in screen reader content as a readable word" }, "lessThanCharacterDescriptor": { - "message": "Less than", + "message": "Λιγότερο από", "description": "Represents the < key in screen reader content as a readable word" }, "greaterThanCharacterDescriptor": { - "message": "Greater than", + "message": "Μεγαλύτερο από", "description": "Represents the > key in screen reader content as a readable word" }, "commaCharacterDescriptor": { - "message": "Comma", + "message": "Κόμμα", "description": "Represents the , key in screen reader content as a readable word" }, "periodCharacterDescriptor": { - "message": "Period", + "message": "Τελεία", "description": "Represents the . key in screen reader content as a readable word" }, "questionCharacterDescriptor": { - "message": "Question mark", + "message": "Αγγλικό ερωτηματικό", "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "Εμπρός κάθετος", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { - "message": "Lowercase" + "message": "Πεζά" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "Κεφαλαία" }, "generatedPassword": { - "message": "Generated password" + "message": "Τυχαίος κωδικός πρόσβασης" }, "compactMode": { - "message": "Compact mode" + "message": "Συμπαγής μορφή" }, "beta": { - "message": "Beta" + "message": "Beta (Δοκιμαστική)" }, "importantNotice": { - "message": "Important notice" + "message": "Σημαντική ειδοποίηση" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Ρύθμιση σύνδεσης δύο βημάτων" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Το Bitwarden θα στείλει έναν κωδικό στο ηλ. ταχυδρομείο του λογαριασμού σας για να επαληθεύσει τις συνδέσεις από τις νέες συσκευές που ξεκινούν τον Φεβρουάριο του 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Μπορείτε να ορίσετε σύνδεση δύο βημάτων ως εναλλακτικό τρόπο προστασίας του λογαριασμού σας ή να αλλάξετε το ηλ. ταχυδρομείο σας σε ένα που μπορείτε να έχετε πρόσβαση." }, "remindMeLater": { - "message": "Remind me later" + "message": "Υπενθύμιση αργότερα" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Έχετε αξιόπιστη πρόσβαση στο ηλ. ταχυδρομείο σας, $EMAIL$;", "placeholders": { "email": { "content": "$1", @@ -4935,24 +4828,24 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Όχι, δεν έχω" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Ναι, μπορώ να συνδεθώ αξιόπιστα στο ηλ. ταχυδρομείο μου" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Ενεργοποίηση σύνδεσης δύο βημάτων" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Αλλαγή ηλ. ταχυδρομείου λογαριασμού" }, "extensionWidth": { - "message": "Extension width" + "message": "Πλάτος εφαρμογής" }, "wide": { - "message": "Wide" + "message": "Φαρδύ" }, "extraWide": { - "message": "Extra wide" + "message": "Εξαιρετικά φαρδύ" } } diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index a771b390b1b..2c13f1b9259 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy auto-fill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organisation" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organisation policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organisation policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 17c06b57c2a..b6031381d2d 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy auto-fill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organisation" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organisation policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion Date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration Date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Disable this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current Access Count" - }, "createSend": { "message": "Create New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organisation policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate Username" - }, "generateUsername": { "message": "Generate Username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username Type" - }, "plusAddressedEmail": { "message": "Plus Addressed Email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website Name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password Type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index eaff576d94b..d26716dd909 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Longitud" }, - "passwordMinLength": { - "message": "Longitud mínima de contraseña" - }, "uppercase": { "message": "Mayúsculas (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mínimo de caracteres especiales" }, - "avoidAmbChar": { - "message": "Evitar caracteres ambiguos", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Evitar caracteres ambiguos", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Listar los elementos de identidad en la página para facilitar el auto-rellenado." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Vaciar portapapeles", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Mover a la Organización" }, - "share": { - "message": "Compartir" - }, "movedItemToOrg": { "message": "$ITEMNAME$ se desplazó a $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clonar" }, - "passwordGeneratorPolicyInEffect": { - "message": "Una o más políticas de la organización están afectando la configuración del generador" - }, "passwordGenerator": { "message": "Generador de contraseñas" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Buscar Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Añadir Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Texto" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Número máximo de accesos alcanzado", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Caducado" }, - "pendingDeletion": { - "message": "Borrado pendiente" - }, "passwordProtected": { "message": "Protegido por contraseña" }, @@ -2472,24 +2447,9 @@ "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "¿Qué tipo de Send es este?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Un nombre amigable para describir este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "El archivo que desea enviar." - }, "deletionDate": { "message": "Fecha de eliminación" }, - "deletionDateDesc": { - "message": "El Send se eliminará permanentemente en la fecha y hora especificadas.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Fecha de caducidad" }, - "expirationDateDesc": { - "message": "Si se establece, el acceso a este Send caducará en la fecha y hora especificadas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 día" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalizado" }, - "maximumAccessCount": { - "message": "Número máximo de accesos" - }, - "maximumAccessCountDesc": { - "message": "Si se establece, los usuarios ya no podrán acceder a este Send una vez que se alcance el número máximo de accesos.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Opcionalmente se requiere una contraseña para que los usuarios accedan a este Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Notas privadas sobre este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Desactiva este Send para que nadie pueda acceder a él.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copiar el enlace del Send en el portapapeles al guardar.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "El texto que quieres enviar." - }, - "sendHideText": { - "message": "Ocultar el texto de este Envío por defecto.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Número de acceso actual" - }, "createSend": { "message": "Crear Envío nuevo", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Antes de empezar" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Para usar un selector de fechas de estilo calendario", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "haz click aquí", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "para abrir la ventana.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "La fecha de caducidad proporcionada no es válida." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Hubo un error al guardar las fechas de eliminación y caducidad." }, - "hideEmail": { - "message": "Ocultar mi dirección de correo electrónico a los destinatarios." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Una o más políticas de organización están afectando sus opciones del Send." - }, "passwordPrompt": { "message": "Volver a preguntar contraseña maestra" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerar nombre de usuario" - }, "generateUsername": { "message": "Generar nombre de usuario" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tipo de nombre de usuario" - }, "plusAddressedEmail": { "message": "Dirección con sufijo", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nombre del sitio web" }, - "whatWouldYouLikeToGenerate": { - "message": "¿Qué te gustaría generar?" - }, - "passwordType": { - "message": "Tipo de contraseña" - }, "service": { "message": "Servicio" }, diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index c772a7b23e7..069135ddb08 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Pikkus" }, - "passwordMinLength": { - "message": "Lühim lubatud parooli pikkus" - }, "uppercase": { "message": "Suurtäht (A-Z) ", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Vähim arv spetsiaalmärke" }, - "avoidAmbChar": { - "message": "Väldi ebamääraseid kirjamärke", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Väldi raskesti eristatavaid tähti ja sümboleid", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Kuvab \"Kaart\" vaates identiteete, et neid saaks kiiresti sisestada" }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Lõikelaua sisu kustutamine", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Teisalda organisatsiooni" }, - "share": { - "message": "Jaga" - }, "movedItemToOrg": { "message": "$ITEMNAME$ teisaldati $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Kloon" }, - "passwordGeneratorPolicyInEffect": { - "message": "Organisatsiooni seaded mõjutavad parooli genereerija sätteid." - }, "passwordGenerator": { "message": "Parooli genereerija" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Otsi Sende", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Lisa Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Maksimaalne ligipääsude arv on saavutatud", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Aegunud" }, - "pendingDeletion": { - "message": "Kustutamise ootel" - }, "passwordProtected": { "message": "Parooliga kaitstud" }, @@ -2472,24 +2447,9 @@ "message": "Muuda Sendi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Mis tüüpi Send see on?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Sisesta Sendi nimi (kohustuslik).", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Fail, mida soovid saata." - }, "deletionDate": { "message": "Kustutamise kuupäev" }, - "deletionDateDesc": { - "message": "Send kustutatakse määratud kuupäeval ja kellaajal jäädavalt.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Aegumiskuupäev" }, - "expirationDateDesc": { - "message": "Selle valimisel ei pääse sellele Sendile enam pärast määratud kuupäeva ligi.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 päev" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Kohandatud" }, - "maximumAccessCount": { - "message": "Maksimaalne ligipääsude arv" - }, - "maximumAccessCountDesc": { - "message": "Selle valimisel ei saa kasutajad pärast maksimaalse ligipääsude arvu saavutamist sellele Sendile enam ligi.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Soovi korral nõua parooli, millega Sendile ligi pääseb.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Privaatne märkus selle Sendi kohta.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Keela see Send, et keegi ei pääseks sellele ligi.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopeeri Sendi salvestamisel link lõikelauale.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Tekst, mida soovid saata." - }, - "sendHideText": { - "message": "Vaikeolekus peida selle Sendi tekst.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Hetkeline ligipääsude arv" - }, "createSend": { "message": "Loo uus Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Enne alustamist" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Kalendri stiilis kuupäeva valimiseks", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "kliki siia,", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "et avada Bitwarden uues aknas.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Valitud aegumiskuupäev ei ole õige." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Kustutamis- ja aegumiskuupäevade salvestamisel ilmnes tõrge." }, - "hideEmail": { - "message": "Ära näita saajatele minu e-posti aadressi." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Organisatsiooni seaded mõjutavad sinu Sendi sätteid." - }, "passwordPrompt": { "message": "Nõutav on ülemparool" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Viga" }, - "regenerateUsername": { - "message": "Genereeri kasutajanimi uuesti" - }, "generateUsername": { "message": "Genereeri kasutajanimi" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Kasutajanime tüüp" - }, "plusAddressedEmail": { "message": "Plussiga e-posti aadress", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Veebilehe nimi" }, - "whatWouldYouLikeToGenerate": { - "message": "Mida sa soovid genereerida?" - }, - "passwordType": { - "message": "Parooli tüüp" - }, "service": { "message": "Teenus" }, diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 117751b3794..47a56583c64 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Luzera" }, - "passwordMinLength": { - "message": "Pasahitzaren gutxieneko luzera" - }, "uppercase": { "message": "Letra larria (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Gutxieneko karaktere bereziak" }, - "avoidAmbChar": { - "message": "Saihestu karaktere anbiguoak", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Erakutsi identitateak fitxa orrian, erraz auto-betetzeko." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Hustu arbela", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Mugitu erakundera" }, - "share": { - "message": "Partekatu" - }, "movedItemToOrg": { "message": "$ITEMNAME$ $ORGNAME$-ra mugituta", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klonatu" }, - "passwordGeneratorPolicyInEffect": { - "message": "Erakundeko politika batek edo gehiagok sortzailearen konfigurazioari eragiten diote." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Send-ak bilatu", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Gehitu Send-a", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Testua" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Sarbide kopuru maximoa gaindituta", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Iraungita" }, - "pendingDeletion": { - "message": "Ezabatzea egiteke" - }, "passwordProtected": { "message": "Pasahitz babestua" }, @@ -2472,24 +2447,9 @@ "message": "Editatu Send-a", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Zein Send mota da hau?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Send hau deskribatzeko izena.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Bidali nahi duzun fitxategia." - }, "deletionDate": { "message": "Ezabatze data" }, - "deletionDateDesc": { - "message": "Send-a betiko ezabatuko da zehaztutako datan eta orduan.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Iraungitze data" }, - "expirationDateDesc": { - "message": "Hala ezartzen bada, Send honetarako sarbidea zehaztutako egunean eta orduan amaituko da.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "Egun 1" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Pertsonalizatua" }, - "maximumAccessCount": { - "message": "Sarbide kopuru maximoa" - }, - "maximumAccessCountDesc": { - "message": "Hala ezartzen bada, erabiltzaileak ezin izango dira Send honetara sartu gehienezko sarbide kopurura iritsi ondoren.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Nahi izanez gero, pasahitza eskatu erabiltzaileak Send honetara sar daitezen.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Send honi buruzko ohar pribatuak.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Desgaitu Send hau inor sar ez dadin.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Gordetzean, kopiatu Send honen esteka arbelean.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Bidali nahi duzun testua." - }, - "sendHideText": { - "message": "Ezkutatu Send-eko testu hau, modu lehenetsian.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Uneko sarbide kopurua" - }, "createSend": { "message": "Sortu Send berria", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Hasi aurretik" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Data aukeratzeko egutegi modua erabiltzeko", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klikatu hemen", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "leihoa irekitzeko.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Iraungitze data ez da baliozkoa." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Akatsa gertatu da ezabatze eta iraungitze datak gordetzean." }, - "hideEmail": { - "message": "Ezkutatu nire emaila hartzaileei." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Erakundeko politika batek edo gehiagok Send-eko aukerei eragiten diote." - }, "passwordPrompt": { "message": "Berriro eskatu pasahitz nagusia" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Akatsa" }, - "regenerateUsername": { - "message": "Berrezarri erabiltzaile izena" - }, "generateUsername": { "message": "Sortu erabiltzaile izena" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Erabiltzaile izen mota" - }, "plusAddressedEmail": { "message": "Atzizkidun emaila", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Webgune izena" }, - "whatWouldYouLikeToGenerate": { - "message": "Zer sortu nahi duzu?" - }, - "passwordType": { - "message": "Pasahitz mota" - }, "service": { "message": "Zerbitzua" }, diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 47bf414db2f..2b8a5e20da1 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -454,9 +454,6 @@ "length": { "message": "طول" }, - "passwordMinLength": { - "message": "حداقل طول گذرواژه" - }, "uppercase": { "message": "حروف بزرگ (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "حداقل حرف خاص" }, - "avoidAmbChar": { - "message": "از کاراکترهای مبهم اجتناب کن", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "موارد هویتی را در صفحه برگه برای پر کردن خودکار آسان فهرست کن." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "پاکسازی کلیپ بورد", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "انتقال به سازمان" }, - "share": { - "message": "اشتراک گذاری" - }, "movedItemToOrg": { "message": "$ITEMNAME$ منتقل شد به $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "شبیه سازی" }, - "passwordGeneratorPolicyInEffect": { - "message": "یک یا چند سیاست سازمان بر تنظیمات تولید کننده شما تأثیر می‌گذارد." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "جستجوی ارسال‌ها", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "افزودن ارسال", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "متن" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "به حداکثر تعداد دسترسی رسیده است", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "منقضی شده" }, - "pendingDeletion": { - "message": "در انتظار حذف" - }, "passwordProtected": { "message": "محافظت ‌شده با کلمه عبور" }, @@ -2472,24 +2447,9 @@ "message": "ویرایش ارسال", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "این چه نوع ارسالی است؟", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "یک نام دوستانه برای توصیف این ارسال.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "پرونده ای که می‌خواهید ارسال کنید." - }, "deletionDate": { "message": "تاریخ حذف" }, - "deletionDateDesc": { - "message": "ارسال در تاریخ و ساعت مشخص شده برای همیشه حذف خواهد شد.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "تاريخ انقضاء" }, - "expirationDateDesc": { - "message": "در صورت تنظیم، دسترسی به این ارسال در تاریخ و ساعت مشخص شده منقضی می‌شود.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "۱ روز" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "سفارشی" }, - "maximumAccessCount": { - "message": "تعداد دسترسی حداکثر" - }, - "maximumAccessCountDesc": { - "message": "در صورت تنظیم، با رسیدن به حداکثر تعداد دسترسی، کاربران دیگر نمی‌توانند به این ارسال دسترسی پیدا کنند.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "به صورت اختیاری برای دسترسی کاربران به این ارسال به یک کلمه عبور نیاز دارید.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "یادداشت های خصوصی در مورد این ارسال.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "این ارسال را غیرفعال کنید تا کسی نتواند به آن دسترسی پیدا کند.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "پس از ذخیره، این پیوند ارسال را به کلیپ بورد کپی کن.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "متنی که می‌خواهید ارسال کنید." - }, - "sendHideText": { - "message": "متن این ارسال را به طور پیش فرض پنهان کن.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "تعداد دسترسی فعلی" - }, "createSend": { "message": "ارسال جدید", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "قبل از اینکه شروع کنی" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "برای استفاده از انتخابگر تاریخ به سبک تقویم", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "اینجا کلیک کنید", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "برای خروج از پنجره خود.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "تاریخ انقضاء ارائه شده معتبر نیست." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "هنگام ذخیره حذف و تاریخ انقضاء شما خطایی روی داد." }, - "hideEmail": { - "message": "نشانی ایمیلم را از گیرندگان مخفی کن." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "یک یا چند سیاست سازمان بر گزینه های ارسال شما تأثیر می‌گذارد." - }, "passwordPrompt": { "message": "درخواست مجدد کلمه عبور اصلی" }, @@ -2884,9 +2789,6 @@ "error": { "message": "خطا" }, - "regenerateUsername": { - "message": "ایجاد مجدد نام کاربری" - }, "generateUsername": { "message": "ایجاد نام کاربری" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "نوع نام کاربری" - }, "plusAddressedEmail": { "message": "به علاوه نشانی ایمیل داده شده", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "نام وب‌سایت" }, - "whatWouldYouLikeToGenerate": { - "message": "چه چیزی دوست دارید تولید کنید؟" - }, - "passwordType": { - "message": "نوع کلمه عبور" - }, "service": { "message": "سرویس" }, diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index f0104488d32..2c621dc4621 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -193,10 +193,10 @@ "message": "Automaattitäytä henkilöllisyys" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Täytä vahvistuskoodi" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "Täytä vahvistuskoodi", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -454,9 +454,6 @@ "length": { "message": "Pituus" }, - "passwordMinLength": { - "message": "Salasanan vähimmäispituus" - }, "uppercase": { "message": "Isot kirjaimet (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Erikoismerkkejä vähintään" }, - "avoidAmbChar": { - "message": "Vältä epäselviä merkkejä", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Vältä epäselviä merkkejä", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Näytä henkilöllisyydet Välilehti-sivulla automaattitäytön helpottamiseksi." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Tyhjennä leikepöytä", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Siirrä organisaatiolle" }, - "share": { - "message": "Jaa" - }, "movedItemToOrg": { "message": "$ITEMNAME$ siirrettiin organisaatioon $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Kloonaa" }, - "passwordGeneratorPolicyInEffect": { - "message": "Yksi tai useampi organisaatiokäytäntö vaikuttaa generaattorisi asetuksiin." - }, "passwordGenerator": { "message": "Salasanageneraattori" }, @@ -2389,14 +2379,6 @@ "message": "Sendin tiedot", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Etsi Sendeistä", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Lisää Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Teksti" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Piilota teksti oletuksena" }, - "maxAccessCountReached": { - "message": "Käyttökertojen enimmäismäärä saavutettu", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Erääntynyt" }, - "pendingDeletion": { - "message": "Odottaa poistoa" - }, "passwordProtected": { "message": "Salasanasuojattu" }, @@ -2472,24 +2447,9 @@ "message": "Muokkaa Sendiä", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Minkä tyyppinen Send tämä on?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Kuvaava nimi Sendille.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Tiedosto, jonka haluat lähettää." - }, "deletionDate": { "message": "Poistoajankohta" }, - "deletionDateDesc": { - "message": "Send poistuu pysyvästi määritettynä ajankohtana.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send poistuu pysyvästi tänä päivänä.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Erääntymisajankohta" }, - "expirationDateDesc": { - "message": "Jos määritetty, Send erääntyy määritettynä ajankohtana.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 päivä" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Mukautettu" }, - "maximumAccessCount": { - "message": "Käyttöoikeuksien enimmäismäärä" - }, - "maximumAccessCountDesc": { - "message": "Jos määritetty, käyttäjät eivät voi avata Sendiä käyttökertojen enimmäismäärän täytyttyä.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Halutessasi, vaadi käyttäjiä syöttämään salasana Sendin avaamiseksi.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Lisää valinnainen salasana vastaanottajille tähän Sendiin.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Yksityisiä merkintöjä tästä Sendistä.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Poista Send käytöstä, jottei kukaan voi avata sitä.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopioi Sendin linkki leikepöydälle tallennettaessa.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Teksti, jonka haluat lähettää." - }, - "sendHideText": { - "message": "Piilota Sendin teksti oletuksena.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Käyttökertojen nykyinen määrä" - }, "createSend": { "message": "Uusi Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Ennen kuin aloitat" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Käyttääksesi kalenterityylistä päivämäärän valintaa", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klikkaa tästä", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "erillistä valintaa varten.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Määritetty erääntymismisajankohta on virheellinen." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Tapahtui virhe tallennettaessa poisto- ja erääntymisajankohtia." }, - "hideEmail": { - "message": "Piilota sähköpostiosoitteeni vastaanottajilta." - }, "hideYourEmail": { "message": "Piilota sähköpostiosoitteeni avaajilta." }, - "sendOptionsPolicyInEffect": { - "message": "Yksi tai useampi organisaatiokäytäntö vaikuttaa Send-asetuksiisi." - }, "passwordPrompt": { "message": "Pääsalasanan uudelleenkysely" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Virhe" }, - "regenerateUsername": { - "message": "Luo uusi käyttäjätunnus" - }, "generateUsername": { "message": "Luo käyttäjätunnus" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Käyttäjätunnuksen tyyppi" - }, "plusAddressedEmail": { "message": "Plus+merkkinen sähköposti", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Verkkosivuston nimi" }, - "whatWouldYouLikeToGenerate": { - "message": "Mitä haluat luoda?" - }, - "passwordType": { - "message": "Salasanan tyyppi" - }, "service": { "message": "Palvelu" }, @@ -3585,7 +3478,7 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Aikaperusteinen kertakäyttöinen salasanan vahvistuskoodi", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { @@ -4677,7 +4570,7 @@ "message": "Näytä automaattitäytön ehdotusten määrä laajennuksen kuvakkeessa" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Näytä pikakopiointitoiminnot holvissa" }, "systemDefault": { "message": "Järjestelmän oletus" @@ -4911,10 +4804,10 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Tärkeä ilmoitus" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Määritä kaksivaiheinen kirjautuminen" }, "newDeviceVerificationNoticeContentPage1": { "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." @@ -4923,7 +4816,7 @@ "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." }, "remindMeLater": { - "message": "Remind me later" + "message": "Muistuta myöhemmin" }, "newDeviceVerificationNoticePageOneFormContent": { "message": "Do you have reliable access to your email, $EMAIL$?", @@ -4941,10 +4834,10 @@ "message": "Yes, I can reliably access my email" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Ota kaksivaiheinen kirjautuminen käyttöön" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Muuta tilin sähköpostiosoitetta" }, "extensionWidth": { "message": "Laajennuksen leveys" diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index ebaf884a141..a504cbd3174 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Kahabaan" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Inakamababang espesyal" }, - "avoidAmbChar": { - "message": "Iwasan ang mga hindi malinaw na character", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Itala ang mga item ng pagkatao sa Tab page para sa madaling auto-fill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Linisin ang clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Lumipat sa organisasyon" }, - "share": { - "message": "I-share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ lumipat sa $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Kopyahin ang item" }, - "passwordGeneratorPolicyInEffect": { - "message": "Isang o higit pang patakaran ng organisasyon ay nakakaapekto sa iyong mga setting ng generator." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Maghanap ng Mga Padala", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Idagdag ang Padala", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Teksto" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Ang pinaka-access count ay nakaabot na", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Paso na" }, - "pendingDeletion": { - "message": "Nakabinbing pagbura" - }, "passwordProtected": { "message": "Protektado ng Password" }, @@ -2472,24 +2447,9 @@ "message": "I-edit ang Ipadala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Anong uri ng Ipadala ang ito?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Isang friendly name upang ilarawan ang Ipadala na ito.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Ang file na gusto mong ipadala." - }, "deletionDate": { "message": "Petsa ng Pagtanggal" }, - "deletionDateDesc": { - "message": "Ang Ipadala ay tatanggalin nang permanente sa tinukoy na petsa at oras.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Petsa ng pag-expire" }, - "expirationDateDesc": { - "message": "Kung nakatakda, ang access sa Send na ito ay mag-expire sa tinukoy na petsa at oras.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 araw" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Pasadyang" }, - "maximumAccessCount": { - "message": "Pinakamataas na Bilang ng Access" - }, - "maximumAccessCountDesc": { - "message": "Kung nakatakda, ang mga user ay hindi na maaaring ma-access ang Send na ito pagkatapos makarating sa maximum access count.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Maipapayo na mag-require ng password para sa mga user na ma-access ang Send na ito.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Pribadong mga tala tungkol sa Send na ito.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "I-deactivate ang Send na ito para hindi na ito ma-access.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopyahin ang link ng Send na ito sa clipboard pagkatapos i-save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Ang teksto na nais mong ipadala." - }, - "sendHideText": { - "message": "Itago ang default na teksto ng Send na ito.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Kasalukuyang access count" - }, "createSend": { "message": "Bagong Ipadala", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Bago ka magsimula" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Upang gamitin ang isang calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "mag-click dito", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "upang bumalik sa iyong window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Ang ibinigay na petsa ng pagpaso ay hindi wasto." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Nagkaroon ng error sa pag-save ng iyong mga petsa ng pagbura at pagpaso." }, - "hideEmail": { - "message": "Itago ang aking email address mula sa mga tatanggap." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Isang o higit pang mga patakaran ng organisasyon ay nakaapekto sa iyong mga pagpipilian sa Pagpadala." - }, "passwordPrompt": { "message": "Muling pagsusuri sa master password" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Mali" }, - "regenerateUsername": { - "message": "Muling bumuo ng username" - }, "generateUsername": { "message": "Lumikha ng username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Uri ng username" - }, "plusAddressedEmail": { "message": "Plus na naka-address na email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Pangalan ng website" }, - "whatWouldYouLikeToGenerate": { - "message": "Ano ang nais mong bumuo?" - }, - "passwordType": { - "message": "Uri ng Password" - }, "service": { "message": "Serbisyo" }, diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 0ff35958be0..9566f457861 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Longueur" }, - "passwordMinLength": { - "message": "Longueur minimale du mot de passe" - }, "uppercase": { "message": "Majuscules (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum de caractères spéciaux" }, - "avoidAmbChar": { - "message": "Éviter les caractères ambigus", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Éviter les caractères ambigus", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Liste les éléments d'identité sur la Page d'onglet pour faciliter la saisie automatique." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Effacer le presse-papiers", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Déplacer vers l'organisation" }, - "share": { - "message": "Partager" - }, "movedItemToOrg": { "message": "$ITEMNAME$ a été déplacé vers $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Cloner" }, - "passwordGeneratorPolicyInEffect": { - "message": "Une ou plusieurs politiques de sécurité de l'organisation affectent les paramètres de votre générateur." - }, "passwordGenerator": { "message": "Générateur de mot de passe" }, @@ -2389,14 +2379,6 @@ "message": "Détails du Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Rechercher dans les Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Ajouter un Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Texte" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Masquer le texte par défaut" }, - "maxAccessCountReached": { - "message": "Nombre maximum d'accès atteint", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expiré" }, - "pendingDeletion": { - "message": "En attente de suppression" - }, "passwordProtected": { "message": "Protégé par un mot de passe" }, @@ -2472,24 +2447,9 @@ "message": "Modifier le Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "De quel type de Send s'agit-il ?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Un nom convivial pour décrire ce Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Le fichier que vous voulez envoyer." - }, "deletionDate": { "message": "Date de suppression" }, - "deletionDateDesc": { - "message": "Le Send sera définitivement supprimé à la date et heure spécifiées.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Le Send sera définitivement supprimé à la date spécifiée.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Date d'expiration" }, - "expirationDateDesc": { - "message": "Si défini, l'accès à ce Send expirera à la date et heure spécifiées.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 jour" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personnalisé" }, - "maximumAccessCount": { - "message": "Nombre maximum d'accès" - }, - "maximumAccessCountDesc": { - "message": "Si défini, les utilisateurs ne seront plus en mesure d'accéder à ce Send une fois que le nombre maximum d'accès sera atteint.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Vous pouvez, si vous le souhaitez, exiger un mot de passe pour accéder à ce Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Ajouter un mot de passe facultatif pour que les destinataires puissent accéder à ce Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Notes privées à propos de ce Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Désactiver ce Send pour que personne ne puisse y accéder.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copier le lien de ce Send dans le presse-papiers lors de l'enregistrement.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Le texte que vous voulez envoyer." - }, - "sendHideText": { - "message": "Masquer le texte de ce Send par défaut.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Nombre d'accès actuel" - }, "createSend": { "message": "Nouveau Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Avant de commencer" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Pour utiliser un sélecteur de date en forme de calendrier,", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "cliquez ici", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "pour ouvrir une nouvelle fenêtre.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "La date d'expiration indiquée n'est pas valide." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Une erreur s'est produite lors de l'enregistrement de vos dates de suppression et d'expiration." }, - "hideEmail": { - "message": "Masquer mon adresse électronique aux destinataires." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Une ou plusieurs politiques de sécurité de l'organisation affectent vos options Send." - }, "passwordPrompt": { "message": "Ressaisir le mot de passe principal" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Erreur" }, - "regenerateUsername": { - "message": "Régénérer un nom d'utilisateur" - }, "generateUsername": { "message": "Générer un nom d'utilisateur" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Type de nom d'utilisateur" - }, "plusAddressedEmail": { "message": "Courriel sous-adressé", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nom du site web" }, - "whatWouldYouLikeToGenerate": { - "message": "Que souhaitez-vous générer ?" - }, - "passwordType": { - "message": "Type de mot de passe" - }, "service": { "message": "Service" }, @@ -4911,22 +4804,22 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Avis important" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Configurer l'identification à deux facteurs" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden enverra un code au courriel de votre compte pour vérifier les connexions depuis de nouveaux appareils à partir de février 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Vous pouvez configurer l'identification à deux facteurs comme un moyen alternatif de protéger votre compte ou de changer votre adresse courriel à une autre à laquelle vous pouvez accéder." }, "remindMeLater": { - "message": "Remind me later" + "message": "Me le rappeler plus tard" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Avez-vous un accès fiable à votre courriel $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4935,16 +4828,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Non, je ne l'ai pas" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Oui, je peux accéder à mon courriel de manière fiable" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Activer l'identification à deux facteurs" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Changer le courriel du compte" }, "extensionWidth": { "message": "Largeur de l'extension" diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index beeae76232a..b3eaae64486 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -3,39 +3,39 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden - Xestor de contrasinais", + "message": "Xestor de Contrasinais Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "Na casa, no traballo ou en ruta, Bitwarden protexe os teus contrasinais, chaves de acceso e datos sensíbeis", + "message": "Na casa, no traballo ou en movemento, Bitwarden protexe os teus contrasinais, Claves de acceso e datos sensíbeis", "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { - "message": "Rexístrate ou crea unha nova conta para acceder á túa caixa forte." + "message": "Inicia sesión ou rexístrate para acceder á túa caixa forte." }, "inviteAccepted": { - "message": "Invitation accepted" + "message": "Invitación aceptada" }, "createAccount": { "message": "Crea unha conta" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Novo en Bitwarden?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Iniciar sesión con Clave de acceso" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Usar inicio de sesión único" }, "welcomeBack": { - "message": "Welcome back" + "message": "Benvido de novo" }, "setAStrongPassword": { - "message": "Set a strong password" + "message": "Crea un contrasinal forte" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Remata de crear a túa conta creando un contrasinal" }, "enterpriseSingleSignOn": { "message": "Inicio de sesión único empresarial" @@ -62,7 +62,7 @@ "message": "Unha pista do contrasinal mestre pode axudarte a lembrar o teu contrasinal se o esqueces." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Se esqueces o teu contrasinal, pódese enviar a pista do contrasinal ó teu correo. Máximo de $CURRENT$/$MAXIMUM$ caracteres.", "placeholders": { "current": { "content": "$1", @@ -81,10 +81,10 @@ "message": "Pista do contrasinal mestre (opcional)" }, "joinOrganization": { - "message": "Join organization" + "message": "Unirse a esta organización" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "Unirse a $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -93,10 +93,10 @@ } }, "finishJoiningThisOrganizationBySettingAMasterPassword": { - "message": "Finish joining this organization by setting a master password." + "message": "Remata de unirte á organización creando un contrasinal mestre." }, "tab": { - "message": "Separador" + "message": "Pestana" }, "vault": { "message": "Caixa forte" @@ -114,13 +114,13 @@ "message": "Axustes" }, "currentTab": { - "message": "Separador actual" + "message": "Pestana actual" }, "copyPassword": { "message": "Copiar contrasinal" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "Copiar frase de contrasinal" }, "copyNote": { "message": "Copiar nota" @@ -138,31 +138,31 @@ "message": "Copiar código de seguranza" }, "copyName": { - "message": "Copy name" + "message": "Copiar nome" }, "copyCompany": { - "message": "Copy company" + "message": "Copiar empresa" }, "copySSN": { - "message": "Copy Social Security number" + "message": "Copiar número de Seguridade Social" }, "copyPassportNumber": { - "message": "Copy passport number" + "message": "Copiar número de pasaporte" }, "copyLicenseNumber": { - "message": "Copy license number" + "message": "Copiar número de matrícula" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "Copiar clave privada" }, "copyPublicKey": { - "message": "Copy public key" + "message": "Copiar clave pública" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "Copiar pegada dixital" }, "copyCustomField": { - "message": "Copy $FIELD$", + "message": "Copiar $FIELD$", "placeholders": { "field": { "content": "$1", @@ -171,32 +171,32 @@ } }, "copyWebsite": { - "message": "Copy website" + "message": "Copiar sitio web" }, "copyNotes": { - "message": "Copy notes" + "message": "Copiar notas" }, "fill": { - "message": "Fill", + "message": "Encher", "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { - "message": "Auto-encher" + "message": "Autoencher" }, "autoFillLogin": { - "message": "Encher automaticamente inicio de sesión" + "message": "Autoencher credenciais" }, "autoFillCard": { - "message": "Encher automaticamente tarxeta" + "message": "Autoencher tarxeta" }, "autoFillIdentity": { - "message": "Encher automaticamente identidade" + "message": "Autoencher automaticamente identidade" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Encher código de verificación" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "Encher código de verificación", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -206,7 +206,7 @@ "message": "Copiar nome de campo personalizado" }, "noMatchingLogins": { - "message": "Sen inicios de sesión coincidentes" + "message": "Sen credenciais coincidentes" }, "noCards": { "message": "Sen tarxetas" @@ -215,7 +215,7 @@ "message": "Sen identidades" }, "addLoginMenu": { - "message": "Engadir inicio de sesión" + "message": "Engadir credenciais" }, "addCardMenu": { "message": "Engadir tarxeta" @@ -224,31 +224,31 @@ "message": "Engadir identidade" }, "unlockVaultMenu": { - "message": "Desbloquear a súa caixa forte" + "message": "Desbloquear a caixa forte" }, "loginToVaultMenu": { - "message": "Rexistrarse na súa caixa forte" + "message": "Iniciar sesión na caixa forte" }, "autoFillInfo": { - "message": "Non hai inicios de sesión dispoñíbeis para encher automaticamente para o separador actual do navegador." + "message": "Non hai credenciais dispoñibles para autoenchido na pestana actual." }, "addLogin": { - "message": "Engadir inicio de sesión" + "message": "Engadir unha credencial" }, "addItem": { - "message": "Engadir elemento" + "message": "Engadir entrada" }, "accountEmail": { - "message": "Account email" + "message": "Correo electrónico da conta" }, "requestHint": { - "message": "Request hint" + "message": "Solicitar pista" }, "requestPasswordHint": { - "message": "Request password hint" + "message": "Solicitar pista do contrasinal" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Introduce o teu correo electrónico e enviarémosche a túa pista do contrasinal mestre" }, "passwordHint": { "message": "Pista do contrasinal" @@ -284,29 +284,29 @@ "message": "Continuar á aplicación web?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "Descobre máis funcionalidades da túa conta de Bitwarden na aplicación web." }, "continueToHelpCenter": { - "message": "Continue to Help Center?" + "message": "Ir ó Centro de Axuda?" }, "continueToHelpCenterDesc": { - "message": "Learn more about how to use Bitwarden on the Help Center." + "message": "Aprende máis acerca de como usar Bitwarden no Centro de Axuda." }, "continueToBrowserExtensionStore": { - "message": "Continue to browser extension store?" + "message": "Ir á tenda de extensións do navegador?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now." + "message": "Axuda a outros a saber que Bitwarden é o que buscan! Visita a tenda de extensións do navegador e déixanos a túa opinión." }, "changeMasterPasswordOnWebConfirmation": { "message": "Podes cambiar o teu contrasinal mestre na aplicación web de Bitwarden." }, "fingerprintPhrase": { - "message": "Frase de pegada dactilar", + "message": "Frase de pegada dixital", "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." }, "yourAccountsFingerprint": { - "message": "Frase de pegada dactilar da túa conta", + "message": "Frase de pegada dixital da túa conta", "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." }, "twoStepLogin": { @@ -316,43 +316,43 @@ "message": "Pechar sesión" }, "aboutBitwarden": { - "message": "About Bitwarden" + "message": "Acerca de Bitwarden" }, "about": { "message": "Acerca de" }, "moreFromBitwarden": { - "message": "More from Bitwarden" + "message": "Máis de Bitwarden" }, "continueToBitwardenDotCom": { - "message": "Continue to bitwarden.com?" + "message": "Ir a bitwarden.com?" }, "bitwardenForBusiness": { - "message": "Bitwarden for Business" + "message": "Bitwarden para Empresas" }, "bitwardenAuthenticator": { - "message": "Bitwarden Authenticator" + "message": "Autenticador 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": "O Autenticador Bitwarden permite almacenar claves de autenticación e xerar códigos de un uso para fluxos de verificación en 2 pasos. Aprende máis en bitwarden.com" }, "bitwardenSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Xestor de Segredos de Bitwarden" }, "continueToSecretsManagerPageDesc": { - "message": "Securely store, manage, and share developer secrets with Bitwarden Secrets Manager. Learn more on the bitwarden.com website." + "message": "Almacenar, xestionar e compartir de maneira segura segredos de desarrollo co Xestor de Segredos de Bitwarden. Aprende máis en bitwarden.com." }, "passwordlessDotDev": { "message": "Passwordless.dev" }, "continueToPasswordlessDotDevPageDesc": { - "message": "Create smooth and secure login experiences free from traditional passwords with Passwordless.dev. Learn more on the bitwarden.com website." + "message": "Crea experiencias de inicio de sesión cómodas e seguras libres de contrasinais tradicionais con Passwordless.dev. Descobre como en bitwarden.com." }, "freeBitwardenFamilies": { - "message": "Free Bitwarden Families" + "message": "Plan Familiar Gratuíto Bitwarden" }, "freeBitwardenFamiliesPageDesc": { - "message": "You are eligible for Free Bitwarden Families. Redeem this offer today in the web app." + "message": "Es candidato para Bitwarden Familiar Gratuíto. Troca esta oferta hoxe mesmo na aplicación web." }, "version": { "message": "Versión" @@ -373,22 +373,22 @@ "message": "Editar cartafol" }, "newFolder": { - "message": "New folder" + "message": "Novo cartafol" }, "folderName": { - "message": "Folder name" + "message": "Nome do cartafol" }, "folderHintText": { - "message": "Nest a folder by adding the parent folder's name followed by a “/”. Example: Social/Forums" + "message": "Aniñar un cartafol engadindo o nome do cartafol pai seguido dun \"/\". Exemplo: Social/Foros" }, "noFoldersAdded": { - "message": "No folders added" + "message": "Sen cartafois" }, "createFoldersToOrganize": { - "message": "Create folders to organize your vault items" + "message": "Crea cartafoles para organizar as entradas da túa caixa forte" }, "deleteFolderPermanently": { - "message": "Are you sure you want to permanently delete this folder?" + "message": "Estás seguro de querer eliminar permanentemente este cartafol?" }, "deleteFolder": { "message": "Eliminar cartafol" @@ -428,13 +428,13 @@ "description": "Short for 'credential generator'." }, "passGenInfo": { - "message": "Xera automaticamente contrasinais fortes e únicos para os seus inicios de sesión." + "message": "Xera automaticamente contrasinais fortes e únicos para os teus inicios de sesión." }, "bitWebVaultApp": { - "message": "Bitwarden web app" + "message": "Aplicación web de Bitwarden" }, "importItems": { - "message": "Importar elementos" + "message": "Importar entradas" }, "select": { "message": "Seleccionar" @@ -443,7 +443,7 @@ "message": "Xerar contrasinal" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Xerar frase de contrasinal" }, "regeneratePassword": { "message": "Volver xerar contrasinal" @@ -454,9 +454,6 @@ "length": { "message": "Lonxitude" }, - "passwordMinLength": { - "message": "Lonxitude mínima do contrasinal" - }, "uppercase": { "message": "Maiúsculas (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -474,11 +471,11 @@ "description": "deprecated. Use specialCharactersLabel instead." }, "include": { - "message": "Include", + "message": "Incluír", "description": "Card header for password generator include block" }, "uppercaseDescription": { - "message": "Include uppercase characters", + "message": "Incluír caracteres en maiúsculas", "description": "Tooltip for the password generator uppercase character checkbox" }, "uppercaseLabel": { @@ -486,7 +483,7 @@ "description": "Label for the password generator uppercase character checkbox" }, "lowercaseDescription": { - "message": "Include lowercase characters", + "message": "Incluír caracteres en minúsculas", "description": "Full description for the password generator lowercase character checkbox" }, "lowercaseLabel": { @@ -494,7 +491,7 @@ "description": "Label for the password generator lowercase character checkbox" }, "numbersDescription": { - "message": "Include numbers", + "message": "Incluír números", "description": "Full description for the password generator numbers checkbox" }, "numbersLabel": { @@ -502,7 +499,7 @@ "description": "Label for the password generator numbers checkbox" }, "specialCharactersDescription": { - "message": "Include special characters", + "message": "Incluír caracteres especiais", "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { @@ -516,28 +513,24 @@ "message": "Separador de palabras" }, "capitalize": { - "message": "Facer a primeira letra da palabra maiúscula", + "message": "Primeira letra maiúscula", "description": "Make the first letter of a work uppercase." }, "includeNumber": { "message": "Incluír número" }, "minNumbers": { - "message": "Mínimo de números" + "message": "Mínimo de cifras" }, "minSpecial": { "message": "Mínimo de caracteres especiais" }, - "avoidAmbChar": { - "message": "Evitar caracteres ambiguos", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { - "message": "Avoid ambiguous characters", + "message": "Evitar caracteres ambiguos", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "Os requisitos da política empresarial foron aplicados ás opcións do teu xerador.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -550,10 +543,10 @@ "message": "Ver" }, "noItemsInList": { - "message": "Non hai elementos que listar." + "message": "Non hai entradas que listar." }, "itemInformation": { - "message": "Información do elemento" + "message": "Información da entrada" }, "username": { "message": "Nome de usuario" @@ -562,7 +555,7 @@ "message": "Contrasinal" }, "totp": { - "message": "Secreto de autenticador" + "message": "Segredo de autenticador" }, "passphrase": { "message": "Frase de contrasinal" @@ -571,19 +564,19 @@ "message": "Favorito" }, "unfavorite": { - "message": "Unfavorite" + "message": "Suprimir dos favoritos" }, "itemAddedToFavorites": { - "message": "Item added to favorites" + "message": "Engadido a favoritos" }, "itemRemovedFromFavorites": { - "message": "Item removed from favorites" + "message": "Eliminado dos favoritos" }, "notes": { "message": "Notas" }, "privateNote": { - "message": "Private note" + "message": "Nota privada" }, "note": { "message": "Nota" @@ -604,10 +597,10 @@ "message": "Iniciar" }, "launchWebsite": { - "message": "Launch website" + "message": "Abrir web" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Abrir web $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -631,16 +624,16 @@ "message": "Opcións de desbloqueo" }, "unlockMethodNeededToChangeTimeoutActionDesc": { - "message": "Configura un método de desbloqueo para cambiar a túa acción de peche de sesión da caixa forte." + "message": "Configura un método de desbloqueo para cambiar a acción do temporizador da caixa forte." }, "unlockMethodNeeded": { "message": "Configura un método de desbloqueo nos axustes" }, "sessionTimeoutHeader": { - "message": "Tempo de sesión esgotado" + "message": "Temporizador da sesión esgotado" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "Temporizador da caixa forte" }, "otherOptions": { "message": "Outras opcións" @@ -649,7 +642,7 @@ "message": "Valorar a extensión" }, "browserNotSupportClipboard": { - "message": "O teu navegador web non soporta copia doada ao portapapeis. Cópiao manualmente no seu lugar." + "message": "O navegador non permite copia doada ó portapapeis. Debes copialo manualmente." }, "verifyIdentity": { "message": "Verificar identidade" @@ -658,19 +651,19 @@ "message": "A túa caixa forte está bloqueada. Verifica a túa identidade para continuar." }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "A caixa forte está pechada" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "A conta está pechada" }, "or": { - "message": "or" + "message": "ou" }, "unlock": { "message": "Desbloquear" }, "loggedInAsOn": { - "message": "Conectado coma $EMAIL$ en $HOSTNAME$.", + "message": "Conectado como $EMAIL$ en $HOSTNAME$.", "placeholders": { "email": { "content": "$1", @@ -689,13 +682,13 @@ "message": "Tempo de espera da caixa forte" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Tempo esgotado" }, "lockNow": { - "message": "Bloquear agora" + "message": "Pechar agora" }, "lockAll": { - "message": "Bloquear todo" + "message": "Pechar todo" }, "immediately": { "message": "Inmediatamente" @@ -731,10 +724,10 @@ "message": "4 horas" }, "onLocked": { - "message": "Ao bloquear o sistema" + "message": "Ó bloquear o sistema" }, "onRestart": { - "message": "Ao reiniciar o navegador" + "message": "Ó reiniciar o navegador" }, "never": { "message": "Nunca" @@ -743,16 +736,16 @@ "message": "Seguridade" }, "confirmMasterPassword": { - "message": "Confirm master password" + "message": "Repetir o contrasinal mestre" }, "masterPassword": { - "message": "Master password" + "message": "Contrasinal mestre" }, "masterPassImportant": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "O contrasinal mestre non pode ser recuperado se o esqueces!" }, "masterPassHintLabel": { - "message": "Master password hint" + "message": "Obter pista do contrasinal mestre" }, "errorOccurred": { "message": "Produciuse un erro" @@ -770,7 +763,7 @@ "message": "É preciso volver escribir o contrasinal mestre." }, "masterPasswordMinlength": { - "message": "O contrasinal mestre debe ter polo menos $VALUE$ caracteres de lonxitude.", + "message": "O contrasinal mestre debe ter polo menos $VALUE$ caracteres.", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -780,19 +773,19 @@ } }, "masterPassDoesntMatch": { - "message": "A confirmación de contrasinal mestre non coincide." + "message": "O contrasinal mestre repetido non coincide." }, "newAccountCreated": { "message": "A túa nova conta foi creada! Podes iniciar sesión agora." }, "newAccountCreated2": { - "message": "Your new account has been created!" + "message": "A túa nova conta foi creada!" }, "youHaveBeenLoggedIn": { - "message": "You have been logged in!" + "message": "A túa sesión foi iniciada!" }, "youSuccessfullyLoggedIn": { - "message": "Iniciaches sesión correctamente" + "message": "Sesión iniciada con éxito" }, "youMayCloseThisWindow": { "message": "Podes pechar está ventá" @@ -801,10 +794,10 @@ "message": "Enviámoste un correo electrónico coa túa pista de contrasinal mestre." }, "verificationCodeRequired": { - "message": "É preciso código de verificación." + "message": "É preciso un código de verificación." }, "webauthnCancelOrTimeout": { - "message": "The authentication was cancelled or took too long. Please try again." + "message": "O proceso de autenticación foi cancelado ou levou moito tempo. Por favor, volve intentalo." }, "invalidVerificationCode": { "message": "Código de verificación non válido" @@ -820,28 +813,28 @@ } }, "autofillError": { - "message": "Incapaz de encher automaticamente o elemento seleccionado nesta páxina. Copia e pega a información no seu lugar." + "message": "Non se puido autoencher o formulario nesta páxina. Copia e pega a información manualmente." }, "totpCaptureError": { - "message": "Incapaz escanear o código QR da páxina web actual" + "message": "Non se puido escanear o código QR da páxina web" }, "totpCaptureSuccess": { "message": "Clave de autenticación engadida" }, "totpCapture": { - "message": "Escanea o código QR autenticador da páxina web actual" + "message": "Escanea o código QR do autenticador da páxina web" }, "totpHelperTitle": { - "message": "Make 2-step verification seamless" + "message": "Fai a verificación en 2 pasos imperceptible" }, "totpHelper": { - "message": "Bitwarden can store and fill 2-step verification codes. Copy and paste the key into this field." + "message": "Bitwarden pode gardar e encher códigos de verificación en 2 pasos. Copia e pega a clave neste campo." }, "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 pode gardar e encher códigos de verificación en 2 pasos. Preme a icona da cámara para extraer o código QR do autenticador desta web, ou copia e pega a clave neste campo." }, "learnMoreAboutAuthenticators": { - "message": "Learn more about authenticators" + "message": "Aprende máis sobre autenticadores." }, "copyTOTP": { "message": "Copiar clave de autenticación (TOTP)" @@ -850,31 +843,31 @@ "message": "Sesión pechada" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "A túa sesión foi pechada." }, "loginExpired": { "message": "A túa sesión caducou." }, "logIn": { - "message": "Log in" + "message": "Iniciar sesión" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Iniciar sesión en Bitwarden" }, "restartRegistration": { - "message": "Restart registration" + "message": "Reiniciar rexistro" }, "expiredLink": { - "message": "Expired link" + "message": "Ligazón caducada" }, "pleaseRestartRegistrationOrTryLoggingIn": { - "message": "Please restart registration or try logging in." + "message": "Por favor, reinicia o rexistro ou tenta iniciar sesión." }, "youMayAlreadyHaveAnAccount": { - "message": "You may already have an account" + "message": "Pode que xa teñas unha conta" }, "logOutConfirmation": { - "message": "Are you sure you want to log out?" + "message": "Estás seguro de que queres pechar a sesión?" }, "yes": { "message": "Si" @@ -886,19 +879,19 @@ "message": "Produciuse un erro inesperado." }, "nameRequired": { - "message": "Requírese o nome." + "message": "Nome requirido." }, "addedFolder": { "message": "Cartafol engadido" }, "twoStepLoginConfirmation": { - "message": "Two-step login makes your account more secure by requiring you to verify your login with another device such as a security key, authenticator app, SMS, phone call, or email. Two-step login can be set up on the bitwarden.com web vault. Do you want to visit the website now?" + "message": "A verificación en 2 pasos (2FA) fai a túa conta máis segura requirindo confirmar o inicio de sesión con métodos como unha clave de seguridade, aplicación de autenticación, SMS, chamada telefónica ou correo electrónico. A 2FA pode configurarse na aplicación web. Queres ir agora?" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "Fai a túa conta máis segura activando a verificación en 2 pasos na aplicación web." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "Ir á aplicación web?" }, "editedFolder": { "message": "Cartafol gardado" @@ -910,10 +903,10 @@ "message": "Cartafol eliminado" }, "gettingStartedTutorial": { - "message": "Tutorial introdutivo" + "message": "Titorial de Primeiros pasos" }, "gettingStartedTutorialVideo": { - "message": "Watch our getting started tutorial to learn how to get the most out of the browser extension." + "message": "Mira o noso titorial de Primeiros pasos para aprender a sacar partido á extensión de navegador." }, "syncingComplete": { "message": "Sincronización completa" @@ -941,32 +934,32 @@ "message": "Nova URI" }, "addDomain": { - "message": "Add domain", + "message": "Engadir dominio", "description": "'Domain' here refers to an internet domain name (e.g. 'bitwarden.com') and the message in whole described the act of putting a domain value into the context." }, "addedItem": { - "message": "Elemento engadido" + "message": "Entrada engadida" }, "editedItem": { - "message": "Elemento gardado" + "message": "Entrada gardada" }, "deleteItemConfirmation": { - "message": "Realmente queres enviar ao lixo?" + "message": "Seguro que queres envialo ó lixo?" }, "deletedItem": { - "message": "Elemento enviado ao lixo" + "message": "Entrada enviada ó lixo" }, "overwritePassword": { "message": "Sobrescribir contrasinal" }, "overwritePasswordConfirmation": { - "message": "Estás seguro de que queres sobrescribir o contrasinal actual?" + "message": "Seguro que queres sobrescribir o contrasinal actual?" }, "overwriteUsername": { "message": "Sobrescribir nome de usuario" }, "overwriteUsernameConfirmation": { - "message": "Estás seguro de que queres sobrescribir o nome de usuario actual?" + "message": "Seguro que queres sobrescribir o nome de usuario actual?" }, "searchFolder": { "message": "Buscar cartafol" @@ -982,103 +975,106 @@ "description": "This is the folder for uncategorized items" }, "enableAddLoginNotification": { - "message": "Solicita engadir inicio de sesión" + "message": "Ofrecer gardar credenciais" }, "vaultSaveOptionsTitle": { - "message": "Save to vault options" + "message": "Gardar nas opcións da caixa forte" }, "addLoginNotificationDesc": { - "message": "Ask to add an item if one isn't found in your vault." + "message": "Ofrecer gardar un elemento se non se atopa na caixa forte." }, "addLoginNotificationDescAlt": { - "message": "Ask to add an item if one isn't found in your vault. Applies to all logged in accounts." + "message": "Ofrecer gardar un elemento se non se atopa na caixa forte. Aplica a tódalas sesións iniciadas." }, "showCardsInVaultView": { - "message": "Show cards as Autofill suggestions on Vault view" + "message": "Na caixa forte, amosar tarxetas como suxestións de Autoenchido" }, "showCardsCurrentTab": { - "message": "Amosar tarxetas no separador" + "message": "Amosar tarxetas na pestana" }, "showCardsCurrentTabDesc": { - "message": "Lista os elementos de tarxeta no separador para fácil auto-completado." + "message": "Lista na pestana actual as tarxetas gardadas para autoenchido." }, "showIdentitiesInVaultView": { - "message": "Show identities as Autofill suggestions on Vault view" + "message": "Na caixa forte, amosar identidades como suxestións de Autoenchido" }, "showIdentitiesCurrentTab": { - "message": "Mostrar identidades no separador" + "message": "Amosar identidades na pestana" }, "showIdentitiesCurrentTabDesc": { - "message": "Lista os elementos de identidade no separador para fácil auto-completado." + "message": "Lista na pestana actual as identidades gardadas para autoenchido." + }, + "clickToAutofillOnVault": { + "message": "Clicar nas entradas da caixa forte para autoencher" }, "clearClipboard": { - "message": "Limpar portapapeis", + "message": "Baleirar portapapeis", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "clearClipboardDesc": { - "message": "Automatically clear copied values from your clipboard.", + "message": "Limpar automaticamente os valores copiados do teu portapapeis.", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." }, "notificationAddDesc": { - "message": "Should Bitwarden remember this password for you?" + "message": "Debería Bitwarden lembrar este contrasinal?" }, "notificationAddSave": { "message": "Gardar" }, "enableChangedPasswordNotification": { - "message": "Ask to update existing login" + "message": "Ofrecer actualizar as credenciais xa gardadas" }, "changedPasswordNotificationDesc": { - "message": "Ask to update a login's password when a change is detected on a website." + "message": "Ofrecer actualizar o contrasinal dunha credencial ó detectar un cambio." }, "changedPasswordNotificationDescAlt": { - "message": "Ask to update a login's password when a change is detected on a website. Applies to all logged in accounts." + "message": "Ofrecer actualizar o contrasinal dunha credencial ó detectar un cambio. Aplica a tódalas sesións iniciadas." }, "enableUsePasskeys": { - "message": "Ask to save and use passkeys" + "message": "Ofrecer gardar e empregar Claves de acceso" }, "usePasskeysDesc": { - "message": "Ask to save new passkeys or log in with passkeys stored in your vault. Applies to all logged in accounts." + "message": "Ofrecer gardar e empregar Claves de acceso na caixa forte. Aplica a tódalas sesións iniciadas." }, "notificationChangeDesc": { - "message": "Do you want to update this password in Bitwarden?" + "message": "Queres actualizar este contrasinal en Bitwarden?" }, "notificationChangeSave": { "message": "Actualizar" }, "notificationUnlockDesc": { - "message": "Unlock your Bitwarden vault to complete the autofill request." + "message": "Abre a caixa forte de Bitwarden para poder continuar co autoenchido." }, "notificationUnlock": { - "message": "Desbloquear" + "message": "Abrir" }, "additionalOptions": { - "message": "Additional options" + "message": "Opcións adicionais" }, "enableContextMenuItem": { - "message": "Show context menu options" + "message": "Amosar opcións no menú contextual" }, "contextMenuItemDesc": { - "message": "Use a secondary click to access password generation and matching logins for the website." + "message": "Usar o clic dereito para acceder á xeración de contrasinais e autoenchido para a web." }, "contextMenuItemDescAlt": { - "message": "Use a secondary click to access password generation and matching logins for the website. Applies to all logged in accounts." + "message": "Usar o clic dereito para acceder á xeración de contrasinais e autoenchido para a web. Aplica a tódalas sesións iniciadas." }, "defaultUriMatchDetection": { - "message": "Default URI match detection", + "message": "Detección de coincidencias de URI por defecto", "description": "Default URI match detection for autofill." }, "defaultUriMatchDetectionDesc": { - "message": "Choose the default way that URI match detection is handled for logins when performing actions such as autofill." + "message": "Selecciona o tipo de Detección de coincidencias de URI que se empregará por defecto para accións como o autoenchido." }, "theme": { "message": "Tema" }, "themeDesc": { - "message": "Change the application's color theme." + "message": "Cambiar o tema de cor da aplicación." }, "themeDescAlt": { - "message": "Change the application's color theme. Applies to all logged in accounts." + "message": "Cambiar o tema de cor da aplicación. Aplica a tódalas sesións iniciadas." }, "dark": { "message": "Escuro", @@ -1093,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": "Exportar dende" }, "exportVault": { "message": "Exportar caixa forte" @@ -1102,28 +1098,28 @@ "message": "Formato de ficheiro" }, "fileEncryptedExportWarningDesc": { - "message": "This file export will be password protected and require the file password to decrypt." + "message": "O arquivo exportado estará protexido e requirirá o contrasinal do arquivo para descifralo." }, "filePassword": { - "message": "File password" + "message": "Contrasinal do arquivo" }, "exportPasswordDescription": { - "message": "This password will be used to export and import this file" + "message": "Este contrasinal empregarase para exportar e importar o arquivo" }, "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": "Empregar a clave de cifrado da túa conta, derivada do teu nome de usuario e contrasinal, para cifrar o arquivo exportado e limitar o importado á conta de usuario actual." }, "passwordProtectedOptionDescription": { - "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption." + "message": "Crea un contrasinal para cifrar o arquivo exportado e importalo en calquera conta de Bitwarden empregando este contrasinal." }, "exportTypeHeading": { - "message": "Export type" + "message": "Tipo de exportado" }, "accountRestricted": { - "message": "Account restricted" + "message": "Conta restrinxida" }, "filePasswordAndConfirmFilePasswordDoNotMatch": { - "message": "“File password” and “Confirm file password“ do not match." + "message": "\"Contrasinal do arquivo\" e \"Repetir contrasinal do arquivo\" non coinciden." }, "warning": { "message": "ADVERTENCIA", @@ -1134,34 +1130,31 @@ "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { - "message": "Confirm vault export" + "message": "Confirmar o exportado da caixa forte" }, "exportWarningDesc": { - "message": "This export contains your vault data in an unencrypted format. You should not store or send the exported file over unsecure channels (such as email). Delete it immediately after you are done using it." + "message": "Esta exportación contén os teus datos nun formato sen cifrar. Non deberías gardar ou enviar o arquivo por canais inseguros (como correo electrónico). Elimínao inmediatamente despois de finalizar o seu uso." }, "encExportKeyWarningDesc": { - "message": "This export encrypts your data using your account's encryption key. If you ever rotate your account's encryption key you should export again since you will not be able to decrypt this export file." + "message": "Este tipo de exportado cifra os teus datos empregando a clave de cifrado da túa conta. Se cambias o teu contrasinal ou nome de usuario deberás volver xerar o arquivo." }, "encExportAccountWarningDesc": { - "message": "Account encryption keys are unique to each Bitwarden user account, so you can't import an encrypted export into a different account." + "message": "As claves de cifrado son únicas para cada usuario, polo que non poderás importar un arquivo exportado desta maneira nunha conta distinta." }, "exportMasterPassword": { - "message": "Enter your master password to export your vault data." + "message": "Introduce o teu contrasinal mestre para exportar a caixa forte." }, "shared": { "message": "Compartido" }, "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 para Empresas permite compartir entradas da caixa forte empregando unha organización. Aprende máis en bitwarden.com." }, "moveToOrganization": { - "message": "Move to organization" - }, - "share": { - "message": "Compartir" + "message": "Mover á organización" }, "movedItemToOrg": { - "message": "$ITEMNAME$ moved to $ORGNAME$", + "message": "$ITEMNAME$ moveuse a $ORGNAME$", "placeholders": { "itemname": { "content": "$1", @@ -1174,7 +1167,7 @@ } }, "moveToOrgDesc": { - "message": "Choose an organization that you wish to move this item to. Moving to an organization transfers ownership of the item to that organization. You will no longer be the direct owner of this item once it has been moved." + "message": "Escolle a organización á que queres transferir esta entrada. Ó transferila, tamén transfires a súa propiedade á organización. Unha vez transferida, xa non serás o propietario directo desde elemento." }, "learnMore": { "message": "Máis información" @@ -1210,82 +1203,82 @@ "message": "Anexo gardado" }, "file": { - "message": "Ficheiro" + "message": "Arquivo" }, "fileToShare": { - "message": "File to share" + "message": "Arquivo a compartir" }, "selectFile": { - "message": "Selecciona un ficheiro" + "message": "Selecciona un arquivo" }, "maxFileSize": { - "message": "O tamaño máximo de ficheiro é de 500 MB." + "message": "O tamaño máximo é de 500 MB." }, "featureUnavailable": { - "message": "Característica non dispoñible" + "message": "Función non dispoñible" }, "encryptionKeyMigrationRequired": { - "message": "Encryption key migration required. Please login through the web vault to update your encryption key." + "message": "Requírese mudar a clave de cifrado. Por favor, inicia sesión na aplicación web para actualizala." }, "premiumMembership": { - "message": "Membresía de luxo" + "message": "Plan Prémium" }, "premiumManage": { - "message": "Xestionar membresía" + "message": "Xestionar plan" }, "premiumManageAlert": { - "message": "You can manage your membership on the bitwarden.com web vault. Do you want to visit the website now?" + "message": "Podes xestionar o teu plan na caixa forte web de bitwarden.com. Queres visitala agora?" }, "premiumRefresh": { - "message": "Refresh membership" + "message": "Actualizar o teu plan" }, "premiumNotCurrentMember": { - "message": "You are not currently a Premium member." + "message": "Actualmente non es usuario Prémium." }, "premiumSignUpAndGet": { - "message": "Sign up for a Premium membership and get:" + "message": "Actualiza a unha conta Premium e recibe:" }, "ppremiumSignUpStorage": { - "message": "1 GB encrypted storage for file attachments." + "message": "1 GB de almacenamento cifrado para arquivos anexos." }, "premiumSignUpEmergency": { - "message": "Emergency access." + "message": "Acceso de emerxencia." }, "premiumSignUpTwoStepOptions": { - "message": "Proprietary two-step login options such as YubiKey and Duo." + "message": "Opcións de verificación en 2 pasos privadas tales coma YubiKey ou Duo." }, "ppremiumSignUpReports": { - "message": "Password hygiene, account health, and data breach reports to keep your vault safe." + "message": "Limpeza de contrasinais, saúde de contas e informes de filtración de datos para manter a túa caixa forte segura." }, "ppremiumSignUpTotp": { - "message": "TOTP verification code (2FA) generator for logins in your vault." + "message": "Xerador de códigos TOTP (2FA) para as credenciais da túa caixa forte." }, "ppremiumSignUpSupport": { - "message": "Priority customer support." + "message": "Atención ó cliente prioritaria." }, "ppremiumSignUpFuture": { - "message": "All future Premium features. More coming soon!" + "message": "Tódalas funcións Prémium futuras!" }, "premiumPurchase": { - "message": "Purchase Premium" + "message": "Adquirir Prémium" }, "premiumPurchaseAlert": { - "message": "You can purchase Premium membership on the bitwarden.com web vault. Do you want to visit the website now?" + "message": "Podes adquirir o plan Prémium na aplicación web de bitwarden.com. Queres visitala agora mesmo?" }, "premiumPurchaseAlertV2": { - "message": "You can purchase Premium from your account settings on the Bitwarden web app." + "message": "Podes adquirir o plan Prémium dende os axustes de conta da aplicación web de Bitwarden." }, "premiumCurrentMember": { - "message": "You are a Premium member!" + "message": "Xa es un usuario Prémium!" }, "premiumCurrentMemberThanks": { - "message": "Thank you for supporting Bitwarden." + "message": "Grazas por apoiar Bitwarden." }, "premiumFeatures": { - "message": "Upgrade to Premium and receive:" + "message": "Mellora a Prémium e recibe:" }, "premiumPrice": { - "message": "All for just $PRICE$ /year!", + "message": "Todo por só $PRICE$/ano!", "placeholders": { "price": { "content": "$1", @@ -1294,7 +1287,7 @@ } }, "premiumPriceV2": { - "message": "All for just $PRICE$ per year!", + "message": "Todo por só $PRICE$ ó ano!", "placeholders": { "price": { "content": "$1", @@ -1303,34 +1296,34 @@ } }, "refreshComplete": { - "message": "Refresh complete" + "message": "Actualización completada" }, "enableAutoTotpCopy": { - "message": "Copy TOTP automatically" + "message": "Copiar TOTP automaticamente" }, "disableAutoTotpCopyDesc": { - "message": "If a login has an authenticator key, copy the TOTP verification code to your clip-board when you autofill the login." + "message": "Se unha credencial ten clave de autenticación, copia o código TOTP no portapapeis ó autoencher os datos." }, "enableAutoBiometricsPrompt": { - "message": "Ask for biometrics on launch" + "message": "Requirir biometría no inicio" }, "premiumRequired": { - "message": "Premium required" + "message": "Plan Prémium requirido" }, "premiumRequiredDesc": { - "message": "A Premium membership is required to use this feature." + "message": "Requírese un plan Prémium para poder empregar esta función." }, "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." + "message": "Insire o código de 6 díxitos da túa aplicación de autenticación." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Tempo límite de autenticación superado" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "Superouse o tempo límite da sesión de autenticación. Recomeza o proceso." }, "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", + "message": "Insire o código de verificación de 6 díxitos enviado a $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -1339,7 +1332,7 @@ } }, "verificationCodeEmailSent": { - "message": "Verification email sent to $EMAIL$.", + "message": "Enviouse un correo de verificación a $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -1351,40 +1344,40 @@ "message": "Lémbrame" }, "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" + "message": "Enviar un novo correo de verificación" }, "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" + "message": "Empregar outro método de verificación en 2 pasos" }, "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." + "message": "Conecta a túa YubiKey no porto USB, despois preme o seu botón." }, "insertU2f": { - "message": "Insert your security key into your computer's USB port. If it has a button, touch it." + "message": "Conecta a túa YubiKey no porto USB. Se ten un botón, prémeo." }, "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." + "message": "Para iniciar o proceso de verificación WebAuthn 2FA, clica no botón embaixo e segue as instrucións na pestana que se abrirá." }, "webAuthnNewTabOpen": { - "message": "Abrir novo separador" + "message": "Abrir nova pestana" }, "webAuthnAuthenticate": { "message": "Autenticar con WebAuthn" }, "loginUnavailable": { - "message": "Inicio de sesión non dispoñíbel" + "message": "Inicio de sesión non dispoñible" }, "noTwoStepProviders": { - "message": "This account has two-step login set up, however, none of the configured two-step providers are supported by this web browser." + "message": "Esta conta ten activada a verificación en 2 pasos, pero ningún dos métodos dispoñibles é compatible con este navegador." }, "noTwoStepProviders2": { - "message": "Please use a supported web browser (such as Chrome) and/or add additional providers that are better supported across web browsers (such as an authenticator app)." + "message": "Por favor, emprega un navegador compatible (como Chrome) ou un método de maior compatibilidade con distintos navegadores (como unha aplicación de autenticación)." }, "twoStepOptions": { - "message": "Opcións de inicio de sesión en dous pasos" + "message": "Opcións de verificación en dous pasos" }, "recoveryCodeDesc": { - "message": "Lost access to all of your two-factor providers? Use your recovery code to turn off all two-factor providers from your account." + "message": "Perdiche o acceso ós provedores de verificación en dous pasos (2FA)? Emprega o teu código de recuperación para desactivalos." }, "recoveryCodeTitle": { "message": "Código de recuperación" @@ -1393,61 +1386,61 @@ "message": "Aplicación de autenticación" }, "authenticatorAppDescV2": { - "message": "Enter a code generated by an authenticator app like Bitwarden Authenticator.", + "message": "Insire un código xerado por unha aplicación de autenticación coma Bitwarden Authenticator.", "description": "'Bitwarden Authenticator' is a product name and should not be translated." }, "yubiKeyTitleV2": { - "message": "Yubico OTP Security Key" + "message": "Clave de seguridade OTP de Yubico" }, "yubiKeyDesc": { - "message": "Use a YubiKey to access your account. Works with YubiKey 4, 4 Nano, 4C, and NEO devices." + "message": "Emprega YubiKey para acceder á túa conta. Funciona con dispositivos YubiKey 4, 4 Nano, 4C e Neo." }, "duoDescV2": { - "message": "Enter a code generated by Duo Security.", + "message": "Emprega un código xerado por Duo Security.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { - "message": "Verify with Duo Security for your organization using the Duo Mobile app, SMS, phone call, or U2F security key.", + "message": "Protexe a túa organización con Duo Security ca app móbil Duo Mobile, SMS, chamada telefónica ou chave de seguridade U2F.", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "webAuthnTitle": { "message": "FIDO2 WebAuthn" }, "webAuthnDesc": { - "message": "Use any WebAuthn compatible security key to access your account." + "message": "Emprega unha clave de seguridade compatible con WebAuthn para acceder á túa conta." }, "emailTitle": { "message": "Correo electrónico" }, "emailDescV2": { - "message": "Enter a code sent to your email." + "message": "Insire o código enviado ó teu correo electrónico." }, "selfHostedEnvironment": { - "message": "Entorno de auto-aloxamento" + "message": "Entorno de aloxamento propio" }, "selfHostedEnvironmentFooter": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation." + "message": "Especifica a URL base do teu servidor Bitwarden de aloxamento propio." }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Especifica a URL base do teu servidor Bitwarden de aloxamento propio. Ex.: https://bitwarden.compañia.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Para configuración avanzada, específica de forma independente a URL base de cada servizo." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Debes engadir ou a URL base do servidor ou, polo menos, un entorno personalizado." }, "customEnvironment": { "message": "Entorno personalizado" }, "customEnvironmentFooter": { - "message": "Para usuarios avanzados. Poder especificar o URL base de cada servizo de xeito independente." + "message": "Para usuarios avanzados. Podes especificar o URL base de cada servizo de xeito independente." }, "baseUrl": { "message": "URL do servidor" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL do servidor de aloxamento propio", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1469,101 +1462,101 @@ "message": "URLs do entorno gardadas" }, "showAutoFillMenuOnFormFields": { - "message": "Show autofill menu on form fields", + "message": "Amosar menú de autoenchido en formularios", "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Autofill suggestions" + "message": "Suxestións de autoenchido" }, "showInlineMenuLabel": { - "message": "Show autofill suggestions on form fields" + "message": "Amosar suxestións de autoenchido en formularios" }, "showInlineMenuIdentitiesLabel": { - "message": "Display identities as suggestions" + "message": "Amosar identidades como suxestións" }, "showInlineMenuCardsLabel": { - "message": "Display cards as suggestions" + "message": "Amosar tarxetas como suxestións" }, "showInlineMenuOnIconSelectionLabel": { - "message": "Display suggestions when icon is selected" + "message": "Amosar as suxestións ó premer a icona de Bitwarden" }, "showInlineMenuOnFormFieldsDescAlt": { - "message": "Applies to all logged in accounts." + "message": "Aplica a tódalas sesións iniciadas." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Turn off your browser's built in password manager settings to avoid conflicts." + "message": "Desactiva o xestor de contrasinais do teu navegador para evitar conflitos." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { - "message": "Edit browser settings." + "message": "Cambiar axustes do navegador." }, "autofillOverlayVisibilityOff": { "message": "Apagado", "description": "Overlay setting select option for disabling autofill overlay" }, "autofillOverlayVisibilityOnFieldFocus": { - "message": "When field is selected (on focus)", + "message": "Cando o campo está seleccionado (activo)", "description": "Overlay appearance select option for showing the field on focus of the input element" }, "autofillOverlayVisibilityOnButtonClick": { - "message": "When autofill icon is selected", + "message": "Cando a icona de autoenchido está seleccionada", "description": "Overlay appearance select option for showing the field on click of the overlay icon" }, "enableAutoFillOnPageLoadSectionTitle": { - "message": "Autofill on page load" + "message": "Autoencher ó cargar a páxina" }, "enableAutoFillOnPageLoad": { - "message": "Autofill on page load" + "message": "Autoencher ó cargar a páxina" }, "enableAutoFillOnPageLoadDesc": { - "message": "If a login form is detected, autofill when the web page loads." + "message": "Se se detecta un formulario de inicio de sesión, autoenchelo ó cargar a páxina." }, "experimentalFeature": { - "message": "Compromised or untrusted websites can exploit autofill on page load." + "message": "As webs comprometidas ou non fiables poden aproveitarse do autoenchido ó cargar a páxina." }, "learnMoreAboutAutofillOnPageLoadLinkText": { - "message": "Learn more about risks" + "message": "Saber máis dos riscos" }, "learnMoreAboutAutofill": { - "message": "Learn more about autofill" + "message": "Saber máis do autoenchido" }, "defaultAutoFillOnPageLoad": { - "message": "Default autofill setting for login items" + "message": "Axustes de autoenchido por defecto para as credenciais" }, "defaultAutoFillOnPageLoadDesc": { - "message": "You can turn off autofill on page load for individual login items from the item's Edit view." + "message": "Podes apagar o autoenchido para entradas concretas nas súas páxinas de edición." }, "itemAutoFillOnPageLoad": { - "message": "Autofill on page load (if set up in Options)" + "message": "Autoenchido ó cargar a páxina (se está activado nos Axustes)" }, "autoFillOnPageLoadUseDefault": { - "message": "Use default setting" + "message": "Usar axustes por defecto" }, "autoFillOnPageLoadYes": { - "message": "Autofill on page load" + "message": "Autoencher ó cargar a páxina" }, "autoFillOnPageLoadNo": { - "message": "Do not autofill on page load" + "message": "Non autoencher ó cargar a páxina" }, "commandOpenPopup": { - "message": "Open vault popup" + "message": "Abrir ventá emerxente da caixa forte" }, "commandOpenSidebar": { - "message": "Open vault in sidebar" + "message": "Abrir caixa forte na barra lateral" }, "commandAutofillLoginDesc": { - "message": "Autofill the last used login for the current website" + "message": "Autoencher a última credencial empregada nesta web" }, "commandAutofillCardDesc": { - "message": "Autofill the last used card for the current website" + "message": "Autoencher a última tarxeta empregada nesta web" }, "commandAutofillIdentityDesc": { - "message": "Autofill the last used identity for the current website" + "message": "Autoencher a última identidade empregada nesta web" }, "commandGeneratePasswordDesc": { - "message": "Generate and copy a new random password to the clipboard" + "message": "Xerar e copiar un novo contrasinal aleatorio ó portapapeis" }, "commandLockVaultDesc": { - "message": "Lock the vault" + "message": "Cerrar a caixa forte" }, "customFields": { "message": "Campos personalizados" @@ -1590,7 +1583,7 @@ "message": "Booleano" }, "cfTypeCheckbox": { - "message": "Checkbox" + "message": "Caixa" }, "cfTypeLinked": { "message": "Vinculado", @@ -1601,28 +1594,28 @@ "description": "This describes a value that is 'linked' (tied) to another value." }, "popup2faCloseMessage": { - "message": "Clicking outside the popup window to check your email for your verification code will cause this popup to close. Do you want to open this popup in a new window so that it does not close?" + "message": "Se clicas fóra desta ventá emerxente para comprobar o código do correo, cerrarase. Queres convertila nunha nova ventá completa para que non se cerre?" }, "popupU2fCloseMessage": { - "message": "This browser cannot process U2F requests in this popup window. Do you want to open this popup in a new window so that you can log in using U2F?" + "message": "Este navegador non pode procesar peticións U2F nesta ventá emerxente. Queres convertila nunha ventá completa para poder continuar?" }, "enableFavicon": { - "message": "Show website icons" + "message": "Amosar iconas web" }, "faviconDesc": { - "message": "Show a recognizable image next to each login." + "message": "Amosar unha imaxe recoñecible xunto a cada credencial." }, "faviconDescAlt": { - "message": "Show a recognizable image next to each login. Applies to all logged in accounts." + "message": "Amosar unha imaxe recoñecible xunto a cada credencial. Aplica a tódalas sesións iniciadas en Bitwarden." }, "enableBadgeCounter": { - "message": "Show badge counter" + "message": "Amosar contador na icona" }, "badgeCounterDesc": { - "message": "Indicate how many logins you have for the current web page." + "message": "Indicar cantas credenciais tes gardadas para a web aberta." }, "cardholderName": { - "message": "Nome do titular da tarxeta" + "message": "Titular da tarxeta" }, "number": { "message": "Número" @@ -1631,7 +1624,7 @@ "message": "Marca" }, "expirationMonth": { - "message": "Mes de expiración" + "message": "Mes de vencemento" }, "expirationYear": { "message": "Ano de vencemento" @@ -1697,7 +1690,7 @@ "message": "Dr" }, "mx": { - "message": "Mx" + "message": "Srx" }, "firstName": { "message": "Nome" @@ -1712,19 +1705,19 @@ "message": "Nome completo" }, "identityName": { - "message": "Nome de identidade" + "message": "Nome da identidade" }, "company": { "message": "Empresa" }, "ssn": { - "message": "Número da seguridade social" + "message": "Número da Seguridade Social" }, "passportNumber": { "message": "Número de pasaporte" }, "licenseNumber": { - "message": "Número de licencia" + "message": "Número de matrícula" }, "email": { "message": "Correo electrónico" @@ -1763,7 +1756,7 @@ "message": "Inicio de sesión" }, "typeLogins": { - "message": "Inicios se sesión" + "message": "Inicios de sesión" }, "typeSecureNote": { "message": "Nota segura" @@ -1775,10 +1768,10 @@ "message": "Identidade" }, "typeSshKey": { - "message": "SSH key" + "message": "Clave SSH" }, "newItemHeader": { - "message": "New $TYPE$", + "message": "Novo $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1787,7 +1780,7 @@ } }, "editItemHeader": { - "message": "Edit $TYPE$", + "message": "Modificar $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1796,7 +1789,7 @@ } }, "viewItemHeader": { - "message": "View $TYPE$", + "message": "Ver $TYPE$", "placeholders": { "type": { "content": "$1", @@ -1808,13 +1801,13 @@ "message": "Historial de contrasinais" }, "generatorHistory": { - "message": "Generator history" + "message": "Historial do xerador" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Baleirar historial do xerador" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Se continúas, tódalas entradas serán eliminadas permanentemente do historial do xerador. Seguro que queres continuar?" }, "back": { "message": "Atrás" @@ -1823,7 +1816,7 @@ "message": "Coleccións" }, "nCollections": { - "message": "$COUNT$ collections", + "message": "$COUNT$ coleccións", "placeholders": { "count": { "content": "$1", @@ -1835,7 +1828,7 @@ "message": "Favoritos" }, "popOutNewWindow": { - "message": "Pop out to a new window" + "message": "Sacar a unha nova ventá" }, "refresh": { "message": "Actualizar" @@ -1847,23 +1840,23 @@ "message": "Identidades" }, "logins": { - "message": "Inicios de sesión" + "message": "Credenciais" }, "secureNotes": { "message": "Notas seguras" }, "sshKeys": { - "message": "SSH Keys" + "message": "Claves SSH" }, "clear": { "message": "Limpar", "description": "To clear something out. example: To clear browser history." }, "checkPassword": { - "message": "Check if password has been exposed." + "message": "Comprobar se o contrasinal foi filtrado." }, "passwordExposed": { - "message": "This password has been exposed $VALUE$ time(s) in data breaches. You should change it.", + "message": "Este contrasinal foi filtrado $VALUE$ vez/veces. Deberías cambialo.", "placeholders": { "value": { "content": "$1", @@ -1872,14 +1865,14 @@ } }, "passwordSafe": { - "message": "This password was not found in any known data breaches. It should be safe to use." + "message": "Este contrasinal non foi atopado en ningunha filtración de datos. Debería ser seguro." }, "baseDomain": { "message": "Dominio base", "description": "Domain name. Ex. website.com" }, "baseDomainOptionRecommended": { - "message": "Base domain (recommended)", + "message": "Dominio base (recomendado)", "description": "Domain name. Ex. website.com" }, "domainName": { @@ -1887,7 +1880,7 @@ "description": "Domain name. Ex. website.com" }, "host": { - "message": "Anfitrión", + "message": "Servidor", "description": "A URL's host value. For example, the host of https://sub.domain.com:443 is 'sub.domain.com:443'." }, "exact": { @@ -1901,18 +1894,18 @@ "description": "A programming term, also known as 'RegEx'." }, "matchDetection": { - "message": "Match detection", + "message": "Detección de coincidencias", "description": "URI match detection for autofill." }, "defaultMatchDetection": { - "message": "Default match detection", + "message": "Detección de coincidencias por defecto", "description": "Default URI match detection for autofill." }, "toggleOptions": { - "message": "Toggle options" + "message": "Alternar opcións" }, "toggleCurrentUris": { - "message": "Toggle current URIs", + "message": "Alternar URIs actuais", "description": "Toggle the display of the URIs of the currently open tabs in the browser." }, "currentUri": { @@ -1927,19 +1920,19 @@ "message": "Tipos" }, "allItems": { - "message": "Todos os elementos" + "message": "Todas as entradas" }, "noPasswordsInList": { "message": "Non hai contrasinais que listar." }, "clearHistory": { - "message": "Clear history" + "message": "Baleirar historial" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Nada que amosar" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Non xerache nada recentemente" }, "remove": { "message": "Eliminar" @@ -1960,26 +1953,26 @@ "description": "ex. Date this password was updated" }, "neverLockWarning": { - "message": "Are you sure you want to use the \"Never\" option? Setting your lock options to \"Never\" stores your vault's encryption key on your device. If you use this option you should ensure that you keep your device properly protected." + "message": "Seguro que queres marcar a opción \"Nunca\"? Isto almacenará a clave de cifrado da túa caixa forte no teu dispositivo. Se usas esta opción debes asegurarte de ter o dispositivo ben protexido." }, "noOrganizationsList": { - "message": "You do not belong to any organizations. Organizations allow you to securely share items with other users." + "message": "Non pertences a ningunha organización. As organizacións permiten compartir entradas con outros usuarios." }, "noCollectionsInList": { - "message": "There are no collections to list." + "message": "Non hai coleccións que listar." }, "ownership": { "message": "Propiedade" }, "whoOwnsThisItem": { - "message": "Quen posúe este elemento?" + "message": "Quen posúe esta entrada?" }, "strong": { "message": "Forte", "description": "ex. A strong password. Scale: Weak -> Good -> Strong" }, "good": { - "message": "Boa", + "message": "Bo", "description": "ex. A good password. Scale: Weak -> Good -> Strong" }, "weak": { @@ -1990,94 +1983,91 @@ "message": "Contrasinal mestre feble" }, "weakMasterPasswordDesc": { - "message": "The master password you have chosen is weak. You should use a strong master password (or a passphrase) to properly protect your Bitwarden account. Are you sure you want to use this master password?" + "message": "O contrasinal mestre creado é feble. Debes empregar un contrasinal ou frase de contrasinal mestre forte para protexer debidamente a túa conta. Seguro que queres continuar con este contrasinal?" }, "pin": { "message": "PIN", "description": "PIN code. Ex. The short code (often numeric) that you use to unlock a device." }, "unlockWithPin": { - "message": "Unlock with PIN" + "message": "Abrir con PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "Definir PIN" }, "setYourPinButton": { - "message": "Set PIN" + "message": "Crear PIN" }, "setYourPinCode": { - "message": "Set your PIN code for unlocking Bitwarden. Your PIN settings will be reset if you ever fully log out of the application." + "message": "Crea un PIN para abrir a caixa forte. Se algunha vez pechas a sesión en Bitwarden perderase a configuración deste PIN." }, "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": "O PIN empregarase no lugar do contrasinal mestre para abrir a caixa forte. Se pechas a sesión en Bitwarden perderase a configuración do PIN." }, "pinRequired": { - "message": "PIN code is required." + "message": "PIN requirido." }, "invalidPin": { - "message": "Invalid PIN code." + "message": "PIN incorrecto." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "Múltiples intentos fallidos de PIN. Pechando a sesión." }, "unlockWithBiometrics": { - "message": "Unlock with biometrics" + "message": "Abrir con biometría" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "Abrir con contrasinal mestre" }, "awaitDesktop": { - "message": "Awaiting confirmation from desktop" + "message": "Agardando pola confirmación do escritorio" }, "awaitDesktopDesc": { - "message": "Please confirm using biometrics in the Bitwarden desktop application to set up biometrics for browser." + "message": "Por favor confirma o uso de biometría na aplicación de escritorio de Bitwarden para activar a biometría no navegador." }, "lockWithMasterPassOnRestart": { - "message": "Lock with master password on browser restart" + "message": "Bloquear con contrasinal mestre ó pechar o navegador" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Requirir contrasinal mestre ó abrir o navegador" }, "selectOneCollection": { - "message": "You must select at least one collection." + "message": "Debes seleccionar polo menos unha colección." }, "cloneItem": { - "message": "Clonar elemento" + "message": "Duplicar entrada" }, "clone": { "message": "Clonar" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { - "message": "Password generator" + "message": "Xerador de contrasinais" }, "usernameGenerator": { - "message": "Username generator" + "message": "Xerador de nomes de usuario" }, "useThisPassword": { - "message": "Use this password" + "message": "Usar este contrasinal" }, "useThisUsername": { - "message": "Use this username" + "message": "Usar este nome de usuario" }, "securePasswordGenerated": { - "message": "Secure password generated! Don't forget to also update your password on the website." + "message": "Contrasinal seguro xerado! Non esquezas actualizar o contrasinal na web." }, "useGeneratorHelpTextPartOne": { - "message": "Use the generator", + "message": "Usar o xerador", "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": "para crear un contrasinal forte", "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": "Vault timeout action" + "message": "Acción do temporizador da caixa forte" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Acción do temporizador" }, "lock": { "message": "Bloquear", @@ -2088,55 +2078,55 @@ "description": "Noun: a special folder to hold deleted items" }, "searchTrash": { - "message": "Search trash" + "message": "Buscar no lixo" }, "permanentlyDeleteItem": { - "message": "Permanently delete item" + "message": "Eliminar entrada permanentemente" }, "permanentlyDeleteItemConfirmation": { - "message": "Are you sure you want to permanently delete this item?" + "message": "Seguro que queres eliminar permanentemente esta entrada?" }, "permanentlyDeletedItem": { - "message": "Item permanently deleted" + "message": "Entrada eliminada permanente" }, "restoreItem": { - "message": "Restore item" + "message": "Restaurar entrada" }, "restoredItem": { - "message": "Item restored" + "message": "Entrada restaurada" }, "alreadyHaveAccount": { - "message": "Already have an account?" + "message": "Xa tes unha conta?" }, "vaultTimeoutLogOutConfirmation": { - "message": "Logging out will remove all access to your vault and requires online authentication after the timeout period. Are you sure you want to use this setting?" + "message": "Cerrar a sesión despois dun tempo elimina o acceso á caixa forte ata que se volva iniciar sesión. Seguro que queres empregar esta opción?" }, "vaultTimeoutLogOutConfirmationTitle": { - "message": "Timeout action confirmation" + "message": "Confirmación de acción do temporizador" }, "autoFillAndSave": { - "message": "Autofill and save" + "message": "Autoencher e gardar" }, "fillAndSave": { - "message": "Fill and save" + "message": "Encher e gardar" }, "autoFillSuccessAndSavedUri": { - "message": "Item autofilled and URI saved" + "message": "Entrada autoenchida e URI gardada" }, "autoFillSuccess": { - "message": "Item autofilled " + "message": "Entrada autoenchida " }, "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": "Aviso: esta é unha páxina web HTTP sen cifrar, e calquera información que envíes é visible para terceiros. A credencial foi orixinalmente gardada nunha web HTTPS cifrada." }, "insecurePageWarningFillPrompt": { - "message": "Do you still wish to fill this login?" + "message": "Aínda queres autoencher esta credencial?" }, "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": "O formulario está aloxado nun dominio diferente da URI que gardaches. Clica Aceptar para autoencher igualmente, ou Cancelar para parar." }, "autofillIframeWarningTip": { - "message": "To prevent this warning in the future, save this URI, $HOSTNAME$, to your Bitwarden login item for this site.", + "message": "Para prever este aviso no futuro, garda este URI, $HOSTNAME$, na túa entrada en Bitwarden para este sitio.", "placeholders": { "hostname": { "content": "$1", @@ -2145,22 +2135,22 @@ } }, "setMasterPassword": { - "message": "Set master password" + "message": "Definir contrasinal mestre" }, "currentMasterPass": { - "message": "Current master password" + "message": "Contrasinal mestre actual" }, "newMasterPass": { - "message": "New master password" + "message": "Novo contrasinal mestre" }, "confirmNewMasterPass": { - "message": "Confirm new master password" + "message": "Repetir novo contrasinal mestre" }, "masterPasswordPolicyInEffect": { - "message": "One or more organization policies require your master password to meet the following requirements:" + "message": "As directivas da túa organización esixen que o teu contrasinal mestre cumpra os seguintes requisitos:" }, "policyInEffectMinComplexity": { - "message": "Minimum complexity score of $SCORE$", + "message": "Complexidade mínima de $SCORE$ puntos", "placeholders": { "score": { "content": "$1", @@ -2169,7 +2159,7 @@ } }, "policyInEffectMinLength": { - "message": "Minimum length of $LENGTH$", + "message": "Mínimo de $LENGTH$ caracteres", "placeholders": { "length": { "content": "$1", @@ -2178,16 +2168,16 @@ } }, "policyInEffectUppercase": { - "message": "Contain one or more uppercase characters" + "message": "Conter polo menos unha maiúscula" }, "policyInEffectLowercase": { - "message": "Contain one or more lowercase characters" + "message": "Conter polo menos unha minúscula" }, "policyInEffectNumbers": { - "message": "Contain one or more numbers" + "message": "Conter polo menos un número" }, "policyInEffectSpecial": { - "message": "Contain one or more of the following special characters $CHARS$", + "message": "Conter polo menos un dos seguintes caracteres: $CHARS$", "placeholders": { "chars": { "content": "$1", @@ -2196,155 +2186,155 @@ } }, "masterPasswordPolicyRequirementsNotMet": { - "message": "Your new master password does not meet the policy requirements." + "message": "Este contrasinal mestre non cumpre cas directivas." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Recibe consellos, anuncios e oportunidades de investigación de Bitwarden no teu correo." }, "unsubscribe": { - "message": "Unsubscribe" + "message": "Cancelar subscrición" }, "atAnyTime": { - "message": "at any time." + "message": "en calquera momento." }, "byContinuingYouAgreeToThe": { - "message": "By continuing, you agree to the" + "message": "Ó continuar, estarás aceptando os" }, "and": { - "message": "and" + "message": "e" }, "acceptPolicies": { - "message": "By checking this box you agree to the following:" + "message": "Ó marcar esta caixa aceptas o seguinte:" }, "acceptPoliciesRequired": { - "message": "Terms of Service and Privacy Policy have not been acknowledged." + "message": "Os Termos de Servizo e a Política de Privacidade non foron aceptados." }, "termsOfService": { - "message": "Terms of Service" + "message": "Termos de Servizo" }, "privacyPolicy": { - "message": "Privacy Policy" + "message": "Política de Privacidade" }, "hintEqualsPassword": { - "message": "Your password hint cannot be the same as your password." + "message": "A pista do contrasinal non pode ser o contrasinal." }, "ok": { - "message": "Ok" + "message": "Aceptar" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Erro de actualización do Token de Acceso" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Non se atoparon token de actualización nin claves da API. Por favor trata de volver iniciar sesión." }, "desktopSyncVerificationTitle": { - "message": "Desktop sync verification" + "message": "Verificación de sincronización co escritorio" }, "desktopIntegrationVerificationText": { - "message": "Please verify that the desktop application shows this fingerprint: " + "message": "Por favor verifica que a app de escritorio amosa esta pegada dixital: " }, "desktopIntegrationDisabledTitle": { - "message": "Browser integration is not set up" + "message": "Integración co navegador non configurada" }, "desktopIntegrationDisabledDesc": { - "message": "Browser integration is not set up in the Bitwarden desktop application. Please set it up in the settings within the desktop application." + "message": "A integración co navegador non está activada na app de escritorio de Bitwarden. Por favor configúraa dende os axustes da app de escritorio." }, "startDesktopTitle": { - "message": "Start the Bitwarden desktop application" + "message": "Abrir a app de escritorio de Bitwarden" }, "startDesktopDesc": { - "message": "The Bitwarden desktop application needs to be started before unlock with biometrics can be used." + "message": "Para poder empregar a biometría a aplicación de escritorio de Bitwarden debe estar executada." }, "errorEnableBiometricTitle": { - "message": "Unable to set up biometrics" + "message": "Non foi posible activar a biometría" }, "errorEnableBiometricDesc": { - "message": "Action was canceled by the desktop application" + "message": "Proceso interrompido pola aplicación de escritorio" }, "nativeMessagingInvalidEncryptionDesc": { - "message": "Desktop application invalidated the secure communication channel. Please retry this operation" + "message": "A aplicación de escritorio invalidou a canle de comunicación segura. Por favor volve intentalo" }, "nativeMessagingInvalidEncryptionTitle": { - "message": "Desktop communication interrupted" + "message": "Comunicación co escritorio interrompida" }, "nativeMessagingWrongUserDesc": { - "message": "The desktop application is logged into a different account. Please ensure both applications are logged into the same account." + "message": "A aplicación de escritorio ten unha conta distinta. Por favor asegúrate de que ambas aplicacións iniciaron sesión na mesma conta." }, "nativeMessagingWrongUserTitle": { - "message": "Account missmatch" + "message": "Conta non coincidente" }, "nativeMessagingWrongUserKeyTitle": { - "message": "Biometric key missmatch" + "message": "Clave biométrica non coincidente" }, "nativeMessagingWrongUserKeyDesc": { - "message": "Biometric unlock failed. The biometric secret key failed to unlock the vault. Please try to set up biometrics again." + "message": "Desbloqueo biométrico fallido. A clave biométrica non puido abrir a caixa forte. Por favor proba a volver configurar a biometría." }, "biometricsNotEnabledTitle": { - "message": "Biometrics not set up" + "message": "Biometría non activada" }, "biometricsNotEnabledDesc": { - "message": "Browser biometrics requires desktop biometric to be set up in the settings first." + "message": "A biometría no navegador require que se configure primeiro na app de escritorio." }, "biometricsNotSupportedTitle": { - "message": "Biometrics not supported" + "message": "Biometría non compatible" }, "biometricsNotSupportedDesc": { - "message": "Browser biometrics is not supported on this device." + "message": "Biometría do navegador non compatible con este dispositivo." }, "biometricsNotUnlockedTitle": { - "message": "User locked or logged out" + "message": "Usuario cerrado ou desconectado" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "Por favor desbloquea o usuario na aplicación de escritorio e volve intentalo." }, "biometricsNotAvailableTitle": { - "message": "Biometric unlock unavailable" + "message": "Desbloqueo biométrico non dispoñible" }, "biometricsNotAvailableDesc": { - "message": "Biometric unlock is currently unavailable. Please try again later." + "message": "Desbloqueo biométrico non dispoñible neste momento. Volve intentalo máis tarde." }, "biometricsFailedTitle": { - "message": "Biometrics failed" + "message": "Fallo da biometría" }, "biometricsFailedDesc": { - "message": "Biometrics cannot be completed, consider using a master password or logging out. If this persists, please contact Bitwarden support." + "message": "A biometría non puido ser completada. Proba a usar o contrasinal mestre ou pechar a sesión. Se o problema persiste, contacta con atención ó cliente." }, "nativeMessaginPermissionErrorTitle": { - "message": "Permission not provided" + "message": "Permiso non concedido" }, "nativeMessaginPermissionErrorDesc": { - "message": "Without permission to communicate with the Bitwarden Desktop Application we cannot provide biometrics in the browser extension. Please try again." + "message": "Sen permiso de comunicación ca aplicación de escritorio non podemos prover biometría na extensión de navegador. Por favor, volve intentalo." }, "nativeMessaginPermissionSidebarTitle": { - "message": "Permission request error" + "message": "Error de petición de permisos" }, "nativeMessaginPermissionSidebarDesc": { - "message": "This action cannot be done in the sidebar, please retry the action in the popup or popout." + "message": "Esta acción non pode ser realizada na barra lateral. Inténtao dende a ventá emerxente." }, "personalOwnershipSubmitError": { - "message": "Due to an Enterprise Policy, you are restricted from saving items to your personal vault. Change the Ownership option to an organization and choose from available collections." + "message": "Debido a unha directiva da empresa, non podes gardar entradas na túa caixa forte. Cambia a opción de propiedade a unha organización e elixe unha das coleccións dispoñibles." }, "personalOwnershipPolicyInEffect": { - "message": "An organization policy is affecting your ownership options." + "message": "Unha directiva da empresa está a afectar ás túas opcións de propiedade." }, "personalOwnershipPolicyInEffectImports": { - "message": "An organization policy has blocked importing items into your individual vault." + "message": "Unha directiva da empresa impide importar entradas á túa caixa forte individual." }, "domainsTitle": { - "message": "Domains", + "message": "Dominios", "description": "A category title describing the concept of web domains" }, "excludedDomains": { - "message": "Excluded domains" + "message": "Dominios excluídos" }, "excludedDomainsDesc": { - "message": "Bitwarden will not ask to save login details for these domains. You must refresh the page for changes to take effect." + "message": "Bitwarden non ofrecerá gardar contas para estes dominios. Recarga a páxina para que os cambios fagan efecto." }, "excludedDomainsDescAlt": { - "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." + "message": "Bitwarden non ofrecerá gardar contas para estes dominios en ningunha das sesións iniciadas. Recarga a páxina para que os cambios fornezan efecto." }, "websiteItemLabel": { - "message": "Website $number$ (URI)", + "message": "Web $number$ (URI)", "placeholders": { "number": { "content": "$1", @@ -2353,7 +2343,7 @@ } }, "excludedDomainsInvalidDomain": { - "message": "$DOMAIN$ is not a valid domain", + "message": "$DOMAIN$ non é un dominio válido", "placeholders": { "domain": { "content": "$1", @@ -2362,17 +2352,17 @@ } }, "excludedDomainsSavedSuccess": { - "message": "Excluded domain changes saved" + "message": "Dominios excluídos gardados" }, "limitSendViews": { - "message": "Limit views" + "message": "Limitar visionados" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "Ninguén pode ver este Send dende que se alcance o límite.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "$ACCESSCOUNT$ visionados restantes", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2386,22 +2376,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDetails": { - "message": "Send details", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "searchSends": { - "message": "Buscar Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Engadir Send", + "message": "Detalles do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeText": { "message": "Texto" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "Texto a compartir" }, "sendTypeFile": { "message": "Ficheiro" @@ -2411,36 +2393,29 @@ "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" - }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." + "message": "Ocultar texto por defecto" }, "expired": { - "message": "Caducado" - }, - "pendingDeletion": { - "message": "Pending deletion" + "message": "Vencido" }, "passwordProtected": { - "message": "Password protected" + "message": "Protexido con contrasinal" }, "copyLink": { - "message": "Copy link" + "message": "Copiar ligazón" }, "copySendLink": { "message": "Copiar ligazón Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "removePassword": { - "message": "Remove Password" + "message": "Eliminar contrasinal" }, "delete": { "message": "Eliminar" }, "removedPassword": { - "message": "Password removed" + "message": "Contrasinal eliminado" }, "deletedSend": { "message": "Send eliminado", @@ -2451,55 +2426,36 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "disabled": { - "message": "Disabled" + "message": "Deshabilitado" }, "removePasswordConfirmation": { - "message": "Are you sure you want to remove the password?" + "message": "Seguro que queres eliminar o contrasinal?" }, "deleteSend": { "message": "Eliminar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendConfirmation": { - "message": "Are you sure you want to delete this Send?", + "message": "Seguro que queres eliminar este Send?", "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": "Seguro que queres eliminar permanentemente este Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { - "message": "Deletion date" - }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + "message": "Data de eliminación" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "Este Send será permanente eliminado nesta data.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { - "message": "Expiration date" - }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." + "message": "Data de vencemento" }, "oneDay": { "message": "1 día" @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalizado" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", + "message": "Engade un contrasinal opcional para os destinatarios deste Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "Novo Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2565,7 +2488,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDisabledWarning": { - "message": "Due to an enterprise policy, you are only able to delete an existing Send.", + "message": "Por unha directiva de empresa só podes eliminar un Send existente.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createdSend": { @@ -2573,15 +2496,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 creado con éxito!", "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": "O Send estará dispoñible para calquera ca ligazón durante 1 hora.", "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": "O Send estará dispoñible para calquera ca ligazón durante $HOURS$ horas.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "hours": { @@ -2591,11 +2514,11 @@ } }, "sendExpiresInDaysSingle": { - "message": "The Send will be available to anyone with the link for the next 1 day.", + "message": "O Send estará dispoñible para calquera ca ligazón durante 1 día.", "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": "O Send estará dispoñible para calquera ca ligazón durante $DAYS$ días.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "days": { @@ -2605,7 +2528,7 @@ } }, "sendLinkCopied": { - "message": "Send link copied", + "message": "Ligazón do Send copiado", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editedSend": { @@ -2613,120 +2536,102 @@ "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": "Sacar a extensión?", "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": "Para crear un arquivo Send, necesitas sacar a extensión a unha nova ventá.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { - "message": "In order to choose a file, open the extension in the sidebar (if possible) or pop out to a new window by clicking this banner." + "message": "Para escoller un arquivo, abre a extensión na barra lateral (se é posible) ou sácaa a unha nova ventá premendo este botón." }, "sendFirefoxFileWarning": { - "message": "In order to choose a file using Firefox, open the extension in the sidebar or pop out to a new window by clicking this banner." + "message": "Para escoller un arquivo empregando Firefox, abre a extensión na barra lateral ou sácaa a unha nova ventá premendo este botón." }, "sendSafariFileWarning": { - "message": "In order to choose a file using Safari, pop out to a new window by clicking this banner." + "message": "Para escoller un arquivo empregando Safari, saca a extensión a unha nova ventá premendo este botón." }, "popOut": { - "message": "Pop out" + "message": "Sacar" }, "sendFileCalloutHeader": { - "message": "Before you start" - }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" + "message": "Antes de comezar" }, "expirationDateIsInvalid": { - "message": "The expiration date provided is not valid." + "message": "A data de vencemento non é válida." }, "deletionDateIsInvalid": { - "message": "The deletion date provided is not valid." + "message": "A data de eliminación non é válida." }, "expirationDateAndTimeRequired": { - "message": "An expiration date and time are required." + "message": "Unha data e hora de vencemento son requiridas." }, "deletionDateAndTimeRequired": { - "message": "A deletion date and time are required." + "message": "Unha data e hora de eliminación son requiridas." }, "dateParsingError": { - "message": "There was an error saving your deletion and expiration dates." - }, - "hideEmail": { - "message": "Hide my email address from recipients." + "message": "Produciuse un erro ó gardar as datas de vencemento e eliminación." }, "hideYourEmail": { - "message": "Hide your email address from viewers." - }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." + "message": "Oculta o teu enderezo electrónico ós visitantes." }, "passwordPrompt": { - "message": "Master password re-prompt" + "message": "Volver solicitar o contrasinal mestre" }, "passwordConfirmation": { - "message": "Master password confirmation" + "message": "Repetir o contrasinal mestre" }, "passwordConfirmationDesc": { - "message": "This action is protected. To continue, please re-enter your master password to verify your identity." + "message": "Esta acción está protexida. Para continuar por favor volve introducir o teu contrasinal mestre." }, "emailVerificationRequired": { - "message": "Email verification required" + "message": "Verificación do correo electrónico requirida" }, "emailVerifiedV2": { - "message": "Email verified" + "message": "Correo electrónico verificado" }, "emailVerificationRequiredDesc": { - "message": "You must verify your email to use this feature. You can verify your email in the web vault." + "message": "Debes verificar o teu correo electrónico para empregar esta función. Podes facelo dende a aplicación web." }, "updatedMasterPassword": { - "message": "Updated master password" + "message": "Contrasinal mestre actualizado" }, "updateMasterPassword": { - "message": "Update master password" + "message": "Actualizar contrasinal mestre" }, "updateMasterPasswordWarning": { - "message": "Your master password was recently changed by an administrator in your organization. In order to access the vault, you must update it now. Proceeding will log you out of your current session, requiring you to log back in. Active sessions on other devices may continue to remain active for up to one hour." + "message": "O teu contrasinal mestre foi recentemente cambiado por un administrador da túa organización. Para poder acceder á caixa forte debes actualizalo. A continuación cerrarase a túa sesión, requirindo volver iniciala. As sesións activas noutros dispositivos poden permanecer activas por unha hora." }, "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." + "message": "O teu contrasinal mestre non cumpre algún dos requisitos das directivas da empresa. Para poder acceder a caixa forte debes actualizar o teu contrasinal mestre. A continuación cerrarase a túa sesión, requirindo volver iniciala. As sesións activas noutros dispositivos poden permanecer activas por unha hora." }, "tdeDisabledMasterPasswordRequired": { - "message": "Your organization has disabled trusted device encryption. Please set a master password to access your vault." + "message": "A túa organización desactivou cifrado en dispositivos de confianza. Por favor, crea un contrasinal mestre para acceder á túa caixa forte." }, "resetPasswordPolicyAutoEnroll": { - "message": "Automatic enrollment" + "message": "Rexistro automático" }, "resetPasswordAutoEnrollInviteWarning": { - "message": "This organization has an enterprise policy that will automatically enroll you in password reset. Enrollment will allow organization administrators to change your master password." + "message": "Esta organización ten unha directiva de empresa que te rexistrará automaticamente nun restablecemento de contrasinal. O rexistro permitirá a organización cambiar o teu contrasinal mestre." }, "selectFolder": { - "message": "Select folder..." + "message": "Seleccionar cartafol..." }, "noFoldersFound": { - "message": "No folders found", + "message": "Cartafol non atopado", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { - "message": "Your organization permissions were updated, requiring you to set a master password.", + "message": "Os permisos da organización foron actualizados, requirindo que crees un contrasinal mestre.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "orgRequiresYouToSetPassword": { - "message": "Your organization requires you to set a master password.", + "message": "A túa urbanización require que crees un contrasinal mestre.", "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": "de $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -2735,7 +2640,7 @@ } }, "verificationRequired": { - "message": "Verification required", + "message": "Verificación requirida", "description": "Default title for the user verification dialog." }, "hours": { @@ -2745,10 +2650,10 @@ "message": "Minutos" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "Directivas da empresa foron aplicadas ás opcións do temporizador da túa Caixa forte" }, "vaultTimeoutPolicyInEffect": { - "message": "Your organization policies have set your maximum allowed vault timeout to $HOURS$ hour(s) and $MINUTES$ minute(s).", + "message": "Directivas da empresa restrinxen o temporizador da túa Caixa forte a un máximo de $HOURS$ hora(s) e $MINUTES$ minuto(s).", "placeholders": { "hours": { "content": "$1", @@ -2761,7 +2666,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "$HOURS$ hora(s) e $MINUTES$ minuto(s) de máximo.", "placeholders": { "hours": { "content": "$1", @@ -2774,7 +2679,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Timeout exceeds the restriction set by your organization: $HOURS$ hour(s) and $MINUTES$ minute(s) maximum", + "message": "O tempo indicado excede as restricións definidas pola túa organización: un máximo de $HOURS$ hora(s) e $MINUTES$ minuto(s)", "placeholders": { "hours": { "content": "$1", @@ -2787,7 +2692,7 @@ } }, "vaultTimeoutPolicyWithActionInEffect": { - "message": "Your organization policies are affecting your vault timeout. Maximum allowed vault timeout is $HOURS$ hour(s) and $MINUTES$ minute(s). Your vault timeout action is set to $ACTION$.", + "message": "As directivas da empresa restrinxen o temporizador da túa Caixa forte a $HOURS$ hora(s) e $MINUTES$ minuto(s) de máximo. A acción a realizar será: $ACTION$.", "placeholders": { "hours": { "content": "$1", @@ -2804,7 +2709,7 @@ } }, "vaultTimeoutActionPolicyInEffect": { - "message": "Your organization policies have set your vault timeout action to $ACTION$.", + "message": "As directivas da empresa definiron o temporizador da túa Caixa forte en $ACTION$.", "placeholders": { "action": { "content": "$1", @@ -2813,22 +2718,22 @@ } }, "vaultTimeoutTooLarge": { - "message": "Your vault timeout exceeds the restrictions set by your organization." + "message": "O temporizador da túa Caixa forte excede as restricións definidas pola túa organización." }, "vaultExportDisabled": { - "message": "Vault export unavailable" + "message": "Exportado da Caixa forte non dispoñible" }, "personalVaultExportPolicyInEffect": { - "message": "One or more organization policies prevents you from exporting your individual vault." + "message": "Directivas da empresa impiden exportar a túa caixa forte individual." }, "copyCustomFieldNameInvalidElement": { - "message": "Unable to identify a valid form element. Try inspecting the HTML instead." + "message": "No se puido identificar un elemento de formulario válido. Intenta inspeccionar no HTML en seu lugar." }, "copyCustomFieldNameNotUnique": { - "message": "No unique identifier found." + "message": "Non se atopou ningún identificador único." }, "convertOrganizationEncryptionDesc": { - "message": "$ORGANIZATION$ is using SSO with a self-hosted key server. A master password is no longer required to log in for members of this organization.", + "message": "$ORGANIZATION$ emprega SSO con un servidor de claves propio. Os membros da organización xa non precisan dun contrasinal mestre para iniciar sesión.", "placeholders": { "organization": { "content": "$1", @@ -2837,31 +2742,31 @@ } }, "leaveOrganization": { - "message": "Leave organization" + "message": "Deixar a organización" }, "removeMasterPassword": { - "message": "Remove master password" + "message": "Eliminar contrasinal mestre" }, "removedMasterPassword": { - "message": "Master password removed" + "message": "Contrasinal mestre eliminado" }, "leaveOrganizationConfirmation": { - "message": "Are you sure you want to leave this organization?" + "message": "Estás seguro de que queres deixar esta organización?" }, "leftOrganization": { - "message": "You have left the organization." + "message": "Deixache a organización." }, "toggleCharacterCount": { - "message": "Toggle character count" + "message": "Alternar contador de caracteres" }, "sessionTimeout": { - "message": "Your session has timed out. Please go back and try logging in again." + "message": "O temporizador da sesión rematou. Por favor, volve iniciar a sesión." }, "exportingPersonalVaultTitle": { - "message": "Exporting individual vault" + "message": "Exportando caixa forte individual" }, "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.", + "message": "Só se exportarán as entradas persoais da caixa forte asociada a $EMAIL$. As entradas da Caixa forte da organización non se incluirán. Tampouco se incluirá ningún arquivo anexo ás entradas.", "placeholders": { "email": { "content": "$1", @@ -2870,10 +2775,10 @@ } }, "exportingOrganizationVaultTitle": { - "message": "Exporting organization vault" + "message": "Exportar Caixa forte da organización" }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "Só se exportará a Caixa forte asociada a $ORGANIZATION$. As entradas en Caixas fortes individuais ou doutras organizacións non se incluirán.", "placeholders": { "organization": { "content": "$1", @@ -2884,17 +2789,14 @@ "error": { "message": "Erro" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { - "message": "Generate username" + "message": "Xerar nome de usuario" }, "generateEmail": { - "message": "Generate email" + "message": "Xerar enderezo electrónico" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "O valor debe estar entre $MIN$ e $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2908,7 +2810,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": "Usar $RECOMMENDED$ caracteres ou máis para xerar un contrasinal seguro.", "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": { @@ -2918,7 +2820,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": "Usar $RECOMMENDED$ palabras ou máis para xerar unha frase de contrasinal segura.", "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": { @@ -2927,21 +2829,18 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { - "message": "Plus addressed email", + "message": "Correo con alias", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "Use your email provider's sub-addressing capabilities." + "message": "Usar as funcións de subdireccionamento do teu provedor de correo." }, "catchallEmail": { - "message": "Catch-all email" + "message": "Correo \"catch-all\"" }, "catchallEmailDesc": { - "message": "Use your domain's configured catch-all inbox." + "message": "Usar a caixa de entrada \"catch-all\" configurada para o teu dominio." }, "random": { "message": "Aleatorio" @@ -2952,31 +2851,25 @@ "websiteName": { "message": "Nome do sitio web" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { - "message": "Service" + "message": "Servizo" }, "forwardedEmail": { - "message": "Forwarded email alias" + "message": "Alias de correo redirixido" }, "forwardedEmailDesc": { - "message": "Generate an email alias with an external forwarding service." + "message": "Xerar un alias de correo cun servizo de redirecionado externo." }, "forwarderDomainName": { - "message": "Email domain", + "message": "Dominio de correo", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "Seleccionar un dominio compatible co servizo seleccionado", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "Erro de $SERVICENAME$: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -2990,11 +2883,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Xerado por Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Web: $WEBSITE$. Xerada por Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -3004,7 +2897,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Token da API de $SERVICENAME$ inválido", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -3014,7 +2907,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Token da API de $SERVICENAME$ inválido: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3028,7 +2921,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "Non foi posible obter o ID de correo enmascarado de $SERVICENAME$.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -3038,7 +2931,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Dominio de $SERVICENAME$ inválido.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -3048,7 +2941,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Url de $SERVICENAME$ inválido.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -3058,7 +2951,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Ocorreu un erro de $SERVICENAME$ descoñecido.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -3068,7 +2961,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Redireccionador descoñecido: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -3088,19 +2981,19 @@ "message": "Clave da API" }, "ssoKeyConnectorError": { - "message": "Key connector error: make sure key connector is available and working correctly." + "message": "Erro de conector de clave: asegúrate de que o conector de clave está dispoñible e funcionando correctamente." }, "premiumSubcriptionRequired": { - "message": "Premium subscription required" + "message": "Requírese plan Prémium" }, "organizationIsDisabled": { - "message": "Organization suspended." + "message": "Organización suspendida." }, "disabledOrganizationFilterError": { - "message": "Items in suspended Organizations cannot be accessed. Contact your Organization owner for assistance." + "message": "As entradas de organizacións suspendidas son inaccesibles. Contacta co propietario da organización para asistencia." }, "loggingInTo": { - "message": "Logging in to $DOMAIN$", + "message": "Iniciando sesión en $DOMAIN$", "placeholders": { "domain": { "content": "$1", @@ -3109,25 +3002,25 @@ } }, "settingsEdited": { - "message": "Settings have been edited" + "message": "Os axustes foron modificados" }, "environmentEditedClick": { - "message": "Click here" + "message": "Preme aquí" }, "environmentEditedReset": { - "message": "to reset to pre-configured settings" + "message": "para volver á configuración por defecto" }, "serverVersion": { - "message": "Server version" + "message": "Versión do Servidor" }, "selfHostedServer": { "message": "autoaloxado" }, "thirdParty": { - "message": "Third-party" + "message": "De terceiros" }, "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": "Conectado a un servidor dun terceiro, $SERVERNAME$. Por favor verifica bugs empregando o servidor oficial, ou comunícallos ó servidor da terceira parte.", "placeholders": { "servername": { "content": "$1", @@ -3136,7 +3029,7 @@ } }, "lastSeenOn": { - "message": "last seen on: $DATE$", + "message": "Visto por última vez o: $DATE$", "placeholders": { "date": { "content": "$1", @@ -3145,82 +3038,82 @@ } }, "loginWithMasterPassword": { - "message": "Log in with master password" + "message": "Iniciar sesión co contrasinal mestre" }, "loggingInAs": { - "message": "Logging in as" + "message": "Iniciando sesión como" }, "notYou": { - "message": "Not you?" + "message": "Non es ti?" }, "newAroundHere": { - "message": "New around here?" + "message": "Novo por aquí?" }, "rememberEmail": { - "message": "Remember email" + "message": "Lembrar correo" }, "loginWithDevice": { - "message": "Log in with device" + "message": "Iniciar sesión cun dispositivo" }, "loginWithDeviceEnabledInfo": { - "message": "Log in with device must be set up in the settings of the Bitwarden app. Need another option?" + "message": "O inicio de sesión con dispositivos debe estar activado nos axustes da app de Bitwarden. Precisas doutro método?" }, "fingerprintPhraseHeader": { - "message": "Fingerprint phrase" + "message": "Frase de pegada dixital" }, "fingerprintMatchInfo": { - "message": "Please make sure your vault is unlocked and the Fingerprint phrase matches on the other device." + "message": "Por favor asegúrate de que a caixa forte está desbloqueada e a frase de pegada dixital coincide ca do outro dispositivo." }, "resendNotification": { - "message": "Resend notification" + "message": "Volver enviar notificación" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Ver todas as opcións de inicio de sesión" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "Ver todas as opcións de inicio de sesión" }, "notificationSentDevice": { - "message": "A notification has been sent to your device." + "message": "Enviouse unha notificación ó teu dispositivo." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Enviouse unha notificación ó teu dispositivo" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Por favor asegúrate de que a sesión está aberta e a frase de pegada dixital coincide ca do outro dispositivo" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Serás notificado unha vez se aprobe a solicitude" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Precisas doutro método?" }, "loginInitiated": { - "message": "Login initiated" + "message": "Inicio de sesión comezado" }, "exposedMasterPassword": { - "message": "Exposed Master Password" + "message": "Contrasinal mestre filtrado" }, "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": "Contrasinal atopado nunha filtración de datos. Emprega un contrasinal único para a túa conta. Seguro que queres utilizar un contrasinal filtrado?" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "Contrasinal mestre filtrado e feble" }, "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": "Contrasinal feble e atopado nunha filtración de datos. Emprega un contrasinal forte e único para a túa conta. Seguro que queres utilizar este contrasinal?" }, "checkForBreaches": { - "message": "Check known data breaches for this password" + "message": "Comprobar este contrasinal en filtracións de datos coñecidas" }, "important": { - "message": "Important:" + "message": "Importante:" }, "masterPasswordHint": { - "message": "Your master password cannot be recovered if you forget it!" + "message": "O contrasinal mestre non pode ser recuperado se o esqueces!" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "Mínimo $LENGTH$ caracteres", "placeholders": { "length": { "content": "$1", @@ -3229,13 +3122,13 @@ } }, "autofillPageLoadPolicyActivated": { - "message": "Your organization policies have turned on autofill on page load." + "message": "As directivas da organización activaron o autoenchido ó cargar a páxina." }, "howToAutofill": { - "message": "How to autofill" + "message": "Como autoencher" }, "autofillSelectInfoWithCommand": { - "message": "Select an item from this screen, use the shortcut $COMMAND$, or explore other options in settings.", + "message": "Selecciona unha entrada desta pantalla, emprega o atallo $COMMAND$, ou explora outras opcións en axustes.", "placeholders": { "command": { "content": "$1", @@ -3244,31 +3137,31 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "Selecciona unha entrada desta pantalla ou explora outras opcións en axustes." }, "gotIt": { - "message": "Got it" + "message": "Entendido" }, "autofillSettings": { - "message": "Autofill settings" + "message": "Axustes de autoenchido" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Autofill shortcut" + "message": "Atallo de autoenchido" }, "autofillKeyboardShortcutUpdateLabel": { - "message": "Change shortcut" + "message": "Mudar atallo" }, "autofillKeyboardManagerShortcutsLabel": { - "message": "Manage shortcuts" + "message": "Xestionar atallos" }, "autofillShortcut": { - "message": "Autofill keyboard shortcut" + "message": "Atallo de teclado de autoenchido" }, "autofillLoginShortcutNotSet": { - "message": "The autofill login shortcut is not set. Change this in the browser's settings." + "message": "O atallo de autoenchido de credenciais non está configurado. Cámbiao nos axustes do navegador." }, "autofillLoginShortcutText": { - "message": "The autofill login shortcut is $COMMAND$. Manage all shortcuts in the browser's settings.", + "message": "O atallo de autoenchido de credenciais é $COMMAND$. Xestiona os atallos nos axustes do navegador.", "placeholders": { "command": { "content": "$1", @@ -3277,7 +3170,7 @@ } }, "autofillShortcutTextSafari": { - "message": "Default autofill shortcut: $COMMAND$.", + "message": "Atallo de autoenchido por defecto: $COMMAND$.", "placeholders": { "command": { "content": "$1", @@ -3286,65 +3179,65 @@ } }, "opensInANewWindow": { - "message": "Opens in a new window" + "message": "Abrir nunha ventá nova" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Lembrar este dispositivo para futuros inicios de sesión imperceptibles" }, "deviceApprovalRequired": { - "message": "Device approval required. Select an approval option below:" + "message": "Aprobación de dispositivo requirida. Selecciona unha das seguintes opcións:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Aprobación de dispositivo requirida" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Selecciona unha das seguintes opcións de aprobado" }, "rememberThisDevice": { - "message": "Remember this device" + "message": "Lembrar este dispositivo" }, "uncheckIfPublicDevice": { - "message": "Uncheck if using a public device" + "message": "Desmarcar se se emprega un dispositivo público" }, "approveFromYourOtherDevice": { - "message": "Approve from your other device" + "message": "Aprobar dende o teu outro dispositivo" }, "requestAdminApproval": { - "message": "Request admin approval" + "message": "Solicitar aprobación do administrador" }, "approveWithMasterPassword": { - "message": "Approve with master password" + "message": "Aprobar con contrasinal mestre" }, "ssoIdentifierRequired": { - "message": "Organization SSO identifier is required." + "message": "Identificador SSO da organización requirido." }, "creatingAccountOn": { - "message": "Creating account on" + "message": "Creando conta en" }, "checkYourEmail": { - "message": "Check your email" + "message": "Revisa o teu correo" }, "followTheLinkInTheEmailSentTo": { - "message": "Follow the link in the email sent to" + "message": "Segue o enlace no correo enviado a" }, "andContinueCreatingYourAccount": { - "message": "and continue creating your account." + "message": "e continúa ca creación da conta." }, "noEmail": { - "message": "No email?" + "message": "Sen correo?" }, "goBack": { - "message": "Go back" + "message": "Volver atrás" }, "toEditYourEmailAddress": { - "message": "to edit your email address." + "message": "para modificar o teu enderezo electrónico." }, "eu": { "message": "UE", "description": "European Union" }, "accessDenied": { - "message": "Access denied. You do not have permission to view this page." + "message": "Acceso denegado. Non tes permiso para ver esta páxina." }, "general": { "message": "Xeral" @@ -3353,51 +3246,51 @@ "message": "Amosar" }, "accountSuccessfullyCreated": { - "message": "Account successfully created!" + "message": "Conta creada con éxito!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "Aprobación do administrador solicitada" }, "adminApprovalRequestSentToAdmins": { - "message": "Your request has been sent to your admin." + "message": "A solicitude foi enviada ó teu administrador." }, "youWillBeNotifiedOnceApproved": { - "message": "You will be notified once approved." + "message": "Serás notificado cando se aprobe." }, "troubleLoggingIn": { - "message": "Trouble logging in?" + "message": "Problemas ao iniciar sesión?" }, "loginApproved": { - "message": "Login approved" + "message": "Inicio de sesión aprobado" }, "userEmailMissing": { - "message": "User email missing" + "message": "Falta o correo electrónico" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Correo electrónico usuario activo non atopado. Cerrando a sesión." }, "deviceTrusted": { - "message": "Device trusted" + "message": "Dispositivo de confianza" }, "sendsNoItemsTitle": { - "message": "No active Sends", + "message": "Sen Sends activos", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendsNoItemsMessage": { - "message": "Use Send to securely share encrypted information with anyone.", + "message": "Usar send para compartir información cifrada con quen queiras.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "inputRequired": { - "message": "Input is required." + "message": "Requírese algunha entrada." }, "required": { - "message": "required" + "message": "requirido" }, "search": { - "message": "Search" + "message": "Busca" }, "inputMinLength": { - "message": "Input must be at least $COUNT$ characters long.", + "message": "A entrada debe ser de polo menos $COUNT$ caracteres.", "placeholders": { "count": { "content": "$1", @@ -3406,7 +3299,7 @@ } }, "inputMaxLength": { - "message": "Input must not exceed $COUNT$ characters in length.", + "message": "A entrada debe ser de máximo $COUNT$ caracteres.", "placeholders": { "count": { "content": "$1", @@ -3415,7 +3308,7 @@ } }, "inputForbiddenCharacters": { - "message": "The following characters are not allowed: $CHARACTERS$", + "message": "Os seguintes caracteres non están permitidos: $CHARACTERS$", "placeholders": { "characters": { "content": "$1", @@ -3424,7 +3317,7 @@ } }, "inputMinValue": { - "message": "Input value must be at least $MIN$.", + "message": "O valor de entrada debe ser de mínimo $MIN$.", "placeholders": { "min": { "content": "$1", @@ -3433,7 +3326,7 @@ } }, "inputMaxValue": { - "message": "Input value must not exceed $MAX$.", + "message": "O valor de entrada nun debe exceder $MAX$.", "placeholders": { "max": { "content": "$1", @@ -3442,17 +3335,17 @@ } }, "multipleInputEmails": { - "message": "1 or more emails are invalid" + "message": "1 ou máis correos son inválidos" }, "inputTrimValidator": { - "message": "Input must not contain only whitespace.", + "message": "A entrada non debe conter só espazos en branco.", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "Input is not an email address." + "message": "A entrada non é un enderezo de correo." }, "fieldsNeedAttention": { - "message": "$COUNT$ field(s) above need your attention.", + "message": "$COUNT$ campo(s) máis arriba precisan revisión.", "placeholders": { "count": { "content": "$1", @@ -3461,10 +3354,10 @@ } }, "singleFieldNeedsAttention": { - "message": "1 field needs your attention." + "message": "Un campo precisa revisión." }, "multipleFieldsNeedAttention": { - "message": "$COUNT$ fields need your attention.", + "message": "$COUNT$ campos precisan revisión.", "placeholders": { "count": { "content": "$1", @@ -3473,22 +3366,22 @@ } }, "selectPlaceholder": { - "message": "-- Select --" + "message": "-- Seleccionar --" }, "multiSelectPlaceholder": { - "message": "-- Type to filter --" + "message": "-- Escribir para filtrar --" }, "multiSelectLoading": { - "message": "Retrieving options..." + "message": "Cargando opcións..." }, "multiSelectNotFound": { - "message": "No items found" + "message": "Non se atoparon entradas" }, "multiSelectClearAll": { - "message": "Clear all" + "message": "Quitar seleccións" }, "plusNMore": { - "message": "+ $QUANTITY$ more", + "message": "+ $QUANTITY$ máis", "placeholders": { "quantity": { "content": "$1", @@ -3497,176 +3390,176 @@ } }, "submenu": { - "message": "Submenu" + "message": "Submenú" }, "toggleCollapse": { - "message": "Toggle collapse", + "message": "Colapsar/Expandir", "description": "Toggling an expand/collapse state." }, "filelessImport": { - "message": "Import your data to Bitwarden?", + "message": "Importar os teus datos a Bitwarden?", "description": "Default notification title for triggering a fileless import." }, "lpFilelessImport": { - "message": "Protect your LastPass data and import to Bitwarden?", + "message": "Protexer os teus datos de LastPass e importar a Bitwarden?", "description": "LastPass specific notification title for triggering a fileless import." }, "lpCancelFilelessImport": { - "message": "Save as unencrypted file", + "message": "Gardar como arquivo sen cifrar", "description": "LastPass specific notification button text for cancelling a fileless import." }, "startFilelessImport": { - "message": "Import to Bitwarden", + "message": "Importar a Bitwarden", "description": "Notification button text for starting a fileless import." }, "importing": { - "message": "Importing...", + "message": "Importando...", "description": "Notification message for when an import is in progress." }, "dataSuccessfullyImported": { - "message": "Data successfully imported!", + "message": "Datos importados con éxito!", "description": "Notification message for when an import has completed successfully." }, "dataImportFailed": { - "message": "Error importing. Check console for details.", + "message": "Erro importando. Comproba a consola para máis detalle.", "description": "Notification message for when an import has failed." }, "importNetworkError": { - "message": "Network error encountered during import.", + "message": "Aconteceu un erro de rede durante a importación.", "description": "Notification message for when an import has failed due to a network error." }, "aliasDomain": { - "message": "Alias domain" + "message": "Alias do dominio" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Items with master password re-prompt cannot be autofilled on page load. Autofill on page load turned off.", + "message": "As entradas que requiran volver a inserir o contrasinal mestre non poden ser autoenchidas ó cargar a páxina.", "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": "Axuste de autoenchido ó cargar a páxina por defecto.", "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": "Desactiva volver a requirir o contrasinal mestre para modificar este campo", "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": "Activar/desactivar navegación lateral" }, "skipToContent": { - "message": "Skip to content" + "message": "Ir ó contido" }, "bitwardenOverlayButton": { - "message": "Bitwarden autofill menu button", + "message": "Botón do menú de autoenchido", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Toggle Bitwarden autofill menu", + "message": "Des/Activar o menú de autoenchido", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden autofill menu", + "message": "Menú de autoenchido", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { - "message": "Unlock your account to view matching logins", + "message": "Abre a caixa forte para ver as credenciais coincidentes", "description": "Text to display in overlay when the account is locked." }, "unlockYourAccountToViewAutofillSuggestions": { - "message": "Unlock your account to view autofill suggestions", + "message": "Abre a caixa forte para ver as suxestións de autoenchido", "description": "Text to display in overlay when the account is locked." }, "unlockAccount": { - "message": "Unlock account", + "message": "Abrir caixa forte", "description": "Button text to display in overlay when the account is locked." }, "unlockAccountAria": { - "message": "Unlock your account, opens in a new window", + "message": "Abrir caixa forte nunha nova ventá", "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Código de verificación basado en tempo de un uso", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "Tempo para que o TOTP actual venza", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { - "message": "Fill credentials for", + "message": "Encher credenciais para", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { - "message": "Partial username", + "message": "Nome de usuario parcial", "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": "Sen entradas que amosar", "description": "Text to show in overlay if there are no matching items" }, "newItem": { - "message": "New item", + "message": "Nova entrada", "description": "Button text to display in overlay when there are no matching items" }, "addNewVaultItem": { - "message": "Add new vault item", + "message": "Engadir unha nova entrada", "description": "Screen reader text (aria-label) for new item button in overlay" }, "newLogin": { - "message": "New login", + "message": "Nova credencial", "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": "Engadir unha nova credencial nunha nova ventá", "description": "Screen reader text (aria-label) for new login button within inline menu" }, "newCard": { - "message": "New card", + "message": "Nova tarxeta", "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": "Engadir unha nova tarxeta nunha nova ventá", "description": "Screen reader text (aria-label) for new card button within inline menu" }, "newIdentity": { - "message": "New identity", + "message": "Nova identidade", "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": "Engadir unha nova identidade nunha nova ventá", "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": "Menú de autoenchido dispoñible. Pulsa a tecla de frecha abaixo para seleccionar.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { - "message": "Turn on" + "message": "Activar" }, "ignore": { - "message": "Ignore" + "message": "Ignorar" }, "importData": { - "message": "Import data", + "message": "Importar datos", "description": "Used for the header of the import dialog, the import button and within the file-password-prompt" }, "importError": { - "message": "Import error" + "message": "Erro ó importar" }, "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": "Houbo un problema cos datos que intentas importar. Por favor, corrixe os erros listados a continuación e volve intentalo." }, "resolveTheErrorsBelowAndTryAgain": { - "message": "Resolve the errors below and try again." + "message": "Corrixe os erros listados a continuación e volve intentalo." }, "description": { - "message": "Description" + "message": "Descrición" }, "importSuccess": { - "message": "Data successfully imported" + "message": "Datos importados con éxito" }, "importSuccessNumberOfItems": { - "message": "A total of $AMOUNT$ items were imported.", + "message": "Importáronse $AMOUNT$ entradas.", "placeholders": { "amount": { "content": "$1", @@ -3675,46 +3568,46 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Tentar de novo" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Verificación requirida para esta acción. Crea un PIN para continuar." }, "setPin": { - "message": "Set PIN" + "message": "Crear PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Verificar con biometría" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Agardando confirmación" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Non se puido completar a biometría." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Precisas dun método alternativo?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Usar contrasinal mestre" }, "usePin": { - "message": "Use PIN" + "message": "Usar PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Usar biometría" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "Insire o código de verificación enviado ó teu correo." }, "resendCode": { - "message": "Resend code" + "message": "Volver enviar o código" }, "total": { "message": "Total" }, "importWarning": { - "message": "You are importing data to $ORGANIZATION$. Your data may be shared with members of this organization. Do you want to proceed?", + "message": "Estás importando datos a $ORGANIZATION$. Estes datos poden ser compartidos con membros da organización. Queres continuar?", "placeholders": { "organization": { "content": "$1", @@ -3723,49 +3616,49 @@ } }, "duoHealthCheckResultsInNullAuthUrlError": { - "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." + "message": "Erro conectando co servizo de Duo. Usa un método de verificación en 2 pasos alternativo ou contacta con Duo." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Executa Duo e segue os pasos para finalizar o inicio de sesión." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "A túa conta require a verificación en 2 pasos de Duo." }, "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." + "message": "Saca a extensión nunha ventá para continuar." }, "popoutExtension": { - "message": "Popout extension" + "message": "Sacar a extensión" }, "launchDuo": { - "message": "Launch Duo" + "message": "Executar Duo" }, "importFormatError": { - "message": "Data is not formatted correctly. Please check your import file and try again." + "message": "Datos non estruturados correctamente. Por favor comproba o arquivo e téntao de novo." }, "importNothingError": { - "message": "Nothing was imported." + "message": "Nada foi importado." }, "importEncKeyError": { - "message": "Error decrypting the exported file. Your encryption key does not match the encryption key used export the data." + "message": "Erro descifrando o arquivo exportado. A túa clave de cifrado non coincide ca utilizada ó exportar os datos." }, "invalidFilePassword": { - "message": "Invalid file password, please use the password you entered when you created the export file." + "message": "Contrasinal do arquivo inválido. Emprega o contrasinal que creaches cando se exportou o arquivo." }, "destination": { - "message": "Destination" + "message": "Destino" }, "learnAboutImportOptions": { - "message": "Learn about your import options" + "message": "Aprende acerca das opcións de importado" }, "selectImportFolder": { - "message": "Select a folder" + "message": "Seleccionar un cartafol" }, "selectImportCollection": { - "message": "Select a collection" + "message": "Seleccionar unha colección" }, "importTargetHint": { - "message": "Select this option if you want the imported file contents moved to a $DESTINATION$", + "message": "Selecciona esta opción se queres que o contido importado se mova a $DESTINATION$", "description": "Located as a hint under the import target. Will be appended by either folder or collection, depending if the user is importing into an individual or an organizational vault.", "placeholders": { "destination": { @@ -3775,25 +3668,25 @@ } }, "importUnassignedItemsError": { - "message": "File contains unassigned items." + "message": "O arquivo contén entradas sen asignar." }, "selectFormat": { - "message": "Select the format of the import file" + "message": "Selecciona o formato do arquivo de importado" }, "selectImportFile": { - "message": "Select the import file" + "message": "Selecciona o arquivo de importado" }, "chooseFile": { - "message": "Choose File" + "message": "Seleccionar arquivo" }, "noFileChosen": { - "message": "No file chosen" + "message": "Ningún arquivo escollido" }, "orCopyPasteFileContents": { - "message": "or copy/paste the import file contents" + "message": "ou copia/pega o contido do arquivo de importado" }, "instructionsFor": { - "message": "$NAME$ Instructions", + "message": "Instrucións para $NAME$", "description": "The title for the import tool instructions.", "placeholders": { "name": { @@ -3803,200 +3696,200 @@ } }, "confirmVaultImport": { - "message": "Confirm vault import" + "message": "Confirmar o importado da caixa forte" }, "confirmVaultImportDesc": { - "message": "This file is password-protected. Please enter the file password to import data." + "message": "Este arquivo está protexido. Insire o contrasinal para importar os datos." }, "confirmFilePassword": { - "message": "Confirm file password" + "message": "Repetir contrasinal do arquivo" }, "exportSuccess": { - "message": "Vault data exported" + "message": "Caixa forte exportada" }, "typePasskey": { - "message": "Passkey" + "message": "Clave de acceso" }, "accessing": { - "message": "Accessing" + "message": "Accedendo" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Sesión iniciada!" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "A Clave de acceso non se vai copiar" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "A Clave de acceso non se incluirá na entrada clonada. Queres continuar co duplicado?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { - "message": "Verification required by the initiating site. This feature is not yet implemented for accounts without master password." + "message": "Verificación requirida polo sitio inicial. Esta función aínda non está implementada para contas sen contrasinal mestre." }, "logInWithPasskeyQuestion": { - "message": "Log in with passkey?" + "message": "Iniciar sesión con Clave de acceso?" }, "passkeyAlreadyExists": { - "message": "A passkey already exists for this application." + "message": "Xa existe unha Clave de acceso para esta aplicación." }, "noPasskeysFoundForThisApplication": { - "message": "No passkeys found for this application." + "message": "Non se atoparon Claves de acceso para esta aplicación." }, "noMatchingPasskeyLogin": { - "message": "You do not have a matching login for this site." + "message": "Non tes Claves de acceso coincidentes para este sitio." }, "noMatchingLoginsForSite": { - "message": "No matching logins for this site" + "message": "Non tes credenciais coincidentes para este sitio" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "Busca ou garda a Clave de acceso como nova credencial" }, "confirm": { - "message": "Confirm" + "message": "Confirmar" }, "savePasskey": { - "message": "Save passkey" + "message": "Gardar Clave de acceso" }, "savePasskeyNewLogin": { - "message": "Save passkey as new login" + "message": "Gardar Clave de acceso como nova credencial" }, "chooseCipherForPasskeySave": { - "message": "Choose a login to save this passkey to" + "message": "Escolle unha credencial na que gardar esta Clave de acceso" }, "chooseCipherForPasskeyAuth": { - "message": "Choose a passkey to log in with" + "message": "Escolle unha Clave de acceso ca que iniciar sesión" }, "passkeyItem": { - "message": "Passkey Item" + "message": "Entrada de Clave de acceso" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "Sobrescribir Clave de acceso?" }, "overwritePasskeyAlert": { - "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + "message": "Esta entrada xa contén unha Clave de acceso. Seguro que queres sobreescribir a existente?" }, "featureNotSupported": { - "message": "Feature not yet supported" + "message": "Función aínda non implementada" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "message": "A autenticación require unha Clave de acceso. Verifica a túa identidade para continuar." }, "multifactorAuthenticationCancelled": { - "message": "Multifactor authentication cancelled" + "message": "Autenticación multifactor cancelada" }, "noLastPassDataFound": { - "message": "No LastPass data found" + "message": "Non se atoparon datos de LastPass" }, "incorrectUsernameOrPassword": { - "message": "Incorrect username or password" + "message": "Nome de usuario ou contrasinal incorrectos" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Contrasinal incorrecto" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Código incorrecto" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "PIN incorrecto" }, "multifactorAuthenticationFailed": { - "message": "Multifactor authentication failed" + "message": "Autenticación multifactor fallida" }, "includeSharedFolders": { - "message": "Include shared folders" + "message": "Incluír cartafois compartidos" }, "lastPassEmail": { - "message": "LastPass Email" + "message": "Correo de LastPass" }, "importingYourAccount": { - "message": "Importing your account..." + "message": "Importar a túa conta..." }, "lastPassMFARequired": { - "message": "LastPass multifactor authentication required" + "message": "Autenticación multifactor de LastPass requirida" }, "lastPassMFADesc": { - "message": "Enter your one-time passcode from your authentication app" + "message": "Insire o código de un uso da túa app de autenticación" }, "lastPassOOBDesc": { - "message": "Approve the login request in your authentication app or enter a one-time passcode." + "message": "Aproba a petición de inicio de sesión na túa app de autenticación ou insire o código dun uso." }, "passcode": { - "message": "Passcode" + "message": "Código de acceso" }, "lastPassMasterPassword": { - "message": "LastPass master password" + "message": "Contrasinal mestre de LastPass" }, "lastPassAuthRequired": { - "message": "LastPass authentication required" + "message": "Autenticación de LastPass requirida" }, "awaitingSSO": { - "message": "Awaiting SSO authentication" + "message": "Agardando pola autenticación SSO" }, "awaitingSSODesc": { - "message": "Please continue to log in using your company credentials." + "message": "Por favor, continúa empregando as credenciais da túa compañía." }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "Ver instrucións detalladas no noso sitio de axuda en", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { - "message": "Import directly from LastPass" + "message": "Importar directamente de LastPass" }, "importFromCSV": { - "message": "Import from CSV" + "message": "Importar dun CSV" }, "lastPassTryAgainCheckEmail": { - "message": "Try again or look for an email from LastPass to verify it's you." + "message": "Volver intentar ou buscar un correo de LastPass para verificar que es ti." }, "collection": { - "message": "Collection" + "message": "Colección" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "Conecta a YubiKey asociada á túa conta de LastPass, e preme o seu botón." }, "switchAccount": { - "message": "Switch account" + "message": "Cambiar de conta" }, "switchAccounts": { - "message": "Switch accounts" + "message": "Cambiar as contas" }, "switchToAccount": { - "message": "Switch to account" + "message": "Cambiar a conta" }, "activeAccount": { - "message": "Active account" + "message": "Activar conta" }, "availableAccounts": { - "message": "Available accounts" + "message": "Contas dispoñibles" }, "accountLimitReached": { - "message": "Account limit reached. Log out of an account to add another." + "message": "Límite de contas alcanzado. Cerra sesión nunha delas para engadir outra." }, "active": { - "message": "active" + "message": "activo/a" }, "locked": { - "message": "locked" + "message": "bloqueado" }, "unlocked": { - "message": "unlocked" + "message": "desbloqueado" }, "server": { - "message": "server" + "message": "servidor" }, "hostedAt": { - "message": "hosted at" + "message": "aloxado en" }, "useDeviceOrHardwareKey": { - "message": "Use your device or hardware key" + "message": "Usa o teu dispositivo ou chave de hardware" }, "justOnce": { - "message": "Just once" + "message": "Só unha vez" }, "alwaysForThisSite": { - "message": "Always for this site" + "message": "Sempre para este sitio" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "$DOMAIN$ engadido ós dominios excluídos.", "placeholders": { "domain": { "content": "$1", @@ -4005,103 +3898,103 @@ } }, "commonImportFormats": { - "message": "Common formats", + "message": "Formatos comúns", "description": "Label indicating the most common import formats" }, "confirmContinueToBrowserSettingsTitle": { - "message": "Continue to browser settings?", + "message": "Ir ós axustes do navegador?", "description": "Title for dialog which asks if the user wants to proceed to a relevant browser settings page" }, "confirmContinueToHelpCenter": { - "message": "Continue to Help Center?", + "message": "Ir ó Centro de Axuda?", "description": "Title for dialog which asks if the user wants to proceed to a relevant Help Center page" }, "confirmContinueToHelpCenterPasswordManagementContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "Cambiar os axustes de autoenchido e xestión de contrasinais do navegador.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser password management settings" }, "confirmContinueToHelpCenterKeyboardShortcutsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "Podes ver e crear atallos da extensión nos axustes do teu navegador.", "description": "Body content for dialog which asks if the user wants to proceed to the Help Center's page about browser keyboard shortcut settings" }, "confirmContinueToBrowserPasswordManagementSettingsContent": { - "message": "Change your browser's autofill and password management settings.", + "message": "Cambiar os axustes de autoenchido e xestión de contrasinais do navegador.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's password management settings page" }, "confirmContinueToBrowserKeyboardShortcutSettingsContent": { - "message": "You can view and set extension shortcuts in your browser's settings.", + "message": "Podes ver e crear atallos da extensión nos axustes do teu navegador.", "description": "Body content for dialog which asks if the user wants to proceed to the browser's keyboard shortcut settings page" }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "Facer de Bitwarden o teu xestor de contrasinais por defecto?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between Bitwarden autofill suggestions and your browser's.", + "message": "Ignorar esta opción pode causar conflitos entre Bitwarden e o xestor de contrasinais do teu navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "Facer de Bitwarden o teu xestor de contrasinais por defecto", "description": "Label for the setting that allows overriding the default browser autofill settings" }, "privacyPermissionAdditionNotGrantedTitle": { - "message": "Unable to set Bitwarden as the default password manager", + "message": "Non se puido facer de Bitwarden o xestor de contrasinais por defecto", "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { - "message": "You must grant browser privacy permissions to Bitwarden to set it as the default password manager.", + "message": "Debes conceder ó navegador permisos de privacidade sobre Bitwarden para facelo o xestor de contrasinais por defecto.", "description": "Description for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "makeDefault": { - "message": "Make default", + "message": "Facer o predefinido", "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "Credenciais gardadas con éxito!", "description": "Notification message for when saving credentials has succeeded." }, "passwordSaved": { - "message": "Password saved!", + "message": "Contrasinal gardado!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "Credenciais actualizadas con éxito!", "description": "Notification message for when updating credentials has succeeded." }, "passwordUpdated": { - "message": "Password updated!", + "message": "Contrasinal actualizado!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "Erro ó gardar as credenciais. Comproba a consola para máis detalle.", "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "Éxito" }, "removePasskey": { - "message": "Remove passkey" + "message": "Eliminar Clave de acceso" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Clave de acceso eliminada" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "Suxestións de autoenchido" }, "autofillSuggestionsTip": { - "message": "Save a login item for this site to autofill" + "message": "Gardar unha credencial como suxestión para este sitio" }, "yourVaultIsEmpty": { - "message": "Your vault is empty" + "message": "A caixa forte está baleira" }, "noItemsMatchSearch": { - "message": "No items match your search" + "message": "Non hai entradas que coincidan ca túa busca" }, "clearFiltersOrTryAnother": { - "message": "Clear filters or try another search term" + "message": "Quitar filtros e tentar outro termo de busca" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Copiar información - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -4111,7 +4004,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Copiar nota - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -4121,7 +4014,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Máis opcións, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4131,7 +4024,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Máis opcións - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4141,7 +4034,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Ver entrada - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4151,7 +4044,7 @@ } }, "autofillTitle": { - "message": "Autofill - $ITEMNAME$", + "message": "Autoenchido - $ITEMNAME$", "description": "Title for a button that autofills a login item.", "placeholders": { "itemname": { @@ -4161,40 +4054,40 @@ } }, "noValuesToCopy": { - "message": "No values to copy" + "message": "Non hai valores que copiar" }, "assignToCollections": { - "message": "Assign to collections" + "message": "Vincular con coleccións" }, "copyEmail": { - "message": "Copy email" + "message": "Copiar correo" }, "copyPhone": { - "message": "Copy phone" + "message": "Copiar teléfono" }, "copyAddress": { - "message": "Copy address" + "message": "Copiar enderezo" }, "adminConsole": { - "message": "Admin Console" + "message": "Consola do administrador" }, "accountSecurity": { - "message": "Account security" + "message": "Seguridade da conta" }, "notifications": { - "message": "Notifications" + "message": "Notificacións" }, "appearance": { - "message": "Appearance" + "message": "Aparencia" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Erro ó vincular esta colección." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Erro ó vincular este cartafol." }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Ver entradas en $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -4204,7 +4097,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Volver a $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -4214,10 +4107,10 @@ } }, "new": { - "message": "New" + "message": "Novo" }, "removeItem": { - "message": "Remove $NAME$", + "message": "Eliminar $NAME$", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -4227,16 +4120,16 @@ } }, "itemsWithNoFolder": { - "message": "Items with no folder" + "message": "Entradas sen carpeta" }, "itemDetails": { - "message": "Item details" + "message": "Detalles do entrada" }, "itemName": { - "message": "Item name" + "message": "Nome da entrada" }, "cannotRemoveViewOnlyCollections": { - "message": "You cannot remove collections with View only permissions: $COLLECTIONS$", + "message": "Non podes eliminar coleccións con permisos de Só lectura: $COLLECTIONS$", "placeholders": { "collections": { "content": "$1", @@ -4245,47 +4138,47 @@ } }, "organizationIsDeactivated": { - "message": "Organization is deactivated" + "message": "A organización está desactivada" }, "owner": { - "message": "Owner" + "message": "Propietario" }, "selfOwnershipLabel": { - "message": "You", + "message": "Ti", "description": "Used as a label to indicate that the user is the owner of an item." }, "contactYourOrgAdmin": { - "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance." + "message": "As entradas en organizacións suspendidas son inaccesibles. Contacta co propietario da organización para asistencia." }, "additionalInformation": { - "message": "Additional information" + "message": "Información adicional" }, "itemHistory": { - "message": "Item history" + "message": "Historial da entrada" }, "lastEdited": { - "message": "Last edited" + "message": "Modificado o" }, "ownerYou": { - "message": "Owner: You" + "message": "Propietario: Ti" }, "linked": { - "message": "Linked" + "message": "Vinculado" }, "copySuccessful": { - "message": "Copy Successful" + "message": "Copiado realizado" }, "upload": { - "message": "Upload" + "message": "Subir" }, "addAttachment": { - "message": "Add attachment" + "message": "Anexar arquivo" }, "maxFileSizeSansPunctuation": { - "message": "Maximum file size is 500 MB" + "message": "O tamaño máximo é de 500 MB" }, "deleteAttachmentName": { - "message": "Delete attachment $NAME$", + "message": "Eliminar anexos $NAME$", "placeholders": { "name": { "content": "$1", @@ -4294,7 +4187,7 @@ } }, "downloadAttachmentName": { - "message": "Download $NAME$", + "message": "Descargar $NAME$", "placeholders": { "name": { "content": "$1", @@ -4303,25 +4196,25 @@ } }, "permanentlyDeleteAttachmentConfirmation": { - "message": "Are you sure you want to permanently delete this attachment?" + "message": "Estás seguro de que queres eliminar permanentemente este anexo?" }, "premium": { - "message": "Premium" + "message": "Prémium" }, "freeOrgsCannotUseAttachments": { - "message": "Free organizations cannot use attachments" + "message": "As organizacións gratuitas non poden empregar anexos" }, "filters": { - "message": "Filters" + "message": "Filtros" }, "filterVault": { - "message": "Filter vault" + "message": "Filtros da caixa forte" }, "filterApplied": { - "message": "One filter applied" + "message": "Un filtro en uso" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "$COUNT$ filtros en uso", "placeholders": { "count": { "content": "$1", @@ -4330,16 +4223,16 @@ } }, "personalDetails": { - "message": "Personal details" + "message": "Detalles persoais" }, "identification": { - "message": "Identification" + "message": "Identificación" }, "contactInfo": { - "message": "Contact info" + "message": "Información de contacto" }, "downloadAttachment": { - "message": "Download - $ITEMNAME$", + "message": "Descargar - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -4348,23 +4241,23 @@ } }, "cardNumberEndsWith": { - "message": "card number ends with", + "message": "o número de tarxeta remata en", "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Login credentials" + "message": "Credenciais de inicio de sesión" }, "authenticatorKey": { - "message": "Authenticator key" + "message": "Clave de autenticación" }, "autofillOptions": { - "message": "Autofill options" + "message": "Opcións de autoenchido" }, "websiteUri": { - "message": "Website (URI)" + "message": "Dirección web (URI)" }, "websiteUriCount": { - "message": "Website (URI) $COUNT$", + "message": "Dirección web (URI) $COUNT$", "description": "Label for an input field that contains a website URI. The input field is part of a list of fields, and the count indicates the position of the field in the list.", "placeholders": { "count": { @@ -4374,16 +4267,16 @@ } }, "websiteAdded": { - "message": "Website added" + "message": "Dirección web engadida" }, "addWebsite": { - "message": "Add website" + "message": "Engadir dirección web" }, "deleteWebsite": { - "message": "Delete website" + "message": "Eliminar dirección web" }, "defaultLabel": { - "message": "Default ($VALUE$)", + "message": "Predeterminado ($VALUE$)", "description": "A label that indicates the default value for a field with the current default value in parentheses.", "placeholders": { "value": { @@ -4393,7 +4286,7 @@ } }, "showMatchDetection": { - "message": "Show match detection $WEBSITE$", + "message": "Mostrar detección de coincidencia $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4402,7 +4295,7 @@ } }, "hideMatchDetection": { - "message": "Hide match detection $WEBSITE$", + "message": "Agochar detección de coincidencia $WEBSITE$", "placeholders": { "website": { "content": "$1", @@ -4411,19 +4304,19 @@ } }, "autoFillOnPageLoad": { - "message": "Autofill on page load?" + "message": "Autoencher ó cargar a páxina?" }, "cardExpiredTitle": { - "message": "Expired card" + "message": "Tarxeta vencida" }, "cardExpiredMessage": { - "message": "If you've renewed it, update the card's information" + "message": "Se a renovas, actualiza a información da tarxeta" }, "cardDetails": { - "message": "Card details" + "message": "Detalles da tarxeta" }, "cardBrandDetails": { - "message": "$BRAND$ details", + "message": "Detalles da $BRAND$", "placeholders": { "brand": { "content": "$1", @@ -4432,43 +4325,43 @@ } }, "enableAnimations": { - "message": "Enable animations" + "message": "Activar animacións" }, "showAnimations": { - "message": "Show animations" + "message": "Amosar animacións" }, "addAccount": { - "message": "Add account" + "message": "Engadir conta" }, "loading": { - "message": "Loading" + "message": "Cargando" }, "data": { - "message": "Data" + "message": "Datos" }, "passkeys": { - "message": "Passkeys", + "message": "Claves de acceso", "description": "A section header for a list of passkeys." }, "passwords": { - "message": "Passwords", + "message": "Contrasinais", "description": "A section header for a list of passwords." }, "logInWithPasskeyAriaLabel": { - "message": "Log in with passkey", + "message": "Iniciar sesión con Clave de acceso", "description": "ARIA label for the inline menu button that logs in with a passkey." }, "assign": { - "message": "Assign" + "message": "Asignar" }, "bulkCollectionAssignmentDialogDescriptionSingular": { - "message": "Only organization members with access to these collections will be able to see the item." + "message": "Só os membros da organización con acceso a estas coleccións poderán ver esta entrada." }, "bulkCollectionAssignmentDialogDescriptionPlural": { - "message": "Only organization members with access to these collections will be able to see the items." + "message": "Só os membros da organización con acceso a estas coleccións poderán ver estas entradas." }, "bulkCollectionAssignmentWarning": { - "message": "You have selected $TOTAL_COUNT$ items. You cannot update $READONLY_COUNT$ of the items because you do not have edit permissions.", + "message": "Seleccionaches $TOTAL_COUNT$ entradas. Non vas poder modificar $READONLY_COUNT$ delas porque non tes permisos de edición.", "placeholders": { "total_count": { "content": "$1", @@ -4480,37 +4373,37 @@ } }, "addField": { - "message": "Add field" + "message": "Engadir un campo" }, "add": { - "message": "Add" + "message": "Engadir" }, "fieldType": { - "message": "Field type" + "message": "Tipo de campo" }, "fieldLabel": { - "message": "Field label" + "message": "Título do campo" }, "textHelpText": { - "message": "Use text fields for data like security questions" + "message": "Emprega campos de texto para datos como preguntas de seguridade" }, "hiddenHelpText": { - "message": "Use hidden fields for sensitive data like a password" + "message": "Emprega campos agochados para datos sensibles como contrasinais" }, "checkBoxHelpText": { - "message": "Use checkboxes if you'd like to autofill a form's checkbox, like a remember email" + "message": "Emprega caixas de verificación cando queiras autoencher as dun formulario, como \"Lembrar correo\"" }, "linkedHelpText": { - "message": "Use a linked field when you are experiencing autofill issues for a specific website." + "message": "Emprega un campo vinculado cando teñas problemas coa autoenchido dalgunha web." }, "linkedLabelHelpText": { - "message": "Enter the the field's html id, name, aria-label, or placeholder." + "message": "Insire o ID HTML, nome, aria-label ou exemplo foi campo." }, "editField": { - "message": "Edit field" + "message": "Modificar campo" }, "editFieldLabel": { - "message": "Edit $LABEL$", + "message": "Modificar $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4519,7 +4412,7 @@ } }, "deleteCustomField": { - "message": "Delete $LABEL$", + "message": "Eliminar $LABEL$", "placeholders": { "label": { "content": "$1", @@ -4528,7 +4421,7 @@ } }, "fieldAdded": { - "message": "$LABEL$ added", + "message": "$LABEL$ engadido", "placeholders": { "label": { "content": "$1", @@ -4537,7 +4430,7 @@ } }, "reorderToggleButton": { - "message": "Reorder $LABEL$. Use arrow key to move item up or down.", + "message": "Recolocar $LABEL$. Emprega as frechas do teclado.", "placeholders": { "label": { "content": "$1", @@ -4546,7 +4439,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "Subiuse $LABEL$ á posición $INDEX$ de $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4563,13 +4456,13 @@ } }, "selectCollectionsToAssign": { - "message": "Select collections to assign" + "message": "Seleccionar coleccións a vincular" }, "personalItemTransferWarningSingular": { - "message": "1 item will be permanently transferred to the selected organization. You will no longer own this item." + "message": "Unha entrada será irreversiblemente transferida á organización. Xa non serás o seu propietario." }, "personalItemsTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to the selected organization. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ entradas serán irreversiblemente transferidas á organización. Xa non serás o seu propietario.", "placeholders": { "personal_items_count": { "content": "$1", @@ -4578,7 +4471,7 @@ } }, "personalItemWithOrgTransferWarningSingular": { - "message": "1 item will be permanently transferred to $ORG$. You will no longer own this item.", + "message": "Unha entrada será irreversiblemente transferida a $ORG$. Xa non serás o seu propietario.", "placeholders": { "org": { "content": "$1", @@ -4587,7 +4480,7 @@ } }, "personalItemsWithOrgTransferWarningPlural": { - "message": "$PERSONAL_ITEMS_COUNT$ items will be permanently transferred to $ORG$. You will no longer own these items.", + "message": "$PERSONAL_ITEMS_COUNT$ entradas serán irreversiblemente transferidas a $ORG$. Xa non serás o seu propietario.", "placeholders": { "personal_items_count": { "content": "$1", @@ -4600,13 +4493,13 @@ } }, "successfullyAssignedCollections": { - "message": "Successfully assigned collections" + "message": "Coleccións vinculadas" }, "nothingSelected": { - "message": "You have not selected anything." + "message": "Non tes nada seleccionado." }, "movedItemsToOrg": { - "message": "Selected items moved to $ORGNAME$", + "message": "Entradas seleccionadas transferidas a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4615,7 +4508,7 @@ } }, "itemsMovedToOrg": { - "message": "Items moved to $ORGNAME$", + "message": "Entradas transferidas a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4624,7 +4517,7 @@ } }, "itemMovedToOrg": { - "message": "Item moved to $ORGNAME$", + "message": "Entrada transferida a $ORGNAME$", "placeholders": { "orgname": { "content": "$1", @@ -4633,7 +4526,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "Baixouse $LABEL$ á posición $INDEX$ de $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4650,52 +4543,52 @@ } }, "itemLocation": { - "message": "Item Location" + "message": "Ubicación da entrada" }, "fileSend": { - "message": "File Send" + "message": "Arquivo Send" }, "fileSends": { - "message": "File Sends" + "message": "Arquivos Send" }, "textSend": { - "message": "Text Send" + "message": "Texto Send" }, "textSends": { - "message": "Text Sends" + "message": "Textos Send" }, "bitwardenNewLook": { - "message": "Bitwarden has a new look!" + "message": "Bitwarden ten un novo look!" }, "bitwardenNewLookDesc": { - "message": "It's easier and more intuitive than ever to autofill and search from the Vault tab. Take a look around!" + "message": "É máis fácil e intuitivo que nunca autoencher e buscar dende a caixa forte. Bota un ollo!" }, "accountActions": { - "message": "Account actions" + "message": "Accións da conta" }, "showNumberOfAutofillSuggestions": { - "message": "Show number of login autofill suggestions on extension icon" + "message": "Amosar o número de suxestións de credenciais na icona da extensión" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Amosar accións rápidas de copiado na caixa forte" }, "systemDefault": { - "message": "System default" + "message": "Predefinido do sistema" }, "enterprisePolicyRequirementsApplied": { - "message": "Enterprise policy requirements have been applied to this setting" + "message": "Directivas da empresa foron aplicadas a esta opción" }, "sshPrivateKey": { - "message": "Private key" + "message": "Clave privada" }, "sshPublicKey": { - "message": "Public key" + "message": "Clave pública" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Pegada dixital" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Tipo de clave" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -4710,223 +4603,223 @@ "message": "RSA 4096-Bit" }, "retry": { - "message": "Retry" + "message": "Reintentar" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "O tempo mínimo personalizado é de 1 minuto." }, "additionalContentAvailable": { - "message": "Additional content is available" + "message": "Hai dispoñibles contidos adicionais" }, "fileSavedToDevice": { - "message": "File saved to device. Manage from your device downloads." + "message": "Arquivo gardado no dispositivo. Xestiónao dende as descargas do dispositivo." }, "showCharacterCount": { - "message": "Show character count" + "message": "Amosar contador de caracteres" }, "hideCharacterCount": { - "message": "Hide character count" + "message": "Ocultar contador de caracteres" }, "itemsInTrash": { - "message": "Items in trash" + "message": "Entradas no lixo" }, "noItemsInTrash": { - "message": "No items in trash" + "message": "Sen entradas no lixo" }, "noItemsInTrashDesc": { - "message": "Items you delete will appear here and be permanently deleted after 30 days" + "message": "As entradas que elimines aparecerán aquí serán permanente eliminadas despois de 30 días" }, "trashWarning": { - "message": "Items that have been in trash more than 30 days will automatically be deleted" + "message": "As entradas que estean no lixo máis de 30 días serán automaticamente eliminadas" }, "restore": { - "message": "Restore" + "message": "Restaurar" }, "deleteForever": { - "message": "Delete forever" + "message": "Eliminar permanentemente" }, "noEditPermissions": { - "message": "You don't have permission to edit this item" + "message": "Non tes permiso para modificar esta entrada" }, "authenticating": { - "message": "Authenticating" + "message": "Autenticando" }, "fillGeneratedPassword": { - "message": "Fill generated password", + "message": "Encher co contrasinal xerado", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "Contrasinal xerado de novo", "description": "Notification message for when a password has been regenerated" }, "saveLoginToBitwarden": { - "message": "Save login to Bitwarden?", + "message": "Gardar credenciais en Bitwarden?", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "Espazo", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { - "message": "Tilde", + "message": "Til", "description": "Represents the ~ key in screen reader content as a readable word" }, "backtickCharacterDescriptor": { - "message": "Backtick", + "message": "Plica", "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "Exclamación", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { - "message": "At sign", + "message": "Arroba", "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "Símbolo de almohadilla", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { - "message": "Dollar sign", + "message": "Símbolo do dólar", "description": "Represents the $ key in screen reader content as a readable word" }, "percentSignCharacterDescriptor": { - "message": "Percent sign", + "message": "Símbolo de porcentaxe", "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "Símbolo circunflexo", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { - "message": "Ampersand", + "message": "Símbolo E comercial", "description": "Represents the & key in screen reader content as a readable word" }, "asteriskCharacterDescriptor": { - "message": "Asterisk", + "message": "Símbolo Asterisco", "description": "Represents the * key in screen reader content as a readable word" }, "parenLeftCharacterDescriptor": { - "message": "Left parenthesis", + "message": "Símbolo abrir paréntese", "description": "Represents the ( key in screen reader content as a readable word" }, "parenRightCharacterDescriptor": { - "message": "Right parenthesis", + "message": "Símbolo pechar paréntese", "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "Símbolo guión baixo", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "Símbolo guión", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { - "message": "Plus", + "message": "Símbolo máis", "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "Símbolo igual", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "Símbolo abrir chave", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "Símbolo pechar chave", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "Símbolo abrir corchete", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "Símbolo pechar corchete", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "Símbolo de liña vertical (pipe)", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "Símbolo de barra invertida", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { - "message": "Colon", + "message": "Símbolo de dous puntos", "description": "Represents the : key in screen reader content as a readable word" }, "semicolonCharacterDescriptor": { - "message": "Semicolon", + "message": "Símbolo de punto e coma", "description": "Represents the ; key in screen reader content as a readable word" }, "doubleQuoteCharacterDescriptor": { - "message": "Double quote", + "message": "Símbolo de dobre comilla", "description": "Represents the double quote key in screen reader content as a readable word" }, "singleQuoteCharacterDescriptor": { - "message": "Single quote", + "message": "Símbolo de comilla simple", "description": "Represents the ' key in screen reader content as a readable word" }, "lessThanCharacterDescriptor": { - "message": "Less than", + "message": "Símbolo de menor que", "description": "Represents the < key in screen reader content as a readable word" }, "greaterThanCharacterDescriptor": { - "message": "Greater than", + "message": "Símbolo de maior que", "description": "Represents the > key in screen reader content as a readable word" }, "commaCharacterDescriptor": { - "message": "Comma", + "message": "Símbolo de coma", "description": "Represents the , key in screen reader content as a readable word" }, "periodCharacterDescriptor": { - "message": "Period", + "message": "Símbolo de punto", "description": "Represents the . key in screen reader content as a readable word" }, "questionCharacterDescriptor": { - "message": "Question mark", + "message": "Símbolo de interrogación", "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "Símbolo de barra inclinada", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { - "message": "Lowercase" + "message": "Minúsculas" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "Maiúsculas" }, "generatedPassword": { - "message": "Generated password" + "message": "Contrasinal xerado" }, "compactMode": { - "message": "Compact mode" + "message": "Modo compacto" }, "beta": { "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Aviso importante" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Configurar verificación en dous pasos" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "A partir de febreiro de 2025 Bitwarden comezará a enviar correos con códigos de verificación para confirmar novos inicios de sesión á túa conta." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Podes configurar a verificación en 2 pasos como alternativa para protexer a túa conta ou cambiar o enderezo electrónico a un ó que teñas acceso." }, "remindMeLater": { - "message": "Remind me later" + "message": "Lembrarmo máis tarde" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Tes acceso fiable ó teu correo? ($EMAIL$)", "placeholders": { "email": { "content": "$1", @@ -4935,24 +4828,24 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Non, non o teño" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Si, teño acceso fiable ó meu correo" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Activar verificación en dous pasos" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Mudar de correo electrónico" }, "extensionWidth": { - "message": "Extension width" + "message": "Ancho da extensión" }, "wide": { - "message": "Wide" + "message": "Ancho" }, "extraWide": { - "message": "Extra wide" + "message": "Moi ancho" } } diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index a069afdc69a..5101c11a653 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -454,9 +454,6 @@ "length": { "message": "אורך" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "מינימום תוים מיוחדים" }, - "avoidAmbChar": { - "message": "המנע מאותיות ותוים דומים", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "נקה לוח העתקות", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "שתף" - }, "movedItemToOrg": { "message": "$ITEMNAME$ הועבר ל- $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "שכפול" }, - "passwordGeneratorPolicyInEffect": { - "message": "מדיניות ארגונית אחת או יותר משפיעה על הגדרות המחולל שלך." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "הקובץ שברצונך לשלוח." - }, "deletionDate": { "message": "תאריך מחיקה" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "תאריך תפוגה" }, - "expirationDateDesc": { - "message": "במידה ויוגדר, הגישה ל Send זה תושבת בתאריך ובשעה שהוגדרו.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "יום אחד" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "מותאם אישית" }, - "maximumAccessCount": { - "message": "כמות גישות מרבית" - }, - "maximumAccessCountDesc": { - "message": "במידה ויוגדר, משתמשים לא יוכלו יותר לגשת ל Send זה לאחר שמספר הגישות המרבי יושג.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "שגיאה" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "סוג שם משתמש" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 288aa1171ce..10ad502be82 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -20,16 +20,16 @@ "message": "Create Account" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "बिटवार्डन का परिचय" }, "logInWithPasskey": { "message": "Log in with passkey" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "सिंगल साइन-ऑन प्रयोग करें" }, "welcomeBack": { - "message": "Welcome back" + "message": "आपका पुन: स्वागत है!" }, "setAStrongPassword": { "message": "मजबूत पासवर्ड सेट करें" @@ -138,10 +138,10 @@ "message": "Copy Security Code" }, "copyName": { - "message": "Copy name" + "message": "नाम कॉपी करें" }, "copyCompany": { - "message": "Copy company" + "message": "कंपनी के नाम को कॉपी करें" }, "copySSN": { "message": "Copy Social Security number" @@ -454,9 +454,6 @@ "length": { "message": "लंबाई" }, - "passwordMinLength": { - "message": "न्यूनतम पासवर्ड लंबाई" - }, "uppercase": { "message": "बड़े अक्षर (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum Special" }, - "avoidAmbChar": { - "message": "Avoid Ambiguous Characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "आसान ऑटो-फिल के लिए टैब पेज पर कार्ड आइटम सूचीबद्ध करें।" }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "क्लिपबोर्ड खाली करें", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "संगठन में ले जाएँ" }, - "share": { - "message": "शेयर करें" - }, "movedItemToOrg": { "message": "$ITEMNAME$ $ORGNAME$ गया ", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "क्लोन" }, - "passwordGeneratorPolicyInEffect": { - "message": "एक या एक से अधिक संगठन नीतियां आपकी जनरेटर सेटिंग को प्रभावित कर रही हैं।" - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Sends मे खोजे", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Send जोड़ें", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "शब्द" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "मैक्स एक्सेस काउंट पहुंच गया है", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": " गतावधिक" }, - "pendingDeletion": { - "message": "हटाना लंबित" - }, "passwordProtected": { "message": "पासवर्ड सुरक्षित है" }, @@ -2472,24 +2447,9 @@ "message": "एडिट Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "यह किस प्रकार का सेंड है?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "इस सेंड का वर्णन करने के लिए एक दोस्ताना नाम।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "वह फाइल जो आप सेंड करना चाहते हैं।" - }, "deletionDate": { "message": "हटाने की तारीख" }, - "deletionDateDesc": { - "message": " यह सेंड निर्धारित तिथि और समय पर स्थायी रूप से हटा दिया जाएगा।", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "समाप्ति तिथि" }, - "expirationDateDesc": { - "message": "यदि सेट किया जाता है, तो यह सेंड निर्दिष्ट तिथि और समय पर समाप्त हो जाएगा।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 दिन" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "कस्टम" }, - "maximumAccessCount": { - "message": "अधिकतम एक्सेस काउंट" - }, - "maximumAccessCountDesc": { - "message": "यदि सेट किया जाता है, तो अधिकतम एक्सेस काउंट तक पहुंचने के बाद उपयोगकर्ता अब इस सेंड को एक्सेस नहीं कर पाएंगे।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "वैकल्पिक रूप से उपयोगकर्ताओं को इस सेंड तक पहुंचने के लिए पासवर्ड की आवश्यकता होगी।", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "इस सेंड के बारे में निजी नोट्स।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "इस सेंड को अक्षम करें ताकि कोई भी इसे एक्सेस न कर सके।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "सेव पर क्लिपबोर्ड पर इस सेंड के लिंक को कॉपी करें।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "वह टेक्स्ट जो आप सेंड करना चाहते हैं।" - }, - "sendHideText": { - "message": "इस सेंड के टेक्स्ट को डिफ़ॉल्ट रूप से छिपाएं।", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "वर्तमान एक्सेस काउंट" - }, "createSend": { "message": "नया सेंड बनाएं", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "शुरू करने से पहले" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "कैलेंडर शैली तिथि बीनने वाले का उपयोग करने के लिए", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "यहां क्लिक करें", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "अपनी विंडो पॉप आउट करने के लिए यहां क्लिक करें।", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "प्रदान की गई समाप्ति तिथि मान्य नहीं है।" }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "आपके विलोपन और समाप्ति तिथियों को सहेजने में एक त्रुटि थी।" }, - "hideEmail": { - "message": "प्राप्तकर्ताओं से मेरा ईमेल पता छिपाएं।" - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "एक या एक से अधिक संगठन नीतियां आपके सेंड विकल्पों को प्रभावित कर रही हैं।" - }, "passwordPrompt": { "message": "मास्टर पासवर्ड रि-प्रॉम्प्ट" }, @@ -2884,9 +2789,6 @@ "error": { "message": "एरर" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "उपयोगकर्ता नाम बनाएँ" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "वेबसाइट का नाम" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, @@ -4911,10 +4804,10 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "महत्वपूर्ण सूचना" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "टू-स्टेप लॉगइन" }, "newDeviceVerificationNoticeContentPage1": { "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." @@ -4923,7 +4816,7 @@ "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." }, "remindMeLater": { - "message": "Remind me later" + "message": "बाद में मुझे याद कराएं" }, "newDeviceVerificationNoticePageOneFormContent": { "message": "Do you have reliable access to your email, $EMAIL$?", @@ -4935,16 +4828,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "नहीं, मैं नहीं" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "हाँ, मैं आराम से अपना ईमेल देख सकता हूँ" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "टू-स्टेप लॉगइन सक्षम करें" }, "changeAcctEmail": { - "message": "Change account email" + "message": "अकाउंट का ईमेल बदलें" }, "extensionWidth": { "message": "Extension width" diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index a8c680ac666..3b60cfe45c8 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Duljina" }, - "passwordMinLength": { - "message": "Minimalna duljina lozinke" - }, "uppercase": { "message": "Velika slova (A - Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Najmanje posebnih" }, - "avoidAmbChar": { - "message": "Izbjegavaj dvosmislene znakove", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Izbjegavaj dvosmislene znakove", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Prikazuj identitete za jednostavnu auto-ispunu." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Očisti međuspremnik", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Premjesti u organizaciju" }, - "share": { - "message": "Podijeli" - }, "movedItemToOrg": { "message": "$ITEMNAME$ premješteno u $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Kloniraj" }, - "passwordGeneratorPolicyInEffect": { - "message": "Jedno ili više pravila organizacije utječe na postavke generatora." - }, "passwordGenerator": { "message": "Generator lozinki" }, @@ -2389,14 +2379,6 @@ "message": "Detalji Senda", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Pretraži Sendove", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Dodaj Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Zadano sakrij tekst" }, - "maxAccessCountReached": { - "message": "Dostignut najveći broj pristupanja", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Isteklo" }, - "pendingDeletion": { - "message": "Čeka brisanje" - }, "passwordProtected": { "message": "Zaštićeno lozinkom" }, @@ -2472,24 +2447,9 @@ "message": "Uredi Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Koja je ovo vrsta Senda?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Nadimak za ovaj Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Datoteka koju želiš poslati" - }, "deletionDate": { "message": "Obriši za" }, - "deletionDateDesc": { - "message": "Send će nakon navedenog vremena biti trajno izbrisan.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send će na ovaj datum biti trajno izbrisan.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Vremenski ograničeni pristup" }, - "expirationDateDesc": { - "message": "Pristup ovom Sendu neće biti moguć nakon navednog roka.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dan" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Prilagođeno" }, - "maximumAccessCount": { - "message": "Ograničeni broj pristupanja" - }, - "maximumAccessCountDesc": { - "message": "Ako je određen, ovom Sendu će se moći pristupiti samo ograničeni broj puta.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Neobavezno zahtijevaj korisnika lozinku za pristup ovom Sendu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Dodaj opcionalnu lozinku za primatelje ovog Senda.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Privatne bilješke o Sendu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Onemogući ovaj Send da mu nitko ne može pristupiti.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopiraj vezu na Send nakon spremanja", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Tekst kojeg želiš poslati" - }, - "sendHideText": { - "message": "Sakrij tekst ovog Senda.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Trenutni broj pristupanja" - }, "createSend": { "message": "Stvori novi Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Prije početka" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Biranje datuma na kalendaru", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klikni ovjde", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "za iskočni prozor", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Navedeni rok isteka nije valjan." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Došlo je do greške kod spremanja vaših datuma isteka i brisanja." }, - "hideEmail": { - "message": "Sakrij moju adresu e-pošte od primatelja." - }, "hideYourEmail": { "message": "Autentifikacija" }, - "sendOptionsPolicyInEffect": { - "message": "Jedno ili više pravila organizacije utječe na postavke Senda." - }, "passwordPrompt": { "message": "Ponovno zatraži glavnu lozinku" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Pogreška" }, - "regenerateUsername": { - "message": "Ponovno generiraj korisničko ime" - }, "generateUsername": { "message": "Generiraj korisničko ime" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tip korisničkog imena" - }, "plusAddressedEmail": { "message": "Plus adresa e-pošte", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Naziv web mjesta" }, - "whatWouldYouLikeToGenerate": { - "message": "Što želiš generirati?" - }, - "passwordType": { - "message": "Tip lozinke" - }, "service": { "message": "Usluga" }, @@ -4911,22 +4804,22 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Važna napomena" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Postavi dvostruku autentifikaciju" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden će, počevši od veljače 2025., za provjeru prijava s novih uređaja poslati kôd na e-poštu tvog računa." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Prijavu dvostrukom autentifikacijom možeš postaviti kao alternativni način zaštite svog računa ili promijeni svoju e-poštu u onu kojoj možeš pristupiti." }, "remindMeLater": { - "message": "Remind me later" + "message": "Podsjeti me kasnije" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Imaš li pouzdan pristup svojoj e-pošti: $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4935,16 +4828,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Ne, nemam" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Da, pouzdano mogu pristupiti svojoj e-pošti" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Uključi prijavu dvostrukom autentifikacijom" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Promjeni e-poštu računa" }, "extensionWidth": { "message": "Širina proširenja" diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 07662b83157..8b8c9722909 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Hossz" }, - "passwordMinLength": { - "message": "Minimum jelszó hosszúság" - }, "uppercase": { "message": "Nagybetűs (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimális speciális" }, - "avoidAmbChar": { - "message": "Félreérthető karakterek mellőzése", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Félreérthető karakterek mellőzése", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Azonosítás elemek listázása a Fül oldalon a könnyű automatikus kitöltéshez." }, + "clickToAutofillOnVault": { + "message": "Kattintsunk az elemekre az automatikus kitöltéshez a Széf nézetben" + }, "clearClipboard": { "message": "Vágólap ürítése", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Áthelyezés szervezethez" }, - "share": { - "message": "Megosztás" - }, "movedItemToOrg": { "message": "$ITEMNAME$ átkerült $ORGNAME$ szervezethez", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klónozás" }, - "passwordGeneratorPolicyInEffect": { - "message": "Egy vagy több szervezeti szabály érinti a generátor beállításokat." - }, "passwordGenerator": { "message": "Jelszó generátor" }, @@ -2389,14 +2379,6 @@ "message": "Send részletek", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Send keresése", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Send hozzáadása", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Szöveg" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Szöveg elrejtése alapértelmezetten" }, - "maxAccessCountReached": { - "message": "A maximális hozzáférések száma elérésre került.", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Lejárt" }, - "pendingDeletion": { - "message": "Függőben lévő törlés" - }, "passwordProtected": { "message": "Jelszóval védett" }, @@ -2472,24 +2447,9 @@ "message": "Send szerkesztése", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Milyen típusú ez a Send?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Barátságos név a Send leírására.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "A küldendő fájl." - }, "deletionDate": { "message": "Törlési dátum" }, - "deletionDateDesc": { - "message": "A Send véglegesen törölve lesz a meghatározott időpontban.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "A Send véglegesen törölve lesz ebben az időpontban.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Lejárati dátum" }, - "expirationDateDesc": { - "message": "Amennyiben be van állítva, a hozzáférés ehhez a Sendhez a meghatározott időpontban lejár", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 nap" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Egyedi" }, - "maximumAccessCount": { - "message": "Maximális elérési szám" - }, - "maximumAccessCountDesc": { - "message": "Beállítva a Küldés elérhetetlen lesz a meghatározott hozzáférések számának elérése után.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Opcionálisan megadhatunk egy jelszót a felhasználók számára a Küldés eléréséhez. ", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Adjunk meg egy opcionális jelszót a címzetteknek a Send eléréséhez.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Személyes megjegyzések erről a Küldésről.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "A Send letiltásával senki nem férhet hozzá.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Mentéskor másoljuk a Küldés hivatkozását a vágólapra.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "A küldendő fájl." - }, - "sendHideText": { - "message": "Alapértelmezés szerint elrejti a Küldés szövegét.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Aktuális elérési szám" - }, "createSend": { "message": "Új Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Mielőtt belevágnánk" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Naptár-stílusú dátumválasztáshoz", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "kattintás ide", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "az ablak megnyitásához", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "A megadott lejárati idő nem érvényes." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Hiba történt a törlési és a lejárati dátum mentésekor." }, - "hideEmail": { - "message": "Saját email cím elrejtése a címzettek elől." - }, "hideYourEmail": { "message": "Saját email cím elrejtése a megtekintések elől." }, - "sendOptionsPolicyInEffect": { - "message": "Egy vagy több szervezeti szabály érinti a Send opciókat." - }, "passwordPrompt": { "message": "Mesterjelszó ismételt megadás" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Hiba" }, - "regenerateUsername": { - "message": "Felhasználónév ismételt geneálása" - }, "generateUsername": { "message": "Felhasználónév generálása" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Felhasználónév típusa" - }, "plusAddressedEmail": { "message": "További címzési email cím", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Webhelynév" }, - "whatWouldYouLikeToGenerate": { - "message": "Mit szeretnénk generálni?" - }, - "passwordType": { - "message": "Jelszótípus" - }, "service": { "message": "Szolgáltatás" }, diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index ef8e1431284..7b1ad51e0b7 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Panjang" }, - "passwordMinLength": { - "message": "Panjang kata sandi minimum" - }, "uppercase": { "message": "Huruf besar (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Spesial Minimum" }, - "avoidAmbChar": { - "message": "Hindari Karakter Ambigu", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Hindari karakter ambigu", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Buat tampilan daftar benda dari identitas pada halaman Tab untuk isi otomatis yang mudah." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Hapus Papan Klip", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Pindah ke Organisasi" }, - "share": { - "message": "Bagikan" - }, "movedItemToOrg": { "message": "$ITEMNAME$ pindah ke $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Duplikat" }, - "passwordGeneratorPolicyInEffect": { - "message": "Satu atau lebih kebijakan organisasi mempengaruhi pengaturan pembuat sandi Anda." - }, "passwordGenerator": { "message": "Pembuat kata sandi" }, @@ -2389,14 +2379,6 @@ "message": "Rincian Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Pencarian Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Tambahkan Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Teks" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Sembunyikan teks secara bawaan" }, - "maxAccessCountReached": { - "message": "Jumlah akses maksimum tercapai", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Kedaluwarsa" }, - "pendingDeletion": { - "message": "Penghapusan menunggu keputusan" - }, "passwordProtected": { "message": "Dilindungi kata sandi" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Jenis Send apakah ini?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Nama yang bersahabat untuk menggambarkan Send ini.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "File yang ingin Anda kirim." - }, "deletionDate": { "message": "Tanggal Penghapusan" }, - "deletionDateDesc": { - "message": "Send akan dihapus secara permanen pada tanggal dan waktu yang ditentukan.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send akan dihapus selamanya pada tanggal ini.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Tanggal habis tempo" }, - "expirationDateDesc": { - "message": "Jika disetel, akses ke Send ini akan berakhir pada tanggal dan waktu yang ditentukan.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 hari" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Kustom" }, - "maximumAccessCount": { - "message": "Hitungan Akses Maksimum" - }, - "maximumAccessCountDesc": { - "message": "Jika disetel, pengguna tidak dapat lagi mengakses Send ini setelah jumlah akses maksimum tercapai.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Secara opsional, minta kata sandi bagi pengguna untuk mengakses Send ini.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Tambahkan kata sandi tidak wajib untuk penerima untuk mengakses Send ini.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Catatan pribadi tentang Send ini.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Nonaktifkan Send ini sehingga tidak ada yang dapat mengaksesnya.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Salin tautan Send ini ke papan klip setelah disimpan.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Teks yang ingin Anda kirim." - }, - "sendHideText": { - "message": "Sembunyikan teks Send ini secara default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Hitungan Akses Saat Ini" - }, "createSend": { "message": "Buat Send Baru", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Sebelum kamu memulai" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Untuk menggunakan pemilih tanggal gaya kalender", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klik disini", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "untuk memunculkan jendela Anda.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Tanggal kedaluwarsa yang diberikan tidak valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Terjadi kesalahan saat menyimpan tanggal penghapusan dan kedaluwarsa Anda." }, - "hideEmail": { - "message": "Sembunyikan alamat surel dari penerima." - }, "hideYourEmail": { "message": "Sembunyikan alamat surel Anda dari penonton." }, - "sendOptionsPolicyInEffect": { - "message": "Satu atau lebih kebijakan organisasi mempengaruhi pengaturan feature Send anda." - }, "passwordPrompt": { "message": "Master password ditanyakan kembali" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Galat" }, - "regenerateUsername": { - "message": "Buat nama pengguna baru" - }, "generateUsername": { "message": "Buat nama pengguna baru" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Jenis nama pengguna" - }, "plusAddressedEmail": { "message": "Surel dengan alamat plus", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nama situs web" }, - "whatWouldYouLikeToGenerate": { - "message": "Apa yang ingin Anda buat?" - }, - "passwordType": { - "message": "Jenis kata sandi" - }, "service": { "message": "Layanan" }, diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 5b563d69f75..711f62f4dea 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Lunghezza" }, - "passwordMinLength": { - "message": "Lunghezza minima della password" - }, "uppercase": { "message": "Maiuscole (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimo caratteri speciali" }, - "avoidAmbChar": { - "message": "Evita caratteri ambigui", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Evita caratteri ambigui", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Mostra le identità nella sezione Scheda per riempirle automaticamente." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Cancella appunti", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Sposta in organizzazione" }, - "share": { - "message": "Condividi" - }, "movedItemToOrg": { "message": "$ITEMNAME$ spostato in $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clona" }, - "passwordGeneratorPolicyInEffect": { - "message": "Una o più politiche dell'organizzazione stanno influenzando le impostazioni del tuo generatore." - }, "passwordGenerator": { "message": "Generatore di password" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Cerca Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Aggiungi Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Testo" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Numero massimo di accessi raggiunto", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Scaduto" }, - "pendingDeletion": { - "message": "In attesa di eliminazione" - }, "passwordProtected": { "message": "Protetto da password" }, @@ -2472,24 +2447,9 @@ "message": "Modifica Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Che tipo di Send è questo?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Un nome intuitivo per descrivere questo Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Il file da inviare." - }, "deletionDate": { "message": "Data di eliminazione" }, - "deletionDateDesc": { - "message": "Il Send sarà eliminato definitivamente alla data e ora specificate.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Data di scadenza" }, - "expirationDateDesc": { - "message": "Se impostato, l'accesso a questo Send scadrà alla data e ora specificate.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 giorno" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalizzato" }, - "maximumAccessCount": { - "message": "Numero massimo di accessi" - }, - "maximumAccessCountDesc": { - "message": "Se impostata, gli utenti non potranno più accedere a questo Send una volta raggiunto il numero massimo di accessi.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Richiedi una password agli utenti per accedere a questo Send (facoltativo).", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Note private sul Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Disattiva il Send per renderlo inaccessibile.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copia il link al Send negli appunti dopo averlo salvato.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Il testo che vuoi inviare." - }, - "sendHideText": { - "message": "Nascondi il testo di questo Send in modo predefinito.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Numero di accessi correnti" - }, "createSend": { "message": "Nuovo Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Prima di iniziare" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Per usare un selettore di date stile calendario", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "clicca qui", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "per aprire la finestra.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "La data di scadenza fornita non è valida." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Si è verificato un errore durante il salvataggio delle date di eliminazione e scadenza." }, - "hideEmail": { - "message": "Nascondi il mio indirizzo email dai destinatari." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Una o più politiche dell'organizzazione stanno influenzando le tue opzioni di Send." - }, "passwordPrompt": { "message": "Richiedi di inserire la password principale di nuovo per visualizzare questo elemento" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Errore" }, - "regenerateUsername": { - "message": "Rigenera nome utente" - }, "generateUsername": { "message": "Genera nome utente" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tipo di nome utente" - }, "plusAddressedEmail": { "message": "Indirizzo email alternativo", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nome sito web" }, - "whatWouldYouLikeToGenerate": { - "message": "Cosa vuoi generare?" - }, - "passwordType": { - "message": "Tipo di password" - }, "service": { "message": "Servizio" }, diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index f5998a02f87..0ffe01e7992 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -454,9 +454,6 @@ "length": { "message": "長さ" }, - "passwordMinLength": { - "message": "パスワードの最低文字数" - }, "uppercase": { "message": "大文字(A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "記号の最小数" }, - "avoidAmbChar": { - "message": "あいまいな文字を省く", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "あいまいな文字を避ける", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "自動入力を簡単にするために、タブページに ID アイテムを表示します" }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "クリップボードの消去", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "組織に移動" }, - "share": { - "message": "共有" - }, "movedItemToOrg": { "message": "$ITEMNAME$ を $ORGNAME$ に移動しました", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "複製" }, - "passwordGeneratorPolicyInEffect": { - "message": "一つ以上の組織のポリシーがパスワード生成の設定に影響しています。" - }, "passwordGenerator": { "message": "パスワード生成ツール" }, @@ -2389,14 +2379,6 @@ "message": "Send の詳細", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Send を検索", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Send を追加", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "テキスト" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "デフォルトでテキストを隠す" }, - "maxAccessCountReached": { - "message": "最大アクセス数に達しました", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "有効期限切れ" }, - "pendingDeletion": { - "message": "削除の保留中" - }, "passwordProtected": { "message": "パスワード保護あり" }, @@ -2472,24 +2447,9 @@ "message": "Send を編集", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "この Send の種類は何ですか?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "この Send を説明するわかりやすい名前", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "送信するファイル" - }, "deletionDate": { "message": "削除日時" }, - "deletionDateDesc": { - "message": "Send は指定された日時に完全に削除されます。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send はこの日付で完全に削除されます。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "有効期限" }, - "expirationDateDesc": { - "message": "設定されている場合、この Send へのアクセスは指定された日時に失効します。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1日" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "カスタム" }, - "maximumAccessCount": { - "message": "最大アクセス数" - }, - "maximumAccessCountDesc": { - "message": "設定されている場合、最大アクセス数に達するとユーザーはこの Send にアクセスできなくなります。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "必要に応じて、ユーザーがこの Send にアクセスするためのパスワードを要求します。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "受信者がこの Send にアクセスするための任意のパスワードを追加します。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "この Send に関するプライベートメモ", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "誰もアクセスできないように、この Send を無効にする", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "保存時にこの Send のリンクをクリップボードにコピーする", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "送信したいテキスト" - }, - "sendHideText": { - "message": "この Send のテキストをデフォルトで非表示にする", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "現在のアクセス数" - }, "createSend": { "message": "新しい Send を作成", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "はじめる前に" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "カレンダースタイルの日付ピッカーを使用するには", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "こちらをクリック", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "してください。", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "入力された有効期限は正しくありません。" }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "削除と有効期限の保存中にエラーが発生しました。" }, - "hideEmail": { - "message": "メールアドレスを受信者に表示しない" - }, "hideYourEmail": { "message": "閲覧者にメールアドレスを見せないようにします。" }, - "sendOptionsPolicyInEffect": { - "message": "一つ以上の組織ポリシーが Send の設定に影響しています。" - }, "passwordPrompt": { "message": "マスターパスワードの再要求" }, @@ -2884,9 +2789,6 @@ "error": { "message": "エラー" }, - "regenerateUsername": { - "message": "ユーザー名を再生成" - }, "generateUsername": { "message": "ユーザー名を生成" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "ユーザー名の種類" - }, "plusAddressedEmail": { "message": "プラス付きのメールアドレス", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "ウェブサイト名" }, - "whatWouldYouLikeToGenerate": { - "message": "何を生成しますか?" - }, - "passwordType": { - "message": "パスワードの種類" - }, "service": { "message": "サービス" }, @@ -4911,10 +4804,10 @@ "message": "ベータ" }, "importantNotice": { - "message": "Important notice" + "message": "重要なお知らせ" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "2段階認証を設定する" }, "newDeviceVerificationNoticeContentPage1": { "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." @@ -4923,10 +4816,10 @@ "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." }, "remindMeLater": { - "message": "Remind me later" + "message": "後で再通知" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "新しいメールアドレス $EMAIL$ はあなたが管理しているものですか?", "placeholders": { "email": { "content": "$1", @@ -4935,7 +4828,7 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "いいえ、違います。" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { "message": "Yes, I can reliably access my email" diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 8cef6ece782..5da73c6755b 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -454,9 +454,6 @@ "length": { "message": "სიგრძე" }, - "passwordMinLength": { - "message": "პაროლის მინიმალური სიგრძე" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "ბუფერის გასუფთავება", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "გაზიარება" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "კლონი" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "ტექსტი" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "ვადაგასულია" }, - "pendingDeletion": { - "message": "ელოდება წაშლას" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "ვადა" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 დღე" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "განსხვავებული" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "აქ დააწკაპუნეთ", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "შეცდომა" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "სერვისი" }, diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 8f7673803cb..6ab3755c8f4 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 7507e254447..09e26c18b5b 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -454,9 +454,6 @@ "length": { "message": "ಉದ್ದ" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "ಕನಿಷ್ಠ ವಿಶೇಷ" }, - "avoidAmbChar": { - "message": "ಅಸ್ಪಷ್ಟ ಅಕ್ಷರಗಳನ್ನು ತಪ್ಪಿಸಿ", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "ಕ್ಲಿಪ್‌ಬೋರ್ಡ್ ತೆರವುಗೊಳಿಸಿ", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "ಸಂಸ್ಥೆಗೆ ಸರಿಸಿ" }, - "share": { - "message": "ಹಂಚಿಕೊಳ್ಳಿ" - }, "movedItemToOrg": { "message": "$ITEMNAME$ ಅನ್ನು $ORGNAME$ ಗೆ ಸರಿಸಲಾಗಿದೆ", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "ಕ್ಲೋನ್" }, - "passwordGeneratorPolicyInEffect": { - "message": "ಒಂದು ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಸ್ಥೆ ನೀತಿಗಳು ನಿಮ್ಮ ಜನರೇಟರ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತವೆ" - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "ಹುಡುಕಾಟ ಕಳುಹಿಸುತ್ತದೆ", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "ಕಳುಹಿಸು ಸೇರಿಸಿ", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "ಪಠ್ಯ" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "ಗರಿಷ್ಠ ಪ್ರವೇಶ ಎಣಿಕೆ ತಲುಪಿದೆ", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "ಅವಧಿ ಮೀರಿದೆ" }, - "pendingDeletion": { - "message": "ಅಳಿಸುವಿಕೆ ಬಾಕಿ ಉಳಿದಿದೆ" - }, "passwordProtected": { "message": "ಪಾಸ್ವರ್ಡ್ ರಕ್ಷಿತ" }, @@ -2472,24 +2447,9 @@ "message": "ಕಳುಹಿಸು ಸಂಪಾದಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "ಇದು ಯಾವ ರೀತಿಯ ಕಳುಹಿಸುತ್ತದೆ?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "ಇದನ್ನು ಕಳುಹಿಸಲು ವಿವರಿಸಲು ಸ್ನೇಹಪರ ಹೆಸರು.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "ನೀವು ಕಳುಹಿಸಲು ಬಯಸುವ ಫೈಲ್." - }, "deletionDate": { "message": "ಅಳಿಸುವ ದಿನಾಂಕ" }, - "deletionDateDesc": { - "message": "ಕಳುಹಿಸಿದ ದಿನಾಂಕ ಮತ್ತು ಸಮಯದ ಮೇಲೆ ಕಳುಹಿಸುವಿಕೆಯನ್ನು ಶಾಶ್ವತವಾಗಿ ಅಳಿಸಲಾಗುತ್ತದೆ.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "ಮುಕ್ತಾಯ ದಿನಾಂಕ" }, - "expirationDateDesc": { - "message": "ಹೊಂದಿಸಿದ್ದರೆ, ಈ ಕಳುಹಿಸುವಿಕೆಯ ಪ್ರವೇಶವು ನಿಗದಿತ ದಿನಾಂಕ ಮತ್ತು ಸಮಯದ ಮೇಲೆ ಮುಕ್ತಾಯಗೊಳ್ಳುತ್ತದೆ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 ದಿನ" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "ಕಸ್ಟಮ್" }, - "maximumAccessCount": { - "message": "ಗರಿಷ್ಠ ಪ್ರವೇಶ ಎಣಿಕೆ" - }, - "maximumAccessCountDesc": { - "message": "ಹೊಂದಿಸಿದ್ದರೆ, ಗರಿಷ್ಠ ಪ್ರವೇಶ ಎಣಿಕೆ ತಲುಪಿದ ನಂತರ ಬಳಕೆದಾರರಿಗೆ ಈ ಕಳುಹಿಸುವಿಕೆಯನ್ನು ಪ್ರವೇಶಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "ಈ ಕಳುಹಿಸುವಿಕೆಯನ್ನು ಪ್ರವೇಶಿಸಲು ಬಳಕೆದಾರರಿಗೆ ಪಾಸ್‌ವರ್ಡ್ ಐಚ್ ಗತ್ಯವಿದೆ.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "ಈ ಕಳುಹಿಸುವ ಬಗ್ಗೆ ಖಾಸಗಿ ಟಿಪ್ಪಣಿಗಳು.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "ಇದನ್ನು ಕಳುಹಿಸುವುದನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇದರಿಂದ ಯಾರೂ ಅದನ್ನು ಪ್ರವೇಶಿಸಲಾಗುವುದಿಲ್ಲ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "ಉಳಿಸಿದ ನಂತರ ಈ ಕಳುಹಿಸುವ ಲಿಂಕ್ ಅನ್ನು ಕ್ಲಿಪ್‌ಬೋರ್ಡ್‌ಗೆ ನಕಲಿಸಿ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "ನೀವು ಕಳುಹಿಸಲು ಬಯಸುವ ಪಠ್ಯ." - }, - "sendHideText": { - "message": "ಪೂರ್ವನಿಯೋಜಿತವಾಗಿ ಈ ಕಳುಹಿಸುವ ಪಠ್ಯವನ್ನು ಮರೆಮಾಡಿ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "ಪ್ರಸ್ತುತ ಪ್ರವೇಶ ಎಣಿಕೆ" - }, "createSend": { "message": "ಹೊಸ ಕಳುಹಿಸುವಿಕೆಯನ್ನು ರಚಿಸಿ", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "ನೀವು ಪ್ರಾರಂಭಿಸುವ ಮೊದಲು" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "ಕ್ಯಾಲೆಂಡರ್ ಶೈಲಿಯ ದಿನಾಂಕ ಆಯ್ದುಕೊಳ್ಳುವಿಕೆಯನ್ನು ಬಳಸಲು", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "ಕ್ಲಿಕ್ ಮಾಡಿ", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "ನಿಮ್ಮ ವಿಂಡೋವನ್ನು ಪಾಪ್ಔಟ್ ಮಾಡಲು.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "ಒದಗಿಸಿದ ಮುಕ್ತಾಯ ದಿನಾಂಕವು ಮಾನ್ಯವಾಗಿಲ್ಲ." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "ನಿಮ್ಮ ಅಳಿಸುವಿಕೆ ಮತ್ತು ಮುಕ್ತಾಯ ದಿನಾಂಕಗಳನ್ನು ಉಳಿಸುವಲ್ಲಿ ದೋಷ ಕಂಡುಬಂದಿದೆ." }, - "hideEmail": { - "message": "ಸ್ವೀಕರಿಸುವವರಿಂದ ನನ್ನ ಇಮೇಲ್ ವಿಳಾಸವನ್ನು ಮರೆಮಾಡಿ." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "ಒಂದು ಅಥವಾ ಹೆಚ್ಚಿನ ಸಂಸ್ಥೆಯ ನೀತಿಗಳು ನಿಮ್ಮ ಕಳುಹಿಸುವ ಆಯ್ಕೆಗಳ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತವೆ." - }, "passwordPrompt": { "message": "ಮಾಸ್ಟರ್ ಪಾಸ್ವರ್ಡ್ ಮರು-ಪ್ರಾಂಪ್ಟ್" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 6ab1a467475..d6da55f600d 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -454,9 +454,6 @@ "length": { "message": "길이" }, - "passwordMinLength": { - "message": "최소 비밀번호 길이" - }, "uppercase": { "message": "대문자 (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "특수 문자 최소 개수" }, - "avoidAmbChar": { - "message": "모호한 문자 사용 안 함", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "모호한 문자 사용 안 함", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "간편한 자동완성을 위해 탭에 신원 항목들을 나열" }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "클립보드 비우기", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "조직으로 이동하기" }, - "share": { - "message": "공유" - }, "movedItemToOrg": { "message": "$ITEMNAME$이(가) $ORGNAME$(으)로 이동됨", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "복제" }, - "passwordGeneratorPolicyInEffect": { - "message": "하나 이상의 단체 정책이 생성기 규칙에 영항을 미치고 있습니다." - }, "passwordGenerator": { "message": "비밀번호 생성기" }, @@ -2389,14 +2379,6 @@ "message": "보내기 세부 정보", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": " Send 검색", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": " Send 추가", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "텍스트" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "기본적으로 텍스트 숨기기" }, - "maxAccessCountReached": { - "message": "최대 접근 횟수 도달", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "만료됨" }, - "pendingDeletion": { - "message": "삭제 대기 중" - }, "passwordProtected": { "message": "비밀번호로 보호됨" }, @@ -2472,24 +2447,9 @@ "message": " Send 편집", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "어떤 유형의 Send인가요?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "이 Send을 설명할 이름", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "전송하려는 파일" - }, "deletionDate": { "message": "삭제 날짜" }, - "deletionDateDesc": { - "message": "이 Send가 정해진 일시에 영구적으로 삭제됩니다.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "이 Send가 이 날짜에 영구적으로 삭제됩니다.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "만료 날짜" }, - "expirationDateDesc": { - "message": "설정할 경우, 이 Send에 대한 접근 권한이 정해진 일시에 만료됩니다.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1일" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "사용자 지정" }, - "maximumAccessCount": { - "message": "최대 접근 횟수" - }, - "maximumAccessCountDesc": { - "message": "설정할 경우, 최대 접근 횟수에 도달할 때 이 Send에 접근할 수 없게 됩니다.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "이 Send에 접근하기 위해 암호를 입력하도록 선택적으로 요구합니다.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "수신자가 이 Send에 액세스할 수 있도록 비밀번호 옵션를 추가합니다.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "이 Send에 대한 비공개 메모", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "이 Send를 비활성화하여 아무도 접근할 수 없게 합니다.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "저장할 때 이 Send의 링크를 클립보드에 복사합니다.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "전송하려는 텍스트" - }, - "sendHideText": { - "message": "이 Send의 텍스트를 기본적으로 숨김", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "현재 접근 횟수" - }, "createSend": { "message": "새 Send 생성", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "시작하기 전에" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "달력을 보고 날짜를 선택하려면", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "여기를 클릭하여", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "확장 프로그램을 새 창에서 여세요.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "제공된 만료 날짜가 유효하지 않습니다." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "삭제 날짜와 만료 날짜를 저장하는 도중 오류가 발생했습니다." }, - "hideEmail": { - "message": "받는 사람으로부터 나의 이메일 주소 숨기기" - }, "hideYourEmail": { "message": "사람들로부터 이메일 주소를 숨기세요." }, - "sendOptionsPolicyInEffect": { - "message": "하나 이상의 단체 정책이 Send 설정에 영향을 미치고 있습니다." - }, "passwordPrompt": { "message": "마스터 비밀번호 재확인" }, @@ -2884,9 +2789,6 @@ "error": { "message": "오류" }, - "regenerateUsername": { - "message": "아이디 재생성" - }, "generateUsername": { "message": "아이디 생성" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "아이디 유형" - }, "plusAddressedEmail": { "message": "추가 이메일", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "웹사이트 이름" }, - "whatWouldYouLikeToGenerate": { - "message": "무엇을 생성하실건가요?" - }, - "passwordType": { - "message": "비밀번호 유형" - }, "service": { "message": "서비스" }, diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index f55fb8b3e25..eaf1cb9f9db 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Ilgis" }, - "passwordMinLength": { - "message": "Minimalus slaptažodžio ilgis" - }, "uppercase": { "message": "Didžiosiomis (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mažiausiai simbolių" }, - "avoidAmbChar": { - "message": "Vengti dviprasmiškų simbolių", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Pateikti tapatybės elementų skirtuko puslapyje, kad būtų lengva automatiškai užpildyti." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Išvalyti iškarpinę", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Perkelti į organizaciją" }, - "share": { - "message": "Bendrinti" - }, "movedItemToOrg": { "message": "$ITEMNAME$ perkelta(s) į $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klonuoti" }, - "passwordGeneratorPolicyInEffect": { - "message": "Viena ar daugiau organizacijos politikų turi įtakos Jūsų generatoriaus nustatymams." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Ieškoti „Sends“", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Pridėti „Send“", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekstas" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Pasiektas maksimalus prisijungimų skaičius", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Nebegalioja" }, - "pendingDeletion": { - "message": "Laukiama ištrynimo" - }, "passwordProtected": { "message": "Apsaugota slaptažodžiu" }, @@ -2472,24 +2447,9 @@ "message": "Redaguoti „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Kokio tai tipo „Send“?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Draugiškas pavadinimas, apibūdinantis šį „Send“.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Failas, kurį norite siųsti." - }, "deletionDate": { "message": "Ištrynimo data" }, - "deletionDateDesc": { - "message": "Nurodytos datos ir laiko metu „Send“ bus bus ištrinta visam laikui.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Galiojimo data" }, - "expirationDateDesc": { - "message": "Jei nustatyta, prieiga prie šio „Send“ nustos galioti nurodyta data ir laikui.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 d" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Pasirinktinis" }, - "maximumAccessCount": { - "message": "Maksimalus prisijungimų skaičius" - }, - "maximumAccessCountDesc": { - "message": "Jei nustatyta, vartotojai nebegalės pasiekti šio „Send“, kai bus pasiektas maksimalus prisijungimų skaičius.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Pasirinktinai reikalauti slaptažodžio, kad vartotojai galėtų pasiekti šį „Send“.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Asmeninės pastabos apie šį „Send“.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Išjunkite šį „Send“, kad niekas negalėtų jo pasiekti.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Išsaugant šį „Send“ nukopijuokite nuorodą į mainų sritį.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Tekstas, kurį norite siųsti." - }, - "sendHideText": { - "message": "Pagal numatytuosius nustatymus slėpti šį „Send“ tekstą.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Dabartinis prisijungimų skaičius" - }, "createSend": { "message": "Naujas Siuntinys", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Prieš pradedant" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Norint pasinaudoti kalendoriaus stiliaus datos pasirinkikliu", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "spauskite čia", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "iškelti atskirame lange.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Nurodytas galiojimo laikas negalioja." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Išsaugant jūsų ištrynimo ir galiojimo datas įvyko klaida." }, - "hideEmail": { - "message": "Slėpti mano el. pašto adresą nuo gavėjų." - }, "hideYourEmail": { "message": "Slėpkite savo el. pašto adresą nuo žiūrėtojų." }, - "sendOptionsPolicyInEffect": { - "message": "Viena ar daugiau organizacijos politikų turi įtakos Jūsų „Send“ nustatymams." - }, "passwordPrompt": { "message": "Iš naujo prašoma pagrindinio slaptažodžio" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Klaida" }, - "regenerateUsername": { - "message": "Pergeneruoti vartotojo vardą iš naujo" - }, "generateUsername": { "message": "Generuoti vartotojo vardą" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Vartotojo prisijungimo vardo tipas" - }, "plusAddressedEmail": { "message": "Plius adresuotas el. paštas", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Svetainės pavadinimas" }, - "whatWouldYouLikeToGenerate": { - "message": "Ką norėtumėte sugeneruoti?" - }, - "passwordType": { - "message": "Slaptažodžio tipas" - }, "service": { "message": "Paslauga" }, diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 31bdcd59e45..2c2a9c3c69c 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Garums" }, - "passwordMinLength": { - "message": "Mazākais pieļaujamais paroles garums" - }, "uppercase": { "message": "Lielie burti (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mazākais pieļaujamais īpašo rakstzīmju skaits" }, - "avoidAmbChar": { - "message": "Izvairīties no viegli sajaucamām rakstzīmēm", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Izvairīties no viegli sajaucamām rakstzīmēm", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Attēlot identitātes ciļņu lapā vieglākai aizpildei." }, + "clickToAutofillOnVault": { + "message": "Glabātavas skatā jāklikšķina uz vienumiem, lai automātiski aizpildītu" + }, "clearClipboard": { "message": "Notīrīt starpliktuvi", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Pārvietot uz apvienību" }, - "share": { - "message": "Kopīgot" - }, "movedItemToOrg": { "message": "$ITEMNAME$ pārvietots uz $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Pavairot" }, - "passwordGeneratorPolicyInEffect": { - "message": "Viens vai vairāki apvienības nosacījumi ietekmē veidotāja iestatījumus." - }, "passwordGenerator": { "message": "Paroļu veidotājs" }, @@ -2389,14 +2379,6 @@ "message": "Informācija par Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Meklēt Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Pievienot Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Teksts" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Pēc noklusējuma paslēpt tekstu" }, - "maxAccessCountReached": { - "message": "Sasniegts lielākais pieļaujamais piekļuves reižu skaits", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Beidzies izmantošanas laiks" }, - "pendingDeletion": { - "message": "Gaida dzēšanu" - }, "passwordProtected": { "message": "Aizsargāts ar paroli" }, @@ -2472,24 +2447,9 @@ "message": "Labot Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Kāds ir šī Send veids?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Lasāms nosaukums, kas apraksta šo Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Datne, kuru ir vēlme nosūtīt." - }, "deletionDate": { "message": "Dzēšanas datums" }, - "deletionDateDesc": { - "message": "Send tiks neatgriezeniski izdzēsts norādītajā datumā un laikā.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send šajā datumā tiks neatgriezeniski izdzēsts.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Derīguma beigu datums" }, - "expirationDateDesc": { - "message": "Ja iestatīts, piekļuve šim Send beigsies norādītajā datumā un laikā.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 diena" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Pielāgots" }, - "maximumAccessCount": { - "message": "Lielākais pieļaujamais piekļuves reižu skaits" - }, - "maximumAccessCountDesc": { - "message": "Ja iestatīts, lietotāji nevarēs piekļūt šim Send, kad tiks sasniegts lielākais pieļaujamais piekļūšanas reižu skaits.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Pēc izvēles pieprasīt paroli, lai lietotāji varētu piekļūt šim Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Pēc izvēles var pievienot paroli, lai saņēmēji varētu piekļūt šim Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Personīgas piezīmes par šo Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Izslēgt šo Send, lai neviens tam nevarētu piekļūt.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Saglabāšanas brīdī ievietot šī Send saiti starpliktuvē.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Teksts, kuru ir vēlme nosūtīt." - }, - "sendHideText": { - "message": "Pēc noklusējuma paslēpt šī Send tekstu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Pašreizējais piekļuvju skaits" - }, "createSend": { "message": "Jauns Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Pirms sākšanas" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Lai izmantotu kalendāra veida datumu atlasītāju,", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klikšķināt šeit", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": ", lai atvērtu jaunā logā.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Norādītais derīguma beigu datums nav derīgs." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Atgadījusies kļūda dzēšanas un derīguma beigu datumu saglabāšanā." }, - "hideEmail": { - "message": "Slēpt e-pasta adresi no saņēmējiem." - }, "hideYourEmail": { "message": "Paslēpt e-pasta adresi no apskatītājiem." }, - "sendOptionsPolicyInEffect": { - "message": "Viens vai vairāki apvienības nosacījumi ietekmē Send iespējas." - }, "passwordPrompt": { "message": "Galvenās paroles pārvaicāšana" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Kļūda" }, - "regenerateUsername": { - "message": "Pārizveidot lietotājvārdu" - }, "generateUsername": { "message": "Izveidot lietotājvārdu" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Lietotājvārda veids" - }, "plusAddressedEmail": { "message": "E-pasta adrese ar plusu", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Tīmekļvietnes nosaukums" }, - "whatWouldYouLikeToGenerate": { - "message": "Ko ir nepieciešams izveidot?" - }, - "passwordType": { - "message": "Paroles veids" - }, "service": { "message": "Pakalpojums" }, diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index e3c377b2e8c..cd210c85ce1 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -454,9 +454,6 @@ "length": { "message": "നീളം" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "കുറഞ്ഞ പ്രത്യേക പ്രതീകങ്ങൾ" }, - "avoidAmbChar": { - "message": "അവ്യക്തമായ പ്രതീകങ്ങൾ ഒഴിവാക്കുക", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "ക്ലിപ്ബോര്‍ഡ് മായ്ക്കുക", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "പങ്കിടുക" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "ക്ലോൺ" }, - "passwordGeneratorPolicyInEffect": { - "message": "ഒന്നോ അതിലധികമോ സംഘടന നയങ്ങൾ നിങ്ങളുടെ പാസ്സ്‌വേഡ് സൃഷ്ടാവിൻ്റെ ക്രമീകരണങ്ങളെ ബാധിക്കുന്നു" - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 02c66ea8f69..d156e6d6458 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -454,9 +454,6 @@ "length": { "message": "लांबी" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 8f7673803cb..6ab3755c8f4 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 604597091ef..16469051a0c 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Lengde" }, - "passwordMinLength": { - "message": "Minimum passordlengde" - }, "uppercase": { "message": "Store bokstaver (A–Å)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minste antall spesialtegn" }, - "avoidAmbChar": { - "message": "Unngå tvetydige tegn", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Vis identitetselementer på fanesiden for enkel auto-utfylling." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Tøm utklippstavlen", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Flytt til organisasjon" }, - "share": { - "message": "Del" - }, "movedItemToOrg": { "message": "$ITEMNAME$ flyttet til $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klon" }, - "passwordGeneratorPolicyInEffect": { - "message": "En eller flere av virksomhetens regler påvirker generatorinnstillingene dine." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Søk i Send-ene", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Legg til Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Maksimalt antall tilganger nådd", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Utløpt" }, - "pendingDeletion": { - "message": "Venter på sletting" - }, "passwordProtected": { "message": "Passord beskyttet" }, @@ -2472,24 +2447,9 @@ "message": "Rediger Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Hvilken type Send er dette?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Et vennlig navn for å beskrive dette Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Filen du vil send." - }, "deletionDate": { "message": "Dato for sletting" }, - "deletionDateDesc": { - "message": "Send-en vil bli slettet permanent på den angitte dato og klokkeslett.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Utløpsdato" }, - "expirationDateDesc": { - "message": "Hvis satt, vil tilgang til denne Send gå ut på angitt dato og klokkeslett.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dag" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Egendefinert" }, - "maximumAccessCount": { - "message": "Maksimal antall tilganger" - }, - "maximumAccessCountDesc": { - "message": "Hvis satt, vil ikke brukere lenger ha tilgang til dette Send når maksimal antall tilgang er nådd.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Eventuelt krever et passord for brukere å få tilgang til denne Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notater om denne Send-en.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deaktiver denne Send-en, slik at ingen får tilgang til den.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopier denne Send-ens lenke til utklippstavlen når den har blitt lagret.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Teksten du ønsker å sende." - }, - "sendHideText": { - "message": "Skjul denne Send-ens tekst som standard.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Antall nåværende tilganger" - }, "createSend": { "message": "Lag en ny Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Før du starter" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Hvis du vil bruke en kalenderstil-datovelger", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "kilkk her", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "å pope ut vinduet.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Utløpsdatoen angitt er ikke gyldig." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Det oppstod en feil ved lagring av slettingen og utløpsdatoene." }, - "hideEmail": { - "message": "Skjul min e-postadresse fra mottakere." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "En eller flere av virksomhetens regler påvirker generatorinnstillingene dine." - }, "passwordPrompt": { "message": "Forespørsel om hovedpassord på nytt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Feil" }, - "regenerateUsername": { - "message": "Regenerer brukernavn" - }, "generateUsername": { "message": "Generer brukernavn" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Brukernavntype" - }, "plusAddressedEmail": { "message": "Pluss-adressert e-post", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Navn på nettside" }, - "whatWouldYouLikeToGenerate": { - "message": "Hva vil du generere?" - }, - "passwordType": { - "message": "Passordtype" - }, "service": { "message": "Tjeneste" }, diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 8f7673803cb..6ab3755c8f4 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 170c682aa1c..7a252ee3ddb 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Lengte" }, - "passwordMinLength": { - "message": "Minimale wachtwoordlengte" - }, "uppercase": { "message": "Hoofdletters (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum aantal speciale tekens" }, - "avoidAmbChar": { - "message": "Dubbelzinnige tekens vermijden", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Dubbelzinnige tekens vermijden", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Identiteiten weergeven op de tabpagina voor gemakkelijk automatisch invullen." }, + "clickToAutofillOnVault": { + "message": "Klik op items om automatisch in te vullen op de kluisweergave" + }, "clearClipboard": { "message": "Klembord wissen", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Naar organisatie verplaatsen" }, - "share": { - "message": "Delen" - }, "movedItemToOrg": { "message": "$ITEMNAME$ verplaatst naar $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Dupliceren" }, - "passwordGeneratorPolicyInEffect": { - "message": "Een of meer organisatiebeleidseisen heeft invloed op de instellingen van je generator." - }, "passwordGenerator": { "message": "Wachtwoordgenerator" }, @@ -2389,14 +2379,6 @@ "message": "Send-details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Sends zoeken", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Send toevoegen", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Tekst standaard verbergen" }, - "maxAccessCountReached": { - "message": "Maximum aantal keren benaderd", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Verlopen" }, - "pendingDeletion": { - "message": "Wordt verwijderd" - }, "passwordProtected": { "message": "Beveiligd met wachtwoord" }, @@ -2472,24 +2447,9 @@ "message": "Send bewerken", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Wat voor soort Send is dit?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Een vriendelijke naam om deze Send te beschrijven.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Het bestand dat je wilt versturen." - }, "deletionDate": { "message": "Verwijderingsdatum" }, - "deletionDateDesc": { - "message": "Deze Send wordt op de aangegeven datum en tijd definitief verwijderd.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Op deze datum wordt de Send definitief verwijderd.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Vervaldatum" }, - "expirationDateDesc": { - "message": "Als dit is ingesteld verloopt deze Send op een specifieke datum en tijd.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dag" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Aangepast" }, - "maximumAccessCount": { - "message": "Maximum toegangsaantal" - }, - "maximumAccessCountDesc": { - "message": "Als dit is ingesteld kunnen gebruikers deze Send niet meer benaderen zodra het maximale aantal toegang is bereikt.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Vereis optioneel een wachtwoord voor gebruikers om toegang te krijgen tot deze Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Voeg een optioneel wachtwoord toe voor ontvangers om toegang te krijgen tot deze Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Privénotities over deze Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Schakel deze Send uit zodat niemand hem kan benaderen.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopieer de link van deze Send bij het opslaan naar het klembord.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "De tekst die je wilt versturen." - }, - "sendHideText": { - "message": "De tekst van deze Send standaard verbergen.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Huidige toegangsaantal" - }, "createSend": { "message": "Nieuwe Send aanmaken", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Voor je begint" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Om een datumkiezer in kalenderstijl te gebruiken", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klik hier", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "om een pop-up te openen.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "De opgegeven vervaldatum is niet geldig." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Er is een fout opgetreden bij het opslaan van je verwijder- en vervaldatum." }, - "hideEmail": { - "message": "Verberg mijn e-mailadres voor ontvangers." - }, "hideYourEmail": { "message": "Je e-mailadres voor ontvangers verbergen." }, - "sendOptionsPolicyInEffect": { - "message": "Een of meer organisatiebeleidseisen heeft invloed op de mogelijkheden van je Send." - }, "passwordPrompt": { "message": "Hoofdwachtwoord opnieuw vragen" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Fout" }, - "regenerateUsername": { - "message": "Gebruikersnaam opnieuw genereren" - }, "generateUsername": { "message": "Gebruikersnamen genereren" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Type gebruikersnaam" - }, "plusAddressedEmail": { "message": "E-mailadres-met-plus", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Websitenaam" }, - "whatWouldYouLikeToGenerate": { - "message": "Wat wil je genereren?" - }, - "passwordType": { - "message": "Type wachtwoord" - }, "service": { "message": "Dienst" }, diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 8f7673803cb..6ab3755c8f4 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 8f7673803cb..6ab3755c8f4 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 7025862cb72..5d1cd22c9ef 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Długość" }, - "passwordMinLength": { - "message": "Minimalna długość hasła" - }, "uppercase": { "message": "Wielkie litery (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimalna liczba znaków specjalnych" }, - "avoidAmbChar": { - "message": "Unikaj niejednoznacznych znaków", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Unikaj niejednoznacznych znaków", "description": "Label for the avoid ambiguous characters checkbox." @@ -628,7 +621,7 @@ "message": "Inne" }, "unlockMethods": { - "message": "Odblokuj Opcje" + "message": "Opcje odblokowania" }, "unlockMethodNeededToChangeTimeoutActionDesc": { "message": "Ustaw metodę odblokowania, aby zmienić czas blokowania sejfu." @@ -985,7 +978,7 @@ "message": "Poproś o dodanie danych logowania" }, "vaultSaveOptionsTitle": { - "message": "Zapisz do ustawień sejfu" + "message": "Opcje zapisywania w sejfie" }, "addLoginNotificationDesc": { "message": "\"Dodaj powiadomienia logowania\" automatycznie wyświetla monit o zapisanie nowych danych logowania do sejfu przy każdym pierwszym logowaniu." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Pokaż elementy tożsamości na stronie głównej, aby ułatwić autouzupełnianie." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Wyczyść schowek", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Przenieś do organizacji" }, - "share": { - "message": "Udostępnij" - }, "movedItemToOrg": { "message": "Element $ITEMNAME$ został przeniesiony do organizacji $ORGNAME$", "placeholders": { @@ -1491,7 +1484,7 @@ "message": "Dotyczy wszystkich zalogowanych kont." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Wyłącz wbudowany w przeglądarkę menedżera haseł, aby uniknąć konfliktów." + "message": "Wyłącz wbudowany w przeglądarkę menedżer haseł, aby uniknąć konfliktów." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Edytuj ustawienia przeglądarki." @@ -2047,9 +2040,6 @@ "clone": { "message": "Klonuj" }, - "passwordGeneratorPolicyInEffect": { - "message": "Co najmniej jedna zasada organizacji wpływa na ustawienia generatora." - }, "passwordGenerator": { "message": "Generator hasła" }, @@ -2389,14 +2379,6 @@ "message": "Szczegóły Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Szukaj w wysyłkach", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Dodaj wysyłkę", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Tekst" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Domyślnie ukryj tekst" }, - "maxAccessCountReached": { - "message": "Maksymalna liczba dostępów została osiągnięta", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Wygasła" }, - "pendingDeletion": { - "message": "Oczekiwanie na usunięcie" - }, "passwordProtected": { "message": "Chroniona hasłem" }, @@ -2472,24 +2447,9 @@ "message": "Edytuj wysyłkę", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Jakiego typu jest to wysyłka?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Nazwa wysyłki.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Plik, który chcesz wysłać." - }, "deletionDate": { "message": "Data usunięcia" }, - "deletionDateDesc": { - "message": "Wysyłka zostanie trwale usunięta w określonym czasie.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send zostanie trwale usunięte w tej dacie.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Data wygaśnięcia" }, - "expirationDateDesc": { - "message": "Jeśli funkcja jest włączona, dostęp do wysyłki wygaśnie po określonym czasie.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dzień" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Niestandardowe" }, - "maximumAccessCount": { - "message": "Maksymalna liczba dostępów" - }, - "maximumAccessCountDesc": { - "message": "Jeśli funkcja jest włączona, po osiągnięciu maksymalnej liczby dostępów, użytkownicy nie będą mieli dostępu do tej wysyłki.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Opcjonalne hasło dla użytkownika, aby uzyskać dostęp do wysyłki.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Zabezpiecz tę wiadomość hasłem, które będzie wymagane, aby uzyskać do niej dostęp.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Prywatne notatki o tej wysyłce.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Wyłącz wysyłkę, aby nikt nie miał do niej dostępu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Po zapisaniu wysyłki, skopiuj link do schowka.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Tekst, który chcesz wysłać." - }, - "sendHideText": { - "message": "Ukryj domyślnie tekst wysyłki.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Obecna liczba dostępów" - }, "createSend": { "message": "Nowa wysyłka", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Zanim zaczniesz" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Aby wybrać datę, ", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "kliknij tutaj", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "w celu otwarcia rozszerzenia w oknie.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Data wygaśnięcia nie jest prawidłowa." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Wystąpił błąd podczas zapisywania dat usunięcia i wygaśnięcia." }, - "hideEmail": { - "message": "Ukryj mój adres e-mail przed odbiorcami." - }, "hideYourEmail": { "message": "Ukryj mój adres e-mail przed oglądającymi." }, - "sendOptionsPolicyInEffect": { - "message": "Co najmniej jedna zasada organizacji wpływa na ustawienia wysyłek." - }, "passwordPrompt": { "message": "Potwierdź hasłem głównym" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Błąd" }, - "regenerateUsername": { - "message": "Wygeneruj ponownie nazwę użytkownika" - }, "generateUsername": { "message": "Wygeneruj nazwę użytkownika" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Rodzaj nazwy użytkownika" - }, "plusAddressedEmail": { "message": "Adres e-mail z plusem", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nazwa strony" }, - "whatWouldYouLikeToGenerate": { - "message": "Co chcesz wygenerować?" - }, - "passwordType": { - "message": "Rodzaj hasła" - }, "service": { "message": "Usługa" }, diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index d7a8ae6ea4d..cd0c9979103 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -3,7 +3,7 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Gerenciador de Senhas", + "message": "Gerenciador de senhas Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { @@ -193,10 +193,10 @@ "message": "Preenchimento automático identidade" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Preencher o código de verificação" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "Preencher o código de verificação", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -242,7 +242,7 @@ "message": "Correio eletrônico da conta" }, "requestHint": { - "message": "Pedir dica" + "message": "Solicitar dica" }, "requestPasswordHint": { "message": "Dica da senha mestra" @@ -296,7 +296,7 @@ "message": "Continuar na extensão da loja do navegador?" }, "continueToBrowserExtensionStoreDesc": { - "message": "Ajude outros a descobrir se o Bitwarden está certo para eles. Visite a loja de extensões do seu navegador e deixe uma classificação agora." + "message": "Ajude outras pessoas a descobrirem se o Bitwarden é o que elas estão procurando. Visite a loja de extensões do seu navegador e deixe uma classificação agora." }, "changeMasterPasswordOnWebConfirmation": { "message": "Você pode alterar a sua senha mestra no aplicativo web Bitwarden." @@ -340,7 +340,7 @@ "message": "Gerenciador de Segredos Bitwarden" }, "continueToSecretsManagerPageDesc": { - "message": "Armazene, gerencie e compartilhe segredos de desenvolvedor com o Gerenciador de segredos do Bitwarden. Saiba mais no site bitwarden.com." + "message": "Armazene, gerencie e compartilhe senhas de desenvolvedor com o Gerenciador de segredos do Bitwarden. Saiba mais no site bitwarden.com." }, "passwordlessDotDev": { "message": "Passwordless.dev" @@ -349,10 +349,10 @@ "message": "Crie experiências de login suaves e seguras, livres de senhas tradicionais com Passwordless.dev. Saiba mais no site bitwarden.com." }, "freeBitwardenFamilies": { - "message": "Famílias do Bitwarden Grátis" + "message": "Plano Familiar do Bitwarden Grátis" }, "freeBitwardenFamiliesPageDesc": { - "message": "Você é elegível para as Famílias do Bitwarden Grátis. Resgate esta oferta hoje no aplicativo web." + "message": "Você é elegível para o plano Familiar do Bitwarden Grátis. Resgate esta oferta hoje no aplicativo web." }, "version": { "message": "Versão" @@ -454,9 +454,6 @@ "length": { "message": "Comprimento" }, - "passwordMinLength": { - "message": "Tamanho mínimo da senha" - }, "uppercase": { "message": "Maiúsculas (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,12 +525,8 @@ "minSpecial": { "message": "Especiais Mínimos" }, - "avoidAmbChar": { - "message": "Evitar Caracteres Ambíguos", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { - "message": "Evitar Caracteres Ambíguos", + "message": "Evitar caracteres ambíguos", "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { @@ -898,7 +891,7 @@ "message": "Torne sua conta mais segura configurando o 'login' em duas etapas no aplicativo ‘web’ do Bitwarden." }, "twoStepLoginConfirmationTitle": { - "message": "Continuar para o aplicativo da ‘web’?" + "message": "Continuar para o aplicativo web?" }, "editedFolder": { "message": "Pasta Editada" @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Liste os itens de identidade na aba atual para facilitar preenchimento automático." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Limpar Área de Transferência", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1130,7 +1126,7 @@ "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "Atenção", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Mover para a Organização" }, - "share": { - "message": "Compartilhar" - }, "movedItemToOrg": { "message": "$ITEMNAME$ movido para $ORGNAME$", "placeholders": { @@ -1225,7 +1218,7 @@ "message": "Funcionalidade Indisponível" }, "encryptionKeyMigrationRequired": { - "message": "Migração de chave de criptografia necessária. Faça login através do cofre web para atualizar sua chave de criptografia." + "message": "É necessário migrar sua chave de criptografia. Faça login através do cofre web para atualizar sua chave de criptografia." }, "premiumMembership": { "message": "Assinatura Premium" @@ -1324,10 +1317,10 @@ "message": "Insira o código de verificação de 6 dígitos do seu aplicativo de autenticação." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Tempo de autenticação esgotado" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "A sessão de autenticação expirou. Por favor, reinicie o processo de login." }, "enterVerificationCodeEmail": { "message": "Insira o código de verificação de 6 dígitos que foi enviado por e-mail para $EMAIL$.", @@ -1491,7 +1484,7 @@ "message": "Aplica-se a todas as contas conectadas." }, "turnOffBrowserBuiltInPasswordManagerSettings": { - "message": "Desative as configurações do gerenciador de senhas do seu navegador para evitar conflitos." + "message": "Desative o gerenciador de senhas padrão do seu navegador para evitar conflitos." }, "turnOffBrowserBuiltInPasswordManagerSettingsLink": { "message": "Editar configurações do navegador." @@ -1853,7 +1846,7 @@ "message": "Notas seguras" }, "sshKeys": { - "message": "SSH Keys" + "message": "Chaves SSH" }, "clear": { "message": "Limpar", @@ -2047,9 +2040,6 @@ "clone": { "message": "Clonar" }, - "passwordGeneratorPolicyInEffect": { - "message": "Uma ou mais políticas da organização estão afetando as suas configurações do gerador." - }, "passwordGenerator": { "message": "Gerador de Senha" }, @@ -2199,7 +2189,7 @@ "message": "A sua nova senha mestra não cumpre aos requisitos da política." }, "receiveMarketingEmailsV2": { - "message": "Obtenha conselhos, novidades, e oportunidades de pesquisa do Bitwarden em sua caixa de entrada." + "message": "Obtenha dicas, novidades e oportunidades de pesquisa do Bitwarden em sua caixa de entrada." }, "unsubscribe": { "message": "Cancelar subscrição" @@ -2389,14 +2379,6 @@ "message": "Enviar detalhes", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Pesquisar Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Adicionar Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Texto" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Ocultar texto por padrão" }, - "maxAccessCountReached": { - "message": "Número máximo de acessos atingido", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expirado" }, - "pendingDeletion": { - "message": "Exclusão pendente" - }, "passwordProtected": { "message": "Protegido por senha" }, @@ -2472,24 +2447,9 @@ "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Que tipo de Send é este?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Um nome amigável para descrever este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "O arquivo que você deseja enviar." - }, "deletionDate": { "message": "Data de Exclusão" }, - "deletionDateDesc": { - "message": "O Send será eliminado permanentemente na data e hora especificadas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "O envio será eliminado permanentemente na data e hora especificadas.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Data de Validade" }, - "expirationDateDesc": { - "message": "Se definido, o acesso a este Send expirará na data e hora especificadas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dia" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalizado" }, - "maximumAccessCount": { - "message": "Contagem Máxima de Acessos" - }, - "maximumAccessCountDesc": { - "message": "Se atribuído, usuários não poderão mais acessar este Send assim que o número máximo de acessos for atingido.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Exigir opcionalmente uma senha para os usuários acessarem este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Adicione uma senha opcional para os destinatários para acessar este Envio.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Notas privadas sobre esse Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Desative este Send para que ninguém possa acessá-lo.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copiar o link deste Send para área de transferência após salvar.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "O texto que você deseja enviar." - }, - "sendHideText": { - "message": "Ocultar o texto deste Send por padrão.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Contagem Atual de Acessos" - }, "createSend": { "message": "Criar Novo Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Antes de começar" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Para usar um seletor de data no estilo calendário", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "clique aqui", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "para abrir a sua janela.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "A data de validade fornecida não é válida." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Ocorreu um erro ao salvar as suas datas de exclusão e validade." }, - "hideEmail": { - "message": "Ocultar meu endereço de e-mail dos destinatários." - }, "hideYourEmail": { "message": "Ocultar meu endereço de correio eletrônico dos destinatários." }, - "sendOptionsPolicyInEffect": { - "message": "Uma ou mais políticas da organização estão afetando as suas opções de Send." - }, "passwordPrompt": { "message": "Solicitação nova de senha mestra" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Erro" }, - "regenerateUsername": { - "message": "Recriar Usuário" - }, "generateUsername": { "message": "Gerar Usuário" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tipo de usuário" - }, "plusAddressedEmail": { "message": "E-mail alternativo (com um +)", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nome do Site" }, - "whatWouldYouLikeToGenerate": { - "message": "O que você gostaria de gerar?" - }, - "passwordType": { - "message": "Categoria de Senha" - }, "service": { "message": "Serviço" }, @@ -3175,25 +3068,25 @@ "message": "Reenviar notificação" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Visualizar todas as opções de login" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "Visualizar todas as opções de login" }, "notificationSentDevice": { "message": "Uma notificação foi enviada para seu dispositivo." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Uma notificação foi enviada para o seu dispositivo" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Certifique-se que sua conta esteja desbloqueada e que a frase de identificação corresponda à do outro dispositivo" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Você será notificado assim que a requisição for aprovada" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Precisa de outra opção?" }, "loginInitiated": { "message": "Login iniciado" @@ -3289,16 +3182,16 @@ "message": "Abrir em uma nova janela" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Lembrar deste dispositivo para permanecer conectado" }, "deviceApprovalRequired": { "message": "Aprovação do dispositivo necessária. Selecione uma opção de aprovação abaixo:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Aprovação do dispositivo necessária" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Selecione uma opção de aprovação abaixo" }, "rememberThisDevice": { "message": "Lembrar deste dispositivo" @@ -3374,7 +3267,7 @@ "message": "E-mail do usuário ausente" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "E-mail de usuário ativo não encontrado. Desconectando." }, "deviceTrusted": { "message": "Dispositivo confiável" @@ -3585,11 +3478,11 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Código de Verificação TOTP", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "Tempo até expirar o código", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { @@ -3821,7 +3714,7 @@ "message": "Acessando" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Sessão Iniciada!" }, "passkeyNotCopied": { "message": "A chave de acesso não será copiada" @@ -4315,13 +4208,13 @@ "message": "Filtros" }, "filterVault": { - "message": "Filter vault" + "message": "Filtrar cofre" }, "filterApplied": { - "message": "One filter applied" + "message": "Um filtro aplicado" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "Foram aplicados $COUNT$ filtros", "placeholders": { "count": { "content": "$1", @@ -4911,22 +4804,22 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Aviso importante" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Configurar login em duas etapas" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden enviará um código para o seu e-mail para verificar novos dispositivos a partir de fevereiro de 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Você pode configurar o login em duas etapas como uma forma alternativa de proteger sua conta ou mudar seu e-mail para um que você possa acessar." }, "remindMeLater": { - "message": "Remind me later" + "message": "Lembre-me depois" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Você tem acesso ao seu e-mail, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4935,24 +4828,24 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Não tenho" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Sim, posso acessar meu e-mail de forma confiável" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Ativar login em duas etapas" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Alterar e-mail" }, "extensionWidth": { - "message": "Extension width" + "message": "Largura da janela" }, "wide": { - "message": "Wide" + "message": "Grande" }, "extraWide": { - "message": "Extra wide" + "message": "Extra Grande" } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 9bac24872e2..24caa7e813d 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Comprimento" }, - "passwordMinLength": { - "message": "Comprimento mínimo da palavra-passe" - }, "uppercase": { "message": "Maiúsculas (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Mínimo de caracteres especiais" }, - "avoidAmbChar": { - "message": "Evitar caracteres ambíguos", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Evitar caracteres ambíguos", "description": "Label for the avoid ambiguous characters checkbox." @@ -568,7 +561,7 @@ "message": "Frase de acesso" }, "favorite": { - "message": "Favorito" + "message": "Adicionar aos favoritos" }, "unfavorite": { "message": "Remover dos favoritos" @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Listar itens de identidades na página Separador para facilitar o preenchimento automático." }, + "clickToAutofillOnVault": { + "message": "Clique nos itens para preencher automaticamente na vista do cofre" + }, "clearClipboard": { "message": "Limpar área de transferência", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Mover para a organização" }, - "share": { - "message": "Partilhar" - }, "movedItemToOrg": { "message": "$ITEMNAME$ movido para $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Duplicar" }, - "passwordGeneratorPolicyInEffect": { - "message": "Uma ou mais políticas da organização estão a afetar as suas definições do gerador." - }, "passwordGenerator": { "message": "Gerador de palavras-passe" }, @@ -2389,14 +2379,6 @@ "message": "Detalhes do Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Procurar Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Adicionar Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Texto" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Ocultar texto por predefinição" }, - "maxAccessCountReached": { - "message": "Número máximo de acessos atingido", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expirado" }, - "pendingDeletion": { - "message": "Eliminação pendente" - }, "passwordProtected": { "message": "Protegido por palavra-passe" }, @@ -2472,24 +2447,9 @@ "message": "Editar Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Que tipo de Send é este?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Um nome simpático para descrever este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "O ficheiro que deseja enviar." - }, "deletionDate": { "message": "Data de eliminação" }, - "deletionDateDesc": { - "message": "O Send será permanentemente eliminado na data e hora especificadas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "O Send será permanentemente eliminado nesta data.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Prazo de validade" }, - "expirationDateDesc": { - "message": "Se definido, o acesso a este Send expirará na data e hora especificadas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dia" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalizado" }, - "maximumAccessCount": { - "message": "Número máximo de acessos" - }, - "maximumAccessCountDesc": { - "message": "Se definido, os utilizadores deixarão de poder aceder a este Send quando a contagem máxima de acessos for atingida.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Opcionalmente, exigir uma palavra-passe para os utilizadores acederem a este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Adicione uma palavra-passe opcional para os destinatários acederem a este Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Notas privadas sobre este Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Desative este Send para que ninguém possa aceder ao mesmo.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copiar o link deste Send para a área de transferência ao guardar.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "O texto que deseja enviar." - }, - "sendHideText": { - "message": "Ocultar o texto deste Send por defeito.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Número de acessos atual" - }, "createSend": { "message": "Novo Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Antes de começar" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Para utilizar um seletor de datas do tipo calendário,", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "clique aqui", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "para abrir a janela.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "O prazo de validade fornecido não é válido." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Ocorreu um erro ao guardar as suas datas de eliminação e validade." }, - "hideEmail": { - "message": "Ocultar o meu endereço de e-mail dos destinatários." - }, "hideYourEmail": { "message": "Oculte o seu endereço de e-mail dos visualizadores." }, - "sendOptionsPolicyInEffect": { - "message": "Uma ou mais políticas da organização estão a afetar as suas opções do Send." - }, "passwordPrompt": { "message": "Pedir novamente a palavra-passe mestra" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Erro" }, - "regenerateUsername": { - "message": "Regenerar nome de utilizador" - }, "generateUsername": { "message": "Gerar nome de utilizador" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tipo de nome de utilizador" - }, "plusAddressedEmail": { "message": "E-mail com subendereço", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nome do site" }, - "whatWouldYouLikeToGenerate": { - "message": "O que é que gostaria de gerar?" - }, - "passwordType": { - "message": "Tipo de palavra-passe" - }, "service": { "message": "Serviço" }, diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index cde1f233488..58c0a313f69 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Lungime" }, - "passwordMinLength": { - "message": "Lungimea minimă a parolei" - }, "uppercase": { "message": "Litere mari (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minim de caractere speciale" }, - "avoidAmbChar": { - "message": "Se evită caracterele ambigue", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Listați elementelor de identitate de pe pagina Filă pentru a facilita completarea automată." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Golire clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Mutare la organizație" }, - "share": { - "message": "Partajare" - }, "movedItemToOrg": { "message": "$ITEMNAME$ mutat la $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clonare" }, - "passwordGeneratorPolicyInEffect": { - "message": "Una sau mai multe politici organizaționale vă afectează setările generatorului." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Căutare Send-uri", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Adăugare Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "S-a atins numărul maxim de accesări", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expirat" }, - "pendingDeletion": { - "message": "Ștergere în așteptare" - }, "passwordProtected": { "message": "Protejat cu parolă" }, @@ -2472,24 +2447,9 @@ "message": "Editare Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Ce fel de Send este acesta?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Un nume prietenos pentru a descrie acest Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Fișierul pe care doriți să-l trimiteți." - }, "deletionDate": { "message": "Data ștergerii" }, - "deletionDateDesc": { - "message": "Send-ul va fi șters definitiv la data și ora specificate.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Data expirării" }, - "expirationDateDesc": { - "message": "Dacă este setat, accesul la acest Send va expira la data și ora specificate.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 zi" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Personalizat" }, - "maximumAccessCount": { - "message": "Număr maxim de accesări" - }, - "maximumAccessCountDesc": { - "message": "Dacă este configurat, utilizatorii nu vor mai putea accesa acest Send când a fost atins numărul maxim de accesări.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Opțional, este necesară o parolă pentru ca utilizatorii să acceseze acest Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Note private despre acest Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Dezactivați acest Send pentru ca nimeni să nu-l poată accesa.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copiază acest link de Send în clipboard la salvare.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Textul pe care doriți să-l trimiteți." - }, - "sendHideText": { - "message": "Ascunde în mod implicit textul acestui Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Numărul actual de accesări" - }, "createSend": { "message": "Nou Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Înainte de a începe" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Pentru a utiliza un selector de date în stil calendar,", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "faceți clic aici", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "pentru ca fereastra dvs să apară.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Data de expirare furnizată nu este validă." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "A survenit o eroare la salvarea datelor de ștergere și de expirare." }, - "hideEmail": { - "message": "Ascundeți adresa mea de e-mail de la destinatari." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Una sau mai multe politici organizaționale vă afectează opțiunile Send-ului." - }, "passwordPrompt": { "message": "Re-solicitare parolă principală" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Eroare" }, - "regenerateUsername": { - "message": "Regenerare nume de utilizator" - }, "generateUsername": { "message": "Generare nume de utilizator" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Tip de nume de utilizator" - }, "plusAddressedEmail": { "message": "E-mail Plus adresat", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Nume website" }, - "whatWouldYouLikeToGenerate": { - "message": "Ce doriți să generați?" - }, - "passwordType": { - "message": "Tip de parolă" - }, "service": { "message": "Serviciu" }, diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index a0279460363..acdee563ceb 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Длина" }, - "passwordMinLength": { - "message": "Минимальная длина пароля" - }, "uppercase": { "message": "Прописные буквы (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Минимум символов" }, - "avoidAmbChar": { - "message": "Избегать неоднозначных символов", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Избегать неоднозначных символов", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Личности будут отображены на вкладке для удобного автозаполнения." }, + "clickToAutofillOnVault": { + "message": "Кликните элементы для автозаполнения в режиме просмотра хранилища" + }, "clearClipboard": { "message": "Очистить буфер обмена", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Переместить в организацию" }, - "share": { - "message": "Поделиться" - }, "movedItemToOrg": { "message": "$ITEMNAME$ перемещен в $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Клонировать" }, - "passwordGeneratorPolicyInEffect": { - "message": "На настройки генератора влияют одна или несколько политик организации." - }, "passwordGenerator": { "message": "Генератор паролей" }, @@ -2389,14 +2379,6 @@ "message": "Информация о Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Поиск Send’ов", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Добавить Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Текст" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Скрыть текст по умолчанию" }, - "maxAccessCountReached": { - "message": "Достигнут максимум обращений", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Срок истек" }, - "pendingDeletion": { - "message": "Ожидание удаления" - }, "passwordProtected": { "message": "Защищено паролем" }, @@ -2472,24 +2447,9 @@ "message": "Изменить Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Выберите тип Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Понятное имя для описания этой Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Файл, который вы хотите отправить." - }, "deletionDate": { "message": "Дата удаления" }, - "deletionDateDesc": { - "message": "Эта Send будет окончательно удалена в указанные дату и время.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "С этой даты Send будет удалена навсегда.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Дата истечения" }, - "expirationDateDesc": { - "message": "Если задано, доступ к этой Send истечет в указанные дату и время.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 день" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Пользовательский" }, - "maximumAccessCount": { - "message": "Максимум обращений" - }, - "maximumAccessCountDesc": { - "message": "Если задано, пользователи больше не смогут получить доступ к этой Send, как только будет достигнуто максимальное количество обращений.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "По возможности запрашивать у пользователей пароль для доступа к этой Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Добавьте опциональный пароль для доступа получателей к этой Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Личные заметки об этой Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Деактивировать эту Send, чтобы никто не мог получить к ней доступ.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Скопировать ссылку на эту Send в буфер обмена после сохранения.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Текст, который вы хотите отправить." - }, - "sendHideText": { - "message": "Скрыть текст этой Send по умолчанию.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Текущих обращений" - }, "createSend": { "message": "Новая Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Перед тем, как начать" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Для использования календарного стиля выбора даты,", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "нажмите здесь", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "для открытия в новом окне.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Срок истечения указан некорректно." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Произошла ошибка при сохранении данных о сроках удаления и истечения." }, - "hideEmail": { - "message": "Скрыть мой адрес email от получателей." - }, "hideYourEmail": { "message": "Скрыть ваш email от просматривающих." }, - "sendOptionsPolicyInEffect": { - "message": "На параметры Send влияют одна или несколько политик организации." - }, "passwordPrompt": { "message": "Повторный запрос мастер-пароля" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Ошибка" }, - "regenerateUsername": { - "message": "Пересоздать имя пользователя" - }, "generateUsername": { "message": "Создать имя пользователя" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Тип имени пользователя" - }, "plusAddressedEmail": { "message": "Субадресованные email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Название сайта" }, - "whatWouldYouLikeToGenerate": { - "message": "Что вы хотите сгенерировать?" - }, - "passwordType": { - "message": "Тип пароля" - }, "service": { "message": "Служба" }, diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 624e6f6f56e..b25c2fd30d5 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -454,9 +454,6 @@ "length": { "message": "දිග" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "අවම විශේෂ" }, - "avoidAmbChar": { - "message": "අපැහැදිලි චරිත වලින් වළකින්න", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "පසුරු පුවරුවට පැහැදිලි", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "සංවිධානය වෙත ගෙනයන්න" }, - "share": { - "message": "බෙදාගන්න" - }, "movedItemToOrg": { "message": "$ITEMNAME$ $ORGNAME$වෙත ගෙන ගියේය", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "ක්ලෝන" }, - "passwordGeneratorPolicyInEffect": { - "message": "සංවිධාන ප්රතිපත්ති එකක් හෝ වැඩි ගණනක් ඔබේ උත්පාදක සැකසුම් වලට බලපායි." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "සෙවුම් යවයි", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "යවන්න එකතු කරන්න", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "පෙළ" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "මැක්ස් ප්රවේශ ගණන ළඟා", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "කල් ඉකුත්" }, - "pendingDeletion": { - "message": "මකාදැමීම" - }, "passwordProtected": { "message": "මුරපදය ආරක්ෂා" }, @@ -2472,24 +2447,9 @@ "message": "යැවීම සංස්කරණය", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "මෙය කුමන ආකාරයේ යවන්න ද?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "මෙම යවන්න විස්තර කිරීමට මිත්රශීලී නමක්.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "ඔබට යැවීමට අවශ්ය ගොනුව." - }, "deletionDate": { "message": "මකාදැමීමේ දිනය" }, - "deletionDateDesc": { - "message": "නියම කරන ලද දිනය හා වේලාව මත Send ස්ථිරවම මකා දමනු ලැබේ.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "කල් ඉකුත්වන දිනය" }, - "expirationDateDesc": { - "message": "සකසා ඇත්නම්, මෙම යවන්න වෙත ප්රවේශය නිශ්චිත දිනය හා වේලාව කල් ඉකුත් වනු ඇත.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "දින 1" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "අභිරුචි" }, - "maximumAccessCount": { - "message": "උපරිම ප්රවේශ ගණන්" - }, - "maximumAccessCountDesc": { - "message": "සකසා ඇත්නම්, උපරිම ප්රවේශ ගණන ළඟා වූ පසු පරිශීලකයින්ට මෙම Send වෙත ප්රවේශ වීමට තවදුරටත් නොහැකි වනු ඇත.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "විකල්පයක් ලෙස පරිශීලකයින්ට මෙම යවන්න වෙත ප්රවේශ වීමට මුරපදයක් අවශ්ය වේ.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "මේ ගැන පෞද්ගලික සටහන් යවන්න.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "මෙය අක්රීය කරන්න යවන්න එවිට කිසිවෙකුට එයට ප්රවේශ විය නොහැක.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "සුරකින්න මත මෙම යවන්න ගේ සබැඳිය පසුරු පුවරුවට පිටපත් කරන්න.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "ඔබට යැවීමට අවශ්ය පෙළ." - }, - "sendHideText": { - "message": "මෙම යවන්න පෙළ පෙරනිමියෙන් සඟවන්න.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "වත්මන් ප්රවේශ ගණන්" - }, "createSend": { "message": "නව යවන්න නිර්මාණය", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "ඔබ ආරම්භ කිරීමට පෙර" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "දින දර්ශනය ශෛලිය දිනය ජීව අත්බෝම්බයක් සමග භාවිතා කිරීමට", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "මෙහි ක්ලික් කරන්න", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "ඔබේ කවුළුව දිස්වේ.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "ලබා දී ඇති කල් ඉකුත්වන දිනය වලංගු නොවේ." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "ඔබගේ මකාදැමීම සහ කල් ඉකුත් වීමේ දිනයන් ඉතිරි කිරීමේ දෝෂයක් තිබුණි." }, - "hideEmail": { - "message": "ලබන්නන්ගෙන් මගේ විද්යුත් තැපැල් ලිපිනය සඟවන්න." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "සංවිධාන ප්රතිපත්ති එකක් හෝ කිහිපයක් ඔබගේ Send විකල්පයන්ට බලපායි." - }, "passwordPrompt": { "message": "ප්රධාන මුරපදය නැවත විමසුමක්" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 48c5007b54b..5d11227f003 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Dĺžka" }, - "passwordMinLength": { - "message": "Minimálna dĺžka hesla" - }, "uppercase": { "message": "Veľké písmená (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum špeciálnych znakov" }, - "avoidAmbChar": { - "message": "Vyhnúť sa zameniteľným znakom", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Vyhnúť sa zameniteľným znakom", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Zoznam položiek identity na stránke \"Aktuálna karta\" na jednoduché automatické vypĺňanie." }, + "clickToAutofillOnVault": { + "message": "Kliknutím na položku v trezore automaticky vyplniť" + }, "clearClipboard": { "message": "Vymazať schránku", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Presunúť do organizácie" }, - "share": { - "message": "Zdieľať" - }, "movedItemToOrg": { "message": "$ITEMNAME$ presunuté do $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klonovať" }, - "passwordGeneratorPolicyInEffect": { - "message": "Jedno alebo viac nastavení organizácie ovplyvňujú vaše nastavenia generátora." - }, "passwordGenerator": { "message": "Generátor hesla" }, @@ -2389,14 +2379,6 @@ "message": "Podrobnosti o Sende", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Hľadať Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Pridať Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "V predvolenom nastavení skryť text" }, - "maxAccessCountReached": { - "message": "Bol dosiahnutý maximálny počet prístupov", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expirované" }, - "pendingDeletion": { - "message": "Čakajúce odstránenie" - }, "passwordProtected": { "message": "Chránené heslom" }, @@ -2472,24 +2447,9 @@ "message": "Upraviť Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Aký typ Sendu to je?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Priateľský názov pre popísanie tohto Sendu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Súbor, ktorý chcete odoslať." - }, "deletionDate": { "message": "Dátum odstránenia" }, - "deletionDateDesc": { - "message": "Send bude natrvalo odstránený v zadaný dátum a čas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send bude natrvalo odstránený v tento deň.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Dátum exspirácie" }, - "expirationDateDesc": { - "message": "Ak je nastavené, prístup k tomuto Sendu vyprší v zadaný dátum a čas.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 deň" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Vlastné" }, - "maximumAccessCount": { - "message": "Maximálny počet prístupov" - }, - "maximumAccessCountDesc": { - "message": "Ak je nastavené, používatelia už nebudú mať prístup k tomuto Sendu po dosiahnutí maximálneho počtu prístupov.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Voliteľne môžete vyžadovať heslo pre používateľov na prístup k tomuto Sendu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Pridajte voliteľné heslo pre príjemcov na prístup k tomuto Sendu.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Zabezpečená poznámka o tomto Sende.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Vypnúť tento Send, aby k nemu nikto nemal prístup.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Pri uložení kopírovať odkaz na Send do schránky.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Text, ktorý chcete odoslať." - }, - "sendHideText": { - "message": "Predvolene skryť text tohto Sendu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Súčasný počet prístupov" - }, "createSend": { "message": "Vytvoriť nový Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Skôr než začnete" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Ak chcete použiť pre výber dátumu štýl kalendára", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "kliknite sem", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "a vysunie sa.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Uvedený dátum exspirácie nie je platný." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Pri ukladaní dátumov odstránenia a vypršania platnosti sa vyskytla chyba." }, - "hideEmail": { - "message": "Skryť moju emailovú adresu pred príjemcami." - }, "hideYourEmail": { "message": "Skryť moju e-mailovú adresu pri zobrazení." }, - "sendOptionsPolicyInEffect": { - "message": "Jedno alebo viac pravidiel organizácie ovplyvňujú vaše možnosti funkcie Send." - }, "passwordPrompt": { "message": "Znova zadajte hlavné heslo" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Chyba" }, - "regenerateUsername": { - "message": "Vygenerovať nové používateľské meno" - }, "generateUsername": { "message": "Vygenerovať používateľské meno" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Typ používateľského mena" - }, "plusAddressedEmail": { "message": "E-mail s plusovým aliasom", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Názov stránky" }, - "whatWouldYouLikeToGenerate": { - "message": "Čo by ste chceli vygenerovať?" - }, - "passwordType": { - "message": "Typ hesla" - }, "service": { "message": "Služba" }, diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 823b2ae0f18..490f991d252 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Dolžina" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Velike črke (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimalno posebnih znakov" }, - "avoidAmbChar": { - "message": "Izogibaj se dvoumnim znakom", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Na strani Zavihek prikaži elemente identitete za lažje samodejno izpolnjevanje." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Počisti odložišče", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Premakni v organizacijo" }, - "share": { - "message": "Deli" - }, "movedItemToOrg": { "message": "Element $ITEMNAME$ premaknjen v $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Podvoji" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Išči pošiljke", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Dodaj pošiljko", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Besedilo" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Poteklo" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Uredi pošiljko", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Kakšna vrsta pošiljke je to?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Prijazno ime, ki opisuje to pošiljko", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Datoteka, ki jo želite poslati" - }, "deletionDate": { "message": "Datum izbrisa" }, - "deletionDateDesc": { - "message": "Pošiljka bo trajno izbrisana ob izbranem času.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Datum poteka" }, - "expirationDateDesc": { - "message": "Če to nastavite, bo pošiljka potekla ob izbranem času.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dan" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Po meri" }, - "maximumAccessCount": { - "message": "Največje dovoljeno število dostopov" - }, - "maximumAccessCountDesc": { - "message": "Če to nastavite, uporabniki po določenem številu dostopov ne bodo mogli več dostopati do pošiljke.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Za dostop do te pošiljke lahko nastavite geslo.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Zasebni zapiski o tej pošiljki.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Onemogoči to pošiljko, da nihče ne more dostopati do nje.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopiraj povezavo te pošiljke v odložišče, ko shranim.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Besedilo, ki ga želite poslati" - }, - "sendHideText": { - "message": "Privzeto skrij besedilo te pošiljke.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Trenutno število dstopov" - }, "createSend": { "message": "Nova pošiljka", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Preden pričnete" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Za vnos datuma s pomočjo koledarčka", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "kliknite tukaj", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "za prikaz v lastnem oknu.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Datum poteka ni veljaven." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Pri shranjevanju datumov poteka in izbrisa je prišlo do napake." }, - "hideEmail": { - "message": "Skrij moj e-naslov pred prejemniki." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Nekatere nastavitve organizacije vplivajo na možnosti, ki jih imate v zvezi s pošiljkami." - }, "passwordPrompt": { "message": "Ponovno zahtevaj glavno geslo" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Napaka" }, - "regenerateUsername": { - "message": "Ponovno ustvari uporabniško ime" - }, "generateUsername": { "message": "Ustvari uporabniško ime" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Vrsta uporabniškega imena" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Ime spletne strani" }, - "whatWouldYouLikeToGenerate": { - "message": "Kaj želite generirati?" - }, - "passwordType": { - "message": "Vrsta gesla" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index e940c908d6f..1a1ebf69794 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Дужина" }, - "passwordMinLength": { - "message": "Минимална дужина лозинке" - }, "uppercase": { "message": "Велика слова (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Минимално специјалних знакова" }, - "avoidAmbChar": { - "message": "Избегавај двосмислене карактере", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Избегавај двосмислене карактере", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Прикажи ставке идентитета на страници за лакше аутоматско допуњавање." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Обриши привремену меморију", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Премести у организацију" }, - "share": { - "message": "Подели" - }, "movedItemToOrg": { "message": "$ITEMNAME$ премештен у $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Клонирај" }, - "passwordGeneratorPolicyInEffect": { - "message": "Једна или више смерница организације утичу на поставке вашег генератора." - }, "passwordGenerator": { "message": "Генератор Лозинке" }, @@ -2389,14 +2379,6 @@ "message": "Детаљи Send-а", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Тражи „Send“", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Додај „Send“", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Текст" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Сакриј текст подразумевано" }, - "maxAccessCountReached": { - "message": "Достигнут максималан број приступа", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Истекло" }, - "pendingDeletion": { - "message": "Брисање на чекању" - }, "passwordProtected": { "message": "Заштићено лозинком" }, @@ -2472,24 +2447,9 @@ "message": "Уреди „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Који је ово тип „Send“-a?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Име да се опише овај „Send“.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Датотека коју желиш да пошаљеш." - }, "deletionDate": { "message": "Брисање после" }, - "deletionDateDesc": { - "message": "„Send“ ће бити трајно избрисан наведеног датума и времена.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Send ће бити трајно обрисано у наведени датум.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Рок употребе" }, - "expirationDateDesc": { - "message": "Ако је постављено, приступ овом „Send“ истиче на наведени датум и време.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 дан" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Друго" }, - "maximumAccessCount": { - "message": "Максималан број приступа" - }, - "maximumAccessCountDesc": { - "message": "Ако је постављено, корисници више неће моћи да приступе овом „Send“ када се достигне максимални број приступа.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Опционално захтевајте лозинку за приступ корисницима „Send“-у.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Додајте опционалну лозинку за примаоце да приступе овом Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Приватне белешке о овом „Send“.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Онемогућите овај „Send“ да нико не би могао да му приступи.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Након чувања, копирај УРЛ за овај „Send“ у привремену меморију.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Текст који желиш да пошаљеш." - }, - "sendHideText": { - "message": "Подразумевано сакриј текст за овај „Send“.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Тренутни број приступа" - }, "createSend": { "message": "Креирај нови „Send“", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Пре него што почнеш" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Да би користио бирање датума кроз календар", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "кликните овде", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "Да бисте приказали искачући прозор.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Наведени датум истека није исправан." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Појавила се грешка при чувању датума брисања и истека." }, - "hideEmail": { - "message": "Сакриј моју е-адресу од примаоца." - }, "hideYourEmail": { "message": "Сакријте свој имејл од гледалаца." }, - "sendOptionsPolicyInEffect": { - "message": "Једна или више смерница организације утичу на опције „Send“-а." - }, "passwordPrompt": { "message": "Поновно тражење главне лозинке" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Грешка" }, - "regenerateUsername": { - "message": "Поново генериши име" - }, "generateUsername": { "message": "Генериши име" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Тип имена" - }, "plusAddressedEmail": { "message": "Плус имејл адресе", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Име Вашег веб-сајта" }, - "whatWouldYouLikeToGenerate": { - "message": "Шта желите да генеришете?" - }, - "passwordType": { - "message": "Тип лозинке" - }, "service": { "message": "Сервис" }, diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 3cfb2feb37d..84de9bbfa05 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Längd" }, - "passwordMinLength": { - "message": "Minsta tillåtna lösenordslängd" - }, "uppercase": { "message": "Versaler (A-Ö)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minsta antal speciella tecken" }, - "avoidAmbChar": { - "message": "Undvik tvetydiga tecken", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Undvik tvetydiga tecken", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Lista identitetsobjekt på fliksidan för enkel automatisk fyllning." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Rensa urklipp", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Flytta till organisation" }, - "share": { - "message": "Dela" - }, "movedItemToOrg": { "message": "$ITEMNAME$ flyttades till $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klona" }, - "passwordGeneratorPolicyInEffect": { - "message": "En eller flera organisationspolicyer påverkar dina generatorinställningar." - }, "passwordGenerator": { "message": "Lösenordsgenerator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Sök bland Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Lägg till Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Det maximala antalet åtkomster har uppnåtts", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Utgången" }, - "pendingDeletion": { - "message": "Väntar på radering" - }, "passwordProtected": { "message": "Lösenordsskyddad" }, @@ -2472,24 +2447,9 @@ "message": "Redigera Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Vilken typ av Send är detta?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Ett vänligt namn som beskriver denna Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Filen du vill skicka." - }, "deletionDate": { "message": "Raderingsdatum" }, - "deletionDateDesc": { - "message": "Denna Send kommer att raderas permanent på angivet datum och klockslag.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Utgångsdatum" }, - "expirationDateDesc": { - "message": "Om angiven kommer åtkomst till denna Send att upphöra på angivet datum och tid.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 dag" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Anpassad" }, - "maximumAccessCount": { - "message": "Maximalt antal åtkomster" - }, - "maximumAccessCountDesc": { - "message": "Om angivet kommer användare inte längre kunna komma åt denna Send när det maximala antalet åtkomster har uppnåtts.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Kräv valfritt ett lösenord för att användare ska komma åt denna Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Privata anteckningar om denna Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Inaktivera denna Send så att ingen kan komma åt den.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kopiera länken till denna Send vid sparande.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Texten du vill skicka." - }, - "sendHideText": { - "message": "Dölj texten för denna Send som standard", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Nuvarande antal åtkomster" - }, "createSend": { "message": "Ny Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Innan du börjar" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "För att använda en datumväljare med kalenderstil", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "klicka här", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "för att öppna ett nytt fönster.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Det angivna utgångsdatumet är inte giltigt." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Det gick inte att spara raderings- och utgångsdatum." }, - "hideEmail": { - "message": "Dölj min e-postadress för mottagare." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "En eller flera organisationsriktlinjer påverkar dina Send-inställningar." - }, "passwordPrompt": { "message": "Återupprepa huvudlösenord" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Fel" }, - "regenerateUsername": { - "message": "Återskapa användarnamn" - }, "generateUsername": { "message": "Generera användarnamn" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Typ av användarnamn" - }, "plusAddressedEmail": { "message": "Plusadresserad e-post", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Webbplatsnamn" }, - "whatWouldYouLikeToGenerate": { - "message": "Vad skulle du vilja generera?" - }, - "passwordType": { - "message": "Lösenordstyp" - }, "service": { "message": "Tjänst" }, diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 8f7673803cb..6ab3755c8f4 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Length" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "Uppercase (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum special" }, - "avoidAmbChar": { - "message": "Avoid ambiguous characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "List identity items on the Tab page for easy autofill." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Move to organization" }, - "share": { - "message": "Share" - }, "movedItemToOrg": { "message": "$ITEMNAME$ moved to $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Clone" }, - "passwordGeneratorPolicyInEffect": { - "message": "One or more organization policies are affecting your generator settings." - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Search Sends", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Add Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Text" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "Edit Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 day" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "The text you want to send." - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 2d65bb40f1a..d9ff1c3f076 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -454,9 +454,6 @@ "length": { "message": "ความยาว" }, - "passwordMinLength": { - "message": "Minimum password length" - }, "uppercase": { "message": "ตัวพิมพ์ใหญ่ (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Minimum Special" }, - "avoidAmbChar": { - "message": "Avoid Ambiguous Characters", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "แสดงรายการข้อมูลประจำตัวในหน้าแท็บเพื่อให้ป้อนอัตโนมัติได้ง่าย" }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "ล้างคลิปบอร์ด", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "ย้ายไปยังแบบองค์กร" }, - "share": { - "message": "แชร์" - }, "movedItemToOrg": { "message": "ย้าย $ITEMNAME$ ไปยัง $ORGNAME$ แล้ว", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "โคลน" }, - "passwordGeneratorPolicyInEffect": { - "message": "นโยบายองค์กรอย่างน้อยหนึ่งนโยบายส่งผลต่อการตั้งค่าตัวสร้างของคุณ" - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "ค้นหาใน Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "เพิ่ม Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "ข้อความ" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Max access count reached", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Expired" }, - "pendingDeletion": { - "message": "Pending deletion" - }, "passwordProtected": { "message": "Password protected" }, @@ -2472,24 +2447,9 @@ "message": "แก้ไข Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "What type of Send is this?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "A friendly name to describe this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "The file you want to send." - }, "deletionDate": { "message": "Deletion date" }, - "deletionDateDesc": { - "message": "The Send will be permanently deleted on the specified date and time.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Expiration date" }, - "expirationDateDesc": { - "message": "If set, access to this Send will expire on the specified date and time.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 วัน" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Custom" }, - "maximumAccessCount": { - "message": "Maximum Access Count" - }, - "maximumAccessCountDesc": { - "message": "If set, users will no longer be able to access this Send once the maximum access count is reached.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Optionally require a password for users to access this Send.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Private notes about this Send.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Deactivate this Send so that no one can access it.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Copy this Send's link to clipboard upon save.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "ข้อความที่คุณต้องการส่ง" - }, - "sendHideText": { - "message": "Hide this Send's text by default.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Current access count" - }, "createSend": { "message": "New Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Before you start" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "To use a calendar style date picker", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "click here", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "to pop out your window.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "The expiration date provided is not valid." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "There was an error saving your deletion and expiration dates." }, - "hideEmail": { - "message": "Hide my email address from recipients." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "One or more organization policies are affecting your Send options." - }, "passwordPrompt": { "message": "Master password re-prompt" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Error" }, - "regenerateUsername": { - "message": "Regenerate username" - }, "generateUsername": { "message": "Generate username" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Username type" - }, "plusAddressedEmail": { "message": "Plus addressed email", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Website name" }, - "whatWouldYouLikeToGenerate": { - "message": "What would you like to generate?" - }, - "passwordType": { - "message": "Password type" - }, "service": { "message": "Service" }, diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 4c87d5189fe..a4c064e0394 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Uzunluk" }, - "passwordMinLength": { - "message": "Minimum parola uzunluğu" - }, "uppercase": { "message": "Büyük harf (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "En az özel karakter" }, - "avoidAmbChar": { - "message": "Okurken karışabilecek karakterleri kullanma", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Okurken karışabilecek karakterleri kullanma", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Kolay otomatik doldurma için sekme sayfasında kimlikleri listele." }, + "clickToAutofillOnVault": { + "message": "Kasa görünümünde otomatik doldurmak istediğiniz kayıtlara tıklayın" + }, "clearClipboard": { "message": "Panoyu temizle", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Kuruluşa taşı" }, - "share": { - "message": "Paylaş" - }, "movedItemToOrg": { "message": "$ITEMNAME$ $ORGNAME$ kuruluşuna taşındı", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Klonla" }, - "passwordGeneratorPolicyInEffect": { - "message": "Bir ya da daha fazla kuruluş ilkesi, oluşturucu ayarlarınızı etkiliyor." - }, "passwordGenerator": { "message": "Parola üreteci" }, @@ -2389,14 +2379,6 @@ "message": "Send ayrıntıları", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Send'lerde ara", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Send ekle", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Metin" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Metni varsayılan olarak gizle" }, - "maxAccessCountReached": { - "message": "Maksimum erişim sayısına ulaşıldı", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Süresi dolmuş" }, - "pendingDeletion": { - "message": "Silinmesi bekleniyor" - }, "passwordProtected": { "message": "Parola korumalı" }, @@ -2472,24 +2447,9 @@ "message": "Send'i düzenle", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Bu ne tür bir Send?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Bu Send'i açıklayan anlaşılır bir ad", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Göndermek istediğiniz dosya." - }, "deletionDate": { "message": "Silinme tarihi" }, - "deletionDateDesc": { - "message": "Bu Send belirtilen tarih ve saatte kalıcı olacak silinecek.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Bu Send belirtilen tarihte kalıcı olacak silinecek.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Son kullanma tarihi" }, - "expirationDateDesc": { - "message": "Bunu ayarlarsanız belirtilen tarih ve saatten sonra bu Send'e erişilemeyecektir.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 gün" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Özel" }, - "maximumAccessCount": { - "message": "Maksimum erişim sayısı" - }, - "maximumAccessCountDesc": { - "message": "Bunu ayarlarsanız maksimum erişim sayısına ulaşıldıktan sonra bu Send'e erişilemeyecektir.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Kullanıcıların bu Send'e erişmek için parola girmelerini isteyebilirsiniz.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "Alıcıların bu Send'e erişmesi için isterseniz parola ekleyebilirsiniz.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Bu Send ile ilgili özel notlar.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Kimsenin erişememesi için bu Send'i devre dışı bırak.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Kaydettikten sonra bu Send'in linkini panoya kopyala.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Göndermek istediğiniz metin." - }, - "sendHideText": { - "message": "Bu Send'in metnini varsayılan olarak gizle.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Mevcut erişim sayısı" - }, "createSend": { "message": "Yeni Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Başlamadan önce" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Takvim tarzı tarih seçiyi kullanmak için", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "buraya tıklayarak", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "yeni bir pencere açın.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Belirtilen son kullanma tarihi geçersiz." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Silinme ve son kullanma tarihleriniz kaydedilirken bir hata oluştu." }, - "hideEmail": { - "message": "E-posta adresimi alıcılardan gizle." - }, "hideYourEmail": { "message": "E-posta adresimi Send'i görüntüleyenlerden gizle." }, - "sendOptionsPolicyInEffect": { - "message": "Bir veya daha fazla kuruluş ilkesi Send seçeneklerinizi etkiliyor." - }, "passwordPrompt": { "message": "Ana parolayı yeniden iste" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Hata" }, - "regenerateUsername": { - "message": "Kullanıcı adını yeniden oluştur" - }, "generateUsername": { "message": "Kullanıcı adı oluştur" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Kullanıcı adı türü" - }, "plusAddressedEmail": { "message": "Artı adresli e-posta", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Web sitesi adı" }, - "whatWouldYouLikeToGenerate": { - "message": "Ne oluşturmak istersiniz?" - }, - "passwordType": { - "message": "Parola türü" - }, "service": { "message": "Servis" }, diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index af8f6668111..c817b55dab3 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Довжина" }, - "passwordMinLength": { - "message": "Мінімальна довжина пароля" - }, "uppercase": { "message": "Верхній регістр (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Мінімум спеціальних символів" }, - "avoidAmbChar": { - "message": "Уникати неоднозначних символів", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Уникати неоднозначних символів", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Показувати список посвідчень на сторінці вкладки для легкого автозаповнення." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Очистити буфер обміну", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Перемістити до організації" }, - "share": { - "message": "Поділитися" - }, "movedItemToOrg": { "message": "$ITEMNAME$ переміщено до $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Клонувати" }, - "passwordGeneratorPolicyInEffect": { - "message": "На параметри генератора впливають одна чи декілька політик організації." - }, "passwordGenerator": { "message": "Генератор паролів" }, @@ -2389,14 +2379,6 @@ "message": "Надіслати подробиці", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Шукати відправлення", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Додати відправлення", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Текст" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Типово приховувати текст" }, - "maxAccessCountReached": { - "message": "Досягнуто максимальної кількості доступів", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Термін дії завершився" }, - "pendingDeletion": { - "message": "Очікується видалення" - }, "passwordProtected": { "message": "Захищено паролем" }, @@ -2472,24 +2447,9 @@ "message": "Редагування", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Який це тип відправлення?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Опис цього відправлення.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Файл, який ви хочете відправити." - }, "deletionDate": { "message": "Термін дії" }, - "deletionDateDesc": { - "message": "Відправлення буде остаточно видалено у вказаний час.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "Відправлення буде остаточно видалено у вказану дату.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Дата завершення" }, - "expirationDateDesc": { - "message": "Якщо встановлено, термін дії цього відправлення завершиться у вказаний час.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 день" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Власний" }, - "maximumAccessCount": { - "message": "Максимальна кількість доступів" - }, - "maximumAccessCountDesc": { - "message": "Якщо встановлено, користувачі більше не зможуть отримати доступ до цього відправлення після досягнення максимальної кількості доступів.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Ви можете встановити пароль для доступу до цього відправлення.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "За бажання додайте пароль для отримувачів цього відправлення.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Особисті нотатки про це відправлення.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Деактивувати це відправлення для скасування доступу до нього.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Копіювати посилання цього відправлення перед збереженням.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Текст, який ви хочете відправити." - }, - "sendHideText": { - "message": "Приховувати текст цього відправлення.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Поточна кількість доступів" - }, "createSend": { "message": "Нове відправлення", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Перед початком" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Щоб використовувати календарний стиль вибору дати", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "натисніть тут", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "щоб відкріпити ваше вікно.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Вказано недійсний термін дії." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "При збереженні дат видалення і терміну дії виникла помилка." }, - "hideEmail": { - "message": "Приховувати мою адресу електронної пошти від отримувачів." - }, "hideYourEmail": { "message": "Приховати адресу е-пошти від отримувачів." }, - "sendOptionsPolicyInEffect": { - "message": "На параметри відправлень впливають одна чи декілька політик організації." - }, "passwordPrompt": { "message": "Повторний запит головного пароля" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Помилка" }, - "regenerateUsername": { - "message": "Повторно генерувати ім'я користувача" - }, "generateUsername": { "message": "Генерувати ім'я користувача" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Тип імені користувача" - }, "plusAddressedEmail": { "message": "Адреса е-пошти з плюсом", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Назва вебсайту" }, - "whatWouldYouLikeToGenerate": { - "message": "Що ви бажаєте згенерувати?" - }, - "passwordType": { - "message": "Тип пароля" - }, "service": { "message": "Послуга" }, diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index db877e318ef..268b12a6254 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -454,9 +454,6 @@ "length": { "message": "Độ dài" }, - "passwordMinLength": { - "message": "Độ dài mật khẩu tối thiểu" - }, "uppercase": { "message": "Chữ in hoa (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "Số kí tự đặc biệt tối thiểu" }, - "avoidAmbChar": { - "message": "Tránh các ký tự không rõ ràng", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "Liệt kê các mục danh tính trên trang Tab để dễ dàng tự động điền." }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "Dọn dẹp khay nhớ tạm", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "Di chuyển đến tổ chức" }, - "share": { - "message": "Chia sẻ" - }, "movedItemToOrg": { "message": "$ITEMNAME$ đã được di chuyển đến $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "Tạo bản sao" }, - "passwordGeneratorPolicyInEffect": { - "message": "Các chính sách của tổ chức đang ảnh hưởng đến cài đặt tạo mật khẩu của bạn." - }, "passwordGenerator": { "message": "Trình tạo mật khẩu" }, @@ -2389,14 +2379,6 @@ "message": "Send details", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "Tìm kiếm mục Gửi", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "Thêm mục Gửi", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "Văn bản" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "Hide text by default" }, - "maxAccessCountReached": { - "message": "Đã vượt số lần truy cập tối đa", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "Đã hết hạn" }, - "pendingDeletion": { - "message": "Đang chờ xóa" - }, "passwordProtected": { "message": "Mật khẩu đã được bảo vệ" }, @@ -2472,24 +2447,9 @@ "message": "Sửa mục Gửi", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "Đây là loại Send gì?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "Một cái tên thân thiện để mô tả về Send này.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "Tập tin bạn muốn gửi." - }, "deletionDate": { "message": "Ngày xóa" }, - "deletionDateDesc": { - "message": "Mục Gửi sẽ được xóa vĩnh viễn vào ngày và giờ chỉ định.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "Ngày hết hạn" }, - "expirationDateDesc": { - "message": "Nếu được thiết lập, mục Gửi này sẽ hết hạn vào ngày và giờ được chỉ định.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 ngày" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "Tùy chỉnh" }, - "maximumAccessCount": { - "message": "Số lượng truy cập tối đa" - }, - "maximumAccessCountDesc": { - "message": "Nếu được thiết lập, khi đã đạt tới số lượng truy cập tối đa, người dùng sẽ không thể truy cập mục Gửi này nữa.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "Yêu cầu nhập mật khẩu khi người dùng truy cập vào phần Gửi này.", - "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.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "Ghi chú riêng tư về Send này.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "Vô hiệu hoá mục Gửi này để không ai có thể truy cập nó.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "Sao chép liên kết của Send này vào khay nhớ tạm khi lưu.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "Văn bản bạn muốn gửi." - }, - "sendHideText": { - "message": "Ẩn văn bản của Send này theo mặc định.", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "Số lượng truy cập hiện tại" - }, "createSend": { "message": "Send mới", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "Trước khi bạn bắt đầu" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "Để dùng bộ chọn ngày dạng lịch", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "nhấn vào đây", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "để bật cửa sổ của bạn ra.", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "Ngày hết hạn bạn nhập không hợp lệ." }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "Đã xảy ra lỗi khi lưu ngày xoá và ngày hết hạn của bạn." }, - "hideEmail": { - "message": "Ẩn địa chỉ email của tôi khỏi người nhận." - }, "hideYourEmail": { "message": "Hide your email address from viewers." }, - "sendOptionsPolicyInEffect": { - "message": "Các chính sách của tổ chức đang ảnh hưởng đến tùy chọn Gửi của bạn." - }, "passwordPrompt": { "message": "Nhắc lại mật khẩu chính" }, @@ -2884,9 +2789,6 @@ "error": { "message": "Lỗi" }, - "regenerateUsername": { - "message": "Tạo lại tên người dùng" - }, "generateUsername": { "message": "Tạo tên người dùng" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "Loại tên người dùng" - }, "plusAddressedEmail": { "message": "Địa chỉ email có hậu tố", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "Tên website" }, - "whatWouldYouLikeToGenerate": { - "message": "Bạn muốn tạo gì?" - }, - "passwordType": { - "message": "Loại mật khẩu" - }, "service": { "message": "Dịch vụ" }, @@ -4911,10 +4804,10 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Thông báo quan trọng" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Thiết lập đăng nhập hai bước" }, "newDeviceVerificationNoticeContentPage1": { "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." @@ -4923,7 +4816,7 @@ "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." }, "remindMeLater": { - "message": "Remind me later" + "message": "Nhắc sau" }, "newDeviceVerificationNoticePageOneFormContent": { "message": "Do you have reliable access to your email, $EMAIL$?", @@ -4935,16 +4828,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Không, tôi không có" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Có, tôi có quyền truy cập email này" }, "turnOnTwoStepLogin": { "message": "Turn on two-step login" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Đổi email tài khoản" }, "extensionWidth": { "message": "Extension width" diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index a738ea4bb70..39a945360f8 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -50,7 +50,7 @@ "message": "提交" }, "emailAddress": { - "message": "电子邮件地址" + "message": "电子邮箱地址" }, "masterPass": { "message": "主密码" @@ -239,7 +239,7 @@ "message": "添加项目" }, "accountEmail": { - "message": "账户邮件地址" + "message": "账户电子邮箱" }, "requestHint": { "message": "请求提示" @@ -248,13 +248,13 @@ "message": "请求密码提示" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "输入您的账户电子邮件地址,您的密码提示将发送给您" + "message": "输入您的账户电子邮箱地址,您的密码提示将发送给您" }, "passwordHint": { "message": "密码提示" }, "enterEmailToGetHint": { - "message": "请输入您账户的电子邮件地址来接收主密码提示。" + "message": "请输入您的账户电子邮箱地址来接收主密码提示。" }, "getMasterPasswordHint": { "message": "获取主密码提示" @@ -379,7 +379,7 @@ "message": "文件夹名称" }, "folderHintText": { - "message": "通过在父文件夹名后面跟随一个「/」来嵌套文件夹。例如:Social/Forums" + "message": "通过在父文件夹名后面跟随「/」来嵌套文件夹。示例:Social/Forums" }, "noFoldersAdded": { "message": "未添加文件夹" @@ -454,9 +454,6 @@ "length": { "message": "长度" }, - "passwordMinLength": { - "message": "最小密码长度" - }, "uppercase": { "message": "大写 (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "符号最少个数" }, - "avoidAmbChar": { - "message": "避免易混淆的字符", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "避免易混淆的字符", "description": "Label for the avoid ambiguous characters checkbox." @@ -758,10 +751,10 @@ "message": "发生了一个错误" }, "emailRequired": { - "message": "必须填写电子邮件地址。" + "message": "必须填写电子邮箱地址。" }, "invalidEmail": { - "message": "无效的电子邮件地址。" + "message": "无效的电子邮箱地址。" }, "masterPasswordRequired": { "message": "必须填写主密码。" @@ -798,7 +791,7 @@ "message": "您可以关闭此窗口" }, "masterPassSent": { - "message": "我们已经为您发送了包含主密码提示的邮件。" + "message": "我们已经为您发送了包含主密码提示的电子邮件。" }, "verificationCodeRequired": { "message": "必须填写验证码。" @@ -820,7 +813,7 @@ } }, "autofillError": { - "message": "无法在此页面上自动填充所选项目。请改为手动复制并粘贴。" + "message": "无法在此页面上自动填充所选项目。请手动复制并粘贴。" }, "totpCaptureError": { "message": "无法从当前网页扫描二维码" @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "在标签页上列出身份项目,以便于自动填充。" }, + "clickToAutofillOnVault": { + "message": "在密码库视图中点击项目以自动填充" + }, "clearClipboard": { "message": "清空剪贴板", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "移动到组织" }, - "share": { - "message": "共享" - }, "movedItemToOrg": { "message": "$ITEMNAME$ 已移动到 $ORGNAME$", "placeholders": { @@ -1330,7 +1323,7 @@ "message": "身份验证会话超时。请重新启动登录过程。" }, "enterVerificationCodeEmail": { - "message": "请输入发送给电子邮件 $EMAIL$ 的 6 位数验证码。", + "message": "请输入发送给 $EMAIL$ 的 6 位数验证码。", "placeholders": { "email": { "content": "$1", @@ -1407,7 +1400,7 @@ "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { - "message": "为您的组织使用 Duo Security 的 Duo 移动应用、短信、电话或 U2F 安全钥匙来进行验证。", + "message": "为您的组织使用 Duo Security 的 Duo 移动 App、短信、电话或 U2F 安全钥匙来进行验证。", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "webAuthnTitle": { @@ -1417,7 +1410,7 @@ "message": "使用任何 WebAuthn 兼容的安全钥匙访问您的帐户。" }, "emailTitle": { - "message": "电子邮件" + "message": "电子邮箱" }, "emailDescV2": { "message": "输入发送到您的电子邮箱的代码。" @@ -1435,7 +1428,7 @@ "message": "对于高级配置,您可以单独指定每个服务的基础 URL。" }, "selfHostedEnvFormInvalid": { - "message": "您必须添加基础服务器 URL 或至少添加一个自定义环境。" + "message": "您必须添加基础服务器 URL 或至少一个自定义环境。" }, "customEnvironment": { "message": "自定义环境" @@ -1727,7 +1720,7 @@ "message": "许可证号码" }, "email": { - "message": "电子邮件" + "message": "电子邮箱" }, "phone": { "message": "电话" @@ -2047,9 +2040,6 @@ "clone": { "message": "克隆" }, - "passwordGeneratorPolicyInEffect": { - "message": "一个或多个组织策略正在影响您的生成器设置。" - }, "passwordGenerator": { "message": "密码生成器" }, @@ -2205,13 +2195,13 @@ "message": "取消订阅" }, "atAnyTime": { - "message": "随时" + "message": "随时。" }, "byContinuingYouAgreeToThe": { "message": "若继续,代表您同意" }, "and": { - "message": "以及" + "message": "和" }, "acceptPolicies": { "message": "选中此框表示您同意:" @@ -2389,14 +2379,6 @@ "message": "Send 详细信息", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "搜索 Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "添加 Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "文本" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "默认隐藏文本" }, - "maxAccessCountReached": { - "message": "已达最大访问次数", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "已过期" }, - "pendingDeletion": { - "message": "等待删除" - }, "passwordProtected": { "message": "密码保护" }, @@ -2472,24 +2447,9 @@ "message": "编辑 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "这是什么类型的 Send?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "用于描述此 Send 的友好名称。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "您想要发送的文件。" - }, "deletionDate": { "message": "删除日期" }, - "deletionDateDesc": { - "message": "此 Send 将在指定的日期和时间后被永久删除。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "此 Send 将在此日期后被永久删除。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "过期日期" }, - "expirationDateDesc": { - "message": "设置后,对此 Send 的访问将在指定的日期和时间后过期。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 天" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "自定义" }, - "maximumAccessCount": { - "message": "最大访问次数" - }, - "maximumAccessCountDesc": { - "message": "设置后,当达到最大访问次数时用户将不再能访问此 Send。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "可选,用户需要提供密码才能访问此 Send。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "添加一个用于收件人访问此 Send 的可选密码。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "关于此 Send 的私密备注。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "停用此 Send 则任何人无法访问它。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "保存时复制此 Send 的链接到剪贴板。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "您想要发送的文本。" - }, - "sendHideText": { - "message": "默认隐藏此 Send 的文本。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "当前访问次数" - }, "createSend": { "message": "创建 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "在开始之前" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "要使用日历样式的日期选择器", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "点击这里", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "来弹出窗口。", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "所提供的过期日期无效。" }, @@ -2662,14 +2573,8 @@ "dateParsingError": { "message": "保存您的删除和过期日期时出错。" }, - "hideEmail": { - "message": "对收件人隐藏我的电子邮件地址。" - }, "hideYourEmail": { - "message": "对查看者隐藏您的电子邮件地址。" - }, - "sendOptionsPolicyInEffect": { - "message": "一个或多个组织策略正在影响您的 Send 选项。" + "message": "对查看者隐藏您的电子邮箱地址。" }, "passwordPrompt": { "message": "主密码重新提示" @@ -2681,13 +2586,13 @@ "message": "此操作受到保护。若要继续,请重新输入您的主密码以验证您的身份。" }, "emailVerificationRequired": { - "message": "需要验证电子邮件" + "message": "需要验证电子邮箱" }, "emailVerifiedV2": { "message": "电子邮箱已验证" }, "emailVerificationRequiredDesc": { - "message": "您必须验证电子邮件才能使用此功能。您可以在网页密码库中验证您的电子邮件。" + "message": "您必须验证电子邮箱才能使用此功能。您可以在网页密码库中验证您的电子邮箱。" }, "updatedMasterPassword": { "message": "已更新主密码" @@ -2884,14 +2789,11 @@ "error": { "message": "错误" }, - "regenerateUsername": { - "message": "重新生成用户名" - }, "generateUsername": { "message": "生成用户名" }, "generateEmail": { - "message": "生成电子邮件地址" + "message": "生成电子邮箱" }, "spinboxBoundariesHint": { "message": "值必须在 $MIN$ 和 $MAX$ 之间。", @@ -2927,18 +2829,15 @@ } } }, - "usernameType": { - "message": "用户名类型" - }, "plusAddressedEmail": { - "message": "附加地址电子邮件", + "message": "附加地址电子邮箱", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "使用您的电子邮件供应商的子地址功能。" + "message": "使用您的电子邮箱提供商的子地址功能。" }, "catchallEmail": { - "message": "Catch-all 电子邮件" + "message": "Catch-all 电子邮箱" }, "catchallEmailDesc": { "message": "使用您的域名配置的 Catch-all 收件箱。" @@ -2952,23 +2851,17 @@ "websiteName": { "message": "网站名称" }, - "whatWouldYouLikeToGenerate": { - "message": "您想要生成什么?" - }, - "passwordType": { - "message": "密码类型" - }, "service": { "message": "服务" }, "forwardedEmail": { - "message": "转发的电子邮件别名" + "message": "转发的电子邮箱别名" }, "forwardedEmailDesc": { - "message": "使用外部转发服务生成一个电子邮件别名。" + "message": "使用外部转发服务生成一个电子邮箱别名。" }, "forwarderDomainName": { - "message": "电子邮件域名", + "message": "电子邮箱域名", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { @@ -3028,7 +2921,7 @@ } }, "forwarderNoAccountId": { - "message": "无法获取 $SERVICENAME$ 电子邮件账户 ID。", + "message": "无法获取 $SERVICENAME$ 电子邮箱账户 ID。", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -3157,7 +3050,7 @@ "message": "初来乍到吗?" }, "rememberEmail": { - "message": "记住电子邮件地址" + "message": "记住电子邮箱" }, "loginWithDevice": { "message": "使用设备登录" @@ -3319,7 +3212,7 @@ "message": "必须填写组织 SSO 标识符。" }, "creatingAccountOn": { - "message": "正创建账户于" + "message": "创建账户至" }, "checkYourEmail": { "message": "检查您的电子邮箱" @@ -3337,7 +3230,7 @@ "message": "返回" }, "toEditYourEmailAddress": { - "message": "编辑您的电子邮件地址。" + "message": "编辑您的电子邮箱地址。" }, "eu": { "message": "欧盟", @@ -3371,10 +3264,10 @@ "message": "登录已批准" }, "userEmailMissing": { - "message": "缺少用户电子邮件" + "message": "缺少用户电子邮箱" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "未找到活动的用户电子邮件。您将被注销。" + "message": "未找到活动的用户电子邮箱。您将被注销。" }, "deviceTrusted": { "message": "设备已信任" @@ -3442,14 +3335,14 @@ } }, "multipleInputEmails": { - "message": "一个或多个电子邮件地址无效" + "message": "一个或多个电子邮箱无效" }, "inputTrimValidator": { "message": "输入不能只包含空格。", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "输入的不是电子邮件地址。" + "message": "输入的不是电子邮箱地址。" }, "fieldsNeedAttention": { "message": "上面的 $COUNT$ 个字段需要您注意。", @@ -4167,7 +4060,7 @@ "message": "分配到集合" }, "copyEmail": { - "message": "复制电子邮件地址" + "message": "复制电子邮箱" }, "copyPhone": { "message": "复制电话号码" @@ -4270,7 +4163,7 @@ "message": "所有者:您" }, "linked": { - "message": "已链接" + "message": "链接型" }, "copySuccessful": { "message": "复制成功" @@ -4498,10 +4391,10 @@ "message": "对于如密码之类的敏感数据,请使用隐藏型字段" }, "checkBoxHelpText": { - "message": "如果您想自动勾选表单复选框(例如记住电子邮件地址),请使用复选框型" + "message": "如果您想自动勾选表单复选框(例如记住电子邮箱),请使用复选框型字段" }, "linkedHelpText": { - "message": "当您处理特定网站的自动填充问题时,请使用链接型字段。" + "message": "当您处理特定网站的自动填充问题时,请使用链接型字段" }, "linkedLabelHelpText": { "message": "输入字段的 html id、名称、aria-label 或占位符。" @@ -4917,16 +4810,16 @@ "message": "设置两步登录" }, "newDeviceVerificationNoticeContentPage1": { - "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮件地址发送一个代码,以验证从新设备上的登录。" + "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮箱发送一个代码,以验证来自新设备的登录。" }, "newDeviceVerificationNoticeContentPage2": { - "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮件地址更改为您可以访问的电子邮件地址。" + "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" }, "remindMeLater": { "message": "稍后提醒我" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "您可以可靠地访问您的电子邮件地址 $EMAIL$ 吗?", + "message": "您能可靠地访问您的电子邮箱 $EMAIL$ 吗?", "placeholders": { "email": { "content": "$1", @@ -4938,13 +4831,13 @@ "message": "不,我不能" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "是的,我可以可靠地访问我的电子邮件地址" + "message": "是的,我可以可靠地访问我的电子邮箱" }, "turnOnTwoStepLogin": { "message": "开启两步登录" }, "changeAcctEmail": { - "message": "更改账户电子邮件" + "message": "更改账户电子邮箱" }, "extensionWidth": { "message": "扩展宽度" diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index ae903678521..4b215df6ba2 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -454,9 +454,6 @@ "length": { "message": "長度" }, - "passwordMinLength": { - "message": "最小密碼長度" - }, "uppercase": { "message": "大寫 (A-Z)", "description": "deprecated. Use uppercaseLabel instead." @@ -528,10 +525,6 @@ "minSpecial": { "message": "最少符號位數" }, - "avoidAmbChar": { - "message": "避免易混淆的字元", - "description": "deprecated. Use avoidAmbiguous instead." - }, "avoidAmbiguous": { "message": "Avoid ambiguous characters", "description": "Label for the avoid ambiguous characters checkbox." @@ -1011,6 +1004,9 @@ "showIdentitiesCurrentTabDesc": { "message": "於分頁頁面顯示身分以便於自動填入。" }, + "clickToAutofillOnVault": { + "message": "Click items to autofill on Vault view" + }, "clearClipboard": { "message": "清除剪貼簿", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -1157,9 +1153,6 @@ "moveToOrganization": { "message": "移動至組織 " }, - "share": { - "message": "共用" - }, "movedItemToOrg": { "message": "已將 $ITEMNAME$ 移動至 $ORGNAME$", "placeholders": { @@ -2047,9 +2040,6 @@ "clone": { "message": "克隆" }, - "passwordGeneratorPolicyInEffect": { - "message": "一個或多個組織原則正影響密碼產生器設定。" - }, "passwordGenerator": { "message": "Password generator" }, @@ -2389,14 +2379,6 @@ "message": "Send 詳細資訊", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "searchSends": { - "message": "搜尋 Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "addSend": { - "message": "新增 Send", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendTypeText": { "message": "文字" }, @@ -2413,16 +2395,9 @@ "hideTextByDefault": { "message": "默認隱藏文字" }, - "maxAccessCountReached": { - "message": "已達最大存取次數", - "description": "This text will be displayed after a Send has been accessed the maximum amount of times." - }, "expired": { "message": "已逾期" }, - "pendingDeletion": { - "message": "等待刪除" - }, "passwordProtected": { "message": "密碼保護" }, @@ -2472,24 +2447,9 @@ "message": "編輯 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendTypeHeader": { - "message": "這是什麽類型的 Send?", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendNameDesc": { - "message": "用於描述此 Send 的易記名稱。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendFileDesc": { - "message": "您想要傳送的檔案。" - }, "deletionDate": { "message": "刪除日期" }, - "deletionDateDesc": { - "message": "此 Send 將在指定的日期和時間後被永久刪除。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "deletionDateDescV2": { "message": "此 Send 將在指定的日期後被永久刪除。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2497,10 +2457,6 @@ "expirationDate": { "message": "逾期日期" }, - "expirationDateDesc": { - "message": "如果設定此選項,對此 Send 的存取將在指定的日期和時間後逾期。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "oneDay": { "message": "1 天" }, @@ -2516,43 +2472,10 @@ "custom": { "message": "自訂" }, - "maximumAccessCount": { - "message": "最大存取次數" - }, - "maximumAccessCountDesc": { - "message": "如果設定此選項,當達到最大存取次數時,使用者將無法再次存取此 Send。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendPasswordDesc": { - "message": "選用功能。使用者需提供密碼才能存取此 Send。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, "sendPasswordDescV3": { "message": "新增一個用於收件人存取此 Send 的可選密碼。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, - "sendNotesDesc": { - "message": "關於此 Send 的私人備註。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendDisableDesc": { - "message": "停用此 Send 以阻止任何人存取。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendShareDesc": { - "message": "儲存時複製此 Send 的連結至剪貼簿。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "sendTextDesc": { - "message": "您想要傳送的文字。" - }, - "sendHideText": { - "message": "預設隱藏此 Send 的文字。", - "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." - }, - "currentAccessCount": { - "message": "目前存取次數" - }, "createSend": { "message": "建立新 Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." @@ -2635,18 +2558,6 @@ "sendFileCalloutHeader": { "message": "在開始之前" }, - "sendFirefoxCustomDatePopoutMessage1": { - "message": "使用行事曆樣式的日期選擇器", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read '**To use a calendar style date picker ** click here to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage2": { - "message": "點選此處", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker **click here** to pop out your window.'" - }, - "sendFirefoxCustomDatePopoutMessage3": { - "message": "要彈出至視窗。", - "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'To use a calendar style date picker click here **to pop out your window.**'" - }, "expirationDateIsInvalid": { "message": "指定的逾期日期無效。" }, @@ -2662,15 +2573,9 @@ "dateParsingError": { "message": "儲存刪除日期和逾期日期時發生錯誤。" }, - "hideEmail": { - "message": "對收件人隱藏我的電子郵件地址。" - }, "hideYourEmail": { "message": "對查看者隱藏您的電子郵件地址。" }, - "sendOptionsPolicyInEffect": { - "message": "一個或多個組織原則正影響您的 Send 選項。" - }, "passwordPrompt": { "message": "重新詢問主密碼" }, @@ -2884,9 +2789,6 @@ "error": { "message": "錯誤" }, - "regenerateUsername": { - "message": "重新產生使用者名稱" - }, "generateUsername": { "message": "產生使用者名稱" }, @@ -2927,9 +2829,6 @@ } } }, - "usernameType": { - "message": "使用者名稱類型" - }, "plusAddressedEmail": { "message": "加號地址電子郵件", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" @@ -2952,12 +2851,6 @@ "websiteName": { "message": "網站名稱" }, - "whatWouldYouLikeToGenerate": { - "message": "您想要產生什麼?" - }, - "passwordType": { - "message": "密碼類型" - }, "service": { "message": "服務" }, diff --git a/apps/browser/store/locales/gl/copy.resx b/apps/browser/store/locales/gl/copy.resx index 4292ebc4b31..feff0fc99e2 100644 --- a/apps/browser/store/locales/gl/copy.resx +++ b/apps/browser/store/locales/gl/copy.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden – Xestor de contrasinais + Xestor de Contrasinais Bitwarden - En casa, no traballo ou mentres estás a viaxar, Bitwarden protexe doadamente todos os teus contrasinais, chaves de paso, e información sensíbel. + En casa, no traballo ou en movemento, Bitwarden protexe doadamente todos os teus contrasinais, chaves de paso, e información sensíbel. Recoñecido como o mellor xestor de contrasinais por PCMag, WIRED, The Verge, CNET, G2 e moito máis. @@ -181,7 +181,7 @@ As solucións de xestión de credenciais cifradas de extremo a extremo de Bitwar Autocompleta rapidamente os teus datos de acceso en calquera páxina web que visites - A túa caixa forte tamén é facilmente accesible desde o menú de clic dereito + A túa caixa forte tamén é facilmente accesible dende o menú de clic dereito Xera automaticamente contrasinais fortes, aleatorias e seguras diff --git a/apps/browser/store/locales/pt_BR/copy.resx b/apps/browser/store/locales/pt_BR/copy.resx index 24331b3a1ba..f4643115237 100644 --- a/apps/browser/store/locales/pt_BR/copy.resx +++ b/apps/browser/store/locales/pt_BR/copy.resx @@ -121,52 +121,54 @@ Gerenciador de Senhas Bitwarden - Em casa, no trabalho, ou em qualquer lugar, o Bitwarden protege facilmente todas as suas senhas, senhas e informações confidenciais. + Em casa, no trabalho, ou em qualquer lugar, o Bitwarden protege facilmente todas as suas senhas, chaves de acesso e informações sensíveis. Reconhecido como o melhor gerenciador de senhas por "PCMag", 'WIRED', 'The Verge', 'CNET', 'G2', entre outros! PROTEJA A SUA VIDA DIGITAL -Deixe a sua vida digital segura e se proteja contra violações de dados gerando e salvando senhas únicas e fortes para cada conta pessoal. Mantendo tudo isso em um cofre encriptografado de ponta a ponta que apenas você pode acessar. +Deixe a sua vida digital segura e se proteja contra violações de dados gerando e salvando senhas únicas e fortes para cada conta pessoal. Mantendo tudo isso em um cofre criptografado de ponta a ponta em que apenas você pode acessar. ACESSE OS SEUS DADOS, EM QUALQUER LUGAR, HORA E DISPOSITIVO Gerencie, armazene, proteja e compartilhe senhas facilmente entre dispositivos ilimitados e sem restrições. TODOS DEVERIAM TEM FERRAMENTAS PARA SE PROTEGER ONLINE -Utilize Bitwarden de graça sem anuncios ou venda dos seus dados. A Bitwarden acredita que todos deveriam ter a opção de estar seguro online. Planos Premium oferecem recursos mais avançados. +Utilize Bitwarden de graça sem anúncios ou venda dos seus dados. A Bitwarden acredita que todos deveriam ter a opção de estar seguro online. Nossos planos Premium oferecem recursos mais avançados. EMPODERE O SEUS TIMES COM BITWARDEN -Os Planos para times e empresas vem com recursos profissionais para negócios. Alguns exemplos inculuem integração SSO, Auto-hospedagem, integração de diretório e provisionamento SCIM, políticas globais, acesso API, registro de eventos e mais. +Os planos para times e empresas vêm com recursos profissionais para negócios. Alguns exemplos incluem integração SSO, auto-hospedagem, integração de diretório e provisionamento SCIM, políticas globais, acesso API, registro de eventos e mais. -Utilizer Bitwarn para proteger os seus empregados e compartilhar informações sensíveis para os colegas. +Utilize o Bitwarden para proteger os seus colaboradores e compartilhar informações sensíveis com seus colegas. Mais razões para escolher Bitwarden: -Senhas encriptografadas por classe de palavras são protegidas com criptografia de ponta a ponta avançada (AES-256 bit, salted hashtag, and PBKDF2 SHA-256), então os seus dados ficam seguros e privados. +Criptografia mundialmente reconhecida +Suas senhas são protegidas com avançada criptografia ponta a ponta (AES-256, salted hashtag, e PBKDF2 SHA-256) para que os seus dados estejam seguros e privados. Auditoria de Terceiros -Bitwarden regularmente conduz auditorias de terceiros com notáveis empresas de segurança. Essas audições anuais incluem qualificação e penetração do código fonte através de IPs da Bitwarden, servidores e aplicações WEB. +A Bitwarden regularmente conduz auditorias de terceiros com notáveis empresas de segurança. Essas auditorias anuais incluem qualificação do código fonte e testes de invasão contra os IPs da Bitwarden, servidores e aplicações web. 2FA Avançado -Proteja o seu login com um autenticador de doisfatores, códigos de email ou credenciais FIDO2 WebAuthn como chave de segurança por hardware ou chave de acesso. +Proteja o seu login com um autenticador de dois fatores, códigos de email ou credenciais FIDO2 WebAuthn como chave de segurança por hardware ou chave de acesso. Envio Bitwarden -Transmita dados diretamente para outros enquanto mantem segurança de encriptografia ponta a ponta e limitando exposição. +Transmita dados diretamente para outras pessoas enquanto mantém a segurança da criptografia ponta a ponta para limitar sua exposição. Gerador integrado -Crie senhas grandes, complexas e diferentes e nomes de usuário unicos para cada site que visitar. Integre com provedores de email para privacidade adicional +Crie diferentes senhas fortes e complexas e nomes de usuário únicos para cada site que visitar. Integre com provedores de email para privacidade adicional. Tradutores globais -As traduções da Bitwarden estão disponíveis para mais de 60 líguas, traduzidas pela comunidade global através do Crowdin. +As traduções da Bitwarden estão disponíveis para mais de 60 línguas, traduzidas pela comunidade global através do Crowdin. Aplicações Multi-Plataforma -Proteja e compartilhe conteúdo sensível dentro do Vault da Bitwarden de qualquer navegador, dispositivo móvel, ou desktop OS, entre outros. +Proteja e compartilhe conteúdo confidencial dentro do Vault da Bitwarden de qualquer navegador, dispositivo móvel, desktop, entre outros. -Bitwarden protege mais do que apenas soluções em gerenciamento de credenciais de senhas encriptografadas ponta a ponta, Bitwarden empodera organizações para proteger qualquer coisa, incluindo segredos de desenvolvedor e chaves de acesso. -Visite Bitwarden.com para aprender mais sobre Bitwarden Secrets Manager e Bitwarden Passwordless.dev! +Bitwarden protege mais do que apenas senhas +Com nossas soluções em gerenciamento de credenciais criptografadas ponta a ponta, a Bitwarden empodera organizações para proteger qualquer informação, incluindo senhas de desenvolvedor e chaves de acesso. Visite Bitwarden.com para aprender mais sobre Bitwarden Secrets Manager e Bitwarden Passwordless.dev! + - Em casa, no trabalho, ou em qualquer lugar, o Bitwarden protege facilmente todas as suas senhas, senhas e informações confidenciais. + Em casa, no trabalho ou em qualquer lugar, a Bitwarden protege facilmente todas as suas senhas, chaves de acesso e informações sensíveis. Sincronize e acesse o seu cofre através de múltiplos dispositivos From 62b49df7d31e09029f2613a18d9b2f15fa56f3a9 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:56:53 +0000 Subject: [PATCH 03/65] Autosync the updated translations (#12629) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 36 ++++ apps/desktop/src/locales/ar/messages.json | 88 +++++++--- apps/desktop/src/locales/az/messages.json | 36 ++++ apps/desktop/src/locales/be/messages.json | 36 ++++ apps/desktop/src/locales/bg/messages.json | 36 ++++ apps/desktop/src/locales/bn/messages.json | 36 ++++ apps/desktop/src/locales/bs/messages.json | 36 ++++ apps/desktop/src/locales/ca/messages.json | 36 ++++ apps/desktop/src/locales/cs/messages.json | 36 ++++ apps/desktop/src/locales/cy/messages.json | 36 ++++ apps/desktop/src/locales/da/messages.json | 36 ++++ apps/desktop/src/locales/de/messages.json | 36 ++++ apps/desktop/src/locales/el/messages.json | 36 ++++ apps/desktop/src/locales/en_GB/messages.json | 36 ++++ apps/desktop/src/locales/en_IN/messages.json | 36 ++++ apps/desktop/src/locales/eo/messages.json | 36 ++++ apps/desktop/src/locales/es/messages.json | 36 ++++ apps/desktop/src/locales/et/messages.json | 70 ++++++-- apps/desktop/src/locales/eu/messages.json | 36 ++++ apps/desktop/src/locales/fa/messages.json | 36 ++++ apps/desktop/src/locales/fi/messages.json | 40 ++++- apps/desktop/src/locales/fil/messages.json | 36 ++++ apps/desktop/src/locales/fr/messages.json | 68 +++++-- apps/desktop/src/locales/gl/messages.json | 36 ++++ apps/desktop/src/locales/he/messages.json | 36 ++++ apps/desktop/src/locales/hi/messages.json | 36 ++++ apps/desktop/src/locales/hr/messages.json | 176 +++++++++++-------- apps/desktop/src/locales/hu/messages.json | 36 ++++ apps/desktop/src/locales/id/messages.json | 36 ++++ apps/desktop/src/locales/it/messages.json | 36 ++++ apps/desktop/src/locales/ja/messages.json | 38 +++- apps/desktop/src/locales/ka/messages.json | 36 ++++ apps/desktop/src/locales/km/messages.json | 36 ++++ apps/desktop/src/locales/kn/messages.json | 36 ++++ apps/desktop/src/locales/ko/messages.json | 36 ++++ apps/desktop/src/locales/lt/messages.json | 36 ++++ apps/desktop/src/locales/lv/messages.json | 36 ++++ apps/desktop/src/locales/me/messages.json | 36 ++++ apps/desktop/src/locales/ml/messages.json | 36 ++++ apps/desktop/src/locales/mr/messages.json | 36 ++++ apps/desktop/src/locales/my/messages.json | 36 ++++ apps/desktop/src/locales/nb/messages.json | 36 ++++ apps/desktop/src/locales/ne/messages.json | 36 ++++ apps/desktop/src/locales/nl/messages.json | 36 ++++ apps/desktop/src/locales/nn/messages.json | 36 ++++ apps/desktop/src/locales/or/messages.json | 36 ++++ apps/desktop/src/locales/pl/messages.json | 36 ++++ apps/desktop/src/locales/pt_BR/messages.json | 86 ++++++--- apps/desktop/src/locales/pt_PT/messages.json | 38 +++- apps/desktop/src/locales/ro/messages.json | 36 ++++ apps/desktop/src/locales/ru/messages.json | 36 ++++ apps/desktop/src/locales/si/messages.json | 36 ++++ apps/desktop/src/locales/sk/messages.json | 36 ++++ apps/desktop/src/locales/sl/messages.json | 36 ++++ apps/desktop/src/locales/sr/messages.json | 36 ++++ apps/desktop/src/locales/sv/messages.json | 36 ++++ apps/desktop/src/locales/te/messages.json | 36 ++++ apps/desktop/src/locales/th/messages.json | 36 ++++ apps/desktop/src/locales/tr/messages.json | 36 ++++ apps/desktop/src/locales/uk/messages.json | 36 ++++ apps/desktop/src/locales/vi/messages.json | 36 ++++ apps/desktop/src/locales/zh_CN/messages.json | 122 ++++++++----- apps/desktop/src/locales/zh_TW/messages.json | 36 ++++ 63 files changed, 2469 insertions(+), 201 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index 072b13787cb..1f569319953 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index de7d91341d4..d9c702b19d8 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -208,19 +208,19 @@ "message": "أُنشئ مفتاح SSH جديد" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "كلمة المرور التي أدخلتها غير صحيحة." }, "importSshKey": { - "message": "Import" + "message": "استيراد" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "تأكيد كلمة المرور" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "أدخل كلمة المرور لمفتاح SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "أدخل كلمة المرور" }, "sshAgentUnlockRequired": { "message": "الرجاء فتح المخزن الخاص بك للموافقة على طلب مفتاح SSH." @@ -920,10 +920,10 @@ "message": "رابط الخادم" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "مهلة المصادقة" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "انتهت مهلة جَلسة المصادقة. يرجى إعادة بَدْء عملية تسجيل الدخول." }, "selfHostBaseUrl": { "message": "رابط خادم الاستضافة الذاتية", @@ -1393,13 +1393,13 @@ "message": "سجل كلمة المرور" }, "generatorHistory": { - "message": "Generator history" + "message": "سجل المولد" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "محو سجل المولد" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "إذا تابعت، سيتم حذف جميع الإدخالات بشكل دائم من سجل المولد. هل أنت متيقِّن من أنك تريد المتابعة؟" }, "clear": { "message": "مسح", @@ -1409,13 +1409,13 @@ "message": "لا توجد كلمات مرور للعرض." }, "clearHistory": { - "message": "Clear history" + "message": "مسح السجل" }, "nothingToShow": { - "message": "Nothing to show" + "message": "لا يوجد شيء لعرضه" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "لم تقم بتوليد أي شيء مؤخرًا" }, "undo": { "message": "تراجع" @@ -2481,7 +2481,7 @@ "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": { @@ -2495,7 +2495,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": { @@ -2505,7 +2505,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": { @@ -2726,13 +2726,13 @@ "message": "تم إرسال إشعار إلى جهازك." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "أُرسل إشعار إلى جهازك" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "تيقن من أن حسابك مفتوح وأن عبارة البصمة متطابقة على الجهاز الآخر" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "هل تحتاج إلى خيار آخر؟" }, "fingerprintMatchInfo": { "message": "الرجاء التأكد من أن المخزن الخاص بك غير مقفل وأن عبارة بصمة الإصبع تطابق الجهاز الآخر." @@ -2741,13 +2741,13 @@ "message": "عبارة بصمة الإصبع" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "سيتم إعلامك بمجرد الموافقة على الطلب" }, "needAnotherOption": { "message": "تسجيل الدخول باستخدام الجهاز يجب أن يتم إعداده في إعدادات تطبيق Bitwarden. هل تحتاج إلى خيار آخر؟" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "عرض جميع خيارات تسجيل الدخول" }, "viewAllLoginOptions": { "message": "عرض جميع خيارات تسجيل الدخول" @@ -2869,7 +2869,7 @@ "message": "تحقق من خروقات البيانات المعروفة لكلمة المرور هذه" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "سجلت دخولك!" }, "important": { "message": "مهم:" @@ -2902,16 +2902,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": "تذكر هذا الجهاز" @@ -2966,7 +2966,7 @@ "message": "البريد الإلكتروني للمستخدم مفقود" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "لم يتم العثور على البريد الإلكتروني للمستخدم الحالي. يتم تسجيل الخروج." }, "deviceTrusted": { "message": "الجهاز موثوق به" @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "تم حفظ الملف على الجهاز. إدارة من تنزيلات جهازك." + }, + "importantNotice": { + "message": "ملاحظة هامة" + }, + "setupTwoStepLogin": { + "message": "إعداد المصادقة الثنائية" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "سيقوم Bitwarden بإرسال رمز إلى البريد الإلكتروني الخاص بحسابك للتحقق من تسجيلات الدخول من الأجهزة الجديدة ابتداء من فبراير 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "يمكنك إعداد المصادقة الثنائية كطريقة بديلة لحماية حسابك أو تغيير بريدك الإلكتروني إلى بريد يمكنك الوصول إليه." + }, + "remindMeLater": { + "message": "ذكرني لاحقاً" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "هل لديك وصول موثوق إلى بريدك الإلكتروني، $EMAIL$؟", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "لا ليس لديّ" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "نعم، يمكنني الوصول بشكل موثوق إلى بريدي الإلكتروني" + }, + "turnOnTwoStepLogin": { + "message": "تفعيل المصادقة الثنائية" + }, + "changeAcctEmail": { + "message": "تغيير البريد الإلكتروني الخاص بالحساب" } } diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index 91705bf7a84..07519429f12 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Fayl cihazda saxlanıldı. Endirilənləri cihazınızdan idarə edin." + }, + "importantNotice": { + "message": "Vacib bildiriş" + }, + "setupTwoStepLogin": { + "message": "İki addımlı girişi qur" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden, 2025-ci ilin Fevral ayından etibarən yeni cihazlardan gələn girişləri doğrulamaq üçün hesabınızın e-poçtuna bir kod göndərəcək." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Hesabınızı qorumaq üçün alternativ bir yol kimi iki addımlı girişi qura və ya e-poçtunuzu müraciət edə biləcəyiniz e-poçtla dəyişdirə bilərsiniz." + }, + "remindMeLater": { + "message": "Daha sonra xatırlat" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "$EMAIL$ e-poçtunuza güvənli şəkildə müraciət edə bilirsiniz?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Xeyr, edə bilmirəm" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Bəli, e-poçtuma güvənli şəkildə müraciət edə bilirəm" + }, + "turnOnTwoStepLogin": { + "message": "İki addımlı girişi işə sal" + }, + "changeAcctEmail": { + "message": "Hesabın e-poçtunu dəyişdir" } } diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index a37dc6ac5bf..e89d6b5fa6f 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index 0b8e237cfd5..9770e24c5ad 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Файлът е запазен на устройството. Можете да го намерите в мястото за сваляния на устройството." + }, + "importantNotice": { + "message": "Важно съобщение" + }, + "setupTwoStepLogin": { + "message": "Настройте двустепенно удостоверяване" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Битуорден ще изпрати код до е-пощата Ви, за потвърждаване на вписването от нови устройства. Това ще започне от февруари 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Можете да настроите двустепенно удостоверяване, като различен метод на защита, или ако е необходимо да промените е-пощата си с такава, до която имате достъп." + }, + "remindMeLater": { + "message": "Напомнете ми по-късно" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Имате ли сигурен достъп до е-пощата си – $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Не, нямам" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Да, имам достъп до е-пощата си" + }, + "turnOnTwoStepLogin": { + "message": "Включване на двустепенното удостоверяване" + }, + "changeAcctEmail": { + "message": "Промяна на е-пощата" } } diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 50be17bf6b4..8fe871a956f 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 2829a2465c4..e90a7e16c89 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index a0b7703748e..ace7e5defc0 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 0c932907bd8..f73f76f44a5 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Soubor byl uložen. Můžete jej nalézt ve stažené složce v zařízení." + }, + "importantNotice": { + "message": "Důležité upozornění" + }, + "setupTwoStepLogin": { + "message": "Nastavit dvoufázové přihlášení" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden odešle kód na e-mail Vašeho účtu pro ověření přihlášení z nových zařízení počínaje únorem 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Dvoufázové přihlášení můžete nastavit jako alternativní způsob ochrany Vašeho účtu nebo změnit svůj e-mail na ten, k němuž můžete přistupovat." + }, + "remindMeLater": { + "message": "Připomenout později" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Máte spolehlivý přístup ke svému e-mailu $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Ne, nemám" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ano, ke svému e-mailu mám přístup" + }, + "turnOnTwoStepLogin": { + "message": "Zapnout dvoufázové přihlášení" + }, + "changeAcctEmail": { + "message": "Změnit e-mail účtu" } } diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index d423151ad40..00d79c80ec8 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index 13795673198..b2867c4072e 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Fil gemt på enheden. Håndtér fra enhedens downloads." + }, + "importantNotice": { + "message": "Vigtig notits" + }, + "setupTwoStepLogin": { + "message": "Opsæt totrins-login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Startende i februar 2025, sender Bitwarden en kode til kontoe-mailadressen for at bekræfte logins fra nye enheder." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Man kan opsætte totrins-login som en alternativ måde at beskytte sin konto på eller ændre sin e-mail til en, man kan tilgå." + }, + "remindMeLater": { + "message": "Påmind senere" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Er der pålidelig adgang til e-mailadressen, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nej, muligvis ikke" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ja, e-mailadressen kan pålideligt tilgås" + }, + "turnOnTwoStepLogin": { + "message": "Slå totrins-login til" + }, + "changeAcctEmail": { + "message": "Skift kontoe-mailadresse" } } diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index ae8a024fe38..ae20bc0931d 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Datei auf Gerät gespeichert. Greife darauf über die Downloads deines Geräts zu." + }, + "importantNotice": { + "message": "Wichtiger Hinweis" + }, + "setupTwoStepLogin": { + "message": "Zwei-Faktor-Authentifizierung einrichten" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Ab Februar 2025 wird Bitwarden einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten zu verifizieren." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Du kannst die Zwei-Faktor-Authentifizierung als eine alternative Methode einrichten, um dein Konto zu schützen, oder deine E-Mail-Adresse zu einer anderen ändern, auf die du zugreifen kannst." + }, + "remindMeLater": { + "message": "Erinnere mich später" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Hast du zuverlässigen Zugriff auf deine E-Mail-Adresse $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nein, habe ich nicht" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ja, ich kann zuverlässig auf meine E-Mails zugreifen" + }, + "turnOnTwoStepLogin": { + "message": "Zwei-Faktor-Authentifizierung aktivieren" + }, + "changeAcctEmail": { + "message": "E-Mail-Adresse des Kontos ändern" } } diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index ff4a4a0f893..676c016c699 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Το αρχείο αποθηκεύτηκε στη συσκευή. Διαχείριση από τις λήψεις της συσκευής σας." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index c13ceb9b3d7..ee1be4df2e6 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index f7b6552a90a..b8afb36f3a6 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index c30f33aa612..b7fbb2fbe93 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 365c3835137..9cb82ceb92d 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 15161f2cd7b..276d3565f1a 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -27,7 +27,7 @@ "message": "Turvaline märkus" }, "typeSshKey": { - "message": "SSH key" + "message": "SSH võti" }, "folders": { "message": "Kaustad" @@ -64,7 +64,7 @@ } }, "welcomeBack": { - "message": "Welcome back" + "message": "Tere tulemast tagasi" }, "moveToOrgDesc": { "message": "Vali organisatsioon, kuhu soovid seda kirjet teisaldada. Teisaldamisega saab kirje omanikuks organisatsioon. Pärast kirje teisaldamist ei ole sa enam selle otsene omanik." @@ -181,46 +181,46 @@ "message": "Aadress" }, "sshPrivateKey": { - "message": "Private key" + "message": "Privaatvõti" }, "sshPublicKey": { - "message": "Public key" + "message": "Avalik võti" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Sõrmejälg" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Võtme tüüp" }, "sshKeyAlgorithmED25519": { "message": "ED25519" }, "sshKeyAlgorithmRSA2048": { - "message": "RSA 2048-Bit" + "message": "RSA 2048-bitine" }, "sshKeyAlgorithmRSA3072": { - "message": "RSA 3072-Bit" + "message": "RSA 3072-bitine" }, "sshKeyAlgorithmRSA4096": { - "message": "RSA 4096-Bit" + "message": "RSA 4096-bitine" }, "sshKeyGenerated": { - "message": "A new SSH key was generated" + "message": "Uus SSh võti on loodud" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Sinu sisestatud salasõna pole õige." }, "importSshKey": { - "message": "Import" + "message": "Impordi" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Kinnita salasõna" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Sisesta selle SSH võtme salasõna." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Sisesta salasõna" }, "sshAgentUnlockRequired": { "message": "Please unlock your vault to approve the SSH key request." @@ -1113,7 +1113,7 @@ "message": "Hoidla ajalõpp" }, "vaultTimeout1": { - "message": "Timeout" + "message": "Aegumine" }, "vaultTimeoutDesc": { "message": "Vali millal saabub hoidla ajalõpp ning sooritatakse valitud tegevus." @@ -1320,7 +1320,7 @@ "description": "Copy credit card number" }, "copyEmail": { - "message": "Copy email" + "message": "Kopeeri e-posti aadress" }, "copySecurityCode": { "message": "Kopeeri turvakood", @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Fail salvestatud. Halda oma seadmesse allalaaditud faile." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 6283845a905..41e8eda96c7 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index c90e92f1389..fdc9ba6d31b 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 7b661943210..226c44bc352 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -2869,7 +2869,7 @@ "message": "Tarkasta esiintyykö salasanaa tunnetuissa tietovuodoissa" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Kirjautuminen onnistui!" }, "important": { "message": "Tärkeää:" @@ -3372,7 +3372,7 @@ "message": "Vahvista SSH-avainkäyttö" }, "sshkeyApprovalMessageInfix": { - "message": "is requesting access to" + "message": "pyytää pääsyä" }, "unknownApplication": { "message": "Sovellus" @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Tiedosto tallennettiin laitteelle. Hallitse sitä laitteesi latauksista." + }, + "importantNotice": { + "message": "Tärkeä ilmoitus" + }, + "setupTwoStepLogin": { + "message": "Määritä kaksivaiheinen kirjautuminen" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Muistuta myöhemmin" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Ota kaksivaiheinen kirjautuminen käyttöön" + }, + "changeAcctEmail": { + "message": "Muuta tilin sähköpostiosoitetta" } } diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 566c3de07f7..a8a36cd94af 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index b7e3c6f8cfa..d387cbb20a0 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -208,19 +208,19 @@ "message": "Une nouvelle clé SSH a été générée" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Le mot de passe saisi est incorrect." }, "importSshKey": { - "message": "Import" + "message": "Importer" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Confirmez le mot de passe" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Entrez le mot de passe de la clé SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Entrez le mot de passe" }, "sshAgentUnlockRequired": { "message": "Veuillez déverrouiller votre coffre pour approuver la demande de clé SSH." @@ -1393,13 +1393,13 @@ "message": "Historique du mot de passe" }, "generatorHistory": { - "message": "Generator history" + "message": "Historique du générateur" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Effacer l'historique du générateur" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "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 ?" }, "clear": { "message": "Effacer", @@ -1409,13 +1409,13 @@ "message": "Aucun mot de passe à afficher." }, "clearHistory": { - "message": "Clear history" + "message": "Effacer l'historique" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Rien à afficher" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Vous n'avez rien généré récemment" }, "undo": { "message": "Annuler" @@ -2869,7 +2869,7 @@ "message": "Vérifier les brèches de données connues pour ce mot de passe" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Connecté !" }, "important": { "message": "Important :" @@ -2902,16 +2902,16 @@ "message": "Une mise à jour des paramètres est recommandée" }, "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" @@ -2966,7 +2966,7 @@ "message": "E-mail 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" @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Fichier enregistré sur l'appareil. Gérez à partir des téléchargements de votre appareil." + }, + "importantNotice": { + "message": "Avis important" + }, + "setupTwoStepLogin": { + "message": "Configurer l'identification à deux facteurs" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden enverra un code au courriel de votre compte pour vérifier les connexions depuis de nouveaux appareils à partir de février 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Vous pouvez configurer l'identification à deux facteurs comme un moyen alternatif de protéger votre compte ou de changer votre adresse courriel à une autre à laquelle vous pouvez accéder." + }, + "remindMeLater": { + "message": "Me le rappeler plus tard" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Avez-vous un accès fiable à votre courriel $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Non, je ne l'ai pas" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Oui, je peux accéder à mon courriel de manière fiable" + }, + "turnOnTwoStepLogin": { + "message": "Activer l'identification à deux facteurs" + }, + "changeAcctEmail": { + "message": "Changer le courriel du compte" } } diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index f8f81a5ac2c..323d0cd3f7b 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 8e8162732da..dfaa195895e 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 1b489fc49da..13bb5edfa93 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 61e37859dd8..a87261a2027 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -27,7 +27,7 @@ "message": "Sigurna bilješka" }, "typeSshKey": { - "message": "SSH key" + "message": "SSH ključ" }, "folders": { "message": "Mape" @@ -64,13 +64,13 @@ } }, "welcomeBack": { - "message": "Welcome back" + "message": "Dobro došli natrag" }, "moveToOrgDesc": { "message": "Odaberi organizaciju u koju želiš premjestiti ovu stavku. Premještanje prenosi vlasništvo stavke na organizaciju. Nakon premještanja više nećeš biti izravni vlasnik ove stavke." }, "attachments": { - "message": "Privitci" + "message": "Privíci" }, "viewItem": { "message": "Prikaz stavke" @@ -181,16 +181,16 @@ "message": "Adresa" }, "sshPrivateKey": { - "message": "Private key" + "message": "Privatni ključ" }, "sshPublicKey": { - "message": "Public key" + "message": "Javni ključ" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Otisak prsta" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Vrsta ključa" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -205,37 +205,37 @@ "message": "RSA 4096-Bit" }, "sshKeyGenerated": { - "message": "A new SSH key was generated" + "message": "Generiran je novi SSH ključ" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Unesena lozinka nije ispravna." }, "importSshKey": { - "message": "Import" + "message": "Uvoz" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Potvrdi lozinku" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Unesi lozinku za SSH ključ." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Unesi lozinku" }, "sshAgentUnlockRequired": { - "message": "Please unlock your vault to approve the SSH key request." + "message": "Otključaj svoj trezor za odobravanje zahtjeva za SSH ključ." }, "sshAgentUnlockTimeout": { - "message": "SSH key request timed out." + "message": "Zahtjev za SSH ključ istekao." }, "enableSshAgent": { - "message": "Enable SSH agent" + "message": "Uključi SSH agent" }, "enableSshAgentDesc": { - "message": "Enable the SSH agent to sign SSH requests right from your Bitwarden vault." + "message": "Uključi SSH agent za potpis SSH zahtjeva direktno iz tvog Bitwarden trezora." }, "enableSshAgentHelp": { - "message": "The SSH agent is a service targeted at developers that allows you to sign SSH requests directly from your Bitwarden vault." + "message": "SSH agent je servis namijenjen developerima koji omogućuje potpisivanje SSH zahtjeva izravno iz tvojeg Bitwarden trezora." }, "premiumRequired": { "message": "Potrebno Premium članstvo" @@ -323,7 +323,7 @@ "message": "Generiraj lozinku" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Generiraj fraznu lozinku" }, "type": { "message": "Vrsta" @@ -461,13 +461,13 @@ "message": "Kopiraj lozinku" }, "regenerateSshKey": { - "message": "Regenerate SSH key" + "message": "Regeneriraj SSH ključ" }, "copySshPrivateKey": { - "message": "Copy SSH private key" + "message": "Kopiraj privatni SSH ključ" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "Kopiraj fraznu lozinku", "description": "Copy passphrase to clipboard" }, "copyUri": { @@ -530,7 +530,7 @@ "description": "Full description for the password generator special characters checkbox" }, "specialCharactersLabel": { - "message": "!@#$%^&*", + "message": "! @ # $ % ^ & *", "description": "Label for the password generator special characters checkbox" }, "numWords": { @@ -624,7 +624,7 @@ "message": "Stvori račun" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Novi u Bitwardenu?" }, "setAStrongPassword": { "message": "Postavi jaku lozinku" @@ -636,16 +636,16 @@ "message": "Prijavi se" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Prijavi se u Bitwarden" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Prijava pristupnim ključem" }, "loginWithDevice": { - "message": "Log in with device" + "message": "Prijava uređajem" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Jedinstvena prijava (SSO)" }, "submit": { "message": "Pošalji" @@ -694,7 +694,7 @@ "message": "Pridruži se organizaciji" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "Pidruži se $ORGANIZATIONNAME$", "placeholders": { "organizationName": { "content": "$1", @@ -809,10 +809,10 @@ "message": "Nastavi" }, "enterVerificationCodeApp": { - "message": "Unesi 6-znamenkasti kontrolni kôd iz autentifikatorske aplikacije." + "message": "Unesi 6-znamenkasti kôd za provjeru iz autentifikatorske aplikacije." }, "enterVerificationCodeEmail": { - "message": "Unesi 6-znamenkasti kontrolni kôd poslan e-poštom na $EMAIL$.", + "message": "Unesi 6-znamenkasti kôd za provjeru poslan e-poštom na $EMAIL$.", "placeholders": { "email": { "content": "$1", @@ -920,13 +920,13 @@ "message": "URL poslužitelja" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Istek vremena za autentifikaciju" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "Sesija za autentifikaciju je istekla. Ponovi proces prijave." }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL vlastitog poslužitelja", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1320,7 +1320,7 @@ "description": "Copy credit card number" }, "copyEmail": { - "message": "Copy email" + "message": "Kopiraj e-poštu" }, "copySecurityCode": { "message": "Kopiraj kontrolni broj", @@ -1393,13 +1393,13 @@ "message": "Povijest" }, "generatorHistory": { - "message": "Generator history" + "message": "Povijest generatora" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Očisti povijest generatora" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Cijela povijest generatora biti će trajno izbirsana. Sigurno želiš nastaviti?" }, "clear": { "message": "Očisti", @@ -1409,13 +1409,13 @@ "message": "Nema lozinki na popisu." }, "clearHistory": { - "message": "Clear history" + "message": "Očisti povijest" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Ništa za prikazati" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Ništa nije generirano" }, "undo": { "message": "Poništi" @@ -1771,10 +1771,10 @@ "message": "Brisanje računa je TRAJNO i NEPOVRATNO i naknadno ga nije moguće vratiti." }, "cannotDeleteAccount": { - "message": "Cannot delete account" + "message": "Nije moguće izbrisati račun" }, "cannotDeleteAccountDesc": { - "message": "This action cannot be completed because your account is owned by an organization. Contact your organization administrator for additional details." + "message": "Ova radnja ne može se završiti jer je tvoj račun u vlasništvu organizacije. Za detalje, kontaktiraj administratora organizacije." }, "accountDeleted": { "message": "Račun izbrisan" @@ -1887,7 +1887,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": "od $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -2478,10 +2478,10 @@ "message": "Generiraj korisničko ime" }, "generateEmail": { - "message": "Generate email" + "message": "Generiraj e-poštu" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Vrijednost mora biti u rasponu $MIN$ - $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2495,7 +2495,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Koristi $RECOMMENDED$ i više znakova za generiranje jake lozinke.", "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": { @@ -2505,7 +2505,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Koristi $RECOMMENDED$ i više riječi za generiranje jake frazne lozinke.", "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": { @@ -2558,11 +2558,11 @@ "message": "Generiraj pseudonim e-pošte s vanjskom uslugom prosljeđivanja." }, "forwarderDomainName": { - "message": "Email domain", + "message": "Domena e-pošte", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "Odaberi domenu koju podržava odabrani servis", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { @@ -2726,13 +2726,13 @@ "message": "Obavijest je poslana na tvoj uređaj." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Obavijest je poslana na tvoj uređaj" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Trebaš drugu opciju?" }, "fingerprintMatchInfo": { "message": "Provjeri je li trezor otključan i slaže li se jedinstvena fraza s drugim uređajem." @@ -2741,13 +2741,13 @@ "message": "Jedinstvena fraza" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Dobiti ćeš obavijest kada je tvoj zahtjev odobren" }, "needAnotherOption": { "message": "Prijava uređajem mora biti namještena u postavka Bitwarden mobilne aplikacije. Trebaš drugu opciju?" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Pogledaj sve mogućnosti prijave" }, "viewAllLoginOptions": { "message": "Pogledaj sve mogućnosti prijave" @@ -2869,7 +2869,7 @@ "message": "Provjeri je li lozinka ukradena prilikom krađe podataka" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Prijava uspješna!" }, "important": { "message": "Važno:" @@ -2902,16 +2902,16 @@ "message": "Preporučeno ažuriranje postavki" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Zapamti ovaj uređaj kako bi buduće prijave bile brže" }, "deviceApprovalRequired": { "message": "Potrebno je odobriti uređaj. Odaberi metodu odobravanja:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Potrebno odobrenje uređaja" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Odaberi opciju odobrenja" }, "rememberThisDevice": { "message": "Zapamti ovaj uređaj" @@ -2966,7 +2966,7 @@ "message": "Nedostaje e-pošta korisnika" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Nije pronađena e-pošta aktivnog korisnika. Odjava u tijeku..." }, "deviceTrusted": { "message": "Uređaj pouzdan" @@ -3363,36 +3363,72 @@ "message": "Nisu nađeni slobodni portovi za SSO prijavu." }, "authorize": { - "message": "Authorize" + "message": "Autoriziraj" }, "deny": { - "message": "Deny" + "message": "Odbij" }, "sshkeyApprovalTitle": { - "message": "Confirm SSH key usage" + "message": "Potvrdi korištenje SSH ključa" }, "sshkeyApprovalMessageInfix": { - "message": "is requesting access to" + "message": "traži pristup za" }, "unknownApplication": { - "message": "An application" + "message": "Aplikacija" }, "sshKeyPasswordUnsupported": { - "message": "Importing password protected SSH keys is not yet supported" + "message": "Uvoz SSH ključeva zaštićenih lozinkom još nije podržan" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "SSH ključ nije valjan" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "Tip SSH ključa nije podržan" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "Uvezi ključ iz međuspremnika" }, "sshKeyPasted": { - "message": "SSH key imported successfully" + "message": "SSH ključ uspješno uvezen" }, "fileSavedToDevice": { "message": "Datoteka spremljena na uređaj. Upravljaj u preuzimanjima svog uređaja." + }, + "importantNotice": { + "message": "Važna napomena" + }, + "setupTwoStepLogin": { + "message": "Postavi dvostruku autentifikaciju" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden će, počevši od veljače 2025., za provjeru prijava s novih uređaja poslati kôd na e-poštu tvog računa." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Prijavu dvostrukom autentifikacijom možeš postaviti kao alternativni način zaštite svog računa ili promijeni svoju e-poštu u onu kojoj možeš pristupiti." + }, + "remindMeLater": { + "message": "Podsjeti me kasnije" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Imaš li pouzdan pristup svojoj e-pošti: $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Ne, nemam" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Da, pouzdano mogu pristupiti svojoj e-pošti" + }, + "turnOnTwoStepLogin": { + "message": "Uključi prijavu dvostrukom autentifikacijom" + }, + "changeAcctEmail": { + "message": "Promjeni e-poštu računa" } } diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index ffc6a439ff3..11091cde860 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "A fájl mentésre került az eszközre. Kezeljük az eszközről a letöltéseket." + }, + "importantNotice": { + "message": "Fontos megjegyzés" + }, + "setupTwoStepLogin": { + "message": "Kétlépéses bejelentkezés beüzemelése" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "A Bitwarden 2025 februárjától kódot küld a fiókhoz tartozó email-címre, amellyel ellenőrizhetők az új eszközökről történő bejelentkezések." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "A fiók védelmének alternatív módjaként beállíthatunk kétlépcsős bejelentkezést vagy módosíthatjuk az email címet egy elérhetőre." + }, + "remindMeLater": { + "message": "Emlékeztetés később" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Megbízható a hozzáférés $EMAIL$ email címhez?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nem, nem érem el" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Igen, megbízhatóan hozzáférek az emailjeimhez" + }, + "turnOnTwoStepLogin": { + "message": "Kétlépéses bejelentkezés bekapcsolása" + }, + "changeAcctEmail": { + "message": "Fiók email cím megváltoztatása" } } diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index a47f1acb9eb..b9af1c00045 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index ce4b41a1762..e8c0a3d1a39 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File salvato sul dispositivo. Gestisci dai download del dispositivo." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index 4ff2e16300f..c146fb2404c 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -694,7 +694,7 @@ "message": "組織に参加" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "$ORGANIZATIONNAME$ に参加", "placeholders": { "organizationName": { "content": "$1", @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "ファイルをデバイスに保存しました。デバイスのダウンロードで管理できます。" + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 7d748417b17..6c554a82700 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index f8f81a5ac2c..323d0cd3f7b 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index 094c4ced0bb..6182bd3a33d 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 9a63577dca0..89c5430a5fb 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index c6ab4ba6a7b..6e07f4ceee3 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index ba159a52d71..a3db76ac646 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Datne saglabāta ierīcē. Tā ir atrodama ierīces lejupielāžu mapē." + }, + "importantNotice": { + "message": "Svarīgs paziņojums" + }, + "setupTwoStepLogin": { + "message": "Iestatīt divpakāpju pieteikšanos" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden, sākot ar 2025. gada februāri, nosūtīs kodu uz konta e-pasta adresi, lai apliecinātu pieteikšanos jaunās ierīcēs." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Var iestatīt divpakāpju pieteikšanos kā citu veidu, kā aizsargāt savu kontu, vai iestatīt savu e-pasta adresi uz tādu, kurai ir piekļuve." + }, + "remindMeLater": { + "message": "Atgādināt man vēlāk" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Vai ir uzticama piekļuve savai e-pasta adresei $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nē, nav" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Jā, varu uzticami piekļūt savam e-pastam" + }, + "turnOnTwoStepLogin": { + "message": "Ieslēgt divpakāpju pieteikšanos" + }, + "changeAcctEmail": { + "message": "Mainīt konta e-pasta adresi" } } diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index bf7110b77a1..49bf2c60f6c 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index f14d21f2c79..d314ee44578 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index f8f81a5ac2c..323d0cd3f7b 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index dccd56fdb29..c1713e0bb32 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index 08a3ad9528f..f264bb5f092 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 16a52cb1723..fb8d7ec7df5 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 9be7e7f2c58..2cd0232e5d4 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Bestand op apparaat opgeslagen. Beheer vanaf de downloads op je apparaat." + }, + "importantNotice": { + "message": "Belangrijke mededeling" + }, + "setupTwoStepLogin": { + "message": "Tweestapsaanmelding instellen" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Vanaf februari 2025 stuurt Bitwarden een code naar het e-mailadres van je account om inloggen op nieuwe apparaten te verifiëren." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Je kunt tweestapsaanmelding instellen als een alternatieve manier om je account te beschermen of je e-mailadres te veranderen naar een waar je toegang toe hebt." + }, + "remindMeLater": { + "message": "Herinner me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Heb je betrouwbare toegang tot je e-mail, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nee, dat heb ik niet" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Ja, ik heb betrouwbare toegang tot mijn e-mail" + }, + "turnOnTwoStepLogin": { + "message": "Tweestapsaanmelding inschakelen" + }, + "changeAcctEmail": { + "message": "E-mailadres van het account veranderen" } } diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 1b94deb76ab..543f20fc01d 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index ed279134638..2723db4f882 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index 9f160f6329e..9cddf815463 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Plik zapisany na urządzeniu. Zarządzaj plikiem na swoim urządzeniu." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index 1a71014c6c8..3e1b8f54040 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -208,19 +208,19 @@ "message": "Uma nova chave SSH foi gerada" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Sua senha está incorreta." }, "importSshKey": { - "message": "Import" + "message": "Importar" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Confirme a senha" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Digite a senha para a chave SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Insira sua senha" }, "sshAgentUnlockRequired": { "message": "Por favor, desbloqueie seu cofre para aprovar a solicitação de chave SSH." @@ -920,10 +920,10 @@ "message": "URL do Servidor" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Tempo de autenticação esgotado" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "A sessão de autenticação expirou. Por favor, reinicie o processo de login." }, "selfHostBaseUrl": { "message": "URL do servidor auto-host", @@ -1393,13 +1393,13 @@ "message": "Histórico de senhas" }, "generatorHistory": { - "message": "Generator history" + "message": "Histórico do gerador" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Limpar histórico do gerador" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Se continuar, todas as entradas serão permanentemente excluídas do histórico do gerador. Tem certeza que deseja continuar?" }, "clear": { "message": "Limpar", @@ -1409,13 +1409,13 @@ "message": "Não existem senhas para listar." }, "clearHistory": { - "message": "Clear history" + "message": "Limpar histórico" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Nada para mostrar" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Você não gerou uma senha recentemente" }, "undo": { "message": "Desfazer" @@ -2481,7 +2481,7 @@ "message": "Gerar e-mail" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Valor deve ser entre $MIN$ e $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2505,7 +2505,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Utilize as palavras $RECOMMENDED$ ou mais para gerar uma frase secreta forte.", "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": { @@ -2726,13 +2726,13 @@ "message": "Uma notificação foi enviada para seu dispositivo." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Uma notificação foi enviada para seu dispositivo" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Certifique-se que sua conta esteja desbloqueada e que a frase de identificação corresponda à do outro dispositivo" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Precisa de outra opção?" }, "fingerprintMatchInfo": { "message": "Por favor, certifique-se de que o seu cofre esteja desbloqueado e a frase de identificação corresponda ao outro dispositivo." @@ -2741,13 +2741,13 @@ "message": "Frase de identificação" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Você será notificado assim que a requisição for aprovada" }, "needAnotherOption": { "message": "Login com dispositivo deve ser habilitado nas configurações do aplicativo móvel do Bitwarden. Necessita de outra opção?" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Ver todas as opções de login" }, "viewAllLoginOptions": { "message": "Ver todas as opções de login" @@ -2869,7 +2869,7 @@ "message": "Verificar vazamentos de dados conhecidos para esta senha" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Sessão Iniciada!" }, "important": { "message": "Importante:" @@ -2902,16 +2902,16 @@ "message": "Atualização de configurações recomendadas" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Lembrar deste dispositivo para permanecer conectado" }, "deviceApprovalRequired": { "message": "Aprovação do dispositivo necessária. Selecione uma opção de aprovação abaixo:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "É necessária a aprovação do dispositivo" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Selecione uma opção de aprovação abaixo" }, "rememberThisDevice": { "message": "Lembrar deste dispositivo" @@ -2966,7 +2966,7 @@ "message": "E-mail do usuário ausente" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "E-mail de usuário ativo não encontrado. Desconectando." }, "deviceTrusted": { "message": "Dispositivo confiável" @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Arquivo salvo no dispositivo. Gerencie a partir das transferências do seu dispositivo." + }, + "importantNotice": { + "message": "Aviso importante" + }, + "setupTwoStepLogin": { + "message": "Configurar login em duas etapas" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden enviará um código para o seu e-mail para verificar novos dispositivos a partir de fevereiro de 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Você pode configurar o login em duas etapas como uma forma alternativa de proteger sua conta ou mudar seu e-mail para um que você possa acessar." + }, + "remindMeLater": { + "message": "Lembre-me depois" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Você tem acesso ao seu e-mail, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Não tenho" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Sim, eu tenho" + }, + "turnOnTwoStepLogin": { + "message": "Ativar login em duas etapas" + }, + "changeAcctEmail": { + "message": "Alterar e-mail" } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index ffd1f8de2ce..55b031690a8 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -2875,7 +2875,7 @@ "message": "Importante:" }, "accessing": { - "message": "A aceder" + "message": "A aceder a" }, "accessTokenUnableToBeDecrypted": { "message": "A sua sessão foi encerrada porque o seu token de acesso não pôde ser desencriptado. Por favor, inicie sessão novamente para resolver este problema." @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Ficheiro guardado no dispositivo. Gira-o a partir das transferências do seu dispositivo." + }, + "importantNotice": { + "message": "Aviso importante" + }, + "setupTwoStepLogin": { + "message": "Definir a verificação de dois passos" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "O Bitwarden enviará um código para o e-mail da sua conta para verificar as credenciais de novos dispositivos a partir de fevereiro de 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Pode configurar a verificação de dois passos como forma alternativa de proteger a sua conta ou alterar o seu e-mail para um a que possa aceder." + }, + "remindMeLater": { + "message": "Lembrar-me mais tarde" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Tem um acesso fiável ao seu e-mail, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Não, não tenho" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Sim, consigo aceder de forma fiável ao meu e-mail" + }, + "turnOnTwoStepLogin": { + "message": "Ativar a verificação de dois passos" + }, + "changeAcctEmail": { + "message": "Alterar o e-mail da conta" } } diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index 65bc39c4cda..0d26dbb2fc8 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index 83a6c49f689..056c9d32aca 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Файл сохранен на устройстве. Управляйте им из загрузок устройства." + }, + "importantNotice": { + "message": "Важное уведомление" + }, + "setupTwoStepLogin": { + "message": "Настроить двухэтапную аутентификацию" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Начиная с февраля 2025 года Bitwarden будет отправлять код на электронную почту вашего аккаунта для подтверждения авторизации с новых устройств." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "В качестве альтернативного способа защиты учетной записи вы можете настроить двухэтапную аутентификацию или сменить электронную почту на ту, к которой вы можете получить доступ." + }, + "remindMeLater": { + "message": "Напомнить позже" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Есть ли у вас надежный доступ к электронной почте $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Нет, не знаю" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Да, я имею надежный доступ к своей электронной почте" + }, + "turnOnTwoStepLogin": { + "message": "Включить двухэтапную аутентификацию" + }, + "changeAcctEmail": { + "message": "Изменить email аккаунта" } } diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index b47ec4e684d..51625639dda 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 4abf39f0eaa..6013b9b61e0 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Súbor sa uložil do zariadenia. Spravujte stiahnuté súbory zo zariadenia." + }, + "importantNotice": { + "message": "Dôležité upozornenie" + }, + "setupTwoStepLogin": { + "message": "Nastavenie dvojstupňového prihlásenia" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden vám od februára 2025 pošle na e-mail vášho účtu kód na overenie prihlásenia z nových zariadení." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Ako alternatívny spôsob ochrany svojho účtu môžete nastaviť dvojstupňové prihlásenie alebo zmeniť e-mail na taký, ku ktorému máte prístup." + }, + "remindMeLater": { + "message": "Pripomenúť neskôr" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Máte spoľahlivý prístup k svojmu e-mailu, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Nie, nemám" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Áno, mám spoľahlivý prístup k svojmu e-mailu" + }, + "turnOnTwoStepLogin": { + "message": "Zapnúť dvojstupňové prihlásenie" + }, + "changeAcctEmail": { + "message": "Zmeniť e-mail účtu" } } diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index d146f0d72f3..1973f6c017b 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index d99db99d0f8..3196f2c208b 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Датотека је сачувана на уређају. Управљајте преузимањима са свог уређаја." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index a227f5d27c1..c9a463246dd 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index f8f81a5ac2c..323d0cd3f7b 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 21e09c96ae5..16961afcc57 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 15e38ad3dc3..9ff0efe6854 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Dosya cihaza kaydedildi. Cihazınızın indirilenler klasöründen yönetebilirsiniz." + }, + "importantNotice": { + "message": "Önemli uyarı" + }, + "setupTwoStepLogin": { + "message": "İki adımlı girişi ayarlayın" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Şubat 2025 itibarıyla Bitwarden, yeni cihazlardan yeni girişleri doğrulamanız için e-posta adresinize bir kod gönderecektir." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Hesabınızı korumanın alternatif bir yolu olarak iki adımlı girişi etkinleştirebilirsiniz. Aksi halde e-posta adresinizin doğru olduğundan emin olmalısınız." + }, + "remindMeLater": { + "message": "Daha sonra hatırlat" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "$EMAIL$ adresinize sağlıklı bir şekilde erişebiliyor musunuz?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Hayır, erişemiyorum" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Evet, e-postalarıma sağlıklı bir şekilde erişebiliyorum" + }, + "turnOnTwoStepLogin": { + "message": "İki adımlı girişi etkinleştir" + }, + "changeAcctEmail": { + "message": "Hesap e-postasını değiştir" } } diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index 5f9b3eeac65..4103e8b28a6 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "Файл збережено на пристрої. Ви можете його знайти у теці завантажень." + }, + "importantNotice": { + "message": "Важлива інформація" + }, + "setupTwoStepLogin": { + "message": "Налаштувати двоетапну перевірку" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden надсилатиме код підтвердження на електронну пошту вашого облікового запису під час входу з нових пристроїв, починаючи з лютого 2025 року." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "Ви можете налаштувати двоетапну перевірку як альтернативний спосіб захисту свого облікового запису, або змінити електронну пошту на таку, до якої ви маєте доступ." + }, + "remindMeLater": { + "message": "Нагадати пізніше" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Ви маєте постійний доступ до своєї електронної пошти $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "Ні, не маю" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Так, я маю постійний доступ до своєї електронної пошти" + }, + "turnOnTwoStepLogin": { + "message": "Увімкнути двоетапну перевірку" + }, + "changeAcctEmail": { + "message": "Змінити адресу е-пошти" } } diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index a2c2aa7ed0f..e514124414b 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 5a6d68cd90d..dfcd104cf53 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -107,7 +107,7 @@ "message": "编辑项目" }, "emailAddress": { - "message": "电子邮件地址" + "message": "电子邮箱地址" }, "verificationCodeTotp": { "message": "验证码 (TOTP)" @@ -172,7 +172,7 @@ "message": "许可证号码" }, "email": { - "message": "电子邮件" + "message": "电子邮箱" }, "phone": { "message": "电话" @@ -709,7 +709,7 @@ "message": "设置" }, "accountEmail": { - "message": "账户邮件地址" + "message": "账户电子邮箱" }, "requestHint": { "message": "请求提示" @@ -718,22 +718,22 @@ "message": "请求密码提示" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "输入您的账户电子邮件地址,您的密码提示将发送给您" + "message": "输入您的账户电子邮箱地址,您的密码提示将发送给您" }, "passwordHint": { "message": "密码提示" }, "enterEmailToGetHint": { - "message": "请输入您账户的电子邮件地址来接收主密码提示。" + "message": "请输入您的账户电子邮箱地址来接收主密码提示。" }, "getMasterPasswordHint": { "message": "获取主密码提示" }, "emailRequired": { - "message": "必须填写电子邮件地址。" + "message": "必须填写电子邮箱地址。" }, "invalidEmail": { - "message": "无效的电子邮件地址。" + "message": "无效的电子邮箱地址。" }, "masterPasswordRequired": { "message": "必须填写主密码。" @@ -770,7 +770,7 @@ "message": "您已登录!" }, "masterPassSent": { - "message": "我们已经为您发送了包含主密码提示的邮件。" + "message": "我们已经为您发送了包含主密码提示的电子邮件。" }, "unexpectedError": { "message": "发生意外错误。" @@ -812,7 +812,7 @@ "message": "请输入您的验证器 App 中的 6 位数验证码。" }, "enterVerificationCodeEmail": { - "message": "请输入发送给电子邮件 $EMAIL$ 的 6 位数验证码。", + "message": "请输入发送给 $EMAIL$ 的 6 位数验证码。", "placeholders": { "email": { "content": "$1", @@ -868,7 +868,7 @@ "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { - "message": "为您的组织使用 Duo Security 的 Duo 移动应用、短信、电话或 U2F 安全钥匙来进行验证。", + "message": "为您的组织使用 Duo Security 的 Duo 移动 App、短信、电话或 U2F 安全钥匙来进行验证。", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "webAuthnTitle": { @@ -878,7 +878,7 @@ "message": "使用任何 WebAuthn 兼容的安全钥匙访问您的帐户。" }, "emailTitle": { - "message": "电子邮件" + "message": "电子邮箱" }, "emailDescV2": { "message": "输入发送到您的电子邮箱的代码。" @@ -1058,7 +1058,7 @@ "message": "转到网页版密码库" }, "getMobileApp": { - "message": "获取手机应用" + "message": "获取移动应用程序" }, "getBrowserExtension": { "message": "获取浏览器扩展" @@ -1181,37 +1181,37 @@ "message": "显示网站图标" }, "faviconDesc": { - "message": "在每个登录项目旁边显示一个可识别的图像。" + "message": "在每个登录项目旁边显示可识别的图像。" }, "enableMinToTray": { "message": "最小化到托盘图标" }, "enableMinToTrayDesc": { - "message": "最小化窗口后,在系统托盘中显示一个图标。" + "message": "最小化窗口后,在系统托盘中显示图标。" }, "enableMinToMenuBar": { "message": "最小化到菜单栏" }, "enableMinToMenuBarDesc": { - "message": "最小化窗口后,改为在菜单栏中显示一个图标。" + "message": "最小化窗口后,改为在菜单栏中显示图标。" }, "enableCloseToTray": { "message": "关闭到托盘图标" }, "enableCloseToTrayDesc": { - "message": "关闭窗口后,在系统托盘中显示一个图标。" + "message": "关闭窗口后,在系统托盘中显示图标。" }, "enableCloseToMenuBar": { "message": "关闭到菜单栏" }, "enableCloseToMenuBarDesc": { - "message": "关闭窗口后,改为在菜单栏中显示一个图标。" + "message": "关闭窗口后,改为在菜单栏中显示图标。" }, "enableTray": { "message": "显示托盘图标" }, "enableTrayDesc": { - "message": "始终在系统托盘中显示一个图标。" + "message": "始终在系统托盘中显示图标。" }, "startToTray": { "message": "启动到托盘图标" @@ -1320,7 +1320,7 @@ "description": "Copy credit card number" }, "copyEmail": { - "message": "复制电子邮件地址" + "message": "复制电子邮箱" }, "copySecurityCode": { "message": "复制安全码", @@ -1635,7 +1635,7 @@ "description": "ex. Register as an accessibility user at hcaptcha.com" }, "copyPasteLink": { - "message": "复制链接并粘贴在下方以便发送到你的电子邮箱" + "message": "复制发送到您电子邮箱的链接然后粘贴在下方" }, "enterhCaptchaUrl": { "message": "输入 URL 以加载 hCaptcha 的无障碍 Cookie", @@ -1814,7 +1814,7 @@ "message": "服务条款" }, "privacyPolicy": { - "message": "隐私条款" + "message": "隐私政策" }, "unsavedChangesConfirmation": { "message": "确定要离开吗?如果您现在离开,您当前的信息不会被保存。" @@ -1957,13 +1957,13 @@ "message": "取消订阅" }, "atAnyTime": { - "message": "随时" + "message": "随时。" }, "byContinuingYouAgreeToThe": { "message": "若继续,代表您同意" }, "and": { - "message": "以及" + "message": "和" }, "acceptPolicies": { "message": "选中此框表示您同意:" @@ -2225,19 +2225,19 @@ "message": "验证 WebAuthn" }, "hideEmail": { - "message": "对收件人隐藏我的电子邮件地址。" + "message": "对收件人隐藏我的电子邮箱地址。" }, "sendOptionsPolicyInEffect": { "message": "一个或多个组织策略正在影响您的 Send 设置。" }, "emailVerificationRequired": { - "message": "需要验证电子邮件" + "message": "需要验证电子邮箱" }, "emailVerifiedV2": { "message": "电子邮箱已验证" }, "emailVerificationRequiredDesc": { - "message": "您必须验证您的电子邮件才能使用此功能。" + "message": "您必须验证电子邮箱才能使用此功能。" }, "passwordPrompt": { "message": "主密码重新提示" @@ -2478,7 +2478,7 @@ "message": "生成用户名" }, "generateEmail": { - "message": "生成电子邮件地址" + "message": "生成电子邮箱" }, "spinboxBoundariesHint": { "message": "值必须在 $MIN$ 和 $MAX$ 之间。", @@ -2518,14 +2518,14 @@ "message": "用户名类型" }, "plusAddressedEmail": { - "message": "附加地址电子邮件", + "message": "附加地址电子邮箱", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "使用您的电子邮件供应商的子地址功能。" + "message": "使用您的电子邮箱提供商的子地址功能。" }, "catchallEmail": { - "message": "Catch-all 电子邮件" + "message": "Catch-all 电子邮箱" }, "catchallEmailDesc": { "message": "使用您的域名配置的 Catch-all 收件箱。" @@ -2552,13 +2552,13 @@ "message": "搜索我的密码库" }, "forwardedEmail": { - "message": "转发的电子邮件别名" + "message": "转发的电子邮箱别名" }, "forwardedEmailDesc": { - "message": "使用外部转发服务生成一个电子邮件别名。" + "message": "使用外部转发服务生成一个电子邮箱别名。" }, "forwarderDomainName": { - "message": "电子邮件域名", + "message": "电子邮箱域名", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { @@ -2618,7 +2618,7 @@ } }, "forwarderNoAccountId": { - "message": "无法获取 $SERVICENAME$ 电子邮件账户 ID。", + "message": "无法获取 $SERVICENAME$ 电子邮箱账户 ID。", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2699,7 +2699,7 @@ "message": "正登录为" }, "rememberEmail": { - "message": "记住电子邮件地址" + "message": "记住电子邮箱" }, "notYou": { "message": "不是您吗?" @@ -2833,7 +2833,7 @@ "message": "已请求登录" }, "creatingAccountOn": { - "message": "正创建账户于" + "message": "创建账户至" }, "checkYourEmail": { "message": "检查您的电子邮箱" @@ -2851,7 +2851,7 @@ "message": "返回" }, "toEditYourEmailAddress": { - "message": "编辑您的电子邮件地址。" + "message": "编辑您的电子邮箱地址。" }, "exposedMasterPassword": { "message": "已暴露的主密码" @@ -2908,7 +2908,7 @@ "message": "需要设备批准。请在下面选择一个批准选项:" }, "deviceApprovalRequiredV2": { - "message": "已请求设备批准" + "message": "需要设备批准" }, "selectAnApprovalOptionBelow": { "message": "在下方选择一个批准选项" @@ -2963,10 +2963,10 @@ "message": "登录已批准" }, "userEmailMissing": { - "message": "缺少用户电子邮件" + "message": "缺少用户电子邮箱" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "未找到活动的用户电子邮件。您将被注销。" + "message": "未找到活动的用户电子邮箱。您将被注销。" }, "deviceTrusted": { "message": "设备已信任" @@ -3026,14 +3026,14 @@ } }, "multipleInputEmails": { - "message": "一个或多个电子邮件地址无效" + "message": "一个或多个电子邮箱无效" }, "inputTrimValidator": { "message": "输入不能只包含空格。", "description": "Notification to inform the user that a form's input can't contain only whitespace." }, "inputEmail": { - "message": "输入的不是电子邮件地址。" + "message": "输入的不是电子邮箱地址。" }, "fieldsNeedAttention": { "message": "上面的 $COUNT$ 个字段需要您注意。", @@ -3369,7 +3369,7 @@ "message": "拒绝" }, "sshkeyApprovalTitle": { - "message": "确认 SSH 密钥使用" + "message": "确认 SSH 密钥的使用方式" }, "sshkeyApprovalMessageInfix": { "message": "正在请求访问" @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "文件已保存到设备。可以在设备下载中进行管理。" + }, + "importantNotice": { + "message": "重要通知" + }, + "setupTwoStepLogin": { + "message": "设置两步登录" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮箱发送一个代码,以验证来自新设备的登录。" + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" + }, + "remindMeLater": { + "message": "稍后提醒我" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "您能可靠地访问您的电子邮箱 $EMAIL$ 吗?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "不,我不能" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "是的,我可以可靠地访问我的电子邮箱" + }, + "turnOnTwoStepLogin": { + "message": "开启两步登录" + }, + "changeAcctEmail": { + "message": "更改账户电子邮箱" } } diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 23166f4aea8..3c7884a22c5 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -3394,5 +3394,41 @@ }, "fileSavedToDevice": { "message": "File saved to device. Manage from your device downloads." + }, + "importantNotice": { + "message": "Important notice" + }, + "setupTwoStepLogin": { + "message": "Set up two-step login" + }, + "newDeviceVerificationNoticeContentPage1": { + "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + }, + "newDeviceVerificationNoticeContentPage2": { + "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + }, + "remindMeLater": { + "message": "Remind me later" + }, + "newDeviceVerificationNoticePageOneFormContent": { + "message": "Do you have reliable access to your email, $EMAIL$?", + "placeholders": { + "email": { + "content": "$1", + "example": "your_name@email.com" + } + } + }, + "newDeviceVerificationNoticePageOneEmailAccessNo": { + "message": "No, I do not" + }, + "newDeviceVerificationNoticePageOneEmailAccessYes": { + "message": "Yes, I can reliably access my email" + }, + "turnOnTwoStepLogin": { + "message": "Turn on two-step login" + }, + "changeAcctEmail": { + "message": "Change account email" } } From 02f1ec651929d0902c647fcb7d4ccf6e990513dd Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 17:57:10 +0000 Subject: [PATCH 04/65] Autosync the updated translations (#12628) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/bg/messages.json | 6 +- apps/web/src/locales/de/messages.json | 14 +- apps/web/src/locales/eo/messages.json | 18 +-- apps/web/src/locales/fi/messages.json | 10 +- apps/web/src/locales/hr/messages.json | 20 +-- apps/web/src/locales/pt_PT/messages.json | 2 +- apps/web/src/locales/sk/messages.json | 22 +-- apps/web/src/locales/zh_CN/messages.json | 184 +++++++++++------------ 8 files changed, 138 insertions(+), 138 deletions(-) diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 88634c13b98..4a0f650bd3f 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -36,7 +36,7 @@ "message": "Възстановяване на достъпа на членове" }, "cannotRestoreAccessError": { - "message": "Cannot restore organization access" + "message": "Достъпът до организацията не може да бъде възстановен" }, "allApplicationsWithCount": { "message": "Всички приложения ($COUNT$)", @@ -5635,10 +5635,10 @@ "message": "Изключени като неподходящи за това действие." }, "nonCompliantMembersTitle": { - "message": "Non-compliant members" + "message": "Неизпълняващи изискванията членове" }, "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" + "message": "Членове, които не отговарят на изискването за Единствена организация или за Двустепенно удостоверяване не могат да бъдат възстановени, докато не изпълнят тези изисквания" }, "fingerprint": { "message": "Отпечатък" diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 57e5891a702..4ed75be054f 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -3883,7 +3883,7 @@ "message": "Browser aktualisieren" }, "generatingRiskInsights": { - "message": "Deine Risikoübersicht wird generiert..." + "message": "Dein Risiko-Überblick wird generiert..." }, "updateBrowserDesc": { "message": "Du verwendest einen nicht unterstützten Webbrowser. Der Web-Tresor funktioniert möglicherweise nicht richtig." @@ -9888,13 +9888,13 @@ "message": "Wichtiger Hinweis" }, "setupTwoStepLogin": { - "message": "Richte die zweistufige Anmeldung ein" + "message": "Zwei-Faktor-Authentifizierung einrichten" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden wird einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten ab Februar 2025 zu überprüfen." + "message": "Ab Februar 2025 wird Bitwarden einen Code an deine Konto-E-Mail-Adresse senden, um Anmeldungen von neuen Geräten zu verifizieren." }, "newDeviceVerificationNoticeContentPage2": { - "message": "Du kannst die zweistufige Anmeldung als eine alternative Methode einrichten, um deinen Account zu schützen, oder ändere deine E-Mail-Adresse zu einer, auf die du zugreifen kannst." + "message": "Du kannst die Zwei-Faktor-Authentifizierung als eine alternative Methode einrichten, um dein Konto zu schützen, oder deine E-Mail-Adresse zu einer anderen ändern, auf die du zugreifen kannst." }, "remindMeLater": { "message": "Erinnere mich später" @@ -9915,10 +9915,10 @@ "message": "Ja, ich kann zuverlässig auf meine E-Mails zugreifen" }, "turnOnTwoStepLogin": { - "message": "Aktiviere die zweistufige Anmeldung" + "message": "Zwei-Faktor-Authentifizierung aktivieren" }, "changeAcctEmail": { - "message": "Ändere die E-Mail-Adresse des Kontos" + "message": "E-Mail-Adresse des Kontos ändern" }, "removeMembers": { "message": "Mitglieder entfernen" @@ -10003,7 +10003,7 @@ } }, "domainClaimed": { - "message": "Beanspruchte Domain" + "message": "Domain beansprucht" }, "organizationNameMaxLength": { "message": "Der Name der Organisation darf 50 Zeichen nicht überschreiten." diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 2c1aa36046e..06225dba76f 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -1,6 +1,6 @@ { "allApplications": { - "message": "All applications" + "message": "Ĉiuj aplikaĵoj" }, "criticalApplications": { "message": "Critical applications" @@ -39,7 +39,7 @@ "message": "Cannot restore organization access" }, "allApplicationsWithCount": { - "message": "All applications ($COUNT$)", + "message": "Ĉiuj aplikaĵoj ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -416,7 +416,7 @@ "description": "This is the folder for uncategorized items" }, "selfOwnershipLabel": { - "message": "You", + "message": "Vi", "description": "Used as a label to indicate that the user is the owner of an item." }, "addFolder": { @@ -572,7 +572,7 @@ "message": "Sekura noto" }, "typeSshKey": { - "message": "SSH key" + "message": "SSH-ŝlosilo" }, "typeLoginPlural": { "message": "Salutoj" @@ -605,7 +605,7 @@ "message": "Plena Nomo" }, "address": { - "message": "Address" + "message": "Adreso" }, "address1": { "message": "Adreso 1" @@ -677,7 +677,7 @@ } }, "new": { - "message": "New", + "message": "Nova", "description": "for adding new items" }, "item": { @@ -1117,7 +1117,7 @@ "message": "Saluti" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Ensaluti en Bitwarden" }, "authenticationTimeout": { "message": "Authentication timeout" @@ -1254,10 +1254,10 @@ "message": "Retpoŝta Adreso" }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Via trezorejo estas ŝlosita" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "Via konto estas ŝlosita" }, "uuid": { "message": "UUID" diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 90a9078ceb9..a5d576d349d 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -12,7 +12,7 @@ "message": "Risk Insights" }, "passwordRisk": { - "message": "Password Risk" + "message": "Salasanariski" }, "reviewAtRiskPasswords": { "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." @@ -9885,10 +9885,10 @@ "message": "Descriptor code" }, "importantNotice": { - "message": "Important notice" + "message": "Tärkeä ilmoitus" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Määritä kaksivaiheinen kirjautuminen" }, "newDeviceVerificationNoticeContentPage1": { "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." @@ -9915,10 +9915,10 @@ "message": "Yes, I can reliably access my email" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Ota kaksivaiheinen kirjautuminen käyttöön" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Muuta tilin sähköpostiosoitetta" }, "removeMembers": { "message": "Poista jäsenet" diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 9a127140786..5a397cd4b14 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -9885,22 +9885,22 @@ "message": "Šifra uplate" }, "importantNotice": { - "message": "Important notice" + "message": "Važna napomena" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Postavi dvostruku autentifikaciju" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden će, počevši od veljače 2025., za provjeru prijava s novih uređaja poslati kôd na e-poštu tvog računa." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Prijavu dvostrukom autentifikacijom možeš postaviti kao alternativni način zaštite svog računa ili promijeni svoju e-poštu u onu kojoj možeš pristupiti." }, "remindMeLater": { - "message": "Remind me later" + "message": "Podsjeti me kasnije" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Imaš li pouzdan pristup svojoj e-pošti: $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -9909,16 +9909,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Ne, nemam" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Da, pouzdano mogu pristupiti svojoj e-pošti" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Uključi prijavu dvostrukom autentifikacijom" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Promjeni e-poštu računa" }, "removeMembers": { "message": "Ukloni članove" diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 78206bc56a2..28b65826f02 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -502,7 +502,7 @@ "message": "Eliminar" }, "favorite": { - "message": "Favorito" + "message": "Adicionar aos favoritos" }, "unfavorite": { "message": "Remover dos favoritos" diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 8533d50b304..947e459b8fd 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -3883,7 +3883,7 @@ "message": "Aktualizovať prehliadač" }, "generatingRiskInsights": { - "message": "Generating your risk insights..." + "message": "Generuje sa váš prehľad o rizikách..." }, "updateBrowserDesc": { "message": "Používate nepodporovaný prehliadač. Webový trezor nemusí úplne fungovať." @@ -9885,22 +9885,22 @@ "message": "Kód výpisu" }, "importantNotice": { - "message": "Important notice" + "message": "Dôležité upozornenie" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Nastaviť dvojstupňové prihlásenie" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden vám od februára 2025 pošle na e-mail vášho účtu kód na overenie prihlásenia z nových zariadení." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Ako alternatívny spôsob ochrany svojho účtu môžete nastaviť dvojstupňové prihlásenie alebo zmeniť e-mail na taký, ku ktorému máte prístup." }, "remindMeLater": { - "message": "Remind me later" + "message": "Pripomenúť neskôr" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Máte spoľahlivý prístup k svojmu e-mailu, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -9909,16 +9909,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Nie, nemám" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Áno, mám spoľahlivý prístup k svojmu e-mailu" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Zapnúť dvojstupňové prihlásenie" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Zmeniť e-mail účtu" }, "removeMembers": { "message": "Odstrániť členov" diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 0dad065f574..e0856dc4350 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -285,7 +285,7 @@ "message": "许可证号码" }, "email": { - "message": "电子邮件" + "message": "电子邮箱" }, "phone": { "message": "电话" @@ -777,7 +777,7 @@ "message": "复制电话号码" }, "copyEmail": { - "message": "复制电子邮件地址" + "message": "复制电子邮箱" }, "copyCompany": { "message": "复制公司信息" @@ -1135,7 +1135,7 @@ "message": "提交" }, "emailAddressDesc": { - "message": "使用您的电子邮件地址登录。" + "message": "使用您的电子邮箱地址登录。" }, "yourName": { "message": "您的姓名" @@ -1184,7 +1184,7 @@ "message": "设置" }, "accountEmail": { - "message": "账户邮件地址" + "message": "账户电子邮箱" }, "requestHint": { "message": "请求提示" @@ -1193,22 +1193,22 @@ "message": "请求密码提示" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "输入您的账户电子邮件地址,您的密码提示将发送给您" + "message": "输入您的账户电子邮箱地址,您的密码提示将发送给您" }, "passwordHint": { "message": "密码提示" }, "enterEmailToGetHint": { - "message": "输入您账户的电子邮件地址来接收主密码提示。" + "message": "请输入您的账户电子邮箱地址来接收主密码提示。" }, "getMasterPasswordHint": { "message": "获取主密码提示" }, "emailRequired": { - "message": "必须填写电子邮件地址。" + "message": "必须填写电子邮箱地址。" }, "invalidEmail": { - "message": "无效的电子邮件地址。" + "message": "无效的电子邮箱地址。" }, "masterPasswordRequired": { "message": "必须填写主密码。" @@ -1242,7 +1242,7 @@ "message": "账户创建成功。" }, "masterPassSent": { - "message": "我们已经为您发送了包含主密码提示的邮件。" + "message": "我们已经为您发送了包含主密码提示的电子邮件。" }, "unexpectedError": { "message": "发生意外错误。" @@ -1251,7 +1251,7 @@ "message": "请选择一个将来的过期日期。" }, "emailAddress": { - "message": "电子邮件地址" + "message": "电子邮箱地址" }, "yourVaultIsLockedV2": { "message": "您的密码库已锁定" @@ -1339,7 +1339,7 @@ "message": "请输入您的验证器 App 中的 6 位数验证码。" }, "enterVerificationCodeEmail": { - "message": "请输入发送给电子邮件 $EMAIL$ 的 6 位数验证码。", + "message": "请输入发送给 $EMAIL$ 的 6 位数验证码。", "placeholders": { "email": { "content": "$1", @@ -1407,7 +1407,7 @@ "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "duoOrganizationDesc": { - "message": "为您的组织使用 Duo Security 的 Duo 移动应用、短信、电话或 U2F 安全钥匙来进行验证。", + "message": "为您的组织使用 Duo Security 的 Duo 移动 App、短信、电话或 U2F 安全钥匙来进行验证。", "description": "'Duo Security' and 'Duo Mobile' are product names and should not be translated." }, "u2fDesc": { @@ -1426,10 +1426,10 @@ "message": "(迁移自 FIDO)" }, "emailTitle": { - "message": "电子邮件" + "message": "电子邮箱" }, "emailDescV2": { - "message": "输入发送到您的电子邮箱的代码。" + "message": "请输入发送到您的电子邮箱的代码。" }, "continue": { "message": "继续" @@ -1686,19 +1686,19 @@ "message": "账户已保存" }, "changeEmail": { - "message": "修改电子邮件地址" + "message": "更改电子邮箱" }, "changeEmailTwoFactorWarning": { - "message": "继续操作将更改您的账户电子邮件地址。这不会更改用于双重身份验证的电子邮件地址。您可以在两步登录设置中更改它。" + "message": "继续操作将更改您的账户电子邮箱地址。这不会更改用于双重身份验证的电子邮箱地址。您可以在两步登录设置中更改它。" }, "newEmail": { - "message": "新电子邮件地址" + "message": "新的电子邮箱" }, "code": { "message": "代码" }, "changeEmailDesc": { - "message": "我们已将验证码发送到 $EMAIL$。请检查您的电子邮件,在下方输入验证码,以确认更改您的电子邮件地址。", + "message": "我们已将验证码发送到 $EMAIL$。请检查您的电子邮箱,在下方输入验证码,以确认更改您的电子邮箱地址。", "placeholders": { "email": { "content": "$1", @@ -1710,7 +1710,7 @@ "message": "接下来将会注销您当前的会话,要求您重新登录。其他设备上的活动会话可能会继续保持最多一小时。" }, "emailChanged": { - "message": "电子邮件已保存" + "message": "电子邮箱已保存" }, "logBackIn": { "message": "请重新登录。" @@ -1792,7 +1792,7 @@ "message": "取消会话授权" }, "deauthorizeSessionsDesc": { - "message": "您是否担心自己的账户在其他设备上登录过?请按照以下步骤取消对之前使用过的所有计算机或设备的授权。如果您以前使用过公共电脑或不小心曾将密码保存在不属于您的设备上,则建议执行此安全步骤。此步骤还将清除所有以前记住的两步登录会话。" + "message": "您是否担心自己的账户在其他设备上登录过?请按照以下步骤取消对之前使用过的所有计算机或设备的授权。如果您以前使用过公共计算机或不小心曾将密码保存在不属于您的设备上,则建议执行此安全步骤。此步骤还将清除所有以前记住的两步登录会话。" }, "deauthorizeSessionsWarning": { "message": "接下来将会注销您当前的会话,并要求您重新登录。如果有设置两步登录,也需要重新认证。其他设备上的活动会话可能会继续保持最多一小时。" @@ -2168,7 +2168,7 @@ "message": "添加一个新的 YubiKey 到您的账户" }, "twoFactorYubikeyPlugIn": { - "message": "将 YubiKey 插入您电脑的 USB 端口。" + "message": "将 YubiKey 插入计算机的 USB 端口。" }, "twoFactorYubikeySelectKey": { "message": "在下面选择第一个空的 YubiKey 输入字段。" @@ -2183,10 +2183,10 @@ "message": "由于平台的限制,YubiKey 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 YubiKey 时可以访问您的账户。支持的平台:" }, "twoFactorYubikeySupportUsb": { - "message": "具有 USB 端口的设备上的网页版密码库、桌面应用程序、CLI 以及浏览器扩展都可以使用您的 YubiKey。" + "message": "具有可使用 YubiKey 的 USB 端口的设备上的网页版密码库、桌面应用程序、CLI 以及浏览器扩展。" }, "twoFactorYubikeySupportMobile": { - "message": "具有兼容 NFC 或数据端口的设备上的移动应用程序可以使用您的 YubiKey。" + "message": "具有 NFC 功能或可使用 YubiKey 的数据端口的设备上的移动应用程序。" }, "yubikeyX": { "message": "YubiKey $INDEX$", @@ -2243,10 +2243,10 @@ "message": "API 主机名" }, "twoFactorEmailDesc": { - "message": "按照以下步骤设置使用电子邮件的两步登录:" + "message": "按照以下步骤设置使用电子邮箱的两步登录:" }, "twoFactorEmailEnterEmail": { - "message": "输入您希望接收验证码的电子邮件地址" + "message": "输入您希望用于接收验证码的电子邮箱" }, "twoFactorEmailEnterCode": { "message": "输入电子邮件中的 6 位数验证码" @@ -2488,7 +2488,7 @@ "message": "泄露的账户可能会暴露您的个人信息。通过启用 2FA 或创建更强大的密码来保护被泄露的账户。" }, "breachCheckUsernameEmail": { - "message": "检查您使用的任何用户名或电子邮件地址。" + "message": "检查您使用的任何用户名或电子邮箱地址。" }, "checkBreaches": { "message": "检查泄漏情况" @@ -2908,7 +2908,7 @@ "message": "若要创建基于本地托管的组织,您需要上传有效的许可证文件。" }, "accountEmailMustBeVerified": { - "message": "您必须验证账户的电子邮件地址。" + "message": "必须验证您的账户电子邮箱地址。" }, "newOrganizationDesc": { "message": "组织允许您与他人共享您的密码库的部分内容,以及管理特定实体(例如家族、小型团队或大型公司)的相关用户。" @@ -2923,7 +2923,7 @@ "message": "此账户由商业用户拥有。" }, "billingEmail": { - "message": "计费电子邮箱地址" + "message": "计费电子邮箱" }, "businessName": { "message": "公司名称" @@ -3117,7 +3117,7 @@ } }, "trialConfirmationEmail": { - "message": "我们已经发送一封确认邮件到您的团队的计费电子邮箱 " + "message": "我们已经发送了一封确认邮件到您的团队的计费电子邮箱 " }, "monthly": { "message": "每月" @@ -3255,10 +3255,10 @@ } }, "inviteUserDesc": { - "message": "在下面输入 Bitwarden 账户的电子邮件地址,以邀请新用户加入您的组织。如果他们没有 Bitwarden 账户,将会提示他们创建一个。" + "message": "在下面输入 Bitwarden 账户电子邮箱地址,以邀请新用户加入您的组织。如果他们没有 Bitwarden 账户,将会提示他们创建一个。" }, "inviteMultipleEmailDesc": { - "message": "通过逗号分隔,最多输入 $COUNT$ 个电子邮件地址。", + "message": "通过逗号分隔,最多输入 $COUNT$ 个电子邮箱。", "placeholders": { "count": { "content": "$1", @@ -3279,7 +3279,7 @@ "message": "已确认" }, "clientOwnerEmail": { - "message": "客户所有者电子邮件" + "message": "客户所有者电子邮箱" }, "owner": { "message": "所有者" @@ -3766,7 +3766,7 @@ "message": "设备" }, "creatingAccountOn": { - "message": "正创建账户于" + "message": "创建账户至" }, "checkYourEmail": { "message": "检查您的电子邮箱" @@ -3784,7 +3784,7 @@ "message": "返回" }, "toEditYourEmailAddress": { - "message": "编辑您的电子邮件地址。" + "message": "编辑您的电子邮箱地址。" }, "view": { "message": "查看" @@ -3853,37 +3853,37 @@ "message": "结束日期" }, "verifyEmail": { - "message": "验证电子邮件" + "message": "验证电子邮箱" }, "verifyEmailDesc": { - "message": "验证您账户的电子邮件地址来解锁所有功能。" + "message": "验证您的账户电子邮箱地址以解锁所有功能。" }, "verifyEmailFirst": { - "message": "首先必须验证您账户的电子邮件地址。" + "message": "首先必须验证您的账户电子邮箱地址。" }, "checkInboxForVerification": { - "message": "检查您的电子邮件收件箱以获取验证链接。" + "message": "检查您的电子邮箱收件箱以获取验证链接。" }, "emailVerified": { - "message": "账户电子邮件已验证" + "message": "账户电子邮箱已验证" }, "emailVerifiedV2": { "message": "电子邮箱已验证" }, "emailVerifiedFailed": { - "message": "无法验证您的电子邮件。尝试发送新的验证电子邮件。" + "message": "无法验证您的电子邮箱。尝试发送新的验证电子邮件。" }, "emailVerificationRequired": { - "message": "需要验证电子邮件" + "message": "需要验证电子邮箱" }, "emailVerificationRequiredDesc": { - "message": "您必须验证您的电子邮件才能使用此功能。" + "message": "您必须验证电子邮箱才能使用此功能。" }, "updateBrowser": { "message": "更新浏览器" }, "generatingRiskInsights": { - "message": "Generating your risk insights..." + "message": "正在生成风险洞察..." }, "updateBrowserDesc": { "message": "您使用的是不受支持的 Web 浏览器。网页密码库可能无法正常运行。" @@ -3959,7 +3959,7 @@ "message": "邀请已接受" }, "inviteAcceptedDesc": { - "message": "管理员确认您的成员资格后,您将能访问此组织。到时我们将向您发送电子邮件通知。" + "message": "管理员确认您的成员资格后,您就可以访问此组织了。届时我们会向您发送一封电子邮件。" }, "inviteInitAcceptedDesc": { "message": "您现在可以访问这个组织了。" @@ -3977,7 +3977,7 @@ } }, "rememberEmail": { - "message": "记住电子邮件地址" + "message": "记住电子邮箱" }, "recoverAccountTwoStepDesc": { "message": "如果您无法通过常规的两步登录方式访问您的账户,您可以使用两步登录恢复代码来停用账户上的所有两步登录提供程序。" @@ -3992,7 +3992,7 @@ "message": "进一步了解" }, "deleteRecoverDesc": { - "message": "请在下面输入您的电子邮件地址以恢复和删除您的账户。" + "message": "请在下面输入您的电子邮箱地址以恢复和删除您的账户。" }, "deleteRecoverEmailSent": { "message": "如果您的账户存在,我们已经向您发送了电子邮件,其中包含了进一步说明。" @@ -4286,7 +4286,7 @@ "message": "为了提高安全性,我们更改了加密方案。请在下方输入您的主密码以立即更新您的加密密钥。" }, "updateEncryptionKeyWarning": { - "message": "更新加密密钥后,您需要注销所有正在使用的 Bitwarden 应用(比如手机版应用或者浏览器扩展)后重新登录。注销或者重新登录(这将下载新的加密密钥)失败可能会导致数据损坏。我们会尝试自动为您注销,但是,可能会有所延迟。" + "message": "更新加密密钥后,您需要注销所有正在使用的 Bitwarden 应用(比如移动 App 或者浏览器扩展)后重新登录。注销或者重新登录(这将下载新的加密密钥)失败可能会导致数据损坏。我们会尝试自动为您注销,但是,可能会有所延迟。" }, "updateEncryptionKeyExportWarning": { "message": "您保存的任何已加密导出也将变为无效。" @@ -4331,7 +4331,7 @@ "message": "若继续,代表您同意" }, "and": { - "message": "以及" + "message": "和" }, "acceptPolicies": { "message": "选中此框表示您同意:" @@ -4343,7 +4343,7 @@ "message": "服务条款" }, "privacyPolicy": { - "message": "隐私条款" + "message": "隐私政策" }, "filters": { "message": "筛选" @@ -4722,7 +4722,7 @@ "message": "组织标识符" }, "ssoLogInWithOrgIdentifier": { - "message": "要使用您组织的单点登录门户登录。请首先输入您组织的标识符。" + "message": "使用您组织的单点登录门户登录。请输入您组织的 SSO 标识符以开始。" }, "singleSignOnEnterOrgIdentifier": { "message": "输入您组织的 SSO 标识符以开始" @@ -4924,7 +4924,7 @@ "message": "确定移除此密码?" }, "hideEmail": { - "message": "对收件人隐藏我的电子邮件地址。" + "message": "对收件人隐藏我的电子邮箱地址。" }, "disableThisSend": { "message": "停用此 Send 则任何人无法访问它。", @@ -5005,7 +5005,7 @@ "message": "编辑紧急联系人" }, "inviteEmergencyContactDesc": { - "message": "通过在下面输入他们的 Bitwarden 账户电子邮件地址来邀请新的紧急联系人。如果他们还没有 Bitwarden 账户,将提示他们创建一个新账户。" + "message": "通过在下面输入他们的 Bitwarden 账户电子邮箱地址来邀请新的紧急联系人。如果他们还没有 Bitwarden 账户,将提示他们创建一个新账户。" }, "emergencyAccessRecoveryInitiated": { "message": "紧急访问已发起" @@ -5059,7 +5059,7 @@ } }, "emergencyInviteAcceptedDesc": { - "message": "身份确认后,您可以访问该用户的紧急选项。当发生这种情况时,我们会向您发送一封电子邮件。" + "message": "身份确认后,您就可以访问该用户的紧急选项了。届时我们会向您发送一封电子邮件。" }, "requestAccess": { "message": "请求访问权限" @@ -5158,14 +5158,14 @@ "message": "可以管理组织策略的组织成员豁免此策略。" }, "disableHideEmail": { - "message": "在创建或编辑 Send 时,始终向收件人显示成员的电子邮件地址。", + "message": "在创建或编辑 Send 时,始终向收件人显示成员的电子邮箱地址。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendOptionsPolicyInEffect": { "message": "以下组织策略目前正起作用:" }, "sendDisableHideEmailInEffect": { - "message": "用户在创建或编辑 Send 时不允许隐藏他们的电子邮件地址。", + "message": "创建或编辑 Send 时,不允许用户对收件人隐藏他们的电子邮箱地址。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "modifiedPolicyId": { @@ -5405,7 +5405,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Learn more about Bitwarden Send or sign up to **try it today.**'" }, "sendAccessCreatorIdentifier": { - "message": "Bitwarden 成员 $USER_IDENTIFIER$ 与您共享了以下内容", + "message": "Bitwarden 成员 $USER_IDENTIFIER$ 与您分享了以下内容", "placeholders": { "user_identifier": { "content": "$1", @@ -5418,7 +5418,7 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "viewSendHiddenEmailWarning": { - "message": "创建此 Send 的 Bitwarden 用户已选择隐藏他们的电子邮件地址。在使用或下载此链接的内容之前,应确保您信任此链接的来源。", + "message": "创建此 Send 的 Bitwarden 用户已选择隐藏他们的电子邮箱地址。在使用或下载其内容之前,您应确保信任此链接的来源。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDateIsInvalid": { @@ -5693,7 +5693,7 @@ "message": "服务用户可以访问和管理所有客户组织。" }, "providerInviteUserDesc": { - "message": "通过在下面输入他们的 Bitwarden 账户电子邮件地址,以邀请新用户加入您的提供商。如果他们还没有 Bitwarden 账户,将提示他们创建一个。" + "message": "通过在下面输入他们的 Bitwarden 账户电子邮箱地址,以邀请新用户加入您的提供商。如果他们还没有 Bitwarden 账户,将提示他们创建一个新账户。" }, "joinProvider": { "message": "加入提供商" @@ -5965,7 +5965,7 @@ "message": "自定义用户 ID 声明类型" }, "additionalEmailClaimTypes": { - "message": "电子邮件声明类型" + "message": "电子邮箱声明类型" }, "additionalNameClaimTypes": { "message": "自定义名称声明类型" @@ -6043,7 +6043,7 @@ "message": "免费 Bitwarden 家庭" }, "sponsoredFamiliesEligible": { - "message": "您和您的家人有资格享受免费的 Bitwarden 家庭版计划。即使您不在公司上班,您也可以使用个人电子邮件兑换此计划,以保护您的数据安全。" + "message": "您和您的家人有资格享受免费的 Bitwarden 家庭版计划。即使您不在公司上班,您也可以使用个人电子邮箱兑换此计划,以保护您的数据安全。" }, "sponsoredFamiliesEligibleCard": { "message": "立即兑换免费的 Bitwarden 家庭版计划,即使您不在公司上班也能确保您的数据安全。" @@ -6073,7 +6073,7 @@ "message": "您想兑换哪一个免费家庭邀请?" }, "sponsoredFamiliesEmail": { - "message": "输入您的个人电子邮件以兑换 Bitwarden 家庭" + "message": "输入您的个人电子邮箱以兑换 Bitwarden 家庭" }, "sponsoredFamiliesLeaveCopy": { "message": "如果您移除邀请或邀请被赞助组织移除,您的家庭赞助将在下一个续费日到期。" @@ -6529,7 +6529,7 @@ "message": "生成用户名" }, "generateEmail": { - "message": "生成电子邮件地址" + "message": "生成电子邮箱" }, "spinboxBoundariesHint": { "message": "值必须在 $MIN$ 和 $MAX$ 之间。", @@ -6569,14 +6569,14 @@ "message": "用户名类型" }, "plusAddressedEmail": { - "message": "附加地址电子邮件", + "message": "附加地址电子邮箱", "description": "Username generator option that appends a random sub-address to the username. For example: address+subaddress@email.com" }, "plusAddressedEmailDesc": { - "message": "使用您的电子邮件提供商的子地址功能。" + "message": "使用您的电子邮箱提供商的子地址功能。" }, "catchallEmail": { - "message": "Catch-all 电子邮件" + "message": "Catch-all 电子邮箱" }, "catchallEmailDesc": { "message": "使用您的域名配置的 Catch-all 收件箱。" @@ -6615,7 +6615,7 @@ "message": "未知项目,你可能需要申请权限才能访问这个项目。" }, "cannotSponsorSelf": { - "message": "您不能为已启用的账户兑换。请输入其他电子邮件地址。" + "message": "您不能为活动账户兑换。请输入其他电子邮箱。" }, "revokeWhenExpired": { "message": "$DATE$ 到期", @@ -6665,13 +6665,13 @@ "description": "This text is displayed if an organization's billing is managed by a Provider. It tells the user to contact the Provider for assistance." }, "forwardedEmail": { - "message": "转发的电子邮件别名" + "message": "转发的电子邮箱别名" }, "forwardedEmailDesc": { - "message": "使用外部转发服务生成一个电子邮件别名。" + "message": "使用外部转发服务生成一个电子邮箱别名。" }, "forwarderDomainName": { - "message": "电子邮件域名", + "message": "电子邮箱域名", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { @@ -6731,7 +6731,7 @@ } }, "forwarderNoAccountId": { - "message": "无法获取 $SERVICENAME$ 电子邮件账户 ID。", + "message": "无法获取 $SERVICENAME$ 电子邮箱账户 ID。", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -6794,13 +6794,13 @@ "message": "启用设备验证" }, "deviceVerificationDesc": { - "message": "登录未识别的设备时,验证码会发送到您的电子邮箱" + "message": "登录未识别的设备时,验证码会发送到您的电子邮箱地址" }, "updatedDeviceVerification": { "message": "已更新设备验证" }, "areYouSureYouWantToEnableDeviceVerificationTheVerificationCodeEmailsWillArriveAtX": { - "message": "确定要开启设备验证吗?验证码邮件将发送到 $EMAIL$", + "message": "确定要开启设备验证吗?验证码电子邮件将发送到:$EMAIL$", "placeholders": { "email": { "content": "$1", @@ -6873,7 +6873,7 @@ "message": "必须输入内容。" }, "inputEmail": { - "message": "输入的不是电子邮件地址。" + "message": "输入的不是电子邮箱地址。" }, "inputMinLength": { "message": "至少输入 $COUNT$ 个字符。", @@ -6921,10 +6921,10 @@ } }, "multipleInputEmails": { - "message": "一个或多个电子邮件地址无效" + "message": "一个或多个电子邮箱无效" }, "tooManyEmails": { - "message": "您一次只能提交最多 $COUNT$ 个电子邮件地址", + "message": "您一次只能提交最多 $COUNT$ 个电子邮箱", "placeholders": { "count": { "content": "$1", @@ -8339,10 +8339,10 @@ "message": "登录已批准" }, "userEmailMissing": { - "message": "缺少用户电子邮件" + "message": "缺少用户电子邮箱" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "未找到活动的用户电子邮件。您将被注销。" + "message": "未找到活动的用户电子邮箱。您将被注销。" }, "deviceTrusted": { "message": "设备已信任" @@ -8604,7 +8604,7 @@ "message": "感谢您注册 Bitwarden 机密管理器!" }, "smFreeTrialConfirmationEmail": { - "message": "我们已经发送了一封确认邮件到 " + "message": "我们已经发送了一封确认电子邮件到 " }, "sorryToSeeYouGo": { "message": "很遗憾看到您离开!请分享您取消的原因,以帮助改进 Bitwarden。", @@ -9284,7 +9284,7 @@ "message": "没有可列出的客户" }, "providerBillingEmailHint": { - "message": "此电子邮件地址将用于接收与此供应商相关的所有账单", + "message": "此电子邮箱地址将用于接收与此提供商相关的所有账单", "description": "A hint that shows up on the Provider setup page to inform the admin the billing email will receive the provider's invoices." }, "upgradeOrganizationEnterprise": { @@ -9726,10 +9726,10 @@ "message": "对于如密码之类的敏感数据,请使用隐藏型字段" }, "checkBoxHelpText": { - "message": "如果您想自动勾选表单复选框(例如记住电子邮件地址),请使用复选框型" + "message": "如果您想自动勾选表单复选框(例如记住电子邮箱),请使用复选框型字段" }, "linkedHelpText": { - "message": "当您处理特定网站的自动填充问题时,请使用链接型字段。" + "message": "当您处理特定网站的自动填充问题时,请使用链接型字段" }, "linkedLabelHelpText": { "message": "输入字段的 html ID、名称、aria-label 或占位符。" @@ -9885,22 +9885,22 @@ "message": "描述符代码" }, "importantNotice": { - "message": "Important notice" + "message": "重要通知" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "设置两步登录" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮箱发送一个代码,以验证来自新设备的登录。" }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" }, "remindMeLater": { - "message": "Remind me later" + "message": "稍后提醒我" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "您能可靠地访问您的电子邮箱 $EMAIL$ 吗?", "placeholders": { "email": { "content": "$1", @@ -9909,16 +9909,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "不,我不能" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "是的,我可以可靠地访问我的电子邮箱" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "开启两步登录" }, "changeAcctEmail": { - "message": "Change account email" + "message": "更改账户电子邮箱" }, "removeMembers": { "message": "移除成员" @@ -9957,7 +9957,7 @@ "message": "正在验证" }, "claimedDomainsDesc": { - "message": "声明一个域名,以拥有电子邮件地址与该域名匹配的所有成员账户。成员登录时将可以跳过 SSO 标识符。管理员也可以删除成员账户。" + "message": "声明一个域名,以拥有电子邮箱地址与该域名匹配的所有成员账户。成员登录时将可以跳过 SSO 标识符。管理员也可以删除成员账户。" }, "invalidDomainNameClaimMessage": { "message": "输入的格式无效。格式:mydomain.com。子域名需要单独的条目才能声明。" From a07a7e98171385a3b8b9464fec6c3946ea443694 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:57:22 +0100 Subject: [PATCH 05/65] [PM-16094] Remove lowercasing of vault page headers titles (#12438) * Remove lowercasing of View page headers * Remove lowercasing of Add/edit page headers * Remove lowercasing of Web ViewAdd/edit page headers * Fix tests --------- Co-authored-by: Daniel James Smith --- .../vault-v2/add-edit/add-edit-v2.component.ts | 10 +++++----- .../vault-v2/view-v2/view-v2.component.spec.ts | 6 +++--- .../vault-v2/view-v2/view-v2.component.ts | 13 +++++-------- .../vault-item-dialog.component.ts | 10 +++++----- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts index a2b2d1ce581..2d8c4857c1c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.ts @@ -326,15 +326,15 @@ export class AddEditV2Component implements OnInit { switch (type) { case CipherType.Login: - return this.i18nService.t(partOne, this.i18nService.t("typeLogin").toLocaleLowerCase()); + return this.i18nService.t(partOne, this.i18nService.t("typeLogin")); case CipherType.Card: - return this.i18nService.t(partOne, this.i18nService.t("typeCard").toLocaleLowerCase()); + return this.i18nService.t(partOne, this.i18nService.t("typeCard")); case CipherType.Identity: - return this.i18nService.t(partOne, this.i18nService.t("typeIdentity").toLocaleLowerCase()); + return this.i18nService.t(partOne, this.i18nService.t("typeIdentity")); case CipherType.SecureNote: - return this.i18nService.t(partOne, this.i18nService.t("note").toLocaleLowerCase()); + return this.i18nService.t(partOne, this.i18nService.t("note")); case CipherType.SshKey: - return this.i18nService.t(partOne, this.i18nService.t("typeSshKey").toLocaleLowerCase()); + return this.i18nService.t(partOne, this.i18nService.t("typeSshKey")); } } } 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 bc84dd337cb..7ee15aa833b 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 @@ -137,21 +137,21 @@ describe("ViewV2Component", () => { params$.next({ cipherId: mockCipher.id }); flush(); // Resolve all promises - expect(component.headerText).toEqual("viewItemHeader typelogin"); + expect(component.headerText).toEqual("viewItemHeader typeLogin"); // Set header text for a card mockCipher.type = CipherType.Card; params$.next({ cipherId: mockCipher.id }); flush(); // Resolve all promises - expect(component.headerText).toEqual("viewItemHeader typecard"); + expect(component.headerText).toEqual("viewItemHeader typeCard"); // Set header text for an identity mockCipher.type = CipherType.Identity; params$.next({ cipherId: mockCipher.id }); flush(); // Resolve all promises - expect(component.headerText).toEqual("viewItemHeader typeidentity"); + expect(component.headerText).toEqual("viewItemHeader typeIdentity"); // Set header text for a secure note mockCipher.type = CipherType.SecureNote; 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 5afbf8ba77d..55b59c087c5 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 @@ -146,18 +146,15 @@ export class ViewV2Component { setHeader(type: CipherType) { switch (type) { case CipherType.Login: - return this.i18nService.t("viewItemHeader", this.i18nService.t("typeLogin").toLowerCase()); + return this.i18nService.t("viewItemHeader", this.i18nService.t("typeLogin")); case CipherType.Card: - return this.i18nService.t("viewItemHeader", this.i18nService.t("typeCard").toLowerCase()); + return this.i18nService.t("viewItemHeader", this.i18nService.t("typeCard")); case CipherType.Identity: - return this.i18nService.t( - "viewItemHeader", - this.i18nService.t("typeIdentity").toLowerCase(), - ); + return this.i18nService.t("viewItemHeader", this.i18nService.t("typeIdentity")); case CipherType.SecureNote: - return this.i18nService.t("viewItemHeader", this.i18nService.t("note").toLowerCase()); + return this.i18nService.t("viewItemHeader", this.i18nService.t("note")); case CipherType.SshKey: - return this.i18nService.t("viewItemHeader", this.i18nService.t("typeSshkey").toLowerCase()); + return this.i18nService.t("viewItemHeader", this.i18nService.t("typeSshkey")); } } diff --git a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts index 4c1b51a5482..02dc5ef48bb 100644 --- a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts +++ b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts @@ -419,19 +419,19 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { switch (type) { case CipherType.Login: - this.title = this.i18nService.t(partOne, this.i18nService.t("typeLogin").toLowerCase()); + this.title = this.i18nService.t(partOne, this.i18nService.t("typeLogin")); break; case CipherType.Card: - this.title = this.i18nService.t(partOne, this.i18nService.t("typeCard").toLowerCase()); + this.title = this.i18nService.t(partOne, this.i18nService.t("typeCard")); break; case CipherType.Identity: - this.title = this.i18nService.t(partOne, this.i18nService.t("typeIdentity").toLowerCase()); + this.title = this.i18nService.t(partOne, this.i18nService.t("typeIdentity")); break; case CipherType.SecureNote: - this.title = this.i18nService.t(partOne, this.i18nService.t("note").toLowerCase()); + this.title = this.i18nService.t(partOne, this.i18nService.t("note")); break; case CipherType.SshKey: - this.title = this.i18nService.t(partOne, this.i18nService.t("typeSshKey").toLowerCase()); + this.title = this.i18nService.t(partOne, this.i18nService.t("typeSshKey")); break; } } From cdaf877a6d0311a94a5f3444f83385df04efcd76 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Mon, 30 Dec 2024 19:13:46 +0100 Subject: [PATCH 06/65] Remove v1 premium component (#12580) Co-authored-by: Daniel James Smith --- .../popup/settings/premium-v2.component.ts | 2 - .../popup/settings/premium.component.html | 72 ------------------- .../popup/settings/premium.component.ts | 61 ---------------- apps/browser/src/popup/app-routing.module.ts | 7 +- apps/browser/src/popup/app.module.ts | 2 - 5 files changed, 3 insertions(+), 141 deletions(-) delete mode 100644 apps/browser/src/billing/popup/settings/premium.component.html delete mode 100644 apps/browser/src/billing/popup/settings/premium.component.ts diff --git a/apps/browser/src/billing/popup/settings/premium-v2.component.ts b/apps/browser/src/billing/popup/settings/premium-v2.component.ts index f24de0633ac..c17adcd52fe 100644 --- a/apps/browser/src/billing/popup/settings/premium-v2.component.ts +++ b/apps/browser/src/billing/popup/settings/premium-v2.component.ts @@ -21,7 +21,6 @@ import { SectionComponent, } from "@bitwarden/components"; -import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @@ -34,7 +33,6 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co ButtonModule, CardComponent, CommonModule, - CurrentAccountComponent, ItemModule, JslibModule, PopupPageComponent, diff --git a/apps/browser/src/billing/popup/settings/premium.component.html b/apps/browser/src/billing/popup/settings/premium.component.html deleted file mode 100644 index a8f9855e62d..00000000000 --- a/apps/browser/src/billing/popup/settings/premium.component.html +++ /dev/null @@ -1,72 +0,0 @@ -
-
- -
-

- {{ "premiumMembership" | i18n }} -

-
-
-
-
- -

{{ "premiumNotCurrentMember" | i18n }}

-

{{ "premiumSignUpAndGet" | i18n }}

-
    -
  • - - {{ "ppremiumSignUpStorage" | i18n }} -
  • -
  • - - {{ "premiumSignUpTwoStepOptions" | i18n }} -
  • -
  • - - {{ "ppremiumSignUpReports" | i18n }} -
  • -
  • - - {{ "ppremiumSignUpTotp" | i18n }} -
  • -
  • - - {{ "ppremiumSignUpSupport" | i18n }} -
  • -
  • - - {{ "ppremiumSignUpFuture" | i18n }} -
  • -
-

{{ priceString }}

- - -
- -

{{ "premiumCurrentMember" | i18n }}

-

{{ "premiumCurrentMemberThanks" | i18n }}

- -
-
-
diff --git a/apps/browser/src/billing/popup/settings/premium.component.ts b/apps/browser/src/billing/popup/settings/premium.component.ts deleted file mode 100644 index 70c8667646c..00000000000 --- a/apps/browser/src/billing/popup/settings/premium.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { CurrencyPipe, Location } from "@angular/common"; -import { Component } from "@angular/core"; - -import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/vault/components/premium.component"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; - -@Component({ - selector: "app-premium", - templateUrl: "premium.component.html", -}) -export class PremiumComponent extends BasePremiumComponent { - priceString: string; - - constructor( - i18nService: I18nService, - platformUtilsService: PlatformUtilsService, - apiService: ApiService, - configService: ConfigService, - logService: LogService, - private location: Location, - private currencyPipe: CurrencyPipe, - dialogService: DialogService, - environmentService: EnvironmentService, - billingAccountProfileStateService: BillingAccountProfileStateService, - ) { - super( - i18nService, - platformUtilsService, - apiService, - configService, - logService, - dialogService, - environmentService, - billingAccountProfileStateService, - ); - - // Support old price string. Can be removed in future once all translations are properly updated. - const thePrice = this.currencyPipe.transform(this.price, "$"); - // Safari extension crashes due to $1 appearing in the price string ($10.00). Escape the $ to fix. - const formattedPrice = this.platformUtilsService.isSafari() - ? thePrice.replace("$", "$$$") - : thePrice; - this.priceString = i18nService.t("premiumPrice", formattedPrice); - if (this.priceString.indexOf("%price%") > -1) { - this.priceString = this.priceString.replace("%price%", thePrice); - } - } - - goBack() { - this.location.back(); - } -} diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 0a6ff456938..67d51a93cde 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -81,7 +81,6 @@ import { ExcludedDomainsComponent } from "../autofill/popup/settings/excluded-do import { NotificationsSettingsV1Component } from "../autofill/popup/settings/notifications-v1.component"; import { NotificationsSettingsComponent } from "../autofill/popup/settings/notifications.component"; import { PremiumV2Component } from "../billing/popup/settings/premium-v2.component"; -import { PremiumComponent } from "../billing/popup/settings/premium.component"; import BrowserPopupUtils from "../platform/popup/browser-popup-utils"; import { popupRouterCacheGuard } from "../platform/popup/view-cache/popup-router-cache.service"; import { CredentialGeneratorHistoryComponent } from "../tools/popup/generator/credential-generator-history.component"; @@ -395,12 +394,12 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 2 } satisfies RouteDataProperties, }), - ...extensionRefreshSwap(PremiumComponent, PremiumV2Component, { + { path: "premium", - component: PremiumComponent, + component: PremiumV2Component, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, - }), + }, ...extensionRefreshSwap(AppearanceComponent, AppearanceV2Component, { path: "appearance", canActivate: [authGuard], diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index b547078084b..04d681812fe 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -48,7 +48,6 @@ import { ExcludedDomainsV1Component } from "../autofill/popup/settings/excluded- import { ExcludedDomainsComponent } from "../autofill/popup/settings/excluded-domains.component"; import { NotificationsSettingsV1Component } from "../autofill/popup/settings/notifications-v1.component"; import { NotificationsSettingsComponent } from "../autofill/popup/settings/notifications.component"; -import { PremiumComponent } from "../billing/popup/settings/premium.component"; import { PopOutComponent } from "../platform/popup/components/pop-out.component"; import { HeaderComponent } from "../platform/popup/header.component"; import { PopupFooterComponent } from "../platform/popup/layout/popup-footer.component"; @@ -155,7 +154,6 @@ import "../platform/popup/locales"; NotificationsSettingsV1Component, AppearanceComponent, PasswordHistoryComponent, - PremiumComponent, RegisterComponent, SetPasswordComponent, VaultSettingsComponent, From 6539f06654e4596d06c63c85dcd5c5fa04ee290e Mon Sep 17 00:00:00 2001 From: Victoria League Date: Mon, 30 Dec 2024 14:46:29 -0500 Subject: [PATCH 07/65] [CL-135] Fix import statement for standalone component (#12589) --- libs/components/src/badge-list/badge-list.stories.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/components/src/badge-list/badge-list.stories.ts b/libs/components/src/badge-list/badge-list.stories.ts index 24024cb6bbd..ede005f6fd6 100644 --- a/libs/components/src/badge-list/badge-list.stories.ts +++ b/libs/components/src/badge-list/badge-list.stories.ts @@ -13,8 +13,7 @@ export default { component: BadgeListComponent, decorators: [ moduleMetadata({ - imports: [SharedModule, BadgeModule], - declarations: [BadgeListComponent], + imports: [SharedModule, BadgeModule, BadgeListComponent], providers: [ { provide: I18nService, From a95427eee0265c30322afec4c48e489a71ad1d7c Mon Sep 17 00:00:00 2001 From: Victoria League Date: Mon, 30 Dec 2024 16:42:53 -0500 Subject: [PATCH 08/65] [CL-524] Ignore flaky elements in Chromatic tests (#12561) --- .../src/platform/popup/layout/popup-layout.stories.ts | 10 ++++++++-- libs/components/src/menu/menu-trigger-for.directive.ts | 2 +- .../dialog-virtual-scroll-block.component.ts | 4 ++-- .../src/stories/kitchen-sink/kitchen-sink.stories.ts | 3 +++ 4 files changed, 14 insertions(+), 5 deletions(-) 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 cd467cecbd2..c1ac8823261 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -41,7 +41,7 @@ class ExtensionContainerComponent {} @Component({ selector: "vault-placeholder", - template: ` + template: /*html*/ ` @@ -53,7 +53,7 @@ class ExtensionContainerComponent {} - + @@ -301,6 +301,12 @@ class MockVaultSubpageComponent {} export default { title: "Browser/Popup Layout", component: PopupPageComponent, + parameters: { + chromatic: { + // Disable tests while we troubleshoot their flaky-ness + disableSnapshot: true, + }, + }, decorators: [ moduleMetadata({ imports: [ diff --git a/libs/components/src/menu/menu-trigger-for.directive.ts b/libs/components/src/menu/menu-trigger-for.directive.ts index 786554e981c..96d430c5e6a 100644 --- a/libs/components/src/menu/menu-trigger-for.directive.ts +++ b/libs/components/src/menu/menu-trigger-for.directive.ts @@ -36,7 +36,7 @@ export class MenuTriggerForDirective implements OnDestroy { private defaultMenuConfig: OverlayConfig = { panelClass: "bit-menu-panel", hasBackdrop: true, - backdropClass: "cdk-overlay-transparent-backdrop", + backdropClass: ["cdk-overlay-transparent-backdrop", "bit-menu-panel-backdrop"], scrollStrategy: this.overlay.scrollStrategies.reposition(), positionStrategy: this.overlay .position() diff --git a/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts b/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts index a867d9cdf53..02b49a3e915 100644 --- a/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts +++ b/libs/components/src/stories/kitchen-sink/components/dialog-virtual-scroll-block.component.ts @@ -10,9 +10,9 @@ import { TableDataSource, TableModule } from "../../../table"; selector: "dialog-virtual-scroll-block", standalone: true, imports: [DialogModule, IconButtonModule, SectionComponent, TableModule, ScrollingModule], - template: ` + template: /*html*/ ` - + Id diff --git a/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts b/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts index 203c510f814..44080e29049 100644 --- a/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts +++ b/libs/components/src/stories/kitchen-sink/kitchen-sink.stories.ts @@ -130,6 +130,9 @@ export const MenuOpen: Story = { const menuButton = getAllByRole(table, "button")[0]; await userEvent.click(menuButton); }, + parameters: { + chromatic: { ignoreSelectors: [".bit-menu-panel-backdrop"] }, + }, }; export const DefaultDialogOpen: Story = { From 894dd2c89669acb018aaf6caecdc65b9cfda22a2 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Mon, 30 Dec 2024 19:24:31 -0500 Subject: [PATCH 09/65] [PM-16507] update new device verification notice state definition (#12608) --- libs/common/src/platform/state/state-definitions.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index 1ae5b080360..ce9eb5a15c0 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -180,5 +180,8 @@ export const VAULT_BROWSER_UI_ONBOARDING = new StateDefinition("vaultBrowserUiOn export const NEW_DEVICE_VERIFICATION_NOTICE = new StateDefinition( "newDeviceVerificationNotice", "disk", + { + web: "disk-local", + }, ); export const VAULT_APPEARANCE = new StateDefinition("vaultAppearance", "disk"); From 03d09578144b9b362f698fbd2825135a878ecefe Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Tue, 31 Dec 2024 14:56:23 +0100 Subject: [PATCH 10/65] Fix infinite password prompt loop on ssh-key import (#12569) --- apps/desktop/src/vault/app/vault/add-edit.component.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/desktop/src/vault/app/vault/add-edit.component.ts b/apps/desktop/src/vault/app/vault/add-edit.component.ts index b4f62a1254c..a798e61aa88 100644 --- a/apps/desktop/src/vault/app/vault/add-edit.component.ts +++ b/apps/desktop/src/vault/app/vault/add-edit.component.ts @@ -208,6 +208,9 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On }); } else { password = await this.getSshKeyPassword(); + if (password === "") { + return; + } await this.importSshKeyFromClipboard(password); } return; From 899b16966af90878bf9628f9b41a6c4d16cf727a Mon Sep 17 00:00:00 2001 From: cyprain-okeke <108260115+cyprain-okeke@users.noreply.github.com> Date: Tue, 31 Dec 2024 18:06:45 +0100 Subject: [PATCH 11/65] [PM-15814]Alert owners of reseller-managed orgs to renewal events (#12607) * Changes for the reseller alert * Resolve the null error * Refactor the reseller service * Fix the a failing test due to null date * Fix the No overload matches error * Resolve the null error * Resolve the null error * Resolve the null error * Change the date format * Remove unwanted comment * Refactor changes * Add the feature flag --- .../services/reseller-warning.service.ts | 142 ++++++++++++++++++ .../app/vault/org-vault/vault.component.html | 12 ++ .../app/vault/org-vault/vault.component.ts | 21 +++ apps/web/src/locales/en/messages.json | 43 ++++++ .../organization-billing-metadata.response.ts | 13 ++ libs/common/src/enums/feature-flag.enum.ts | 2 + 6 files changed, 233 insertions(+) create mode 100644 apps/web/src/app/billing/services/reseller-warning.service.ts diff --git a/apps/web/src/app/billing/services/reseller-warning.service.ts b/apps/web/src/app/billing/services/reseller-warning.service.ts new file mode 100644 index 00000000000..bfd5be3233a --- /dev/null +++ b/apps/web/src/app/billing/services/reseller-warning.service.ts @@ -0,0 +1,142 @@ +import { Injectable } from "@angular/core"; + +import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; + +export interface ResellerWarning { + type: "info" | "warning"; + message: string; +} + +@Injectable({ providedIn: "root" }) +export class ResellerWarningService { + private readonly RENEWAL_WARNING_DAYS = 14; + private readonly GRACE_PERIOD_DAYS = 30; + + constructor(private i18nService: I18nService) {} + + getWarning( + organization: Organization, + organizationBillingMetadata: OrganizationBillingMetadataResponse, + ): ResellerWarning | null { + if (!organization.hasReseller) { + return null; // If no reseller, return null immediately + } + + // Check for past due warning first (highest priority) + if (this.shouldShowPastDueWarning(organizationBillingMetadata)) { + const gracePeriodEnd = this.getGracePeriodEndDate(organizationBillingMetadata.invoiceDueDate); + if (!gracePeriodEnd) { + return null; + } + return { + type: "warning", + message: this.i18nService.t( + "resellerPastDueWarning", + organization.providerName, + this.formatDate(gracePeriodEnd), + ), + } as ResellerWarning; + } + + // Check for open invoice warning + if (this.shouldShowInvoiceWarning(organizationBillingMetadata)) { + const invoiceCreatedDate = organizationBillingMetadata.invoiceCreatedDate; + const invoiceDueDate = organizationBillingMetadata.invoiceDueDate; + if (!invoiceCreatedDate || !invoiceDueDate) { + return null; + } + return { + type: "info", + message: this.i18nService.t( + "resellerOpenInvoiceWarning", + organization.providerName, + this.formatDate(organizationBillingMetadata.invoiceCreatedDate), + this.formatDate(organizationBillingMetadata.invoiceDueDate), + ), + } as ResellerWarning; + } + + // Check for renewal warning + if (this.shouldShowRenewalWarning(organizationBillingMetadata)) { + const subPeriodEndDate = organizationBillingMetadata.subPeriodEndDate; + if (!subPeriodEndDate) { + return null; + } + + return { + type: "info", + message: this.i18nService.t( + "resellerRenewalWarning", + organization.providerName, + this.formatDate(organizationBillingMetadata.subPeriodEndDate), + ), + } as ResellerWarning; + } + + return null; + } + + private shouldShowRenewalWarning( + organizationBillingMetadata: OrganizationBillingMetadataResponse, + ): boolean { + if ( + !organizationBillingMetadata.hasSubscription || + !organizationBillingMetadata.subPeriodEndDate + ) { + return false; + } + const renewalDate = new Date(organizationBillingMetadata.subPeriodEndDate); + const daysUntilRenewal = Math.ceil( + (renewalDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24), + ); + return daysUntilRenewal <= this.RENEWAL_WARNING_DAYS; + } + + private shouldShowInvoiceWarning( + organizationBillingMetadata: OrganizationBillingMetadataResponse, + ): boolean { + if ( + !organizationBillingMetadata.hasOpenInvoice || + !organizationBillingMetadata.invoiceDueDate + ) { + return false; + } + const invoiceDueDate = new Date(organizationBillingMetadata.invoiceDueDate); + return invoiceDueDate > new Date(); + } + + private shouldShowPastDueWarning( + organizationBillingMetadata: OrganizationBillingMetadataResponse, + ): boolean { + if ( + !organizationBillingMetadata.hasOpenInvoice || + !organizationBillingMetadata.invoiceDueDate + ) { + return false; + } + const invoiceDueDate = new Date(organizationBillingMetadata.invoiceDueDate); + return invoiceDueDate <= new Date() && !organizationBillingMetadata.isSubscriptionUnpaid; + } + + private getGracePeriodEndDate(dueDate: Date | null): Date | null { + if (!dueDate) { + return null; + } + const gracePeriodEnd = new Date(dueDate); + gracePeriodEnd.setDate(gracePeriodEnd.getDate() + this.GRACE_PERIOD_DAYS); + return gracePeriodEnd; + } + + private formatDate(date: Date | null): string { + if (!date) { + return "N/A"; + } + return new Date(date).toLocaleDateString("en-US", { + month: "short", + day: "2-digit", + year: "numeric", + }); + } +} diff --git a/apps/web/src/app/vault/org-vault/vault.component.html b/apps/web/src/app/vault/org-vault/vault.component.html index 52f3ea026ff..512f97144de 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.html +++ b/apps/web/src/app/vault/org-vault/vault.component.html @@ -19,6 +19,18 @@ + + + {{ resellerWarning?.message }} + + (false); protected currentSearchText$: Observable; protected freeTrial$: Observable; + protected resellerWarning$: Observable; /** * A list of collections that the user can assign items to and edit those items within. * @protected @@ -203,6 +208,7 @@ export class VaultComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); protected addAccessStatus$ = new BehaviorSubject(0); private extensionRefreshEnabled: boolean; + private resellerManagedOrgAlert: boolean; private vaultItemDialogRef?: DialogRef | undefined; private readonly unpaidSubscriptionDialog$ = this.organizationService.organizations$.pipe( @@ -259,6 +265,7 @@ export class VaultComponent implements OnInit, OnDestroy { private trialFlowService: TrialFlowService, protected billingApiService: BillingApiServiceAbstraction, private organizationBillingService: OrganizationBillingServiceAbstraction, + private resellerWarningService: ResellerWarningService, ) {} async ngOnInit() { @@ -266,6 +273,10 @@ export class VaultComponent implements OnInit, OnDestroy { FeatureFlag.ExtensionRefresh, ); + this.resellerManagedOrgAlert = await this.configService.getFeatureFlag( + FeatureFlag.ResellerManagedOrgAlert, + ); + this.trashCleanupWarning = this.i18nService.t( this.platformUtilsService.isSelfHost() ? "trashCleanupWarningSelfHosted" @@ -612,6 +623,16 @@ export class VaultComponent implements OnInit, OnDestroy { }), ); + this.resellerWarning$ = organization$.pipe( + filter((org) => org.isOwner && this.resellerManagedOrgAlert), + switchMap((org) => + from(this.billingApiService.getOrganizationBillingMetadata(org.id)).pipe( + map((metadata) => ({ org, metadata })), + ), + ), + map(({ org, metadata }) => this.resellerWarningService.getWarning(org, metadata)), + ); + firstSetup$ .pipe( switchMap(() => this.refresh$), diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index acbb348048c..7c338fc6e97 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -10011,5 +10011,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/libs/common/src/billing/models/response/organization-billing-metadata.response.ts b/libs/common/src/billing/models/response/organization-billing-metadata.response.ts index d9733aa80f2..c5023cb64c1 100644 --- a/libs/common/src/billing/models/response/organization-billing-metadata.response.ts +++ b/libs/common/src/billing/models/response/organization-billing-metadata.response.ts @@ -6,6 +6,10 @@ export class OrganizationBillingMetadataResponse extends BaseResponse { isOnSecretsManagerStandalone: boolean; isSubscriptionUnpaid: boolean; hasSubscription: boolean; + hasOpenInvoice: boolean; + invoiceDueDate: Date | null; + invoiceCreatedDate: Date | null; + subPeriodEndDate: Date | null; constructor(response: any) { super(response); @@ -14,5 +18,14 @@ export class OrganizationBillingMetadataResponse extends BaseResponse { this.isOnSecretsManagerStandalone = this.getResponseProperty("IsOnSecretsManagerStandalone"); this.isSubscriptionUnpaid = this.getResponseProperty("IsSubscriptionUnpaid"); this.hasSubscription = this.getResponseProperty("HasSubscription"); + this.hasOpenInvoice = this.getResponseProperty("HasOpenInvoice"); + + this.invoiceDueDate = this.parseDate(this.getResponseProperty("InvoiceDueDate")); + this.invoiceCreatedDate = this.parseDate(this.getResponseProperty("InvoiceCreatedDate")); + this.subPeriodEndDate = this.parseDate(this.getResponseProperty("SubPeriodEndDate")); + } + + private parseDate(dateString: any): Date | null { + return dateString ? new Date(dateString) : null; } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index cc2abed3ba1..135119bf133 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -43,6 +43,7 @@ export enum FeatureFlag { PM11360RemoveProviderExportPermission = "pm-11360-remove-provider-export-permission", PM12443RemovePagingLogic = "pm-12443-remove-paging-logic", PrivateKeyRegeneration = "pm-12241-private-key-regeneration", + ResellerManagedOrgAlert = "PM-15814-alert-owners-of-reseller-managed-orgs", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -96,6 +97,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.PM11360RemoveProviderExportPermission]: FALSE, [FeatureFlag.PM12443RemovePagingLogic]: FALSE, [FeatureFlag.PrivateKeyRegeneration]: FALSE, + [FeatureFlag.ResellerManagedOrgAlert]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; From e1778f4282f92fba7e0abd00081b4b20c7161641 Mon Sep 17 00:00:00 2001 From: Brant DeBow <125889545+brant-livefront@users.noreply.github.com> Date: Tue, 31 Dec 2024 15:16:31 -0500 Subject: [PATCH 12/65] [PM-16530] [BRE-283] Changes to support hardening on the Mac desktop app (#12632) * [DEVOPS-1424] Changes to support hardening on the Mac desktop app * Remove unsigned memory exception * Remove exceptions from the local (non-MAS) mac builds as well --------- Co-authored-by: Matt Bishop --- apps/desktop/electron-builder.json | 2 +- .../resources/entitlements.desktop_proxy.inherit.plist | 2 ++ apps/desktop/resources/entitlements.desktop_proxy.plist | 2 ++ apps/desktop/resources/entitlements.mac.plist | 4 ---- apps/desktop/resources/entitlements.mas.inherit.plist | 4 +--- apps/desktop/resources/entitlements.mas.plist | 2 ++ 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index 898ad086b29..c8114d947e4 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -133,7 +133,7 @@ "entitlements": "resources/entitlements.mas.plist", "entitlementsInherit": "resources/entitlements.mas.inherit.plist", "entitlementsLoginHelper": "resources/entitlements.mas.loginhelper.plist", - "hardenedRuntime": false, + "hardenedRuntime": true, "extendInfo": { "LSMinimumSystemVersion": "12", "ElectronTeamID": "LTZ2PFU5D6" diff --git a/apps/desktop/resources/entitlements.desktop_proxy.inherit.plist b/apps/desktop/resources/entitlements.desktop_proxy.inherit.plist index 794eada1cad..fca5f02d52d 100644 --- a/apps/desktop/resources/entitlements.desktop_proxy.inherit.plist +++ b/apps/desktop/resources/entitlements.desktop_proxy.inherit.plist @@ -6,5 +6,7 @@ com.apple.security.inherit + com.apple.security.cs.allow-jit + diff --git a/apps/desktop/resources/entitlements.desktop_proxy.plist b/apps/desktop/resources/entitlements.desktop_proxy.plist index d5c7b8a2cc8..1a39a482389 100644 --- a/apps/desktop/resources/entitlements.desktop_proxy.plist +++ b/apps/desktop/resources/entitlements.desktop_proxy.plist @@ -8,5 +8,7 @@ LTZ2PFU5D6.com.bitwarden.desktop + com.apple.security.cs.allow-jit + diff --git a/apps/desktop/resources/entitlements.mac.plist b/apps/desktop/resources/entitlements.mac.plist index 34c561bd03f..e273bcc7eca 100644 --- a/apps/desktop/resources/entitlements.mac.plist +++ b/apps/desktop/resources/entitlements.mac.plist @@ -4,10 +4,6 @@ com.apple.security.cs.allow-jit - com.apple.security.cs.allow-unsigned-executable-memory - - com.apple.security.cs.disable-library-validation - {{ "estimatedTax" | i18n }}: {{ estimatedTax | currency: "USD $" }} diff --git a/apps/web/src/app/billing/individual/premium/premium-v2.component.ts b/apps/web/src/app/billing/individual/premium/premium-v2.component.ts index 72dc5a30d5f..2abab57b7e0 100644 --- a/apps/web/src/app/billing/individual/premium/premium-v2.component.ts +++ b/apps/web/src/app/billing/individual/premium/premium-v2.component.ts @@ -5,10 +5,13 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { combineLatest, concatMap, from, Observable, of } from "rxjs"; +import { debounceTime } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; +import { PreviewIndividualInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-individual-invoice.request"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -44,6 +47,7 @@ export class PremiumV2Component { FeatureFlag.PM11901_RefactorSelfHostingLicenseUploader, ); + protected estimatedTax: number = 0; protected readonly familyPlanMaxUserCount = 6; protected readonly premiumPrice = 10; protected readonly storageGBPrice = 4; @@ -60,6 +64,7 @@ export class PremiumV2Component { private syncService: SyncService, private toastService: ToastService, private tokenService: TokenService, + private taxService: TaxServiceAbstraction, ) { this.isSelfHost = this.platformUtilsService.isSelfHost(); @@ -82,6 +87,12 @@ export class PremiumV2Component { }), ) .subscribe(); + + this.addOnFormGroup.controls.additionalStorage.valueChanges + .pipe(debounceTime(1000), takeUntilDestroyed()) + .subscribe(() => { + this.refreshSalesTax(); + }); } finalizeUpgrade = async () => { @@ -158,12 +169,6 @@ export class PremiumV2Component { return this.storageGBPrice * this.addOnFormGroup.value.additionalStorage; } - protected get estimatedTax(): number { - return this.taxInfoComponent?.taxRate != null - ? (this.taxInfoComponent.taxRate / 100) * this.subtotal - : 0; - } - protected get premiumURL(): string { return `${this.cloudWebVaultURL}/#/settings/subscription/premium`; } @@ -179,4 +184,36 @@ export class PremiumV2Component { protected async onLicenseFileSelectedChanged(): Promise { await this.postFinalizeUpgrade(); } + + private refreshSalesTax(): void { + if (!this.taxInfoComponent.country || !this.taxInfoComponent.postalCode) { + return; + } + const request: PreviewIndividualInvoiceRequest = { + passwordManager: { + additionalStorage: this.addOnFormGroup.value.additionalStorage, + }, + taxInformation: { + postalCode: this.taxInfoComponent.postalCode, + country: this.taxInfoComponent.country, + }, + }; + + this.taxService + .previewIndividualInvoice(request) + .then((invoice) => { + this.estimatedTax = invoice.taxAmount; + }) + .catch((error) => { + this.toastService.showToast({ + title: "", + variant: "error", + message: this.i18nService.t(error.message), + }); + }); + } + + protected onTaxInformationChanged(): void { + this.refreshSalesTax(); + } } diff --git a/apps/web/src/app/billing/individual/premium/premium.component.html b/apps/web/src/app/billing/individual/premium/premium.component.html index 8b848b48dab..12b6932d0f5 100644 --- a/apps/web/src/app/billing/individual/premium/premium.component.html +++ b/apps/web/src/app/billing/individual/premium/premium.component.html @@ -122,7 +122,7 @@

{{ "summary" | i18n }}

{{ "paymentInformation" | i18n }}

- +
{{ "planPrice" | i18n }}: {{ subtotal | currency: "USD $" }} diff --git a/apps/web/src/app/billing/individual/premium/premium.component.ts b/apps/web/src/app/billing/individual/premium/premium.component.ts index 9e2be6dcab1..76ca25c8cc6 100644 --- a/apps/web/src/app/billing/individual/premium/premium.component.ts +++ b/apps/web/src/app/billing/individual/premium/premium.component.ts @@ -1,13 +1,17 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Component, OnInit, ViewChild } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { Router } from "@angular/router"; import { firstValueFrom, Observable } from "rxjs"; +import { debounceTime } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; +import { PreviewIndividualInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-individual-invoice.request"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -39,6 +43,9 @@ export class PremiumComponent implements OnInit { protected addonForm = new FormGroup({ additionalStorage: new FormControl(0, [Validators.max(99), Validators.min(0)]), }); + + private estimatedTax: number = 0; + constructor( private apiService: ApiService, private i18nService: I18nService, @@ -50,9 +57,16 @@ export class PremiumComponent implements OnInit { private environmentService: EnvironmentService, private billingAccountProfileStateService: BillingAccountProfileStateService, private toastService: ToastService, + private taxService: TaxServiceAbstraction, ) { this.selfHosted = platformUtilsService.isSelfHost(); this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + + this.addonForm.controls.additionalStorage.valueChanges + .pipe(debounceTime(1000), takeUntilDestroyed()) + .subscribe(() => { + this.refreshSalesTax(); + }); } protected setSelectedFile(event: Event) { const fileInputEl = event.target; @@ -154,12 +168,42 @@ export class PremiumComponent implements OnInit { } get taxCharges(): number { - return this.taxInfoComponent != null && this.taxInfoComponent.taxRate != null - ? (this.taxInfoComponent.taxRate / 100) * this.subtotal - : 0; + return this.estimatedTax; } get total(): number { return this.subtotal + this.taxCharges || 0; } + + private refreshSalesTax(): void { + if (!this.taxInfoComponent.country || !this.taxInfoComponent.postalCode) { + return; + } + const request: PreviewIndividualInvoiceRequest = { + passwordManager: { + additionalStorage: this.addonForm.value.additionalStorage, + }, + taxInformation: { + postalCode: this.taxInfoComponent.postalCode, + country: this.taxInfoComponent.country, + }, + }; + + this.taxService + .previewIndividualInvoice(request) + .then((invoice) => { + this.estimatedTax = invoice.taxAmount; + }) + .catch((error) => { + this.toastService.showToast({ + title: "", + variant: "error", + message: this.i18nService.t(error.message), + }); + }); + } + + protected onTaxInformationChanged(): void { + this.refreshSalesTax(); + } } diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html index 93751f0ef72..78005275f12 100644 --- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.html +++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.html @@ -344,25 +344,14 @@

{{ "paymentMethod" | i18n }}

- - - - + + + + +

{{ "paymentMethod" | i18n }}

+
+ +

+ + {{ "estimatedTax" | i18n }} + + + {{ estimatedTax | currency: "USD" : "$" }} + +

+
+

(); + protected taxInformation: TaxInformation; + constructor( @Inject(DIALOG_DATA) private dialogParams: ChangePlanDialogParams, private dialogRef: DialogRef, @@ -189,6 +195,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { private organizationApiService: OrganizationApiServiceAbstraction, private configService: ConfigService, private billingApiService: BillingApiServiceAbstraction, + private taxService: TaxServiceAbstraction, ) {} async ngOnInit(): Promise { @@ -267,6 +274,11 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { this.setInitialPlanSelection(); this.loading = false; + + const taxInfo = await this.organizationApiService.getTaxInfo(this.organizationId); + this.taxInformation = TaxInformation.from(taxInfo); + + this.refreshSalesTax(); } setInitialPlanSelection() { @@ -402,6 +414,12 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { } this.selectedPlan = plan; this.formGroup.patchValue({ productTier: plan.productTier }); + + try { + this.refreshSalesTax(); + } catch { + this.estimatedTax = 0; + } } ngOnDestroy() { @@ -567,12 +585,6 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { ); } - get taxCharges() { - return this.taxComponent != null && this.taxComponent.taxRate != null - ? (this.taxComponent.taxRate / 100) * this.passwordManagerSubtotal - : 0; - } - get passwordManagerSeats() { if (this.selectedPlan.productTier === ProductTierType.Families) { return this.selectedPlan.PasswordManager.baseSeats; @@ -584,15 +596,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { if (this.organization.useSecretsManager) { return ( this.passwordManagerSubtotal + - this.additionalStorageTotal(this.selectedPlan) + - this.secretsManagerSubtotal + - this.taxCharges || 0 + this.additionalStorageTotal(this.selectedPlan) + + this.secretsManagerSubtotal + + this.estimatedTax ); } return ( this.passwordManagerSubtotal + - this.additionalStorageTotal(this.selectedPlan) + - this.taxCharges || 0 + this.additionalStorageTotal(this.selectedPlan) + + this.estimatedTax ); } @@ -645,8 +657,8 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { } changedCountry() { - if (this.deprecateStripeSourcesAPI && this.paymentV2Component && this.taxComponent) { - this.paymentV2Component.showBankAccount = this.taxComponent.country === "US"; + if (this.deprecateStripeSourcesAPI && this.paymentV2Component) { + this.paymentV2Component.showBankAccount = this.taxInformation.country === "US"; if ( !this.paymentV2Component.showBankAccount && @@ -654,8 +666,8 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { ) { this.paymentV2Component.select(PaymentMethodType.Card); } - } else if (this.paymentComponent && this.taxComponent) { - this.paymentComponent!.hideBank = this.taxComponent?.taxFormGroup?.value.country !== "US"; + } else if (this.paymentComponent && this.taxInformation) { + this.paymentComponent!.hideBank = this.taxInformation.country !== "US"; // Bank Account payments are only available for US customers if ( this.paymentComponent.hideBank && @@ -667,9 +679,14 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { } } + protected taxInformationChanged(event: TaxInformation): void { + this.taxInformation = event; + this.changedCountry(); + this.refreshSalesTax(); + } + submit = async () => { - if (!this.taxComponent?.taxFormGroup.valid && this.taxComponent?.taxFormGroup.touched) { - this.taxComponent?.taxFormGroup.markAllAsTouched(); + if (this.taxComponent !== undefined && !this.taxComponent.validate()) { return; } @@ -723,8 +740,8 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { this.formGroup.controls.premiumAccessAddon.value; request.planType = this.selectedPlan.type; if (this.showPayment) { - request.billingAddressCountry = this.taxComponent.taxFormGroup?.value.country; - request.billingAddressPostalCode = this.taxComponent.taxFormGroup?.value.postalCode; + request.billingAddressCountry = this.taxInformation.country; + request.billingAddressPostalCode = this.taxInformation.postalCode; } // Secrets Manager @@ -735,15 +752,9 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { const tokenizedPaymentSource = await this.paymentV2Component.tokenize(); const updatePaymentMethodRequest = new UpdatePaymentMethodRequest(); updatePaymentMethodRequest.paymentSource = tokenizedPaymentSource; - updatePaymentMethodRequest.taxInformation = { - country: this.taxComponent.country, - postalCode: this.taxComponent.postalCode, - taxId: this.taxComponent.taxId, - line1: this.taxComponent.line1, - line2: this.taxComponent.line2, - city: this.taxComponent.city, - state: this.taxComponent.state, - }; + updatePaymentMethodRequest.taxInformation = ExpandedTaxInfoUpdateRequest.From( + this.taxInformation, + ); await this.billingApiService.updateOrganizationPaymentMethod( this.organizationId, @@ -754,8 +765,8 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { const paymentRequest = new PaymentRequest(); paymentRequest.paymentToken = tokenResult[0]; paymentRequest.paymentMethodType = tokenResult[1]; - paymentRequest.country = this.taxComponent.taxFormGroup?.value.country; - paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode; + paymentRequest.country = this.taxInformation.country; + paymentRequest.postalCode = this.taxInformation.postalCode; await this.organizationApiService.updatePayment(this.organizationId, paymentRequest); } } @@ -944,4 +955,48 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy { manageSelectableProduct(index: number) { return index; } + + private refreshSalesTax(): void { + if (!this.taxInformation.country || !this.taxInformation.postalCode) { + return; + } + + const request: PreviewOrganizationInvoiceRequest = { + organizationId: this.organizationId, + passwordManager: { + additionalStorage: 0, + plan: this.selectedPlan?.type, + seats: this.sub.seats, + }, + taxInformation: { + postalCode: this.taxInformation.postalCode, + country: this.taxInformation.country, + taxId: this.taxInformation.taxId, + }, + }; + + if (this.organization.useSecretsManager) { + request.secretsManager = { + seats: this.sub.smSeats, + additionalMachineAccounts: this.sub.smServiceAccounts, + }; + } + + this.taxService + .previewOrganizationInvoice(request) + .then((invoice) => { + this.estimatedTax = invoice.taxAmount; + }) + .catch((error) => { + this.toastService.showToast({ + title: "", + variant: "error", + message: this.i18nService.t(error.message), + }); + }); + } + + protected canUpdatePaymentInformation(): boolean { + return this.upgradeRequiresPaymentMethod || this.showPayment || this.isPaymentSourceEmpty(); + } } diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.html b/apps/web/src/app/billing/organizations/organization-plans.component.html index e1b74abea71..d37f95e3aa2 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.html +++ b/apps/web/src/app/billing/organizations/organization-plans.component.html @@ -335,7 +335,7 @@

{{ "summary" | i18n }}

>{{ "additionalUsers" | i18n }}: {{ "users" | i18n }}: - {{ formGroup.controls["additionalSeats"].value || 0 }} × + {{ formGroup.controls.additionalSeats.value || 0 }} × {{ (selectablePlan.isAnnual ? selectablePlan.PasswordManager.seatPrice / 12 @@ -355,7 +355,7 @@

{{ "summary" | i18n }}

*ngIf="selectablePlan.PasswordManager.hasAdditionalStorageOption" > {{ "additionalStorageGb" | i18n }}: - {{ formGroup.controls["additionalStorage"].value || 0 }} × + {{ formGroup.controls.additionalStorage.value || 0 }} × {{ (selectablePlan.isAnnual ? selectablePlan.PasswordManager.additionalStoragePricePerGb / 12 @@ -388,7 +388,7 @@

{{ "summary" | i18n }}

>{{ "additionalUsers" | i18n }}: {{ "users" | i18n }}: - {{ formGroup.controls["additionalSeats"].value || 0 }} × + {{ formGroup.controls.additionalSeats.value || 0 }} × {{ selectablePlan.PasswordManager.seatPrice | currency: "$" }} {{ "monthAbbr" | i18n }} = {{ @@ -403,7 +403,7 @@

{{ "summary" | i18n }}

*ngIf="selectablePlan.PasswordManager.hasAdditionalStorageOption" > {{ "additionalStorageGb" | i18n }}: - {{ formGroup.controls["additionalStorage"].value || 0 }} × + {{ formGroup.controls.additionalStorage.value || 0 }} × {{ selectablePlan.PasswordManager.additionalStoragePricePerGb | currency: "$" }} {{ "monthAbbr" | i18n }} = {{ additionalStorageTotal(selectablePlan) | currency: "$" }} /{{ "month" | i18n }} @@ -440,7 +440,12 @@

- +
{{ "passwordManagerPlanPrice" | i18n }}: {{ passwordManagerSubtotal | currency: "USD $" }} @@ -450,7 +455,7 @@


- {{ "estimatedTax" | i18n }}: {{ taxCharges | currency: "USD $" }} + {{ "estimatedTax" | i18n }}: {{ estimatedTax | currency: "USD $" }}


diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.ts b/apps/web/src/app/billing/organizations/organization-plans.component.ts index e7a011792ae..4592f8de894 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.ts +++ b/apps/web/src/app/billing/organizations/organization-plans.component.ts @@ -12,7 +12,9 @@ import { import { FormBuilder, Validators } from "@angular/forms"; import { Router } from "@angular/router"; import { Subject, takeUntil } from "rxjs"; +import { debounceTime } from "rxjs/operators"; +import { ManageTaxInformationComponent } from "@bitwarden/angular/billing/components"; import { ApiService } from "@bitwarden/common/abstractions/api.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"; @@ -26,9 +28,12 @@ import { OrganizationUpgradeRequest } from "@bitwarden/common/admin-console/mode import { ProviderOrganizationCreateRequest } from "@bitwarden/common/admin-console/models/request/provider/provider-organization-create.request"; import { ProviderResponse } from "@bitwarden/common/admin-console/models/response/provider/provider.response"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; import { PaymentMethodType, PlanType, ProductTierType } from "@bitwarden/common/billing/enums"; +import { TaxInformation } from "@bitwarden/common/billing/models/domain"; import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request"; import { PaymentRequest } from "@bitwarden/common/billing/models/request/payment.request"; +import { PreviewOrganizationInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-organization-invoice.request"; import { UpdatePaymentMethodRequest } from "@bitwarden/common/billing/models/request/update-payment-method.request"; import { BillingResponse } from "@bitwarden/common/billing/models/response/billing.response"; import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response"; @@ -50,7 +55,6 @@ import { OrganizationCreateModule } from "../../admin-console/organizations/crea import { BillingSharedModule, secretsManagerSubscribeFormFactory } from "../shared"; import { PaymentV2Component } from "../shared/payment/payment-v2.component"; import { PaymentComponent } from "../shared/payment/payment.component"; -import { TaxInfoComponent } from "../shared/tax-info.component"; interface OnSuccessArgs { organizationId: string; @@ -72,13 +76,14 @@ const Allowed2020PlansForLegacyProviders = [ export class OrganizationPlansComponent implements OnInit, OnDestroy { @ViewChild(PaymentComponent) paymentComponent: PaymentComponent; @ViewChild(PaymentV2Component) paymentV2Component: PaymentV2Component; - @ViewChild(TaxInfoComponent) taxComponent: TaxInfoComponent; + @ViewChild(ManageTaxInformationComponent) taxComponent: ManageTaxInformationComponent; - @Input() organizationId: string; + @Input() organizationId?: string; @Input() showFree = true; @Input() showCancel = false; @Input() acceptingSponsorship = false; @Input() currentPlan: PlanResponse; + selectedFile: File; @Input() @@ -93,6 +98,8 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { private _productTier = ProductTierType.Free; + protected taxInformation: TaxInformation; + @Input() get plan(): PlanType { return this._plan; @@ -149,7 +156,10 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { billing: BillingResponse; provider: ProviderResponse; - private destroy$ = new Subject(); + protected estimatedTax: number = 0; + protected total: number = 0; + + private destroy$: Subject = new Subject(); constructor( private apiService: ApiService, @@ -168,6 +178,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { private toastService: ToastService, private configService: ConfigService, private billingApiService: BillingApiServiceAbstraction, + private taxService: TaxServiceAbstraction, ) { this.selfHosted = this.platformUtilsService.isSelfHost(); } @@ -181,6 +192,9 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.organization = await this.organizationService.get(this.organizationId); this.billing = await this.organizationApiService.getBilling(this.organizationId); this.sub = await this.organizationApiService.getSubscription(this.organizationId); + this.taxInformation = await this.organizationApiService.getTaxInfo(this.organizationId); + } else { + this.taxInformation = await this.apiService.getTaxInfo(); } if (!this.selfHosted) { @@ -241,6 +255,16 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { } this.loading = false; + + this.formGroup.valueChanges.pipe(debounceTime(1000), takeUntil(this.destroy$)).subscribe(() => { + this.refreshSalesTax(); + }); + + this.secretsManagerForm.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) + .subscribe(() => { + this.refreshSalesTax(); + }); } ngOnDestroy() { @@ -438,17 +462,6 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { return this.selectedPlan.trialPeriodDays != null; } - get taxCharges() { - return this.taxComponent != null && this.taxComponent.taxRate != null - ? (this.taxComponent.taxRate / 100) * - (this.passwordManagerSubtotal + this.secretsManagerSubtotal) - : 0; - } - - get total() { - return this.passwordManagerSubtotal + this.secretsManagerSubtotal + this.taxCharges || 0; - } - get paymentDesc() { if (this.acceptingSponsorship) { return this.i18nService.t("paymentSponsored"); @@ -554,9 +567,9 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.changedProduct(); } - changedCountry() { + protected changedCountry(): void { if (this.deprecateStripeSourcesAPI) { - this.paymentV2Component.showBankAccount = this.taxComponent.country === "US"; + this.paymentV2Component.showBankAccount = this.taxInformation?.country === "US"; if ( !this.paymentV2Component.showBankAccount && this.paymentV2Component.selected === PaymentMethodType.BankAccount @@ -564,7 +577,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.paymentV2Component.select(PaymentMethodType.Card); } } else { - this.paymentComponent.hideBank = this.taxComponent.taxFormGroup?.value.country !== "US"; + this.paymentComponent.hideBank = this.taxInformation?.country !== "US"; if ( this.paymentComponent.hideBank && this.paymentComponent.method === PaymentMethodType.BankAccount @@ -575,28 +588,31 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { } } - cancel() { + protected onTaxInformationChanged(event: TaxInformation): void { + this.taxInformation = event; + this.changedCountry(); + this.refreshSalesTax(); + } + + protected cancel(): void { this.onCanceled.emit(); } - setSelectedFile(event: Event) { + protected setSelectedFile(event: Event): void { const fileInputEl = event.target; this.selectedFile = fileInputEl.files.length > 0 ? fileInputEl.files[0] : null; } submit = async () => { - if (this.taxComponent) { - if (!this.taxComponent?.taxFormGroup.valid) { - this.taxComponent?.taxFormGroup.markAllAsTouched(); - return; - } + if (this.taxComponent && !this.taxComponent.validate()) { + return; } if (this.singleOrgPolicyBlock) { return; } const doSubmit = async (): Promise => { - let orgId: string = null; + let orgId: string; if (this.createOrganization) { const orgKey = await this.keyService.makeOrgKey(); const key = orgKey[0].encryptedString; @@ -607,11 +623,9 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { const collectionCt = collection.encryptedString; const orgKeys = await this.keyService.makeKeyPair(orgKey[1]); - if (this.selfHosted) { - orgId = await this.createSelfHosted(key, collectionCt, orgKeys); - } else { - orgId = await this.createCloudHosted(key, collectionCt, orgKeys, orgKey[1]); - } + orgId = this.selfHosted + ? await this.createSelfHosted(key, collectionCt, orgKeys) + : await this.createCloudHosted(key, collectionCt, orgKeys, orgKey[1]); this.toastService.showToast({ variant: "success", @@ -619,7 +633,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { message: this.i18nService.t("organizationReadyToGo"), }); } else { - orgId = await this.updateOrganization(orgId); + orgId = await this.updateOrganization(); this.toastService.showToast({ variant: "success", title: null, @@ -653,7 +667,63 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.messagingService.send("organizationCreated", { organizationId }); }; - private async updateOrganization(orgId: string) { + protected get showTaxIdField(): boolean { + switch (this.formGroup.controls.productTier.value) { + case ProductTierType.Free: + case ProductTierType.Families: + return false; + default: + return true; + } + } + + private refreshSalesTax(): void { + if (this.formGroup.controls.plan.value == PlanType.Free) { + this.estimatedTax = 0; + return; + } + + if (!this.taxComponent.validate()) { + return; + } + + const request: PreviewOrganizationInvoiceRequest = { + organizationId: this.organizationId, + passwordManager: { + additionalStorage: this.formGroup.controls.additionalStorage.value, + plan: this.formGroup.controls.plan.value, + seats: this.formGroup.controls.additionalSeats.value, + }, + taxInformation: { + postalCode: this.taxInformation.postalCode, + country: this.taxInformation.country, + taxId: this.taxInformation.taxId, + }, + }; + + if (this.secretsManagerForm.controls.enabled.value === true) { + request.secretsManager = { + seats: this.secretsManagerForm.controls.userSeats.value, + additionalMachineAccounts: this.secretsManagerForm.controls.additionalServiceAccounts.value, + }; + } + + this.taxService + .previewOrganizationInvoice(request) + .then((invoice) => { + this.estimatedTax = invoice.taxAmount; + this.total = invoice.totalAmount; + }) + .catch((error) => { + this.toastService.showToast({ + title: "", + variant: "error", + message: this.i18nService.t(error.message), + }); + }); + } + + private async updateOrganization() { const request = new OrganizationUpgradeRequest(); request.additionalSeats = this.formGroup.controls.additionalSeats.value; request.additionalStorageGb = this.formGroup.controls.additionalStorage.value; @@ -661,8 +731,8 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.selectedPlan.PasswordManager.hasPremiumAccessOption && this.formGroup.controls.premiumAccessAddon.value; request.planType = this.selectedPlan.type; - request.billingAddressCountry = this.taxComponent.taxFormGroup?.value.country; - request.billingAddressPostalCode = this.taxComponent.taxFormGroup?.value.postalCode; + request.billingAddressCountry = this.taxInformation?.country; + request.billingAddressPostalCode = this.taxInformation?.postalCode; // Secrets Manager this.buildSecretsManagerRequest(request); @@ -671,10 +741,9 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { if (this.deprecateStripeSourcesAPI) { const updatePaymentMethodRequest = new UpdatePaymentMethodRequest(); updatePaymentMethodRequest.paymentSource = await this.paymentV2Component.tokenize(); - const expandedTaxInfoUpdateRequest = new ExpandedTaxInfoUpdateRequest(); - expandedTaxInfoUpdateRequest.country = this.taxComponent.country; - expandedTaxInfoUpdateRequest.postalCode = this.taxComponent.postalCode; - updatePaymentMethodRequest.taxInformation = expandedTaxInfoUpdateRequest; + updatePaymentMethodRequest.taxInformation = ExpandedTaxInfoUpdateRequest.From( + this.taxInformation, + ); await this.billingApiService.updateOrganizationPaymentMethod( this.organizationId, updatePaymentMethodRequest, @@ -684,8 +753,8 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { const paymentRequest = new PaymentRequest(); paymentRequest.paymentToken = paymentToken; paymentRequest.paymentMethodType = paymentMethodType; - paymentRequest.country = this.taxComponent.taxFormGroup?.value.country; - paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode; + paymentRequest.country = this.taxInformation?.country; + paymentRequest.postalCode = this.taxInformation?.postalCode; await this.organizationApiService.updatePayment(this.organizationId, paymentRequest); } } @@ -709,7 +778,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { collectionCt: string, orgKeys: [string, EncString], orgKey: SymmetricCryptoKey, - ) { + ): Promise { const request = new OrganizationCreateRequest(); request.key = key; request.collectionName = collectionCt; @@ -738,15 +807,13 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { this.selectedPlan.PasswordManager.hasPremiumAccessOption && this.formGroup.controls.premiumAccessAddon.value; request.planType = this.selectedPlan.type; - request.billingAddressPostalCode = this.taxComponent.taxFormGroup?.value.postalCode; - request.billingAddressCountry = this.taxComponent.taxFormGroup?.value.country; - if (this.taxComponent.taxFormGroup?.value.includeTaxId) { - request.taxIdNumber = this.taxComponent.taxFormGroup?.value.taxId; - request.billingAddressLine1 = this.taxComponent.taxFormGroup?.value.line1; - request.billingAddressLine2 = this.taxComponent.taxFormGroup?.value.line2; - request.billingAddressCity = this.taxComponent.taxFormGroup?.value.city; - request.billingAddressState = this.taxComponent.taxFormGroup?.value.state; - } + request.billingAddressPostalCode = this.taxInformation?.postalCode; + request.billingAddressCountry = this.taxInformation?.country; + request.taxIdNumber = this.taxInformation?.taxId; + request.billingAddressLine1 = this.taxInformation?.line1; + request.billingAddressLine2 = this.taxInformation?.line2; + request.billingAddressCity = this.taxInformation?.city; + request.billingAddressState = this.taxInformation?.state; } // Secrets Manager diff --git a/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.html b/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.html index 78f9955d31a..2c2dba938bc 100644 --- a/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.html +++ b/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.html @@ -63,20 +63,5 @@

{{ "paymentMethod" | i18n }}

{{ "paymentChargedWithUnpaidSubscription" | i18n }}

- - -

{{ "taxInformation" | i18n }}

-

{{ "taxInformationDesc" | i18n }}

- - -
diff --git a/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.ts b/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.ts index 4ed35461c72..270ba54f70d 100644 --- a/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.ts +++ b/apps/web/src/app/billing/organizations/payment-method/organization-payment-method.component.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Location } from "@angular/common"; -import { Component, OnDestroy, ViewChild } from "@angular/core"; +import { Component, OnDestroy } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute, Router } from "@angular/router"; import { from, lastValueFrom, switchMap } from "rxjs"; @@ -11,7 +11,6 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions"; import { PaymentMethodType } from "@bitwarden/common/billing/enums"; -import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request"; import { VerifyBankAccountRequest } from "@bitwarden/common/billing/models/request/verify-bank-account.request"; import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/models/response/organization-subscription.response"; import { PaymentSourceResponse } from "@bitwarden/common/billing/models/response/payment-source.response"; @@ -22,7 +21,6 @@ import { DialogService, ToastService } from "@bitwarden/components"; import { FreeTrial } from "../../../core/types/free-trial"; import { TrialFlowService } from "../../services/trial-flow.service"; -import { TaxInfoComponent } from "../../shared"; import { AddCreditDialogResult, openAddCreditDialog, @@ -36,8 +34,6 @@ import { templateUrl: "./organization-payment-method.component.html", }) export class OrganizationPaymentMethodComponent implements OnDestroy { - @ViewChild(TaxInfoComponent) taxInfoComponent: TaxInfoComponent; - organizationId: string; isUnpaid = false; accountCredit: number; @@ -155,6 +151,7 @@ export class OrganizationPaymentMethodComponent implements OnDestroy { data: { initialPaymentMethod: this.paymentSource?.type, organizationId: this.organizationId, + productTier: this.organization?.productTierType, }, }); @@ -170,6 +167,7 @@ export class OrganizationPaymentMethodComponent implements OnDestroy { data: { initialPaymentMethod: this.paymentSource?.type, organizationId: this.organizationId, + productTier: this.organization?.productTierType, }, }); const result = await lastValueFrom(dialogRef.closed); @@ -183,32 +181,6 @@ export class OrganizationPaymentMethodComponent implements OnDestroy { } }; - protected updateTaxInformation = async (): Promise => { - this.taxInfoComponent.taxFormGroup.updateValueAndValidity(); - this.taxInfoComponent.taxFormGroup.markAllAsTouched(); - - if (this.taxInfoComponent.taxFormGroup.invalid) { - return; - } - - const request = new ExpandedTaxInfoUpdateRequest(); - request.country = this.taxInfoComponent.country; - request.postalCode = this.taxInfoComponent.postalCode; - request.taxId = this.taxInfoComponent.taxId; - request.line1 = this.taxInfoComponent.line1; - request.line2 = this.taxInfoComponent.line2; - request.city = this.taxInfoComponent.city; - request.state = this.taxInfoComponent.state; - - await this.billingApiService.updateOrganizationTaxInformation(this.organizationId, request); - - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("taxInfoUpdated"), - }); - }; - protected verifyBankAccount = async (request: VerifyBankAccountRequest): Promise => { await this.billingApiService.verifyOrganizationBankAccount(this.organizationId, request); this.toastService.showToast({ diff --git a/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog-v2.component.html b/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog-v2.component.html index e41d3d961cd..bb06f87ca03 100644 --- a/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog-v2.component.html +++ b/apps/web/src/app/billing/shared/adjust-payment-dialog/adjust-payment-dialog-v2.component.html @@ -5,7 +5,12 @@ [showBankAccount]="!!organizationId" [initialPaymentMethod]="initialPaymentMethod" > - + - - diff --git a/apps/web/src/app/billing/shared/payment-method.component.ts b/apps/web/src/app/billing/shared/payment-method.component.ts index 298573f0852..149b4adf520 100644 --- a/apps/web/src/app/billing/shared/payment-method.component.ts +++ b/apps/web/src/app/billing/shared/payment-method.component.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Location } from "@angular/common"; -import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core"; +import { Component, OnDestroy, OnInit } from "@angular/core"; import { FormBuilder, FormControl, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { lastValueFrom } from "rxjs"; @@ -16,7 +16,6 @@ import { OrganizationSubscriptionResponse } from "@bitwarden/common/billing/mode import { SubscriptionResponse } from "@bitwarden/common/billing/models/response/subscription.response"; import { VerifyBankRequest } from "@bitwarden/common/models/request/verify-bank.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { DialogService, ToastService } from "@bitwarden/components"; @@ -29,15 +28,12 @@ import { AdjustPaymentDialogResult, openAdjustPaymentDialog, } from "./adjust-payment-dialog/adjust-payment-dialog.component"; -import { TaxInfoComponent } from "./tax-info.component"; @Component({ templateUrl: "payment-method.component.html", }) // eslint-disable-next-line rxjs-angular/prefer-takeuntil export class PaymentMethodComponent implements OnInit, OnDestroy { - @ViewChild(TaxInfoComponent) taxInfo: TaxInfoComponent; - loading = false; firstLoaded = false; billing: BillingPaymentResponse; @@ -61,7 +57,6 @@ export class PaymentMethodComponent implements OnInit, OnDestroy { ]), }); - taxForm = this.formBuilder.group({}); launchPaymentModalAutomatically = false; protected freeTrialData: FreeTrial; @@ -72,7 +67,6 @@ export class PaymentMethodComponent implements OnInit, OnDestroy { protected platformUtilsService: PlatformUtilsService, private router: Router, private location: Location, - private logService: LogService, private route: ActivatedRoute, private formBuilder: FormBuilder, private dialogService: DialogService, @@ -198,15 +192,6 @@ export class PaymentMethodComponent implements OnInit, OnDestroy { await this.load(); }; - submitTaxInfo = async () => { - await this.taxInfo.submitTaxInfo(); - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("taxInfoUpdated"), - }); - }; - determineOrgsWithUpcomingPaymentIssues() { this.freeTrialData = this.trialFlowService.checkForOrgsWithUpcomingPaymentIssues( this.organization, @@ -231,10 +216,6 @@ export class PaymentMethodComponent implements OnInit, OnDestroy { return this.organizationId != null; } - get headerClass() { - return this.forOrganization ? ["page-header"] : ["tabbed-header"]; - } - get paymentSourceClasses() { if (this.paymentSource == null) { return []; diff --git a/apps/web/src/app/billing/shared/tax-info.component.html b/apps/web/src/app/billing/shared/tax-info.component.html index 82d5104a53a..4a42c0c1109 100644 --- a/apps/web/src/app/billing/shared/tax-info.component.html +++ b/apps/web/src/app/billing/shared/tax-info.component.html @@ -13,51 +13,41 @@
-
+
{{ "zipPostalCode" | i18n }}
-
- - - {{ "includeVAT" | i18n }} - -
-
-
-
- - {{ "taxIdNumber" | i18n }} - - -
-
-
-
+
{{ "address1" | i18n }}
-
+
{{ "address2" | i18n }}
-
+
{{ "cityTown" | i18n }}
-
+
{{ "stateProvince" | i18n }}
+
+ + {{ "taxIdNumber" | i18n }} + + +
diff --git a/apps/web/src/app/billing/shared/tax-info.component.ts b/apps/web/src/app/billing/shared/tax-info.component.ts index 8ebec5e1dfe..214364e4cf2 100644 --- a/apps/web/src/app/billing/shared/tax-info.component.ts +++ b/apps/web/src/app/billing/shared/tax-info.component.ts @@ -1,31 +1,20 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { Subject, takeUntil } from "rxjs"; +import { debounceTime } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; +import { CountryListItem } from "@bitwarden/common/billing/models/domain"; import { ExpandedTaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/expanded-tax-info-update.request"; -import { TaxInfoUpdateRequest } from "@bitwarden/common/billing/models/request/tax-info-update.request"; -import { TaxInfoResponse } from "@bitwarden/common/billing/models/response/tax-info.response"; -import { TaxRateResponse } from "@bitwarden/common/billing/models/response/tax-rate.response"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { SharedModule } from "../../shared"; -type TaxInfoView = Omit & { - includeTaxId: boolean; - [key: string]: unknown; -}; - -type CountryList = { - name: string; - value: string; - disabled: boolean; -}; - @Component({ selector: "app-tax-info", templateUrl: "tax-info.component.html", @@ -33,359 +22,68 @@ type CountryList = { imports: [SharedModule], }) // eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class TaxInfoComponent implements OnInit { - @Input() trialFlow = false; - @Output() onCountryChanged = new EventEmitter(); +export class TaxInfoComponent implements OnInit, OnDestroy { private destroy$ = new Subject(); + @Input() trialFlow = false; + @Output() countryChanged = new EventEmitter(); + @Output() taxInformationChanged: EventEmitter = new EventEmitter(); + taxFormGroup = new FormGroup({ - country: new FormControl(null, [Validators.required]), - postalCode: new FormControl(null), - includeTaxId: new FormControl(null), - taxId: new FormControl(null), - line1: new FormControl(null), - line2: new FormControl(null), - city: new FormControl(null), - state: new FormControl(null), + country: new FormControl(null, [Validators.required]), + postalCode: new FormControl(null, [Validators.required]), + taxId: new FormControl(null), + line1: new FormControl(null), + line2: new FormControl(null), + city: new FormControl(null), + state: new FormControl(null), }); + protected isTaxSupported: boolean; + loading = true; organizationId: string; providerId: string; - taxInfo: TaxInfoView = { - taxId: null, - line1: null, - line2: null, - city: null, - state: null, - postalCode: null, - country: "US", - includeTaxId: false, - }; - countryList: CountryList[] = [ - { name: "-- Select --", value: "", disabled: false }, - { name: "United States", value: "US", disabled: false }, - { name: "China", value: "CN", disabled: false }, - { name: "France", value: "FR", disabled: false }, - { name: "Germany", value: "DE", disabled: false }, - { name: "Canada", value: "CA", disabled: false }, - { name: "United Kingdom", value: "GB", disabled: false }, - { name: "Australia", value: "AU", disabled: false }, - { name: "India", value: "IN", disabled: false }, - { name: "", value: "-", disabled: true }, - { name: "Afghanistan", value: "AF", disabled: false }, - { name: "Åland Islands", value: "AX", disabled: false }, - { name: "Albania", value: "AL", disabled: false }, - { name: "Algeria", value: "DZ", disabled: false }, - { name: "American Samoa", value: "AS", disabled: false }, - { name: "Andorra", value: "AD", disabled: false }, - { name: "Angola", value: "AO", disabled: false }, - { name: "Anguilla", value: "AI", disabled: false }, - { name: "Antarctica", value: "AQ", disabled: false }, - { name: "Antigua and Barbuda", value: "AG", disabled: false }, - { name: "Argentina", value: "AR", disabled: false }, - { name: "Armenia", value: "AM", disabled: false }, - { name: "Aruba", value: "AW", disabled: false }, - { name: "Austria", value: "AT", disabled: false }, - { name: "Azerbaijan", value: "AZ", disabled: false }, - { name: "Bahamas", value: "BS", disabled: false }, - { name: "Bahrain", value: "BH", disabled: false }, - { name: "Bangladesh", value: "BD", disabled: false }, - { name: "Barbados", value: "BB", disabled: false }, - { name: "Belarus", value: "BY", disabled: false }, - { name: "Belgium", value: "BE", disabled: false }, - { name: "Belize", value: "BZ", disabled: false }, - { name: "Benin", value: "BJ", disabled: false }, - { name: "Bermuda", value: "BM", disabled: false }, - { name: "Bhutan", value: "BT", disabled: false }, - { name: "Bolivia, Plurinational State of", value: "BO", disabled: false }, - { name: "Bonaire, Sint Eustatius and Saba", value: "BQ", disabled: false }, - { name: "Bosnia and Herzegovina", value: "BA", disabled: false }, - { name: "Botswana", value: "BW", disabled: false }, - { name: "Bouvet Island", value: "BV", disabled: false }, - { name: "Brazil", value: "BR", disabled: false }, - { name: "British Indian Ocean Territory", value: "IO", disabled: false }, - { name: "Brunei Darussalam", value: "BN", disabled: false }, - { name: "Bulgaria", value: "BG", disabled: false }, - { name: "Burkina Faso", value: "BF", disabled: false }, - { name: "Burundi", value: "BI", disabled: false }, - { name: "Cambodia", value: "KH", disabled: false }, - { name: "Cameroon", value: "CM", disabled: false }, - { name: "Cape Verde", value: "CV", disabled: false }, - { name: "Cayman Islands", value: "KY", disabled: false }, - { name: "Central African Republic", value: "CF", disabled: false }, - { name: "Chad", value: "TD", disabled: false }, - { name: "Chile", value: "CL", disabled: false }, - { name: "Christmas Island", value: "CX", disabled: false }, - { name: "Cocos (Keeling) Islands", value: "CC", disabled: false }, - { name: "Colombia", value: "CO", disabled: false }, - { name: "Comoros", value: "KM", disabled: false }, - { name: "Congo", value: "CG", disabled: false }, - { name: "Congo, the Democratic Republic of the", value: "CD", disabled: false }, - { name: "Cook Islands", value: "CK", disabled: false }, - { name: "Costa Rica", value: "CR", disabled: false }, - { name: "Côte d'Ivoire", value: "CI", disabled: false }, - { name: "Croatia", value: "HR", disabled: false }, - { name: "Cuba", value: "CU", disabled: false }, - { name: "Curaçao", value: "CW", disabled: false }, - { name: "Cyprus", value: "CY", disabled: false }, - { name: "Czech Republic", value: "CZ", disabled: false }, - { name: "Denmark", value: "DK", disabled: false }, - { name: "Djibouti", value: "DJ", disabled: false }, - { name: "Dominica", value: "DM", disabled: false }, - { name: "Dominican Republic", value: "DO", disabled: false }, - { name: "Ecuador", value: "EC", disabled: false }, - { name: "Egypt", value: "EG", disabled: false }, - { name: "El Salvador", value: "SV", disabled: false }, - { name: "Equatorial Guinea", value: "GQ", disabled: false }, - { name: "Eritrea", value: "ER", disabled: false }, - { name: "Estonia", value: "EE", disabled: false }, - { name: "Ethiopia", value: "ET", disabled: false }, - { name: "Falkland Islands (Malvinas)", value: "FK", disabled: false }, - { name: "Faroe Islands", value: "FO", disabled: false }, - { name: "Fiji", value: "FJ", disabled: false }, - { name: "Finland", value: "FI", disabled: false }, - { name: "French Guiana", value: "GF", disabled: false }, - { name: "French Polynesia", value: "PF", disabled: false }, - { name: "French Southern Territories", value: "TF", disabled: false }, - { name: "Gabon", value: "GA", disabled: false }, - { name: "Gambia", value: "GM", disabled: false }, - { name: "Georgia", value: "GE", disabled: false }, - { name: "Ghana", value: "GH", disabled: false }, - { name: "Gibraltar", value: "GI", disabled: false }, - { name: "Greece", value: "GR", disabled: false }, - { name: "Greenland", value: "GL", disabled: false }, - { name: "Grenada", value: "GD", disabled: false }, - { name: "Guadeloupe", value: "GP", disabled: false }, - { name: "Guam", value: "GU", disabled: false }, - { name: "Guatemala", value: "GT", disabled: false }, - { name: "Guernsey", value: "GG", disabled: false }, - { name: "Guinea", value: "GN", disabled: false }, - { name: "Guinea-Bissau", value: "GW", disabled: false }, - { name: "Guyana", value: "GY", disabled: false }, - { name: "Haiti", value: "HT", disabled: false }, - { name: "Heard Island and McDonald Islands", value: "HM", disabled: false }, - { name: "Holy See (Vatican City State)", value: "VA", disabled: false }, - { name: "Honduras", value: "HN", disabled: false }, - { name: "Hong Kong", value: "HK", disabled: false }, - { name: "Hungary", value: "HU", disabled: false }, - { name: "Iceland", value: "IS", disabled: false }, - { name: "Indonesia", value: "ID", disabled: false }, - { name: "Iran, Islamic Republic of", value: "IR", disabled: false }, - { name: "Iraq", value: "IQ", disabled: false }, - { name: "Ireland", value: "IE", disabled: false }, - { name: "Isle of Man", value: "IM", disabled: false }, - { name: "Israel", value: "IL", disabled: false }, - { name: "Italy", value: "IT", disabled: false }, - { name: "Jamaica", value: "JM", disabled: false }, - { name: "Japan", value: "JP", disabled: false }, - { name: "Jersey", value: "JE", disabled: false }, - { name: "Jordan", value: "JO", disabled: false }, - { name: "Kazakhstan", value: "KZ", disabled: false }, - { name: "Kenya", value: "KE", disabled: false }, - { name: "Kiribati", value: "KI", disabled: false }, - { name: "Korea, Democratic People's Republic of", value: "KP", disabled: false }, - { name: "Korea, Republic of", value: "KR", disabled: false }, - { name: "Kuwait", value: "KW", disabled: false }, - { name: "Kyrgyzstan", value: "KG", disabled: false }, - { name: "Lao People's Democratic Republic", value: "LA", disabled: false }, - { name: "Latvia", value: "LV", disabled: false }, - { name: "Lebanon", value: "LB", disabled: false }, - { name: "Lesotho", value: "LS", disabled: false }, - { name: "Liberia", value: "LR", disabled: false }, - { name: "Libya", value: "LY", disabled: false }, - { name: "Liechtenstein", value: "LI", disabled: false }, - { name: "Lithuania", value: "LT", disabled: false }, - { name: "Luxembourg", value: "LU", disabled: false }, - { name: "Macao", value: "MO", disabled: false }, - { name: "Macedonia, the former Yugoslav Republic of", value: "MK", disabled: false }, - { name: "Madagascar", value: "MG", disabled: false }, - { name: "Malawi", value: "MW", disabled: false }, - { name: "Malaysia", value: "MY", disabled: false }, - { name: "Maldives", value: "MV", disabled: false }, - { name: "Mali", value: "ML", disabled: false }, - { name: "Malta", value: "MT", disabled: false }, - { name: "Marshall Islands", value: "MH", disabled: false }, - { name: "Martinique", value: "MQ", disabled: false }, - { name: "Mauritania", value: "MR", disabled: false }, - { name: "Mauritius", value: "MU", disabled: false }, - { name: "Mayotte", value: "YT", disabled: false }, - { name: "Mexico", value: "MX", disabled: false }, - { name: "Micronesia, Federated States of", value: "FM", disabled: false }, - { name: "Moldova, Republic of", value: "MD", disabled: false }, - { name: "Monaco", value: "MC", disabled: false }, - { name: "Mongolia", value: "MN", disabled: false }, - { name: "Montenegro", value: "ME", disabled: false }, - { name: "Montserrat", value: "MS", disabled: false }, - { name: "Morocco", value: "MA", disabled: false }, - { name: "Mozambique", value: "MZ", disabled: false }, - { name: "Myanmar", value: "MM", disabled: false }, - { name: "Namibia", value: "NA", disabled: false }, - { name: "Nauru", value: "NR", disabled: false }, - { name: "Nepal", value: "NP", disabled: false }, - { name: "Netherlands", value: "NL", disabled: false }, - { name: "New Caledonia", value: "NC", disabled: false }, - { name: "New Zealand", value: "NZ", disabled: false }, - { name: "Nicaragua", value: "NI", disabled: false }, - { name: "Niger", value: "NE", disabled: false }, - { name: "Nigeria", value: "NG", disabled: false }, - { name: "Niue", value: "NU", disabled: false }, - { name: "Norfolk Island", value: "NF", disabled: false }, - { name: "Northern Mariana Islands", value: "MP", disabled: false }, - { name: "Norway", value: "NO", disabled: false }, - { name: "Oman", value: "OM", disabled: false }, - { name: "Pakistan", value: "PK", disabled: false }, - { name: "Palau", value: "PW", disabled: false }, - { name: "Palestinian Territory, Occupied", value: "PS", disabled: false }, - { name: "Panama", value: "PA", disabled: false }, - { name: "Papua New Guinea", value: "PG", disabled: false }, - { name: "Paraguay", value: "PY", disabled: false }, - { name: "Peru", value: "PE", disabled: false }, - { name: "Philippines", value: "PH", disabled: false }, - { name: "Pitcairn", value: "PN", disabled: false }, - { name: "Poland", value: "PL", disabled: false }, - { name: "Portugal", value: "PT", disabled: false }, - { name: "Puerto Rico", value: "PR", disabled: false }, - { name: "Qatar", value: "QA", disabled: false }, - { name: "Réunion", value: "RE", disabled: false }, - { name: "Romania", value: "RO", disabled: false }, - { name: "Russian Federation", value: "RU", disabled: false }, - { name: "Rwanda", value: "RW", disabled: false }, - { name: "Saint Barthélemy", value: "BL", disabled: false }, - { name: "Saint Helena, Ascension and Tristan da Cunha", value: "SH", disabled: false }, - { name: "Saint Kitts and Nevis", value: "KN", disabled: false }, - { name: "Saint Lucia", value: "LC", disabled: false }, - { name: "Saint Martin (French part)", value: "MF", disabled: false }, - { name: "Saint Pierre and Miquelon", value: "PM", disabled: false }, - { name: "Saint Vincent and the Grenadines", value: "VC", disabled: false }, - { name: "Samoa", value: "WS", disabled: false }, - { name: "San Marino", value: "SM", disabled: false }, - { name: "Sao Tome and Principe", value: "ST", disabled: false }, - { name: "Saudi Arabia", value: "SA", disabled: false }, - { name: "Senegal", value: "SN", disabled: false }, - { name: "Serbia", value: "RS", disabled: false }, - { name: "Seychelles", value: "SC", disabled: false }, - { name: "Sierra Leone", value: "SL", disabled: false }, - { name: "Singapore", value: "SG", disabled: false }, - { name: "Sint Maarten (Dutch part)", value: "SX", disabled: false }, - { name: "Slovakia", value: "SK", disabled: false }, - { name: "Slovenia", value: "SI", disabled: false }, - { name: "Solomon Islands", value: "SB", disabled: false }, - { name: "Somalia", value: "SO", disabled: false }, - { name: "South Africa", value: "ZA", disabled: false }, - { name: "South Georgia and the South Sandwich Islands", value: "GS", disabled: false }, - { name: "South Sudan", value: "SS", disabled: false }, - { name: "Spain", value: "ES", disabled: false }, - { name: "Sri Lanka", value: "LK", disabled: false }, - { name: "Sudan", value: "SD", disabled: false }, - { name: "Suriname", value: "SR", disabled: false }, - { name: "Svalbard and Jan Mayen", value: "SJ", disabled: false }, - { name: "Swaziland", value: "SZ", disabled: false }, - { name: "Sweden", value: "SE", disabled: false }, - { name: "Switzerland", value: "CH", disabled: false }, - { name: "Syrian Arab Republic", value: "SY", disabled: false }, - { name: "Taiwan", value: "TW", disabled: false }, - { name: "Tajikistan", value: "TJ", disabled: false }, - { name: "Tanzania, United Republic of", value: "TZ", disabled: false }, - { name: "Thailand", value: "TH", disabled: false }, - { name: "Timor-Leste", value: "TL", disabled: false }, - { name: "Togo", value: "TG", disabled: false }, - { name: "Tokelau", value: "TK", disabled: false }, - { name: "Tonga", value: "TO", disabled: false }, - { name: "Trinidad and Tobago", value: "TT", disabled: false }, - { name: "Tunisia", value: "TN", disabled: false }, - { name: "Turkey", value: "TR", disabled: false }, - { name: "Turkmenistan", value: "TM", disabled: false }, - { name: "Turks and Caicos Islands", value: "TC", disabled: false }, - { name: "Tuvalu", value: "TV", disabled: false }, - { name: "Uganda", value: "UG", disabled: false }, - { name: "Ukraine", value: "UA", disabled: false }, - { name: "United Arab Emirates", value: "AE", disabled: false }, - { name: "United States Minor Outlying Islands", value: "UM", disabled: false }, - { name: "Uruguay", value: "UY", disabled: false }, - { name: "Uzbekistan", value: "UZ", disabled: false }, - { name: "Vanuatu", value: "VU", disabled: false }, - { name: "Venezuela, Bolivarian Republic of", value: "VE", disabled: false }, - { name: "Viet Nam", value: "VN", disabled: false }, - { name: "Virgin Islands, British", value: "VG", disabled: false }, - { name: "Virgin Islands, U.S.", value: "VI", disabled: false }, - { name: "Wallis and Futuna", value: "WF", disabled: false }, - { name: "Western Sahara", value: "EH", disabled: false }, - { name: "Yemen", value: "YE", disabled: false }, - { name: "Zambia", value: "ZM", disabled: false }, - { name: "Zimbabwe", value: "ZW", disabled: false }, - ]; - taxRates: TaxRateResponse[]; + countryList: CountryListItem[] = this.taxService.getCountries(); constructor( private apiService: ApiService, private route: ActivatedRoute, private logService: LogService, private organizationApiService: OrganizationApiServiceAbstraction, + private taxService: TaxServiceAbstraction, ) {} get country(): string { - return this.taxFormGroup.get("country").value; - } - - set country(country: string) { - this.taxFormGroup.get("country").setValue(country); + return this.taxFormGroup.controls.country.value; } get postalCode(): string { - return this.taxFormGroup.get("postalCode").value; - } - - set postalCode(postalCode: string) { - this.taxFormGroup.get("postalCode").setValue(postalCode); - } - - get includeTaxId(): boolean { - return this.taxFormGroup.get("includeTaxId").value; - } - - set includeTaxId(includeTaxId: boolean) { - this.taxFormGroup.get("includeTaxId").setValue(includeTaxId); + return this.taxFormGroup.controls.postalCode.value; } get taxId(): string { - return this.taxFormGroup.get("taxId").value; - } - - set taxId(taxId: string) { - this.taxFormGroup.get("taxId").setValue(taxId); + return this.taxFormGroup.controls.taxId.value; } get line1(): string { - return this.taxFormGroup.get("line1").value; - } - - set line1(line1: string) { - this.taxFormGroup.get("line1").setValue(line1); + return this.taxFormGroup.controls.line1.value; } get line2(): string { - return this.taxFormGroup.get("line2").value; - } - - set line2(line2: string) { - this.taxFormGroup.get("line2").setValue(line2); + return this.taxFormGroup.controls.line2.value; } get city(): string { - return this.taxFormGroup.get("city").value; - } - - set city(city: string) { - this.taxFormGroup.get("city").setValue(city); + return this.taxFormGroup.controls.city.value; } get state(): string { - return this.taxFormGroup.get("state").value; + return this.taxFormGroup.controls.state.value; } - set state(state: string) { - this.taxFormGroup.get("state").setValue(state); + get showTaxIdField(): boolean { + return !!this.organizationId; } async ngOnInit() { @@ -402,22 +100,13 @@ export class TaxInfoComponent implements OnInit { try { const taxInfo = await this.organizationApiService.getTaxInfo(this.organizationId); if (taxInfo) { - this.taxId = taxInfo.taxId; - this.state = taxInfo.state; - this.line1 = taxInfo.line1; - this.line2 = taxInfo.line2; - this.city = taxInfo.city; - this.state = taxInfo.state; - this.postalCode = taxInfo.postalCode; - this.country = taxInfo.country || "US"; - this.includeTaxId = - this.countrySupportsTax(this.country) && - (!!taxInfo.taxId || - !!taxInfo.line1 || - !!taxInfo.line2 || - !!taxInfo.city || - !!taxInfo.state); - this.setTaxInfoObject(); + this.taxFormGroup.controls.taxId.setValue(taxInfo.taxId); + this.taxFormGroup.controls.state.setValue(taxInfo.state); + this.taxFormGroup.controls.line1.setValue(taxInfo.line1); + this.taxFormGroup.controls.line2.setValue(taxInfo.line2); + this.taxFormGroup.controls.city.setValue(taxInfo.city); + this.taxFormGroup.controls.postalCode.setValue(taxInfo.postalCode); + this.taxFormGroup.controls.country.setValue(taxInfo.country); } } catch (e) { this.logService.error(e); @@ -426,119 +115,79 @@ export class TaxInfoComponent implements OnInit { try { const taxInfo = await this.apiService.getTaxInfo(); if (taxInfo) { - this.postalCode = taxInfo.postalCode; - this.country = taxInfo.country || "US"; + this.taxFormGroup.controls.postalCode.setValue(taxInfo.postalCode); + this.taxFormGroup.controls.country.setValue(taxInfo.country); } - this.setTaxInfoObject(); } catch (e) { this.logService.error(e); } } - if (this.country === "US") { - this.taxFormGroup.get("postalCode").setValidators([Validators.required]); - this.taxFormGroup.get("postalCode").updateValueAndValidity(); - } + this.isTaxSupported = await this.taxService.isCountrySupported( + this.taxFormGroup.controls.country.value, + ); - if (this.country !== "US") { - this.onCountryChanged.emit(); - } + this.countryChanged.emit(); }); - this.taxFormGroup - .get("country") - .valueChanges.pipe(takeUntil(this.destroy$)) + this.taxFormGroup.controls.country.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) .subscribe((value) => { - if (value === "US") { - this.taxFormGroup.get("postalCode").setValidators([Validators.required]); - } else { - this.taxFormGroup.get("postalCode").clearValidators(); - } - this.taxFormGroup.get("postalCode").updateValueAndValidity(); - this.setTaxInfoObject(); - this.changeCountry(); + this.taxService + .isCountrySupported(this.taxFormGroup.controls.country.value) + .then((isSupported) => { + this.isTaxSupported = isSupported; + }) + .catch(() => { + this.isTaxSupported = false; + }) + .finally(() => { + if (!this.isTaxSupported) { + this.taxFormGroup.controls.taxId.setValue(null); + this.taxFormGroup.controls.line1.setValue(null); + this.taxFormGroup.controls.line2.setValue(null); + this.taxFormGroup.controls.city.setValue(null); + this.taxFormGroup.controls.state.setValue(null); + } + + this.countryChanged.emit(); + }); + this.taxInformationChanged.emit(); }); - try { - const taxRates = await this.apiService.getTaxRates(); - if (taxRates) { - this.taxRates = taxRates.data; - } - } catch (e) { - this.logService.error(e); - } finally { - this.loading = false; - } - } - - get taxRate() { - if (this.taxRates != null) { - const localTaxRate = this.taxRates.find( - (x) => x.country === this.country && x.postalCode === this.postalCode, - ); - return localTaxRate?.rate ?? null; - } - } - - setTaxInfoObject() { - this.taxInfo.country = this.country; - this.taxInfo.postalCode = this.postalCode; - this.taxInfo.includeTaxId = this.includeTaxId; - this.taxInfo.taxId = this.taxId; - this.taxInfo.line1 = this.line1; - this.taxInfo.line2 = this.line2; - this.taxInfo.city = this.city; - this.taxInfo.state = this.state; - } + this.taxFormGroup.controls.postalCode.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) + .subscribe(() => { + this.taxInformationChanged.emit(); + }); - get showTaxIdCheckbox() { - return ( - (this.organizationId || this.providerId) && - this.country !== "US" && - this.countrySupportsTax(this.taxInfo.country) - ); - } + this.taxFormGroup.controls.taxId.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) + .subscribe(() => { + this.taxInformationChanged.emit(); + }); - get showTaxIdFields() { - return ( - (this.organizationId || this.providerId) && - this.includeTaxId && - this.countrySupportsTax(this.country) - ); + this.loading = false; } - getTaxInfoRequest(): TaxInfoUpdateRequest { - if (this.organizationId || this.providerId) { - const request = new ExpandedTaxInfoUpdateRequest(); - request.country = this.country; - request.postalCode = this.postalCode; - - if (this.includeTaxId) { - request.taxId = this.taxId; - request.line1 = this.line1; - request.line2 = this.line2; - request.city = this.city; - request.state = this.state; - } else { - request.taxId = null; - request.line1 = null; - request.line2 = null; - request.city = null; - request.state = null; - } - return request; - } else { - const request = new TaxInfoUpdateRequest(); - request.postalCode = this.postalCode; - request.country = this.country; - return request; - } + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); } submitTaxInfo(): Promise { this.taxFormGroup.updateValueAndValidity(); this.taxFormGroup.markAllAsTouched(); - const request = this.getTaxInfoRequest(); + + const request = new ExpandedTaxInfoUpdateRequest(); + request.country = this.country; + request.postalCode = this.postalCode; + request.taxId = this.taxId; + request.line1 = this.line1; + request.line2 = this.line2; + request.city = this.city; + request.state = this.state; + return this.organizationId ? this.organizationApiService.updateTaxInfo( this.organizationId, @@ -546,97 +195,4 @@ export class TaxInfoComponent implements OnInit { ) : this.apiService.putTaxInfo(request); } - - changeCountry() { - if (!this.countrySupportsTax(this.country)) { - this.includeTaxId = false; - this.taxId = null; - this.line1 = null; - this.line2 = null; - this.city = null; - this.state = null; - this.setTaxInfoObject(); - } - this.onCountryChanged.emit(); - } - - countrySupportsTax(countryCode: string) { - return this.taxSupportedCountryCodes.includes(countryCode); - } - - private taxSupportedCountryCodes: string[] = [ - "CN", - "FR", - "DE", - "CA", - "GB", - "AU", - "IN", - "AD", - "AR", - "AT", - "BE", - "BO", - "BR", - "BG", - "CL", - "CO", - "CR", - "HR", - "CY", - "CZ", - "DK", - "DO", - "EC", - "EG", - "SV", - "EE", - "FI", - "GE", - "GR", - "HK", - "HU", - "IS", - "ID", - "IQ", - "IE", - "IL", - "IT", - "JP", - "KE", - "KR", - "LV", - "LI", - "LT", - "LU", - "MY", - "MT", - "MX", - "NL", - "NZ", - "NO", - "PE", - "PH", - "PL", - "PT", - "RO", - "RU", - "SA", - "RS", - "SG", - "SK", - "SI", - "ZA", - "ES", - "SE", - "CH", - "TW", - "TH", - "TR", - "UA", - "AE", - "UY", - "VE", - "VN", - ]; } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 7c338fc6e97..08e08ccad15 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -9275,6 +9275,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html index 33a20444c2b..74aa468c42e 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.html @@ -29,7 +29,7 @@

{{ "generalInformation" | i18n }}

- diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts index 46fd6989681..f773db6c11c 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/setup/setup.component.ts @@ -111,9 +111,7 @@ export class SetupComponent implements OnInit, OnDestroy { try { this.formGroup.markAllAsTouched(); - const formIsValid = this.formGroup.valid && this.manageTaxInformationComponent.touch(); - - if (!formIsValid) { + if (!this.manageTaxInformationComponent.validate() || !this.formGroup.valid) { return; } @@ -131,14 +129,11 @@ export class SetupComponent implements OnInit, OnDestroy { request.taxInfo.country = taxInformation.country; request.taxInfo.postalCode = taxInformation.postalCode; - - if (taxInformation.includeTaxId) { - request.taxInfo.taxId = taxInformation.taxId; - request.taxInfo.line1 = taxInformation.line1; - request.taxInfo.line2 = taxInformation.line2; - request.taxInfo.city = taxInformation.city; - request.taxInfo.state = taxInformation.state; - } + request.taxInfo.taxId = taxInformation.taxId; + request.taxInfo.line1 = taxInformation.line1; + request.taxInfo.line2 = taxInformation.line2; + request.taxInfo.city = taxInformation.city; + request.taxInfo.state = taxInformation.state; const provider = await this.providerApiService.postProviderSetup(this.providerId, request); diff --git a/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.html b/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.html index 0b041bd4c06..3f635656fb7 100644 --- a/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.html +++ b/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.html @@ -1,7 +1,7 @@
- + {{ "country" | i18n }}
- + {{ "zipPostalCode" | i18n }}
-
- - - {{ "includeVAT" | i18n }} - -
-
-
-
- - {{ "taxIdNumber" | i18n }} - - -
-
-
-
- - {{ "address1" | i18n }} - - -
-
- - {{ "address2" | i18n }} - - -
-
- - {{ "cityTown" | i18n }} - - -
-
- - {{ "stateProvince" | i18n }} - - + +
+ + {{ "address1" | i18n }} + + +
+
+ + {{ "address2" | i18n }} + + +
+
+ + {{ "cityTown" | i18n }} + + +
+
+ + {{ "stateProvince" | i18n }} + + +
+
+ + {{ "taxIdNumber" | i18n }} + + +
+
+
+
- diff --git a/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts b/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts index a3564b1ebc9..13a6d2d0cc3 100644 --- a/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts +++ b/libs/angular/src/billing/components/manage-tax-information/manage-tax-information.component.ts @@ -3,14 +3,10 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; import { Subject, takeUntil } from "rxjs"; +import { debounceTime } from "rxjs/operators"; -import { TaxInformation } from "@bitwarden/common/billing/models/domain"; - -type Country = { - name: string; - value: string; - disabled: boolean; -}; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; +import { CountryListItem, TaxInformation } from "@bitwarden/common/billing/models/domain"; @Component({ selector: "app-manage-tax-information", @@ -19,12 +15,23 @@ type Country = { export class ManageTaxInformationComponent implements OnInit, OnDestroy { @Input() startWith: TaxInformation; @Input() onSubmit?: (taxInformation: TaxInformation) => Promise; + @Input() showTaxIdField: boolean = true; + + /** + * Emits when the tax information has changed. + */ + @Output() taxInformationChanged = new EventEmitter(); + + /** + * Emits when the tax information has been updated. + */ @Output() taxInformationUpdated = new EventEmitter(); + private taxInformation: TaxInformation; + protected formGroup = this.formBuilder.group({ country: ["", Validators.required], postalCode: ["", Validators.required], - includeTaxId: false, taxId: "", line1: "", line2: "", @@ -32,16 +39,20 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy { state: "", }); + protected isTaxSupported: boolean; + private destroy$ = new Subject(); - private taxInformation: TaxInformation; + protected readonly countries: CountryListItem[] = this.taxService.getCountries(); - constructor(private formBuilder: FormBuilder) {} + constructor( + private formBuilder: FormBuilder, + private taxService: TaxServiceAbstraction, + ) {} - getTaxInformation = (): TaxInformation & { includeTaxId: boolean } => ({ - ...this.taxInformation, - includeTaxId: this.formGroup.value.includeTaxId, - }); + getTaxInformation(): TaxInformation { + return this.taxInformation; + } submit = async () => { this.formGroup.markAllAsTouched(); @@ -52,23 +63,32 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy { this.taxInformationUpdated.emit(); }; - touch = (): boolean => { - this.formGroup.markAllAsTouched(); - return this.formGroup.valid; - }; + validate(): boolean { + if (this.formGroup.dirty) { + this.formGroup.markAllAsTouched(); + return this.formGroup.valid; + } else { + return this.formGroup.valid; + } + } async ngOnInit() { if (this.startWith) { - this.formGroup.patchValue({ - ...this.startWith, - includeTaxId: - this.countrySupportsTax(this.startWith.country) && - (!!this.startWith.taxId || - !!this.startWith.line1 || - !!this.startWith.line2 || - !!this.startWith.city || - !!this.startWith.state), - }); + this.formGroup.controls.country.setValue(this.startWith.country); + this.formGroup.controls.postalCode.setValue(this.startWith.postalCode); + + this.isTaxSupported = + this.startWith && this.startWith.country + ? await this.taxService.isCountrySupported(this.startWith.country) + : false; + + if (this.isTaxSupported) { + this.formGroup.controls.taxId.setValue(this.startWith.taxId); + this.formGroup.controls.line1.setValue(this.startWith.line1); + this.formGroup.controls.line2.setValue(this.startWith.line2); + this.formGroup.controls.city.setValue(this.startWith.city); + this.formGroup.controls.state.setValue(this.startWith.state); + } } this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((values) => { @@ -82,354 +102,47 @@ export class ManageTaxInformationComponent implements OnInit, OnDestroy { state: values.state, }; }); - } - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } + this.formGroup.controls.country.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) + .subscribe((country: string) => { + this.taxService + .isCountrySupported(country) + .then((isSupported) => (this.isTaxSupported = isSupported)) + .catch(() => (this.isTaxSupported = false)) + .finally(() => { + if (!this.isTaxSupported) { + this.formGroup.controls.taxId.setValue(null); + this.formGroup.controls.line1.setValue(null); + this.formGroup.controls.line2.setValue(null); + this.formGroup.controls.city.setValue(null); + this.formGroup.controls.state.setValue(null); + } + if (this.taxInformationChanged) { + this.taxInformationChanged.emit(this.taxInformation); + } + }); + }); - protected countrySupportsTax(countryCode: string) { - return this.taxSupportedCountryCodes.includes(countryCode); - } + this.formGroup.controls.postalCode.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) + .subscribe(() => { + if (this.taxInformationChanged) { + this.taxInformationChanged.emit(this.taxInformation); + } + }); - protected get includeTaxIdIsSelected() { - return this.formGroup.value.includeTaxId; + this.formGroup.controls.taxId.valueChanges + .pipe(debounceTime(1000), takeUntil(this.destroy$)) + .subscribe(() => { + if (this.taxInformationChanged) { + this.taxInformationChanged.emit(this.taxInformation); + } + }); } - protected get selectionSupportsAdditionalOptions() { - return ( - this.formGroup.value.country !== "US" && this.countrySupportsTax(this.formGroup.value.country) - ); + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); } - - protected countries: Country[] = [ - { name: "-- Select --", value: "", disabled: false }, - { name: "United States", value: "US", disabled: false }, - { name: "China", value: "CN", disabled: false }, - { name: "France", value: "FR", disabled: false }, - { name: "Germany", value: "DE", disabled: false }, - { name: "Canada", value: "CA", disabled: false }, - { name: "United Kingdom", value: "GB", disabled: false }, - { name: "Australia", value: "AU", disabled: false }, - { name: "India", value: "IN", disabled: false }, - { name: "", value: "-", disabled: true }, - { name: "Afghanistan", value: "AF", disabled: false }, - { name: "Åland Islands", value: "AX", disabled: false }, - { name: "Albania", value: "AL", disabled: false }, - { name: "Algeria", value: "DZ", disabled: false }, - { name: "American Samoa", value: "AS", disabled: false }, - { name: "Andorra", value: "AD", disabled: false }, - { name: "Angola", value: "AO", disabled: false }, - { name: "Anguilla", value: "AI", disabled: false }, - { name: "Antarctica", value: "AQ", disabled: false }, - { name: "Antigua and Barbuda", value: "AG", disabled: false }, - { name: "Argentina", value: "AR", disabled: false }, - { name: "Armenia", value: "AM", disabled: false }, - { name: "Aruba", value: "AW", disabled: false }, - { name: "Austria", value: "AT", disabled: false }, - { name: "Azerbaijan", value: "AZ", disabled: false }, - { name: "Bahamas", value: "BS", disabled: false }, - { name: "Bahrain", value: "BH", disabled: false }, - { name: "Bangladesh", value: "BD", disabled: false }, - { name: "Barbados", value: "BB", disabled: false }, - { name: "Belarus", value: "BY", disabled: false }, - { name: "Belgium", value: "BE", disabled: false }, - { name: "Belize", value: "BZ", disabled: false }, - { name: "Benin", value: "BJ", disabled: false }, - { name: "Bermuda", value: "BM", disabled: false }, - { name: "Bhutan", value: "BT", disabled: false }, - { name: "Bolivia, Plurinational State of", value: "BO", disabled: false }, - { name: "Bonaire, Sint Eustatius and Saba", value: "BQ", disabled: false }, - { name: "Bosnia and Herzegovina", value: "BA", disabled: false }, - { name: "Botswana", value: "BW", disabled: false }, - { name: "Bouvet Island", value: "BV", disabled: false }, - { name: "Brazil", value: "BR", disabled: false }, - { name: "British Indian Ocean Territory", value: "IO", disabled: false }, - { name: "Brunei Darussalam", value: "BN", disabled: false }, - { name: "Bulgaria", value: "BG", disabled: false }, - { name: "Burkina Faso", value: "BF", disabled: false }, - { name: "Burundi", value: "BI", disabled: false }, - { name: "Cambodia", value: "KH", disabled: false }, - { name: "Cameroon", value: "CM", disabled: false }, - { name: "Cape Verde", value: "CV", disabled: false }, - { name: "Cayman Islands", value: "KY", disabled: false }, - { name: "Central African Republic", value: "CF", disabled: false }, - { name: "Chad", value: "TD", disabled: false }, - { name: "Chile", value: "CL", disabled: false }, - { name: "Christmas Island", value: "CX", disabled: false }, - { name: "Cocos (Keeling) Islands", value: "CC", disabled: false }, - { name: "Colombia", value: "CO", disabled: false }, - { name: "Comoros", value: "KM", disabled: false }, - { name: "Congo", value: "CG", disabled: false }, - { name: "Congo, the Democratic Republic of the", value: "CD", disabled: false }, - { name: "Cook Islands", value: "CK", disabled: false }, - { name: "Costa Rica", value: "CR", disabled: false }, - { name: "Côte d'Ivoire", value: "CI", disabled: false }, - { name: "Croatia", value: "HR", disabled: false }, - { name: "Cuba", value: "CU", disabled: false }, - { name: "Curaçao", value: "CW", disabled: false }, - { name: "Cyprus", value: "CY", disabled: false }, - { name: "Czech Republic", value: "CZ", disabled: false }, - { name: "Denmark", value: "DK", disabled: false }, - { name: "Djibouti", value: "DJ", disabled: false }, - { name: "Dominica", value: "DM", disabled: false }, - { name: "Dominican Republic", value: "DO", disabled: false }, - { name: "Ecuador", value: "EC", disabled: false }, - { name: "Egypt", value: "EG", disabled: false }, - { name: "El Salvador", value: "SV", disabled: false }, - { name: "Equatorial Guinea", value: "GQ", disabled: false }, - { name: "Eritrea", value: "ER", disabled: false }, - { name: "Estonia", value: "EE", disabled: false }, - { name: "Ethiopia", value: "ET", disabled: false }, - { name: "Falkland Islands (Malvinas)", value: "FK", disabled: false }, - { name: "Faroe Islands", value: "FO", disabled: false }, - { name: "Fiji", value: "FJ", disabled: false }, - { name: "Finland", value: "FI", disabled: false }, - { name: "French Guiana", value: "GF", disabled: false }, - { name: "French Polynesia", value: "PF", disabled: false }, - { name: "French Southern Territories", value: "TF", disabled: false }, - { name: "Gabon", value: "GA", disabled: false }, - { name: "Gambia", value: "GM", disabled: false }, - { name: "Georgia", value: "GE", disabled: false }, - { name: "Ghana", value: "GH", disabled: false }, - { name: "Gibraltar", value: "GI", disabled: false }, - { name: "Greece", value: "GR", disabled: false }, - { name: "Greenland", value: "GL", disabled: false }, - { name: "Grenada", value: "GD", disabled: false }, - { name: "Guadeloupe", value: "GP", disabled: false }, - { name: "Guam", value: "GU", disabled: false }, - { name: "Guatemala", value: "GT", disabled: false }, - { name: "Guernsey", value: "GG", disabled: false }, - { name: "Guinea", value: "GN", disabled: false }, - { name: "Guinea-Bissau", value: "GW", disabled: false }, - { name: "Guyana", value: "GY", disabled: false }, - { name: "Haiti", value: "HT", disabled: false }, - { name: "Heard Island and McDonald Islands", value: "HM", disabled: false }, - { name: "Holy See (Vatican City State)", value: "VA", disabled: false }, - { name: "Honduras", value: "HN", disabled: false }, - { name: "Hong Kong", value: "HK", disabled: false }, - { name: "Hungary", value: "HU", disabled: false }, - { name: "Iceland", value: "IS", disabled: false }, - { name: "Indonesia", value: "ID", disabled: false }, - { name: "Iran, Islamic Republic of", value: "IR", disabled: false }, - { name: "Iraq", value: "IQ", disabled: false }, - { name: "Ireland", value: "IE", disabled: false }, - { name: "Isle of Man", value: "IM", disabled: false }, - { name: "Israel", value: "IL", disabled: false }, - { name: "Italy", value: "IT", disabled: false }, - { name: "Jamaica", value: "JM", disabled: false }, - { name: "Japan", value: "JP", disabled: false }, - { name: "Jersey", value: "JE", disabled: false }, - { name: "Jordan", value: "JO", disabled: false }, - { name: "Kazakhstan", value: "KZ", disabled: false }, - { name: "Kenya", value: "KE", disabled: false }, - { name: "Kiribati", value: "KI", disabled: false }, - { name: "Korea, Democratic People's Republic of", value: "KP", disabled: false }, - { name: "Korea, Republic of", value: "KR", disabled: false }, - { name: "Kuwait", value: "KW", disabled: false }, - { name: "Kyrgyzstan", value: "KG", disabled: false }, - { name: "Lao People's Democratic Republic", value: "LA", disabled: false }, - { name: "Latvia", value: "LV", disabled: false }, - { name: "Lebanon", value: "LB", disabled: false }, - { name: "Lesotho", value: "LS", disabled: false }, - { name: "Liberia", value: "LR", disabled: false }, - { name: "Libya", value: "LY", disabled: false }, - { name: "Liechtenstein", value: "LI", disabled: false }, - { name: "Lithuania", value: "LT", disabled: false }, - { name: "Luxembourg", value: "LU", disabled: false }, - { name: "Macao", value: "MO", disabled: false }, - { name: "Macedonia, the former Yugoslav Republic of", value: "MK", disabled: false }, - { name: "Madagascar", value: "MG", disabled: false }, - { name: "Malawi", value: "MW", disabled: false }, - { name: "Malaysia", value: "MY", disabled: false }, - { name: "Maldives", value: "MV", disabled: false }, - { name: "Mali", value: "ML", disabled: false }, - { name: "Malta", value: "MT", disabled: false }, - { name: "Marshall Islands", value: "MH", disabled: false }, - { name: "Martinique", value: "MQ", disabled: false }, - { name: "Mauritania", value: "MR", disabled: false }, - { name: "Mauritius", value: "MU", disabled: false }, - { name: "Mayotte", value: "YT", disabled: false }, - { name: "Mexico", value: "MX", disabled: false }, - { name: "Micronesia, Federated States of", value: "FM", disabled: false }, - { name: "Moldova, Republic of", value: "MD", disabled: false }, - { name: "Monaco", value: "MC", disabled: false }, - { name: "Mongolia", value: "MN", disabled: false }, - { name: "Montenegro", value: "ME", disabled: false }, - { name: "Montserrat", value: "MS", disabled: false }, - { name: "Morocco", value: "MA", disabled: false }, - { name: "Mozambique", value: "MZ", disabled: false }, - { name: "Myanmar", value: "MM", disabled: false }, - { name: "Namibia", value: "NA", disabled: false }, - { name: "Nauru", value: "NR", disabled: false }, - { name: "Nepal", value: "NP", disabled: false }, - { name: "Netherlands", value: "NL", disabled: false }, - { name: "New Caledonia", value: "NC", disabled: false }, - { name: "New Zealand", value: "NZ", disabled: false }, - { name: "Nicaragua", value: "NI", disabled: false }, - { name: "Niger", value: "NE", disabled: false }, - { name: "Nigeria", value: "NG", disabled: false }, - { name: "Niue", value: "NU", disabled: false }, - { name: "Norfolk Island", value: "NF", disabled: false }, - { name: "Northern Mariana Islands", value: "MP", disabled: false }, - { name: "Norway", value: "NO", disabled: false }, - { name: "Oman", value: "OM", disabled: false }, - { name: "Pakistan", value: "PK", disabled: false }, - { name: "Palau", value: "PW", disabled: false }, - { name: "Palestinian Territory, Occupied", value: "PS", disabled: false }, - { name: "Panama", value: "PA", disabled: false }, - { name: "Papua New Guinea", value: "PG", disabled: false }, - { name: "Paraguay", value: "PY", disabled: false }, - { name: "Peru", value: "PE", disabled: false }, - { name: "Philippines", value: "PH", disabled: false }, - { name: "Pitcairn", value: "PN", disabled: false }, - { name: "Poland", value: "PL", disabled: false }, - { name: "Portugal", value: "PT", disabled: false }, - { name: "Puerto Rico", value: "PR", disabled: false }, - { name: "Qatar", value: "QA", disabled: false }, - { name: "Réunion", value: "RE", disabled: false }, - { name: "Romania", value: "RO", disabled: false }, - { name: "Russian Federation", value: "RU", disabled: false }, - { name: "Rwanda", value: "RW", disabled: false }, - { name: "Saint Barthélemy", value: "BL", disabled: false }, - { name: "Saint Helena, Ascension and Tristan da Cunha", value: "SH", disabled: false }, - { name: "Saint Kitts and Nevis", value: "KN", disabled: false }, - { name: "Saint Lucia", value: "LC", disabled: false }, - { name: "Saint Martin (French part)", value: "MF", disabled: false }, - { name: "Saint Pierre and Miquelon", value: "PM", disabled: false }, - { name: "Saint Vincent and the Grenadines", value: "VC", disabled: false }, - { name: "Samoa", value: "WS", disabled: false }, - { name: "San Marino", value: "SM", disabled: false }, - { name: "Sao Tome and Principe", value: "ST", disabled: false }, - { name: "Saudi Arabia", value: "SA", disabled: false }, - { name: "Senegal", value: "SN", disabled: false }, - { name: "Serbia", value: "RS", disabled: false }, - { name: "Seychelles", value: "SC", disabled: false }, - { name: "Sierra Leone", value: "SL", disabled: false }, - { name: "Singapore", value: "SG", disabled: false }, - { name: "Sint Maarten (Dutch part)", value: "SX", disabled: false }, - { name: "Slovakia", value: "SK", disabled: false }, - { name: "Slovenia", value: "SI", disabled: false }, - { name: "Solomon Islands", value: "SB", disabled: false }, - { name: "Somalia", value: "SO", disabled: false }, - { name: "South Africa", value: "ZA", disabled: false }, - { name: "South Georgia and the South Sandwich Islands", value: "GS", disabled: false }, - { name: "South Sudan", value: "SS", disabled: false }, - { name: "Spain", value: "ES", disabled: false }, - { name: "Sri Lanka", value: "LK", disabled: false }, - { name: "Sudan", value: "SD", disabled: false }, - { name: "Suriname", value: "SR", disabled: false }, - { name: "Svalbard and Jan Mayen", value: "SJ", disabled: false }, - { name: "Swaziland", value: "SZ", disabled: false }, - { name: "Sweden", value: "SE", disabled: false }, - { name: "Switzerland", value: "CH", disabled: false }, - { name: "Syrian Arab Republic", value: "SY", disabled: false }, - { name: "Taiwan", value: "TW", disabled: false }, - { name: "Tajikistan", value: "TJ", disabled: false }, - { name: "Tanzania, United Republic of", value: "TZ", disabled: false }, - { name: "Thailand", value: "TH", disabled: false }, - { name: "Timor-Leste", value: "TL", disabled: false }, - { name: "Togo", value: "TG", disabled: false }, - { name: "Tokelau", value: "TK", disabled: false }, - { name: "Tonga", value: "TO", disabled: false }, - { name: "Trinidad and Tobago", value: "TT", disabled: false }, - { name: "Tunisia", value: "TN", disabled: false }, - { name: "Turkey", value: "TR", disabled: false }, - { name: "Turkmenistan", value: "TM", disabled: false }, - { name: "Turks and Caicos Islands", value: "TC", disabled: false }, - { name: "Tuvalu", value: "TV", disabled: false }, - { name: "Uganda", value: "UG", disabled: false }, - { name: "Ukraine", value: "UA", disabled: false }, - { name: "United Arab Emirates", value: "AE", disabled: false }, - { name: "United States Minor Outlying Islands", value: "UM", disabled: false }, - { name: "Uruguay", value: "UY", disabled: false }, - { name: "Uzbekistan", value: "UZ", disabled: false }, - { name: "Vanuatu", value: "VU", disabled: false }, - { name: "Venezuela, Bolivarian Republic of", value: "VE", disabled: false }, - { name: "Viet Nam", value: "VN", disabled: false }, - { name: "Virgin Islands, British", value: "VG", disabled: false }, - { name: "Virgin Islands, U.S.", value: "VI", disabled: false }, - { name: "Wallis and Futuna", value: "WF", disabled: false }, - { name: "Western Sahara", value: "EH", disabled: false }, - { name: "Yemen", value: "YE", disabled: false }, - { name: "Zambia", value: "ZM", disabled: false }, - { name: "Zimbabwe", value: "ZW", disabled: false }, - ]; - - private taxSupportedCountryCodes: string[] = [ - "CN", - "FR", - "DE", - "CA", - "GB", - "AU", - "IN", - "AD", - "AR", - "AT", - "BE", - "BO", - "BR", - "BG", - "CL", - "CO", - "CR", - "HR", - "CY", - "CZ", - "DK", - "DO", - "EC", - "EG", - "SV", - "EE", - "FI", - "GE", - "GR", - "HK", - "HU", - "IS", - "ID", - "IQ", - "IE", - "IL", - "IT", - "JP", - "KE", - "KR", - "LV", - "LI", - "LT", - "LU", - "MY", - "MT", - "MX", - "NL", - "NZ", - "NO", - "PE", - "PH", - "PL", - "PT", - "RO", - "RU", - "SA", - "RS", - "SG", - "SK", - "SI", - "ZA", - "ES", - "SE", - "CH", - "TW", - "TH", - "TR", - "UA", - "AE", - "UY", - "VE", - "VN", - ]; } diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 688507099de..149d553696e 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -138,11 +138,13 @@ import { import { AccountBillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/account/account-billing-api.service.abstraction"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { OrganizationBillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/organizations/organization-billing-api.service.abstraction"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; import { AccountBillingApiService } from "@bitwarden/common/billing/services/account/account-billing-api.service"; import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/billing/services/account/billing-account-profile-state.service"; import { BillingApiService } from "@bitwarden/common/billing/services/billing-api.service"; import { OrganizationBillingApiService } from "@bitwarden/common/billing/services/organization/organization-billing-api.service"; import { OrganizationBillingService } from "@bitwarden/common/billing/services/organization-billing.service"; +import { TaxService } from "@bitwarden/common/billing/services/tax.service"; import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; import { BulkEncryptService } from "@bitwarden/common/platform/abstractions/bulk-encrypt.service"; @@ -1271,6 +1273,11 @@ const safeProviders: SafeProvider[] = [ useClass: BillingApiService, deps: [ApiServiceAbstraction, LogService, ToastService], }), + safeProvider({ + provide: TaxServiceAbstraction, + useClass: TaxService, + deps: [ApiServiceAbstraction], + }), safeProvider({ provide: BillingAccountProfileStateService, useClass: DefaultBillingAccountProfileStateService, diff --git a/libs/common/src/billing/abstractions/tax.service.abstraction.ts b/libs/common/src/billing/abstractions/tax.service.abstraction.ts new file mode 100644 index 00000000000..438d3f394e0 --- /dev/null +++ b/libs/common/src/billing/abstractions/tax.service.abstraction.ts @@ -0,0 +1,18 @@ +import { CountryListItem } from "@bitwarden/common/billing/models/domain"; +import { PreviewIndividualInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-individual-invoice.request"; +import { PreviewOrganizationInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-organization-invoice.request"; +import { PreviewInvoiceResponse } from "@bitwarden/common/billing/models/response/preview-invoice.response"; + +export abstract class TaxServiceAbstraction { + abstract getCountries(): CountryListItem[]; + + abstract isCountrySupported(country: string): Promise; + + abstract previewIndividualInvoice( + request: PreviewIndividualInvoiceRequest, + ): Promise; + + abstract previewOrganizationInvoice( + request: PreviewOrganizationInvoiceRequest, + ): Promise; +} diff --git a/libs/common/src/billing/models/domain/country-list-item.ts b/libs/common/src/billing/models/domain/country-list-item.ts new file mode 100644 index 00000000000..79abb96871c --- /dev/null +++ b/libs/common/src/billing/models/domain/country-list-item.ts @@ -0,0 +1,5 @@ +export type CountryListItem = { + name: string; + value: string; + disabled: boolean; +}; diff --git a/libs/common/src/billing/models/domain/index.ts b/libs/common/src/billing/models/domain/index.ts index 0f53c3e116c..057f6dc4e84 100644 --- a/libs/common/src/billing/models/domain/index.ts +++ b/libs/common/src/billing/models/domain/index.ts @@ -1,2 +1,3 @@ export * from "./bank-account"; +export * from "./country-list-item"; export * from "./tax-information"; diff --git a/libs/common/src/billing/models/request/expanded-tax-info-update.request.ts b/libs/common/src/billing/models/request/expanded-tax-info-update.request.ts index 838249e2d8c..784d2691629 100644 --- a/libs/common/src/billing/models/request/expanded-tax-info-update.request.ts +++ b/libs/common/src/billing/models/request/expanded-tax-info-update.request.ts @@ -12,6 +12,10 @@ export class ExpandedTaxInfoUpdateRequest extends TaxInfoUpdateRequest { state: string; static From(taxInformation: TaxInformation): ExpandedTaxInfoUpdateRequest { + if (!taxInformation) { + return null; + } + const request = new ExpandedTaxInfoUpdateRequest(); request.country = taxInformation.country; request.postalCode = taxInformation.postalCode; diff --git a/libs/common/src/billing/models/request/preview-individual-invoice.request.ts b/libs/common/src/billing/models/request/preview-individual-invoice.request.ts new file mode 100644 index 00000000000..f817398c629 --- /dev/null +++ b/libs/common/src/billing/models/request/preview-individual-invoice.request.ts @@ -0,0 +1,28 @@ +// @ts-strict-ignore +export class PreviewIndividualInvoiceRequest { + passwordManager: PasswordManager; + taxInformation: TaxInformation; + + constructor(passwordManager: PasswordManager, taxInformation: TaxInformation) { + this.passwordManager = passwordManager; + this.taxInformation = taxInformation; + } +} + +class PasswordManager { + additionalStorage: number; + + constructor(additionalStorage: number) { + this.additionalStorage = additionalStorage; + } +} + +class TaxInformation { + postalCode: string; + country: string; + + constructor(postalCode: string, country: string) { + this.postalCode = postalCode; + this.country = country; + } +} diff --git a/libs/common/src/billing/models/request/preview-organization-invoice.request.ts b/libs/common/src/billing/models/request/preview-organization-invoice.request.ts new file mode 100644 index 00000000000..365dff5c110 --- /dev/null +++ b/libs/common/src/billing/models/request/preview-organization-invoice.request.ts @@ -0,0 +1,54 @@ +import { PlanType } from "@bitwarden/common/billing/enums"; + +export class PreviewOrganizationInvoiceRequest { + organizationId?: string; + passwordManager: PasswordManager; + secretsManager?: SecretsManager; + taxInformation: TaxInformation; + + constructor( + passwordManager: PasswordManager, + taxInformation: TaxInformation, + organizationId?: string, + secretsManager?: SecretsManager, + ) { + this.organizationId = organizationId; + this.passwordManager = passwordManager; + this.secretsManager = secretsManager; + this.taxInformation = taxInformation; + } +} + +class PasswordManager { + plan: PlanType; + seats: number; + additionalStorage: number; + + constructor(plan: PlanType, seats: number, additionalStorage: number) { + this.plan = plan; + this.seats = seats; + this.additionalStorage = additionalStorage; + } +} + +class SecretsManager { + seats: number; + additionalMachineAccounts: number; + + constructor(seats: number, additionalMachineAccounts: number) { + this.seats = seats; + this.additionalMachineAccounts = additionalMachineAccounts; + } +} + +class TaxInformation { + postalCode: string; + country: string; + taxId: string; + + constructor(postalCode: string, country: string, taxId: string) { + this.postalCode = postalCode; + this.country = country; + this.taxId = taxId; + } +} diff --git a/libs/common/src/billing/models/response/preview-invoice.response.ts b/libs/common/src/billing/models/response/preview-invoice.response.ts new file mode 100644 index 00000000000..c822a569bb3 --- /dev/null +++ b/libs/common/src/billing/models/response/preview-invoice.response.ts @@ -0,0 +1,16 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +export class PreviewInvoiceResponse extends BaseResponse { + effectiveTaxRate: number; + taxableBaseAmount: number; + taxAmount: number; + totalAmount: number; + + constructor(response: any) { + super(response); + this.effectiveTaxRate = this.getResponseProperty("EffectiveTaxRate"); + this.taxableBaseAmount = this.getResponseProperty("TaxableBaseAmount"); + this.taxAmount = this.getResponseProperty("TaxAmount"); + this.totalAmount = this.getResponseProperty("TotalAmount"); + } +} diff --git a/libs/common/src/billing/models/response/tax-id-types.response.ts b/libs/common/src/billing/models/response/tax-id-types.response.ts new file mode 100644 index 00000000000..0d5cce46c8c --- /dev/null +++ b/libs/common/src/billing/models/response/tax-id-types.response.ts @@ -0,0 +1,28 @@ +import { BaseResponse } from "@bitwarden/common/models/response/base.response"; + +export class TaxIdTypesResponse extends BaseResponse { + taxIdTypes: TaxIdTypeResponse[] = []; + + constructor(response: any) { + super(response); + const taxIdTypes = this.getResponseProperty("TaxIdTypes"); + if (taxIdTypes && taxIdTypes.length) { + this.taxIdTypes = taxIdTypes.map((t: any) => new TaxIdTypeResponse(t)); + } + } +} + +export class TaxIdTypeResponse extends BaseResponse { + code: string; + country: string; + description: string; + example: string; + + constructor(response: any) { + super(response); + this.code = this.getResponseProperty("Code"); + this.country = this.getResponseProperty("Country"); + this.description = this.getResponseProperty("Description"); + this.example = this.getResponseProperty("Example"); + } +} diff --git a/libs/common/src/billing/services/tax.service.ts b/libs/common/src/billing/services/tax.service.ts new file mode 100644 index 00000000000..45e57267ec0 --- /dev/null +++ b/libs/common/src/billing/services/tax.service.ts @@ -0,0 +1,303 @@ +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; +import { CountryListItem } from "@bitwarden/common/billing/models/domain"; +import { PreviewIndividualInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-individual-invoice.request"; +import { PreviewOrganizationInvoiceRequest } from "@bitwarden/common/billing/models/request/preview-organization-invoice.request"; +import { PreviewInvoiceResponse } from "@bitwarden/common/billing/models/response/preview-invoice.response"; + +export class TaxService implements TaxServiceAbstraction { + constructor(private apiService: ApiService) {} + + getCountries(): CountryListItem[] { + return [ + { name: "-- Select --", value: "", disabled: false }, + { name: "United States", value: "US", disabled: false }, + { name: "China", value: "CN", disabled: false }, + { name: "France", value: "FR", disabled: false }, + { name: "Germany", value: "DE", disabled: false }, + { name: "Canada", value: "CA", disabled: false }, + { name: "United Kingdom", value: "GB", disabled: false }, + { name: "Australia", value: "AU", disabled: false }, + { name: "India", value: "IN", disabled: false }, + { name: "", value: "-", disabled: true }, + { name: "Afghanistan", value: "AF", disabled: false }, + { name: "Åland Islands", value: "AX", disabled: false }, + { name: "Albania", value: "AL", disabled: false }, + { name: "Algeria", value: "DZ", disabled: false }, + { name: "American Samoa", value: "AS", disabled: false }, + { name: "Andorra", value: "AD", disabled: false }, + { name: "Angola", value: "AO", disabled: false }, + { name: "Anguilla", value: "AI", disabled: false }, + { name: "Antarctica", value: "AQ", disabled: false }, + { name: "Antigua and Barbuda", value: "AG", disabled: false }, + { name: "Argentina", value: "AR", disabled: false }, + { name: "Armenia", value: "AM", disabled: false }, + { name: "Aruba", value: "AW", disabled: false }, + { name: "Austria", value: "AT", disabled: false }, + { name: "Azerbaijan", value: "AZ", disabled: false }, + { name: "Bahamas", value: "BS", disabled: false }, + { name: "Bahrain", value: "BH", disabled: false }, + { name: "Bangladesh", value: "BD", disabled: false }, + { name: "Barbados", value: "BB", disabled: false }, + { name: "Belarus", value: "BY", disabled: false }, + { name: "Belgium", value: "BE", disabled: false }, + { name: "Belize", value: "BZ", disabled: false }, + { name: "Benin", value: "BJ", disabled: false }, + { name: "Bermuda", value: "BM", disabled: false }, + { name: "Bhutan", value: "BT", disabled: false }, + { name: "Bolivia, Plurinational State of", value: "BO", disabled: false }, + { name: "Bonaire, Sint Eustatius and Saba", value: "BQ", disabled: false }, + { name: "Bosnia and Herzegovina", value: "BA", disabled: false }, + { name: "Botswana", value: "BW", disabled: false }, + { name: "Bouvet Island", value: "BV", disabled: false }, + { name: "Brazil", value: "BR", disabled: false }, + { name: "British Indian Ocean Territory", value: "IO", disabled: false }, + { name: "Brunei Darussalam", value: "BN", disabled: false }, + { name: "Bulgaria", value: "BG", disabled: false }, + { name: "Burkina Faso", value: "BF", disabled: false }, + { name: "Burundi", value: "BI", disabled: false }, + { name: "Cambodia", value: "KH", disabled: false }, + { name: "Cameroon", value: "CM", disabled: false }, + { name: "Cape Verde", value: "CV", disabled: false }, + { name: "Cayman Islands", value: "KY", disabled: false }, + { name: "Central African Republic", value: "CF", disabled: false }, + { name: "Chad", value: "TD", disabled: false }, + { name: "Chile", value: "CL", disabled: false }, + { name: "Christmas Island", value: "CX", disabled: false }, + { name: "Cocos (Keeling) Islands", value: "CC", disabled: false }, + { name: "Colombia", value: "CO", disabled: false }, + { name: "Comoros", value: "KM", disabled: false }, + { name: "Congo", value: "CG", disabled: false }, + { name: "Congo, the Democratic Republic of the", value: "CD", disabled: false }, + { name: "Cook Islands", value: "CK", disabled: false }, + { name: "Costa Rica", value: "CR", disabled: false }, + { name: "Côte d'Ivoire", value: "CI", disabled: false }, + { name: "Croatia", value: "HR", disabled: false }, + { name: "Cuba", value: "CU", disabled: false }, + { name: "Curaçao", value: "CW", disabled: false }, + { name: "Cyprus", value: "CY", disabled: false }, + { name: "Czech Republic", value: "CZ", disabled: false }, + { name: "Denmark", value: "DK", disabled: false }, + { name: "Djibouti", value: "DJ", disabled: false }, + { name: "Dominica", value: "DM", disabled: false }, + { name: "Dominican Republic", value: "DO", disabled: false }, + { name: "Ecuador", value: "EC", disabled: false }, + { name: "Egypt", value: "EG", disabled: false }, + { name: "El Salvador", value: "SV", disabled: false }, + { name: "Equatorial Guinea", value: "GQ", disabled: false }, + { name: "Eritrea", value: "ER", disabled: false }, + { name: "Estonia", value: "EE", disabled: false }, + { name: "Ethiopia", value: "ET", disabled: false }, + { name: "Falkland Islands (Malvinas)", value: "FK", disabled: false }, + { name: "Faroe Islands", value: "FO", disabled: false }, + { name: "Fiji", value: "FJ", disabled: false }, + { name: "Finland", value: "FI", disabled: false }, + { name: "French Guiana", value: "GF", disabled: false }, + { name: "French Polynesia", value: "PF", disabled: false }, + { name: "French Southern Territories", value: "TF", disabled: false }, + { name: "Gabon", value: "GA", disabled: false }, + { name: "Gambia", value: "GM", disabled: false }, + { name: "Georgia", value: "GE", disabled: false }, + { name: "Ghana", value: "GH", disabled: false }, + { name: "Gibraltar", value: "GI", disabled: false }, + { name: "Greece", value: "GR", disabled: false }, + { name: "Greenland", value: "GL", disabled: false }, + { name: "Grenada", value: "GD", disabled: false }, + { name: "Guadeloupe", value: "GP", disabled: false }, + { name: "Guam", value: "GU", disabled: false }, + { name: "Guatemala", value: "GT", disabled: false }, + { name: "Guernsey", value: "GG", disabled: false }, + { name: "Guinea", value: "GN", disabled: false }, + { name: "Guinea-Bissau", value: "GW", disabled: false }, + { name: "Guyana", value: "GY", disabled: false }, + { name: "Haiti", value: "HT", disabled: false }, + { name: "Heard Island and McDonald Islands", value: "HM", disabled: false }, + { name: "Holy See (Vatican City State)", value: "VA", disabled: false }, + { name: "Honduras", value: "HN", disabled: false }, + { name: "Hong Kong", value: "HK", disabled: false }, + { name: "Hungary", value: "HU", disabled: false }, + { name: "Iceland", value: "IS", disabled: false }, + { name: "Indonesia", value: "ID", disabled: false }, + { name: "Iran, Islamic Republic of", value: "IR", disabled: false }, + { name: "Iraq", value: "IQ", disabled: false }, + { name: "Ireland", value: "IE", disabled: false }, + { name: "Isle of Man", value: "IM", disabled: false }, + { name: "Israel", value: "IL", disabled: false }, + { name: "Italy", value: "IT", disabled: false }, + { name: "Jamaica", value: "JM", disabled: false }, + { name: "Japan", value: "JP", disabled: false }, + { name: "Jersey", value: "JE", disabled: false }, + { name: "Jordan", value: "JO", disabled: false }, + { name: "Kazakhstan", value: "KZ", disabled: false }, + { name: "Kenya", value: "KE", disabled: false }, + { name: "Kiribati", value: "KI", disabled: false }, + { name: "Korea, Democratic People's Republic of", value: "KP", disabled: false }, + { name: "Korea, Republic of", value: "KR", disabled: false }, + { name: "Kuwait", value: "KW", disabled: false }, + { name: "Kyrgyzstan", value: "KG", disabled: false }, + { name: "Lao People's Democratic Republic", value: "LA", disabled: false }, + { name: "Latvia", value: "LV", disabled: false }, + { name: "Lebanon", value: "LB", disabled: false }, + { name: "Lesotho", value: "LS", disabled: false }, + { name: "Liberia", value: "LR", disabled: false }, + { name: "Libya", value: "LY", disabled: false }, + { name: "Liechtenstein", value: "LI", disabled: false }, + { name: "Lithuania", value: "LT", disabled: false }, + { name: "Luxembourg", value: "LU", disabled: false }, + { name: "Macao", value: "MO", disabled: false }, + { name: "Macedonia, the former Yugoslav Republic of", value: "MK", disabled: false }, + { name: "Madagascar", value: "MG", disabled: false }, + { name: "Malawi", value: "MW", disabled: false }, + { name: "Malaysia", value: "MY", disabled: false }, + { name: "Maldives", value: "MV", disabled: false }, + { name: "Mali", value: "ML", disabled: false }, + { name: "Malta", value: "MT", disabled: false }, + { name: "Marshall Islands", value: "MH", disabled: false }, + { name: "Martinique", value: "MQ", disabled: false }, + { name: "Mauritania", value: "MR", disabled: false }, + { name: "Mauritius", value: "MU", disabled: false }, + { name: "Mayotte", value: "YT", disabled: false }, + { name: "Mexico", value: "MX", disabled: false }, + { name: "Micronesia, Federated States of", value: "FM", disabled: false }, + { name: "Moldova, Republic of", value: "MD", disabled: false }, + { name: "Monaco", value: "MC", disabled: false }, + { name: "Mongolia", value: "MN", disabled: false }, + { name: "Montenegro", value: "ME", disabled: false }, + { name: "Montserrat", value: "MS", disabled: false }, + { name: "Morocco", value: "MA", disabled: false }, + { name: "Mozambique", value: "MZ", disabled: false }, + { name: "Myanmar", value: "MM", disabled: false }, + { name: "Namibia", value: "NA", disabled: false }, + { name: "Nauru", value: "NR", disabled: false }, + { name: "Nepal", value: "NP", disabled: false }, + { name: "Netherlands", value: "NL", disabled: false }, + { name: "New Caledonia", value: "NC", disabled: false }, + { name: "New Zealand", value: "NZ", disabled: false }, + { name: "Nicaragua", value: "NI", disabled: false }, + { name: "Niger", value: "NE", disabled: false }, + { name: "Nigeria", value: "NG", disabled: false }, + { name: "Niue", value: "NU", disabled: false }, + { name: "Norfolk Island", value: "NF", disabled: false }, + { name: "Northern Mariana Islands", value: "MP", disabled: false }, + { name: "Norway", value: "NO", disabled: false }, + { name: "Oman", value: "OM", disabled: false }, + { name: "Pakistan", value: "PK", disabled: false }, + { name: "Palau", value: "PW", disabled: false }, + { name: "Palestinian Territory, Occupied", value: "PS", disabled: false }, + { name: "Panama", value: "PA", disabled: false }, + { name: "Papua New Guinea", value: "PG", disabled: false }, + { name: "Paraguay", value: "PY", disabled: false }, + { name: "Peru", value: "PE", disabled: false }, + { name: "Philippines", value: "PH", disabled: false }, + { name: "Pitcairn", value: "PN", disabled: false }, + { name: "Poland", value: "PL", disabled: false }, + { name: "Portugal", value: "PT", disabled: false }, + { name: "Puerto Rico", value: "PR", disabled: false }, + { name: "Qatar", value: "QA", disabled: false }, + { name: "Réunion", value: "RE", disabled: false }, + { name: "Romania", value: "RO", disabled: false }, + { name: "Russian Federation", value: "RU", disabled: false }, + { name: "Rwanda", value: "RW", disabled: false }, + { name: "Saint Barthélemy", value: "BL", disabled: false }, + { name: "Saint Helena, Ascension and Tristan da Cunha", value: "SH", disabled: false }, + { name: "Saint Kitts and Nevis", value: "KN", disabled: false }, + { name: "Saint Lucia", value: "LC", disabled: false }, + { name: "Saint Martin (French part)", value: "MF", disabled: false }, + { name: "Saint Pierre and Miquelon", value: "PM", disabled: false }, + { name: "Saint Vincent and the Grenadines", value: "VC", disabled: false }, + { name: "Samoa", value: "WS", disabled: false }, + { name: "San Marino", value: "SM", disabled: false }, + { name: "Sao Tome and Principe", value: "ST", disabled: false }, + { name: "Saudi Arabia", value: "SA", disabled: false }, + { name: "Senegal", value: "SN", disabled: false }, + { name: "Serbia", value: "RS", disabled: false }, + { name: "Seychelles", value: "SC", disabled: false }, + { name: "Sierra Leone", value: "SL", disabled: false }, + { name: "Singapore", value: "SG", disabled: false }, + { name: "Sint Maarten (Dutch part)", value: "SX", disabled: false }, + { name: "Slovakia", value: "SK", disabled: false }, + { name: "Slovenia", value: "SI", disabled: false }, + { name: "Solomon Islands", value: "SB", disabled: false }, + { name: "Somalia", value: "SO", disabled: false }, + { name: "South Africa", value: "ZA", disabled: false }, + { name: "South Georgia and the South Sandwich Islands", value: "GS", disabled: false }, + { name: "South Sudan", value: "SS", disabled: false }, + { name: "Spain", value: "ES", disabled: false }, + { name: "Sri Lanka", value: "LK", disabled: false }, + { name: "Sudan", value: "SD", disabled: false }, + { name: "Suriname", value: "SR", disabled: false }, + { name: "Svalbard and Jan Mayen", value: "SJ", disabled: false }, + { name: "Swaziland", value: "SZ", disabled: false }, + { name: "Sweden", value: "SE", disabled: false }, + { name: "Switzerland", value: "CH", disabled: false }, + { name: "Syrian Arab Republic", value: "SY", disabled: false }, + { name: "Taiwan", value: "TW", disabled: false }, + { name: "Tajikistan", value: "TJ", disabled: false }, + { name: "Tanzania, United Republic of", value: "TZ", disabled: false }, + { name: "Thailand", value: "TH", disabled: false }, + { name: "Timor-Leste", value: "TL", disabled: false }, + { name: "Togo", value: "TG", disabled: false }, + { name: "Tokelau", value: "TK", disabled: false }, + { name: "Tonga", value: "TO", disabled: false }, + { name: "Trinidad and Tobago", value: "TT", disabled: false }, + { name: "Tunisia", value: "TN", disabled: false }, + { name: "Turkey", value: "TR", disabled: false }, + { name: "Turkmenistan", value: "TM", disabled: false }, + { name: "Turks and Caicos Islands", value: "TC", disabled: false }, + { name: "Tuvalu", value: "TV", disabled: false }, + { name: "Uganda", value: "UG", disabled: false }, + { name: "Ukraine", value: "UA", disabled: false }, + { name: "United Arab Emirates", value: "AE", disabled: false }, + { name: "United States Minor Outlying Islands", value: "UM", disabled: false }, + { name: "Uruguay", value: "UY", disabled: false }, + { name: "Uzbekistan", value: "UZ", disabled: false }, + { name: "Vanuatu", value: "VU", disabled: false }, + { name: "Venezuela, Bolivarian Republic of", value: "VE", disabled: false }, + { name: "Viet Nam", value: "VN", disabled: false }, + { name: "Virgin Islands, British", value: "VG", disabled: false }, + { name: "Virgin Islands, U.S.", value: "VI", disabled: false }, + { name: "Wallis and Futuna", value: "WF", disabled: false }, + { name: "Western Sahara", value: "EH", disabled: false }, + { name: "Yemen", value: "YE", disabled: false }, + { name: "Zambia", value: "ZM", disabled: false }, + { name: "Zimbabwe", value: "ZW", disabled: false }, + ]; + } + + async isCountrySupported(country: string): Promise { + const response = await this.apiService.send( + "GET", + "/tax/is-country-supported?country=" + country, + null, + true, + true, + ); + return response; + } + + async previewIndividualInvoice( + request: PreviewIndividualInvoiceRequest, + ): Promise { + const response = await this.apiService.send( + "POST", + "/accounts/billing/preview-invoice", + request, + true, + true, + ); + return new PreviewInvoiceResponse(response); + } + + async previewOrganizationInvoice( + request: PreviewOrganizationInvoiceRequest, + ): Promise { + const response = await this.apiService.send( + "POST", + `/invoices/preview-organization`, + request, + true, + true, + ); + return new PreviewInvoiceResponse(response); + } +} From 5a3681655b04b811f67d0c3b0993b1676425a058 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:28:57 -0500 Subject: [PATCH 23/65] [deps] Platform: Update Rust crate libc to v0.2.169 (#12131) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- apps/desktop/desktop_native/Cargo.lock | 4 ++-- apps/desktop/desktop_native/core/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index e77e66a697c..86c33d34843 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -1508,9 +1508,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.162" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" diff --git a/apps/desktop/desktop_native/core/Cargo.toml b/apps/desktop/desktop_native/core/Cargo.toml index 64ed009ceb5..b4fff01e6b0 100644 --- a/apps/desktop/desktop_native/core/Cargo.toml +++ b/apps/desktop/desktop_native/core/Cargo.toml @@ -31,7 +31,7 @@ base64 = "=0.22.1" byteorder = "=1.5.0" cbc = { version = "=0.1.2", features = ["alloc"] } homedir = "=0.3.4" -libc = "=0.2.162" +libc = "=0.2.169" pin-project = "=1.1.7" dirs = "=5.0.1" futures = "=0.3.31" From 0ae10f0d9bd40470b8e3a0124f65e1122e412238 Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Thu, 2 Jan 2025 14:46:31 -0500 Subject: [PATCH 24/65] fix(safari): make sure to return from bespoke reload clause (#12661) On https://github.com/bitwarden/clients/pull/12326 I refactored and extended a bit of special case logic for process reloads on Safari. This appears to have caused a regression, and I think it's because I didn't return from the function when Safari reloads. This makes it still call `chrome.runtime.reload()`, which makes Safari send an "install" event, which leads to our extension opening it's Getting Started page. This commit returns after the location reload in Safari. This is tricky to test locally as the issue does not appear with sideloaded apps. I'll test it with Testflight! --- apps/browser/src/platform/browser/browser-api.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/browser/src/platform/browser/browser-api.ts b/apps/browser/src/platform/browser/browser-api.ts index dc71d50d4b1..1d8ff65c17d 100644 --- a/apps/browser/src/platform/browser/browser-api.ts +++ b/apps/browser/src/platform/browser/browser-api.ts @@ -458,7 +458,7 @@ export class BrowserApi { // and that prompts us to show a new tab, this apparently doesn't happen on sideloaded // extensions and only shows itself production scenarios. See: https://bitwarden.atlassian.net/browse/PM-12298 if (this.isSafariApi) { - self.location.reload(); + return self.location.reload(); } return chrome.runtime.reload(); } From af4311fa21128af1b2c11ae413db8cdab8d0a61f Mon Sep 17 00:00:00 2001 From: Vince Grassia <593223+vgrassia@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:58:34 -0500 Subject: [PATCH 25/65] BRE-534 - Update workflow to parallelize extension builds (#12640) --- .github/workflows/build-browser.yml | 160 +++++++++++++++------------- 1 file changed, 83 insertions(+), 77 deletions(-) diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index 7740e418e7b..68d1f10a51a 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -114,8 +114,8 @@ jobs: fi - build: - name: Build + build-source: + name: Build browser source runs-on: ubuntu-22.04 needs: - setup @@ -127,7 +127,7 @@ jobs: - name: Check out repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - ref: ${{ github.event.pull_request.head.sha }} + ref: ${{ github.event.pull_request.head.sha }} - name: Set up Node uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 @@ -175,15 +175,85 @@ jobs: path: browser-source.zip if-no-files-found: error + + build: + name: Build + runs-on: ubuntu-22.04 + needs: + - setup + - locales-test + - build-source + env: + _BUILD_NUMBER: ${{ needs.setup.outputs.adj_build_number }} + _NODE_VERSION: ${{ needs.setup.outputs.node_version }} + strategy: + matrix: + include: + - name: "chrome" + npm_command: "dist:chrome" + archive_name: "dist-chrome.zip" + artifact_name: "dist-chrome-MV3" + - name: "edge" + npm_command: "dist:edge" + archive_name: "dist-edge.zip" + artifact_name: "dist-edge" + - name: "edge-mv3" + npm_command: "dist:edge:mv3" + archive_name: "dist-edge.zip" + artifact_name: "DO-NOT-USE-FOR-PROD-dist-edge-MV3" + - name: "firefox" + npm_command: "dist:firefox" + archive_name: "dist-firefox.zip" + artifact_name: "dist-firefox" + - name: "firefox-mv3" + npm_command: "dist:firefox:mv3" + archive_name: "dist-firefox.zip" + artifact_name: "DO-NOT-USE-FOR-PROD-dist-firefox-MV3" + - name: "opera" + npm_command: "dist:opera" + archive_name: "dist-opera.zip" + artifact_name: "dist-opera" + - name: "opera-mv3" + npm_command: "dist:opera:mv3" + archive_name: "dist-opera.zip" + artifact_name: "DO-NOT-USE-FOR-PROD-dist-opera-MV3" + steps: + - name: Check out repo + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: Set up Node + uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0 + with: + cache: 'npm' + cache-dependency-path: '**/package-lock.json' + node-version: ${{ env._NODE_VERSION }} + + - name: Print environment + run: | + node --version + npm --version + + - name: Download browser source + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: browser-source-${{ env._BUILD_NUMBER }}.zip + + - name: Unzip browser source artifact + run: | + unzip browser-source.zip + rm browser-source.zip + - name: NPM setup run: npm ci working-directory: browser-source/ - - name: Download SDK Artifacts + - name: Download SDK artifacts if: ${{ inputs.sdk_branch != '' }} uses: bitwarden/gh-actions/download-artifacts@main with: - github_token: ${{secrets.GITHUB_TOKEN}} + github_token: ${{ secrets.GITHUB_TOKEN }} workflow: build-wasm-internal.yml workflow_conclusion: success branch: ${{ inputs.sdk_branch }} @@ -195,85 +265,19 @@ jobs: - name: Override SDK if: ${{ inputs.sdk_branch != '' }} working-directory: browser-source/ - run: | - npm link ../sdk-internal - - - name: Build Chrome - run: npm run dist:chrome - working-directory: browser-source/apps/browser - - - name: Upload Chrome MV3 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: dist-chrome-MV3-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-chrome.zip - if-no-files-found: error - - - name: Build Edge - run: npm run dist:edge - working-directory: browser-source/apps/browser - - - name: Upload Edge artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: dist-edge-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-edge.zip - if-no-files-found: error - - - name: Build Edge (MV3) - run: npm run dist:edge:mv3 - working-directory: browser-source/apps/browser - - - name: Upload Edge MV3 artifact (DO NOT USE FOR PROD) - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: DO-NOT-USE-FOR-PROD-dist-edge-MV3-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-edge.zip - if-no-files-found: error - - - name: Build Firefox - run: npm run dist:firefox - working-directory: browser-source/apps/browser - - - name: Upload Firefox artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: dist-firefox-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-firefox.zip - if-no-files-found: error + run: npm link ../sdk-internal - - name: Build Firefox (MV3) - run: npm run dist:firefox:mv3 + - name: Build extension + run: npm run ${{ matrix.npm_command }} working-directory: browser-source/apps/browser - - name: Upload Firefox MV3 artifact (DO NOT USE FOR PROD) + - name: Upload extension artifact uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: - name: DO-NOT-USE-FOR-PROD-dist-firefox-MV3-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-firefox.zip + name: ${{ matrix.artifact_name }}-${{ env._BUILD_NUMBER }}.zip + path: browser-source/apps/browser/dist/${{ matrix.archive_name }} if-no-files-found: error - - name: Build Opera - run: npm run dist:opera - working-directory: browser-source/apps/browser - - - name: Upload Opera artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: dist-opera-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-opera.zip - if-no-files-found: error - - - name: Build Opera (MV3) - run: npm run dist:opera:mv3 - working-directory: browser-source/apps/browser - - - name: Upload Opera MV3 artifact (DO NOT USE FOR PROD) - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 - with: - name: DO-NOT-USE-FOR-PROD-dist-opera-MV3-${{ env._BUILD_NUMBER }}.zip - path: browser-source/apps/browser/dist/dist-opera.zip - if-no-files-found: error build-safari: name: Build Safari @@ -448,6 +452,7 @@ jobs: upload_sources: true upload_translations: false + check-failures: name: Check for failures if: always() @@ -455,6 +460,7 @@ jobs: needs: - setup - locales-test + - build-source - build - build-safari - crowdin-push From 15cc4ff1eb936a6da5ba4a7470f6fa07104970bc Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:37:09 -0600 Subject: [PATCH 26/65] [PM-14461] Update organization state after subscription update (#12222) * Update organization state after subscription update * QA: Fix SM trial seat adjustment --- .../adjust-subscription.component.ts | 18 +++++++++++++++++- .../sm-adjust-subscription.component.ts | 14 +++++++++++++- .../organization-api.service.abstraction.ts | 4 ++-- .../organization/organization-api.service.ts | 14 ++++++++------ 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/apps/web/src/app/billing/organizations/adjust-subscription.component.ts b/apps/web/src/app/billing/organizations/adjust-subscription.component.ts index 73dbb0a0026..0166560007e 100644 --- a/apps/web/src/app/billing/organizations/adjust-subscription.component.ts +++ b/apps/web/src/app/billing/organizations/adjust-subscription.component.ts @@ -5,6 +5,8 @@ import { FormBuilder, Validators } from "@angular/forms"; import { Subject, takeUntil } from "rxjs"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { InternalOrganizationServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { OrganizationData } from "@bitwarden/common/admin-console/models/data/organization.data"; import { OrganizationSubscriptionUpdateRequest } from "@bitwarden/common/billing/models/request/organization-subscription-update.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ToastService } from "@bitwarden/components"; @@ -34,6 +36,7 @@ export class AdjustSubscription implements OnInit, OnDestroy { private organizationApiService: OrganizationApiServiceAbstraction, private formBuilder: FormBuilder, private toastService: ToastService, + private internalOrganizationService: InternalOrganizationServiceAbstraction, ) {} ngOnInit() { @@ -64,7 +67,20 @@ export class AdjustSubscription implements OnInit, OnDestroy { this.additionalSeatCount, this.adjustSubscriptionForm.value.newMaxSeats, ); - await this.organizationApiService.updatePasswordManagerSeats(this.organizationId, request); + + const response = await this.organizationApiService.updatePasswordManagerSeats( + this.organizationId, + request, + ); + + const organization = await this.internalOrganizationService.get(this.organizationId); + + const organizationData = new OrganizationData(response, { + isMember: organization.isMember, + isProviderUser: organization.isProviderUser, + }); + + await this.internalOrganizationService.upsert(organizationData); this.toastService.showToast({ variant: "success", diff --git a/apps/web/src/app/billing/organizations/sm-adjust-subscription.component.ts b/apps/web/src/app/billing/organizations/sm-adjust-subscription.component.ts index 4a4f309c68b..fc7a188f967 100644 --- a/apps/web/src/app/billing/organizations/sm-adjust-subscription.component.ts +++ b/apps/web/src/app/billing/organizations/sm-adjust-subscription.component.ts @@ -5,6 +5,8 @@ import { FormBuilder, Validators } from "@angular/forms"; import { Subject, takeUntil } from "rxjs"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { InternalOrganizationServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { OrganizationData } from "@bitwarden/common/admin-console/models/data/organization.data"; import { OrganizationSmSubscriptionUpdateRequest } from "@bitwarden/common/billing/models/request/organization-sm-subscription-update.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -104,6 +106,7 @@ export class SecretsManagerAdjustSubscriptionComponent implements OnInit, OnDest private i18nService: I18nService, private platformUtilsService: PlatformUtilsService, private toastService: ToastService, + private internalOrganizationService: InternalOrganizationServiceAbstraction, ) {} ngOnInit() { @@ -157,11 +160,20 @@ export class SecretsManagerAdjustSubscriptionComponent implements OnInit, OnDest ? this.formGroup.value.maxAutoscaleServiceAccounts : null; - await this.organizationApiService.updateSecretsManagerSubscription( + const response = await this.organizationApiService.updateSecretsManagerSubscription( this.organizationId, request, ); + const organization = await this.internalOrganizationService.get(this.organizationId); + + const organizationData = new OrganizationData(response, { + isMember: organization.isMember, + isProviderUser: organization.isProviderUser, + }); + + await this.internalOrganizationService.upsert(organizationData); + this.toastService.showToast({ variant: "success", title: null, diff --git a/libs/common/src/admin-console/abstractions/organization/organization-api.service.abstraction.ts b/libs/common/src/admin-console/abstractions/organization/organization-api.service.abstraction.ts index 9fd3b358568..0c45c919e95 100644 --- a/libs/common/src/admin-console/abstractions/organization/organization-api.service.abstraction.ts +++ b/libs/common/src/admin-console/abstractions/organization/organization-api.service.abstraction.ts @@ -53,11 +53,11 @@ export class OrganizationApiServiceAbstraction { updatePasswordManagerSeats: ( id: string, request: OrganizationSubscriptionUpdateRequest, - ) => Promise; + ) => Promise; updateSecretsManagerSubscription: ( id: string, request: OrganizationSmSubscriptionUpdateRequest, - ) => Promise; + ) => Promise; updateSeats: (id: string, request: SeatRequest) => Promise; updateStorage: (id: string, request: StorageRequest) => Promise; verifyBank: (id: string, request: VerifyBankRequest) => Promise; diff --git a/libs/common/src/admin-console/services/organization/organization-api.service.ts b/libs/common/src/admin-console/services/organization/organization-api.service.ts index d62fd49a6a4..b3fd11982b8 100644 --- a/libs/common/src/admin-console/services/organization/organization-api.service.ts +++ b/libs/common/src/admin-console/services/organization/organization-api.service.ts @@ -161,27 +161,29 @@ export class OrganizationApiService implements OrganizationApiServiceAbstraction async updatePasswordManagerSeats( id: string, request: OrganizationSubscriptionUpdateRequest, - ): Promise { - return this.apiService.send( + ): Promise { + const r = await this.apiService.send( "POST", "/organizations/" + id + "/subscription", request, true, - false, + true, ); + return new ProfileOrganizationResponse(r); } async updateSecretsManagerSubscription( id: string, request: OrganizationSmSubscriptionUpdateRequest, - ): Promise { - return this.apiService.send( + ): Promise { + const r = await this.apiService.send( "POST", "/organizations/" + id + "/sm-subscription", request, true, - false, + true, ); + return new ProfileOrganizationResponse(r); } async updateSeats(id: string, request: SeatRequest): Promise { From cf9bc7c4555ffe891335774e9d42d19f1c00388d Mon Sep 17 00:00:00 2001 From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com> Date: Thu, 2 Jan 2025 15:37:48 -0600 Subject: [PATCH 27/65] Vault Strict Typing cleanup (#12512) * remove strict types from `NewDeviceVerificationNotice` - Add null default value for class properties - Enforce that the userId is passed - noticeState$ can return null * remove strict types from `CopyCipherFieldService` - refactor title to be a string rather than null * remove strict types from `PasswordRepromptComponent` - add guard to exit early on submit but also solves removing null/undefined from typing * use bang to ensure required input * remove strict types from `CopyCipherFieldDirective` - add bang for required types - add default values for null types * add bang for constant variables in cipher form stories * remove strict types from `DeleteAttachmentComponent` - add bang for required types - refactor title to be an empty string * fix tests --- libs/vault/src/cipher-form/cipher-form.stories.ts | 10 ++++------ .../delete-attachment.component.spec.ts | 2 +- .../delete-attachment/delete-attachment.component.ts | 8 +++----- .../src/components/copy-cipher-field.directive.ts | 10 ++++------ libs/vault/src/components/org-icon.directive.ts | 4 +--- .../src/components/password-reprompt.component.ts | 8 ++++++-- .../src/services/copy-cipher-field.service.spec.ts | 2 +- libs/vault/src/services/copy-cipher-field.service.ts | 4 +--- .../services/new-device-verification-notice.service.ts | 10 ++++------ 9 files changed, 25 insertions(+), 33 deletions(-) diff --git a/libs/vault/src/cipher-form/cipher-form.stories.ts b/libs/vault/src/cipher-form/cipher-form.stories.ts index 98ccdec360e..1d44e4542bc 100644 --- a/libs/vault/src/cipher-form/cipher-form.stories.ts +++ b/libs/vault/src/cipher-form/cipher-form.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { importProvidersFrom } from "@angular/core"; import { action } from "@storybook/addon-actions"; import { @@ -234,7 +232,7 @@ export const Edit: Story = { config: { ...defaultConfig, mode: "edit", - originalCipher: defaultConfig.originalCipher, + originalCipher: defaultConfig.originalCipher!, }, }, }; @@ -245,7 +243,7 @@ export const PartialEdit: Story = { config: { ...defaultConfig, mode: "partial-edit", - originalCipher: defaultConfig.originalCipher, + originalCipher: defaultConfig.originalCipher!, }, }, }; @@ -256,7 +254,7 @@ export const Clone: Story = { config: { ...defaultConfig, mode: "clone", - originalCipher: defaultConfig.originalCipher, + originalCipher: defaultConfig.originalCipher!, }, }, }; @@ -269,7 +267,7 @@ export const NoPersonalOwnership: Story = { mode: "add", allowPersonalOwnership: false, originalCipher: defaultConfig.originalCipher, - organizations: defaultConfig.organizations, + organizations: defaultConfig.organizations!, }, }, }; diff --git a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts index 749093902d7..8e0d4f7a665 100644 --- a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts +++ b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.spec.ts @@ -98,7 +98,7 @@ describe("DeleteAttachmentComponent", () => { expect(showToast).toHaveBeenCalledWith({ variant: "success", - title: null, + title: "", message: "deletedAttachment", }); }); diff --git a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts index d5a7039ad70..b1ada907b1d 100644 --- a/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts +++ b/libs/vault/src/cipher-form/components/attachments/delete-attachment/delete-attachment.component.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { CommonModule } from "@angular/common"; import { Component, EventEmitter, Input, Output } from "@angular/core"; @@ -24,10 +22,10 @@ import { }) export class DeleteAttachmentComponent { /** Id of the cipher associated with the attachment */ - @Input({ required: true }) cipherId: string; + @Input({ required: true }) cipherId!: string; /** The attachment that is can be deleted */ - @Input({ required: true }) attachment: AttachmentView; + @Input({ required: true }) attachment!: AttachmentView; /** Emits when the attachment is successfully deleted */ @Output() onDeletionSuccess = new EventEmitter(); @@ -56,7 +54,7 @@ export class DeleteAttachmentComponent { this.toastService.showToast({ variant: "success", - title: null, + title: "", message: this.i18nService.t("deletedAttachment"), }); diff --git a/libs/vault/src/components/copy-cipher-field.directive.ts b/libs/vault/src/components/copy-cipher-field.directive.ts index 19bf25a2e2e..1eb96a30449 100644 --- a/libs/vault/src/components/copy-cipher-field.directive.ts +++ b/libs/vault/src/components/copy-cipher-field.directive.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Directive, HostBinding, HostListener, Input, OnChanges, Optional } from "@angular/core"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -28,9 +26,9 @@ export class CopyCipherFieldDirective implements OnChanges { alias: "appCopyField", required: true, }) - action: Exclude; + action!: Exclude; - @Input({ required: true }) cipher: CipherView; + @Input({ required: true }) cipher!: CipherView; constructor( private copyCipherFieldService: CopyCipherFieldService, @@ -52,7 +50,7 @@ export class CopyCipherFieldDirective implements OnChanges { @HostListener("click") async copy() { const value = this.getValueToCopy(); - await this.copyCipherFieldService.copy(value, this.action, this.cipher); + await this.copyCipherFieldService.copy(value ?? "", this.action, this.cipher); } async ngOnChanges() { @@ -69,7 +67,7 @@ export class CopyCipherFieldDirective implements OnChanges { // If the directive is used on a menu item, update the menu item to prevent keyboard navigation if (this.menuItemDirective) { - this.menuItemDirective.disabled = this.disabled; + this.menuItemDirective.disabled = this.disabled ?? false; } } diff --git a/libs/vault/src/components/org-icon.directive.ts b/libs/vault/src/components/org-icon.directive.ts index bcf42503760..69a19b46c65 100644 --- a/libs/vault/src/components/org-icon.directive.ts +++ b/libs/vault/src/components/org-icon.directive.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Directive, ElementRef, HostBinding, Input, Renderer2 } from "@angular/core"; import { ProductTierType } from "@bitwarden/common/billing/enums"; @@ -11,7 +9,7 @@ export type OrgIconSize = "default" | "small" | "large"; selector: "[appOrgIcon]", }) export class OrgIconDirective { - @Input({ required: true }) tierType: ProductTierType; + @Input({ required: true }) tierType!: ProductTierType; @Input() size?: OrgIconSize = "default"; constructor( diff --git a/libs/vault/src/components/password-reprompt.component.ts b/libs/vault/src/components/password-reprompt.component.ts index acedcd79b81..abefac58747 100644 --- a/libs/vault/src/components/password-reprompt.component.ts +++ b/libs/vault/src/components/password-reprompt.component.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { DialogRef } from "@angular/cdk/dialog"; import { Component } from "@angular/core"; import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; @@ -51,6 +49,12 @@ export class PasswordRepromptComponent { ) {} submit = async () => { + // Exit early when a master password is not provided. + // The form field required error will be shown to users in these cases. + if (!this.formGroup.value.masterPassword) { + return; + } + const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))); if (userId == null) { diff --git a/libs/vault/src/services/copy-cipher-field.service.spec.ts b/libs/vault/src/services/copy-cipher-field.service.spec.ts index fa148b0e2e3..48510b2efd9 100644 --- a/libs/vault/src/services/copy-cipher-field.service.spec.ts +++ b/libs/vault/src/services/copy-cipher-field.service.spec.ts @@ -76,7 +76,7 @@ describe("CopyCipherFieldService", () => { expect(toastService.showToast).toHaveBeenCalledWith({ variant: "success", message: "Username copied", - title: null, + title: "", }); expect(i18nService.t).toHaveBeenCalledWith("username"); expect(i18nService.t).toHaveBeenCalledWith("valueCopied", "Username"); diff --git a/libs/vault/src/services/copy-cipher-field.service.ts b/libs/vault/src/services/copy-cipher-field.service.ts index 1b3bb6c0a8c..bfcf3495865 100644 --- a/libs/vault/src/services/copy-cipher-field.service.ts +++ b/libs/vault/src/services/copy-cipher-field.service.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Injectable } from "@angular/core"; import { firstValueFrom } from "rxjs"; @@ -131,7 +129,7 @@ export class CopyCipherFieldService { this.toastService.showToast({ variant: "success", message: this.i18nService.t("valueCopied", this.i18nService.t(action.typeI18nKey)), - title: null, + title: "", }); if (action.event !== undefined) { diff --git a/libs/vault/src/services/new-device-verification-notice.service.ts b/libs/vault/src/services/new-device-verification-notice.service.ts index bb096ff0c2c..a925cf09ec3 100644 --- a/libs/vault/src/services/new-device-verification-notice.service.ts +++ b/libs/vault/src/services/new-device-verification-notice.service.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; import { Jsonify } from "type-fest"; @@ -17,8 +15,8 @@ import { UserId } from "@bitwarden/common/types/guid"; // If a user dismisses the notice, use "last_dismissal" to wait 7 days before re-prompting // permanent_dismissal will be checked if the user should never see the notice again export class NewDeviceVerificationNotice { - last_dismissal: Date; - permanent_dismissal: boolean; + last_dismissal: Date | null = null; + permanent_dismissal: boolean | null = null; constructor(obj: Partial) { if (obj == null) { @@ -52,12 +50,12 @@ export class NewDeviceVerificationNoticeService { return this.stateProvider.getUser(userId, NEW_DEVICE_VERIFICATION_NOTICE_KEY); } - noticeState$(userId: UserId): Observable { + noticeState$(userId: UserId): Observable { return this.noticeState(userId).state$; } async updateNewDeviceVerificationNoticeState( - userId: UserId | null, + userId: UserId, newState: NewDeviceVerificationNotice, ): Promise { await this.noticeState(userId).update(() => { From b9660194be665eb42d96252840148f89c232c056 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:38:29 -0500 Subject: [PATCH 28/65] [deps] Platform: Update tsconfig-paths-webpack-plugin to v4.2.0 (#12136) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 9 +++++---- package.json | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ab4e6f1cab..197b7cb0093 100644 --- a/package-lock.json +++ b/package-lock.json @@ -171,7 +171,7 @@ "tailwindcss": "3.4.17", "ts-jest": "29.2.2", "ts-loader": "9.5.1", - "tsconfig-paths-webpack-plugin": "4.1.0", + "tsconfig-paths-webpack-plugin": "4.2.0", "type-fest": "2.19.0", "typescript": "5.4.2", "typescript-strict-plugin": "^2.4.4", @@ -30565,14 +30565,15 @@ } }, "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", - "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==", "dev": true, "license": "MIT", "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.7.0", + "tapable": "^2.2.1", "tsconfig-paths": "^4.1.2" }, "engines": { diff --git a/package.json b/package.json index 513c96c0a2e..907723c3a02 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "tailwindcss": "3.4.17", "ts-jest": "29.2.2", "ts-loader": "9.5.1", - "tsconfig-paths-webpack-plugin": "4.1.0", + "tsconfig-paths-webpack-plugin": "4.2.0", "type-fest": "2.19.0", "typescript": "5.4.2", "typescript-strict-plugin": "^2.4.4", From 10c8a2101a7b973d9c92e509fe33cfd87c9f34d5 Mon Sep 17 00:00:00 2001 From: SmithThe4th Date: Thu, 2 Jan 2025 17:16:33 -0500 Subject: [PATCH 29/65] [PM-12049] Remove usage of ActiveUserState from folder service (#11880) * Migrated folder service from using active user state to single user state Added extra test cases for encrypted folder and decrypted folders Updated derived state to use decrypt with key * Update callers in the web * Update callers in the browser * Update callers in libs * Update callers in cli * Fixed test * Fixed folder state test * Fixed test * removed duplicate activeUserId * Added takewhile operator to only make calls when userId is present * Simplified to accept a single user id instead of an observable * Required userid to be passed from notification service * [PM-15635] Folders not working on desktop (#12333) * Added folders memory state definition * added decrypted folders state * Refactored service to remove derived state * removed combinedstate and added clear decrypted folders to methods * Fixed test * Fixed issue with editing folder on the desktop app * Fixed test * Changed state name * fixed ts strict issue * fixed ts strict issue * fixed ts strict issue * removed unnecessasry null encrypteed folder check * Handle null folderdata * [PM-16197] "Items with No Folder" shows as a folder to edit name and delete (#12470) * Force redcryption anytime encryption state changes * Fixed text file * revert changes * create new object with nofolder instead of modifying exisiting object * Fixed failing test * switched to use memory-large-object * Fixed ts sctrict issue --------- Co-authored-by: Matt Bishop Co-authored-by: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com> --- .../notification.background.spec.ts | 15 +- .../background/notification.background.ts | 22 +- .../sync/foreground-sync.service.spec.ts | 5 +- .../add-edit-folder-dialog.component.spec.ts | 2 +- .../add-edit-folder-dialog.component.ts | 12 +- .../vault-popup-list-filters.service.spec.ts | 11 +- .../vault-popup-list-filters.service.ts | 105 +++++----- .../settings/folders-v2.component.spec.ts | 6 +- .../popup/settings/folders-v2.component.ts | 11 +- .../vault/popup/settings/folders.component.ts | 15 +- .../vault/services/vault-filter.service.ts | 3 +- apps/cli/src/commands/edit.command.ts | 20 +- apps/cli/src/commands/get.command.ts | 15 +- apps/cli/src/commands/list.command.ts | 9 +- apps/cli/src/oss-serve-configurator.ts | 2 + apps/cli/src/vault.program.ts | 2 + apps/cli/src/vault/create.command.ts | 18 +- apps/cli/src/vault/delete.command.ts | 11 +- .../emergency-view-dialog.component.spec.ts | 7 + .../migrate-legacy-encryption.component.ts | 2 +- .../bulk-move-dialog.component.ts | 9 +- .../folder-add-edit.component.ts | 6 +- .../services/vault-filter.service.spec.ts | 3 +- .../services/vault-filter.service.ts | 14 +- .../individual-vault/view.component.spec.ts | 4 + .../vault-filter/vault-filter.service.ts | 3 + .../vault/components/add-edit.component.ts | 8 +- .../components/folder-add-edit.component.ts | 19 +- .../src/vault/components/view.component.ts | 8 +- .../services/vault-filter.service.ts | 12 +- .../src/platform/state/state-definitions.ts | 3 + .../src/platform/sync/core-sync.service.ts | 24 ++- libs/common/src/platform/sync/sync.service.ts | 3 +- .../src/services/notifications.service.ts | 6 +- .../vault-timeout.service.spec.ts | 2 +- .../vault-timeout/vault-timeout.service.ts | 2 +- .../folder/folder-api.service.abstraction.ts | 8 +- .../folder/folder.service.abstraction.ts | 28 +-- .../services/folder/folder-api.service.ts | 14 +- .../services/folder/folder.service.spec.ts | 157 +++++++------- .../vault/services/folder/folder.service.ts | 193 +++++++++++++----- .../services/key-state/folder.state.spec.ts | 64 ++---- .../vault/services/key-state/folder.state.ts | 29 +-- .../src/components/import.component.ts | 10 +- .../individual-vault-export.service.spec.ts | 10 +- .../individual-vault-export.service.ts | 13 +- .../src/services/vault-export.service.spec.ts | 10 +- .../default-cipher-form-config.service.ts | 10 +- .../src/cipher-view/cipher-view.component.ts | 14 +- 49 files changed, 592 insertions(+), 387 deletions(-) diff --git a/apps/browser/src/autofill/background/notification.background.spec.ts b/apps/browser/src/autofill/background/notification.background.spec.ts index e043dbfdd2e..37c05a55a3a 100644 --- a/apps/browser/src/autofill/background/notification.background.spec.ts +++ b/apps/browser/src/autofill/background/notification.background.spec.ts @@ -60,10 +60,18 @@ describe("NotificationBackground", () => { const configService = mock(); const accountService = mock(); + const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>({ + id: "testId" as UserId, + email: "test@example.com", + emailVerified: true, + name: "Test User", + }); + beforeEach(() => { activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Locked); authService = mock(); authService.activeAccountStatus$ = activeAccountStatusMock$; + accountService.activeAccount$ = activeAccountSubject; notificationBackground = new NotificationBackground( autofillService, cipherService, @@ -683,13 +691,6 @@ describe("NotificationBackground", () => { }); describe("saveOrUpdateCredentials", () => { - const activeAccountSubject = new BehaviorSubject<{ id: UserId } & AccountInfo>({ - id: "testId" as UserId, - email: "test@example.com", - emailVerified: true, - name: "Test User", - }); - let getDecryptedCipherByIdSpy: jest.SpyInstance; let getAllDecryptedForUrlSpy: jest.SpyInstance; let updatePasswordSpy: jest.SpyInstance; diff --git a/apps/browser/src/autofill/background/notification.background.ts b/apps/browser/src/autofill/background/notification.background.ts index 0947ce1e1da..5c6ff3c2c8c 100644 --- a/apps/browser/src/autofill/background/notification.background.ts +++ b/apps/browser/src/autofill/background/notification.background.ts @@ -83,6 +83,8 @@ export default class NotificationBackground { getWebVaultUrlForNotification: () => this.getWebVaultUrl(), }; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private autofillService: AutofillService, private cipherService: CipherService, @@ -569,9 +571,7 @@ export default class NotificationBackground { return; } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.activeUserId$); const cipher = await this.cipherService.encrypt(newCipher, activeUserId); try { @@ -611,10 +611,7 @@ export default class NotificationBackground { return; } - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); - + const activeUserId = await firstValueFrom(this.activeUserId$); const cipher = await this.cipherService.encrypt(cipherView, activeUserId); try { // We've only updated the password, no need to broadcast editedCipher message @@ -647,17 +644,15 @@ export default class NotificationBackground { if (Utils.isNullOrWhitespace(folderId) || folderId === "null") { return false; } - - const folders = await firstValueFrom(this.folderService.folderViews$); + const activeUserId = await firstValueFrom(this.activeUserId$); + const folders = await firstValueFrom(this.folderService.folderViews$(activeUserId)); return folders.some((x) => x.id === folderId); } private async getDecryptedCipherById(cipherId: string) { const cipher = await this.cipherService.get(cipherId); if (cipher != null && cipher.type === CipherType.Login) { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.activeUserId$); return await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), @@ -697,7 +692,8 @@ export default class NotificationBackground { * Returns the first value found from the folder service's folderViews$ observable. */ private async getFolderData() { - return await firstValueFrom(this.folderService.folderViews$); + const activeUserId = await firstValueFrom(this.activeUserId$); + return await firstValueFrom(this.folderService.folderViews$(activeUserId)); } private async getWebVaultUrl(): Promise { diff --git a/apps/browser/src/platform/sync/foreground-sync.service.spec.ts b/apps/browser/src/platform/sync/foreground-sync.service.spec.ts index e1e921cc3a3..f5daff93815 100644 --- a/apps/browser/src/platform/sync/foreground-sync.service.spec.ts +++ b/apps/browser/src/platform/sync/foreground-sync.service.spec.ts @@ -3,7 +3,6 @@ import { Subject } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; @@ -30,12 +29,12 @@ describe("ForegroundSyncService", () => { const cipherService = mock(); const collectionService = mock(); const apiService = mock(); - const accountService = mock(); + const accountService = mockAccountServiceWith(userId); const authService = mock(); const sendService = mock(); const sendApiService = mock(); const messageListener = mock(); - const stateProvider = new FakeStateProvider(mockAccountServiceWith(userId)); + const stateProvider = new FakeStateProvider(accountService); const sut = new ForegroundSyncService( stateService, diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts index 4e222a554f7..cbec7903031 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.spec.ts @@ -171,7 +171,7 @@ describe("AddEditFolderDialogComponent", () => { it("deletes the folder", async () => { await component.deleteFolder(); - expect(deleteFolder).toHaveBeenCalledWith(folderView.id); + expect(deleteFolder).toHaveBeenCalledWith(folderView.id, ""); expect(showToast).toHaveBeenCalledWith({ variant: "success", title: null, diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts b/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts index 5fbd54d9d78..a50403cea2d 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit-folder-dialog/add-edit-folder-dialog.component.ts @@ -13,7 +13,7 @@ import { } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; -import { firstValueFrom } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -67,6 +67,7 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { name: ["", Validators.required], }); + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); private destroyRef = inject(DestroyRef); constructor( @@ -114,10 +115,10 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { this.folder.name = this.folderForm.controls.name.value; try { - const activeUserId = await firstValueFrom(this.accountService.activeAccount$); - const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId.id); + const activeUserId = await firstValueFrom(this.activeUserId$); + const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const folder = await this.folderService.encrypt(this.folder, userKey); - await this.folderApiService.save(folder); + await this.folderApiService.save(folder, activeUserId); this.toastService.showToast({ variant: "success", @@ -144,7 +145,8 @@ export class AddEditFolderDialogComponent implements AfterViewInit, OnInit { } try { - await this.folderApiService.delete(this.folder.id); + const activeUserId = await firstValueFrom(this.activeUserId$); + await this.folderApiService.delete(this.folder.id, activeUserId); this.toastService.showToast({ variant: "success", title: null, diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts index 580514de610..0eb91c6cbe2 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts @@ -7,9 +7,12 @@ import { OrganizationService } from "@bitwarden/common/admin-console/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 { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { StateProvider } from "@bitwarden/common/platform/state"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -32,7 +35,7 @@ describe("VaultPopupListFiltersService", () => { } as unknown as CollectionService; const folderService = { - folderViews$, + folderViews$: () => folderViews$, } as unknown as FolderService; const cipherService = { @@ -60,6 +63,8 @@ describe("VaultPopupListFiltersService", () => { policyAppliesToActiveUser$.next(false); policyService.policyAppliesToActiveUser$.mockClear(); + const accountService = mockAccountServiceWith("userId" as UserId); + collectionService.getAllNested = () => Promise.resolve([]); TestBed.configureTestingModule({ providers: [ @@ -92,6 +97,10 @@ describe("VaultPopupListFiltersService", () => { useValue: { getGlobal: () => ({ state$, update }) }, }, { provide: FormBuilder, useClass: FormBuilder }, + { + provide: AccountService, + useValue: accountService, + }, ], }); diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts index 0ab08d01e46..8455fd587d0 100644 --- a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts +++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts @@ -20,6 +20,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/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 { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -102,6 +103,8 @@ export class VaultPopupListFiltersService { map((ciphers) => Object.values(ciphers)), ); + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private folderService: FolderService, private cipherService: CipherService, @@ -111,6 +114,7 @@ export class VaultPopupListFiltersService { private formBuilder: FormBuilder, private policyService: PolicyService, private stateProvider: StateProvider, + private accountService: AccountService, ) { this.filterForm.controls.organization.valueChanges .pipe(takeUntilDestroyed()) @@ -264,60 +268,67 @@ export class VaultPopupListFiltersService { /** * Folder array structured to be directly passed to `ChipSelectComponent` */ - folders$: Observable[]> = combineLatest([ - this.filters$.pipe( - distinctUntilChanged( - (previousFilter, currentFilter) => - // Only update the collections when the organizationId filter changes - previousFilter.organization?.id === currentFilter.organization?.id, - ), - ), - this.folderService.folderViews$, - this.cipherViews$, - ]).pipe( - map(([filters, folders, cipherViews]): [PopupListFilter, FolderView[], CipherView[]] => { - if (folders.length === 1 && folders[0].id === null) { - // Do not display folder selections when only the "no folder" option is available. - return [filters, [], cipherViews]; - } + folders$: Observable[]> = this.activeUserId$.pipe( + switchMap((userId) => + combineLatest([ + this.filters$.pipe( + distinctUntilChanged( + (previousFilter, currentFilter) => + // Only update the collections when the organizationId filter changes + previousFilter.organization?.id === currentFilter.organization?.id, + ), + ), + this.folderService.folderViews$(userId), + this.cipherViews$, + ]).pipe( + map(([filters, folders, cipherViews]): [PopupListFilter, FolderView[], CipherView[]] => { + if (folders.length === 1 && folders[0].id === null) { + // Do not display folder selections when only the "no folder" option is available. + return [filters, [], cipherViews]; + } - // Sort folders by alphabetic name - folders.sort(Utils.getSortFunction(this.i18nService, "name")); - let arrangedFolders = folders; + // Sort folders by alphabetic name + folders.sort(Utils.getSortFunction(this.i18nService, "name")); + let arrangedFolders = folders; - const noFolder = folders.find((f) => f.id === null); + const noFolder = folders.find((f) => f.id === null); - if (noFolder) { - // Update `name` of the "no folder" option to "Items with no folder" - noFolder.name = this.i18nService.t("itemsWithNoFolder"); + if (noFolder) { + // Update `name` of the "no folder" option to "Items with no folder" + const updatedNoFolder = { + ...noFolder, + name: this.i18nService.t("itemsWithNoFolder"), + }; - // Move the "no folder" option to the end of the list - arrangedFolders = [...folders.filter((f) => f.id !== null), noFolder]; - } - return [filters, arrangedFolders, cipherViews]; - }), - map(([filters, folders, cipherViews]) => { - const organizationId = filters.organization?.id ?? null; + // Move the "no folder" option to the end of the list + arrangedFolders = [...folders.filter((f) => f.id !== null), updatedNoFolder]; + } + return [filters, arrangedFolders, cipherViews]; + }), + map(([filters, folders, cipherViews]) => { + const organizationId = filters.organization?.id ?? null; - // When no org or "My vault" is selected, return all folders - if (organizationId === null || organizationId === MY_VAULT_ID) { - return folders; - } + // When no org or "My vault" is selected, return all folders + if (organizationId === null || organizationId === MY_VAULT_ID) { + return folders; + } - const orgCiphers = cipherViews.filter((c) => c.organizationId === organizationId); + const orgCiphers = cipherViews.filter((c) => c.organizationId === organizationId); - // Return only the folders that have ciphers within the filtered organization - return folders.filter((f) => orgCiphers.some((oc) => oc.folderId === f.id)); - }), - map((folders) => { - const nestedFolders = this.getAllFoldersNested(folders); - return new DynamicTreeNode({ - fullList: folders, - nestedList: nestedFolders, - }); - }), - map((folders) => - folders.nestedList.map((f) => this.convertToChipSelectOption(f, "bwi-folder")), + // Return only the folders that have ciphers within the filtered organization + return folders.filter((f) => orgCiphers.some((oc) => oc.folderId === f.id)); + }), + map((folders) => { + const nestedFolders = this.getAllFoldersNested(folders); + return new DynamicTreeNode({ + fullList: folders, + nestedList: nestedFolders, + }); + }), + map((folders) => + folders.nestedList.map((f) => this.convertToChipSelectOption(f, "bwi-folder")), + ), + ), ), ); diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts b/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts index eecad04613e..9c202e26fef 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.spec.ts @@ -4,10 +4,13 @@ import { By } from "@angular/platform-browser"; import { mock } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { DialogService } from "@bitwarden/components"; @@ -52,8 +55,9 @@ describe("FoldersV2Component", () => { { provide: PlatformUtilsService, useValue: mock() }, { provide: ConfigService, useValue: mock() }, { provide: LogService, useValue: mock() }, - { provide: FolderService, useValue: { folderViews$ } }, + { provide: FolderService, useValue: { folderViews$: () => folderViews$ } }, { provide: I18nService, useValue: { t: (key: string) => key } }, + { provide: AccountService, useValue: mockAccountServiceWith("UserId" as UserId) }, ], }) .overrideComponent(FoldersV2Component, { diff --git a/apps/browser/src/vault/popup/settings/folders-v2.component.ts b/apps/browser/src/vault/popup/settings/folders-v2.component.ts index ce196132f88..b1db949f2ee 100644 --- a/apps/browser/src/vault/popup/settings/folders-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/folders-v2.component.ts @@ -1,8 +1,10 @@ import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; -import { map, Observable } from "rxjs"; +import { filter, map, Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { @@ -45,18 +47,21 @@ export class FoldersV2Component { folders$: Observable; NoFoldersIcon = VaultIcons.NoFolders; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); constructor( private folderService: FolderService, private dialogService: DialogService, + private accountService: AccountService, ) { - this.folders$ = this.folderService.folderViews$.pipe( + this.folders$ = this.activeUserId$.pipe( + filter((userId): userId is UserId => userId !== null), + switchMap((userId) => this.folderService.folderViews$(userId)), map((folders) => { // Remove the last folder, which is the "no folder" option folder if (folders.length > 0) { return folders.slice(0, folders.length - 1); } - return folders; }), ); diff --git a/apps/browser/src/vault/popup/settings/folders.component.ts b/apps/browser/src/vault/popup/settings/folders.component.ts index edf7fe939e8..1e3f182b43d 100644 --- a/apps/browser/src/vault/popup/settings/folders.component.ts +++ b/apps/browser/src/vault/popup/settings/folders.component.ts @@ -1,7 +1,9 @@ import { Component } from "@angular/core"; import { Router } from "@angular/router"; -import { map, Observable } from "rxjs"; +import { filter, map, Observable, switchMap } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; @@ -12,16 +14,21 @@ import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; export class FoldersComponent { folders$: Observable; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private folderService: FolderService, private router: Router, + private accountService: AccountService, ) { - this.folders$ = this.folderService.folderViews$.pipe( + this.folders$ = this.activeUserId$.pipe( + filter((userId): userId is UserId => userId != null), + switchMap((userId) => this.folderService.folderViews$(userId)), map((folders) => { + // Remove the last folder, which is the "no folder" option folder if (folders.length > 0) { - folders = folders.slice(0, folders.length - 1); + return folders.slice(0, folders.length - 1); } - return folders; }), ); diff --git a/apps/browser/src/vault/services/vault-filter.service.ts b/apps/browser/src/vault/services/vault-filter.service.ts index ba1d11f5d27..305c7de487b 100644 --- a/apps/browser/src/vault/services/vault-filter.service.ts +++ b/apps/browser/src/vault/services/vault-filter.service.ts @@ -24,7 +24,7 @@ export class VaultFilterService extends BaseVaultFilterService { collectionService: CollectionService, policyService: PolicyService, stateProvider: StateProvider, - private accountService: AccountService, + accountService: AccountService, ) { super( organizationService, @@ -33,6 +33,7 @@ export class VaultFilterService extends BaseVaultFilterService { collectionService, policyService, stateProvider, + accountService, ); this.vaultFilter.myVaultOnly = false; this.vaultFilter.selectedOrganizationId = null; diff --git a/apps/cli/src/commands/edit.command.ts b/apps/cli/src/commands/edit.command.ts index da7c98a35d6..dd99d03b086 100644 --- a/apps/cli/src/commands/edit.command.ts +++ b/apps/cli/src/commands/edit.command.ts @@ -24,6 +24,8 @@ import { CipherResponse } from "../vault/models/cipher.response"; import { FolderResponse } from "../vault/models/folder.response"; export class EditCommand { + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private cipherService: CipherService, private folderService: FolderService, @@ -121,12 +123,12 @@ export class EditCommand { cipher.collectionIds = req; try { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); const updatedCipher = await this.cipherService.saveCollectionsWithServer(cipher); const decCipher = await updatedCipher.decrypt( - await this.cipherService.getKeyForCipherKeyDecryption(updatedCipher, activeUserId), + await this.cipherService.getKeyForCipherKeyDecryption( + updatedCipher, + await firstValueFrom(this.activeUserId$), + ), ); const res = new CipherResponse(decCipher); return Response.success(res); @@ -136,7 +138,8 @@ export class EditCommand { } private async editFolder(id: string, req: FolderExport) { - const folder = await this.folderService.getFromState(id); + const activeUserId = await firstValueFrom(this.activeUserId$); + const folder = await this.folderService.getFromState(id, activeUserId); if (folder == null) { return Response.notFound(); } @@ -144,12 +147,11 @@ export class EditCommand { let folderView = await folder.decrypt(); folderView = FolderExport.toView(req, folderView); - const activeUserId = await firstValueFrom(this.accountService.activeAccount$); - const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId.id); + const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const encFolder = await this.folderService.encrypt(folderView, userKey); try { - await this.folderApiService.save(encFolder); - const updatedFolder = await this.folderService.get(folder.id); + await this.folderApiService.save(encFolder, activeUserId); + const updatedFolder = await this.folderService.get(folder.id, activeUserId); const decFolder = await updatedFolder.decrypt(); const res = new FolderResponse(decFolder); return Response.success(res); diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index 1a835befd01..7c3cc7caa9f 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -51,6 +51,8 @@ import { FolderResponse } from "../vault/models/folder.response"; import { DownloadCommand } from "./download.command"; export class GetCommand extends DownloadCommand { + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private cipherService: CipherService, private folderService: FolderService, @@ -113,10 +115,8 @@ export class GetCommand extends DownloadCommand { let decCipher: CipherView = null; if (Utils.isGuid(id)) { const cipher = await this.cipherService.get(id); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); if (cipher != null) { + const activeUserId = await firstValueFrom(this.activeUserId$); decCipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); @@ -383,13 +383,14 @@ export class GetCommand extends DownloadCommand { private async getFolder(id: string) { let decFolder: FolderView = null; + const activeUserId = await firstValueFrom(this.activeUserId$); if (Utils.isGuid(id)) { - const folder = await this.folderService.getFromState(id); + const folder = await this.folderService.getFromState(id, activeUserId); if (folder != null) { decFolder = await folder.decrypt(); } } else if (id.trim() !== "") { - let folders = await this.folderService.getAllDecryptedFromState(); + let folders = await this.folderService.getAllDecryptedFromState(activeUserId); folders = CliUtils.searchFolders(folders, id); if (folders.length > 1) { return Response.multipleResults(folders.map((f) => f.id)); @@ -551,9 +552,7 @@ export class GetCommand extends DownloadCommand { private async getFingerprint(id: string) { let fingerprint: string[] = null; if (id === "me") { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.activeUserId$); const publicKey = await firstValueFrom(this.keyService.userPublicKey$(activeUserId)); fingerprint = await this.keyService.getFingerprint(activeUserId, publicKey); } else if (Utils.isGuid(id)) { diff --git a/apps/cli/src/commands/list.command.ts b/apps/cli/src/commands/list.command.ts index 9cb36f71496..92da86b696a 100644 --- a/apps/cli/src/commands/list.command.ts +++ b/apps/cli/src/commands/list.command.ts @@ -1,4 +1,4 @@ -import { firstValueFrom } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { OrganizationUserApiService, @@ -12,6 +12,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { EventType } from "@bitwarden/common/enums"; import { ListResponse as ApiListResponse } from "@bitwarden/common/models/response/list.response"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -38,6 +39,7 @@ export class ListCommand { private organizationUserApiService: OrganizationUserApiService, private apiService: ApiService, private eventCollectionService: EventCollectionService, + private accountService: AccountService, ) {} async run(object: string, cmdOptions: Record): Promise { @@ -135,7 +137,10 @@ export class ListCommand { } private async listFolders(options: Options) { - let folders = await this.folderService.getAllDecryptedFromState(); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.id)), + ); + let folders = await this.folderService.getAllDecryptedFromState(activeUserId); if (options.search != null && options.search.trim() !== "") { folders = CliUtils.searchFolders(folders, options.search); diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index 71c372ef301..9bd3a2bee5f 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -76,6 +76,7 @@ export class OssServeConfigurator { this.serviceContainer.organizationUserApiService, this.serviceContainer.apiService, this.serviceContainer.eventCollectionService, + this.serviceContainer.accountService, ); this.createCommand = new CreateCommand( this.serviceContainer.cipherService, @@ -115,6 +116,7 @@ export class OssServeConfigurator { this.serviceContainer.folderApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.cipherAuthorizationService, + this.serviceContainer.accountService, ); this.confirmCommand = new ConfirmCommand( this.serviceContainer.apiService, diff --git a/apps/cli/src/vault.program.ts b/apps/cli/src/vault.program.ts index 1cdf23bcd89..3eb0e68de09 100644 --- a/apps/cli/src/vault.program.ts +++ b/apps/cli/src/vault.program.ts @@ -113,6 +113,7 @@ export class VaultProgram extends BaseProgram { this.serviceContainer.organizationUserApiService, this.serviceContainer.apiService, this.serviceContainer.eventCollectionService, + this.serviceContainer.accountService, ); const response = await command.run(object, cmd); @@ -321,6 +322,7 @@ export class VaultProgram extends BaseProgram { this.serviceContainer.folderApiService, this.serviceContainer.billingAccountProfileStateService, this.serviceContainer.cipherAuthorizationService, + this.serviceContainer.accountService, ); const response = await command.run(object, id, cmd); this.processResponse(response); diff --git a/apps/cli/src/vault/create.command.ts b/apps/cli/src/vault/create.command.ts index aa01ec3c491..47e91cb55ff 100644 --- a/apps/cli/src/vault/create.command.ts +++ b/apps/cli/src/vault/create.command.ts @@ -30,6 +30,8 @@ import { CipherResponse } from "./models/cipher.response"; import { FolderResponse } from "./models/folder.response"; export class CreateCommand { + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private cipherService: CipherService, private folderService: FolderService, @@ -86,9 +88,7 @@ export class CreateCommand { } private async createCipher(req: CipherExport) { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.activeUserId$); const cipher = await this.cipherService.encrypt(CipherExport.toView(req), activeUserId); try { const newCipher = await this.cipherService.createWithServer(cipher); @@ -152,9 +152,7 @@ export class CreateCommand { } try { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.activeUserId$); const updatedCipher = await this.cipherService.saveAttachmentRawWithServer( cipher, fileName, @@ -171,12 +169,12 @@ export class CreateCommand { } private async createFolder(req: FolderExport) { - const activeAccountId = await firstValueFrom(this.accountService.activeAccount$); - const userKey = await this.keyService.getUserKeyWithLegacySupport(activeAccountId.id); + const activeUserId = await firstValueFrom(this.activeUserId$); + const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const folder = await this.folderService.encrypt(FolderExport.toView(req), userKey); try { - await this.folderApiService.save(folder); - const newFolder = await this.folderService.get(folder.id); + await this.folderApiService.save(folder, activeUserId); + const newFolder = await this.folderService.get(folder.id, activeUserId); const decFolder = await newFolder.decrypt(); const res = new FolderResponse(decFolder); return Response.success(res); diff --git a/apps/cli/src/vault/delete.command.ts b/apps/cli/src/vault/delete.command.ts index 7f79c89b17c..6b66b8bc7bb 100644 --- a/apps/cli/src/vault/delete.command.ts +++ b/apps/cli/src/vault/delete.command.ts @@ -1,6 +1,7 @@ -import { firstValueFrom } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -19,6 +20,7 @@ export class DeleteCommand { private folderApiService: FolderApiServiceAbstraction, private accountProfileService: BillingAccountProfileStateService, private cipherAuthorizationService: CipherAuthorizationService, + private accountService: AccountService, ) {} async run(object: string, id: string, cmdOptions: Record): Promise { @@ -103,13 +105,16 @@ export class DeleteCommand { } private async deleteFolder(id: string) { - const folder = await this.folderService.getFromState(id); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.id)), + ); + const folder = await this.folderService.getFromState(id, activeUserId); if (folder == null) { return Response.notFound(); } try { - await this.folderApiService.delete(id); + await this.folderApiService.delete(id, activeUserId); return Response.success(); } catch (e) { return Response.error(e); diff --git a/apps/web/src/app/auth/settings/emergency-access/view/emergency-view-dialog.component.spec.ts b/apps/web/src/app/auth/settings/emergency-access/view/emergency-view-dialog.component.spec.ts index 341e44f643b..0ad7eef81be 100644 --- a/apps/web/src/app/auth/settings/emergency-access/view/emergency-view-dialog.component.spec.ts +++ b/apps/web/src/app/auth/settings/emergency-access/view/emergency-view-dialog.component.spec.ts @@ -6,7 +6,11 @@ import { mock } from "jest-mock-extended"; import { CollectionService } from "@bitwarden/admin-console/common"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +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 { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -29,6 +33,8 @@ describe("EmergencyViewDialogComponent", () => { card: {}, } as CipherView; + const accountService: FakeAccountService = mockAccountServiceWith(Utils.newGuid() as UserId); + beforeEach(async () => { open.mockClear(); close.mockClear(); @@ -43,6 +49,7 @@ describe("EmergencyViewDialogComponent", () => { { provide: DialogService, useValue: { open } }, { provide: DialogRef, useValue: { close } }, { provide: DIALOG_DATA, useValue: { cipher: mockCipher } }, + { provide: AccountService, useValue: accountService }, ], }).compileComponents(); diff --git a/apps/web/src/app/key-management/migrate-encryption/migrate-legacy-encryption.component.ts b/apps/web/src/app/key-management/migrate-encryption/migrate-legacy-encryption.component.ts index bb5a1c511c6..2361293fe80 100644 --- a/apps/web/src/app/key-management/migrate-encryption/migrate-legacy-encryption.component.ts +++ b/apps/web/src/app/key-management/migrate-encryption/migrate-legacy-encryption.component.ts @@ -83,7 +83,7 @@ export class MigrateFromLegacyEncryptionComponent { }); if (deleteFolders) { - await this.folderApiService.deleteAll(); + await this.folderApiService.deleteAll(activeUser.id); await this.syncService.fullSync(true, true); await this.submit(); return; diff --git a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts index d68e3b9d732..b7f99fb7b44 100644 --- a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts +++ b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-move-dialog/bulk-move-dialog.component.ts @@ -3,8 +3,9 @@ import { DialogConfig, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; import { Component, Inject, OnInit } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; -import { firstValueFrom, Observable } from "rxjs"; +import { firstValueFrom, map, Observable } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -47,6 +48,8 @@ export class BulkMoveDialogComponent implements OnInit { }); folders$: Observable; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( @Inject(DIALOG_DATA) params: BulkMoveDialogParams, private dialogRef: DialogRef, @@ -55,12 +58,14 @@ export class BulkMoveDialogComponent implements OnInit { private i18nService: I18nService, private folderService: FolderService, private formBuilder: FormBuilder, + private accountService: AccountService, ) { this.cipherIds = params.cipherIds ?? []; } async ngOnInit() { - this.folders$ = this.folderService.folderViews$; + const activeUserId = await firstValueFrom(this.activeUserId$); + this.folders$ = this.folderService.folderViews$(activeUserId); this.formGroup.patchValue({ folderId: (await firstValueFrom(this.folders$))[0].id, }); diff --git a/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts b/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts index 4d181a0510d..88af1ef601b 100644 --- a/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts +++ b/apps/web/src/app/vault/individual-vault/folder-add-edit.component.ts @@ -61,7 +61,7 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent { } try { - await this.folderApiService.delete(this.folder.id); + await this.folderApiService.delete(this.folder.id, await firstValueFrom(this.activeUserId$)); this.toastService.showToast({ variant: "success", title: null, @@ -82,10 +82,10 @@ export class FolderAddEditComponent extends BaseFolderAddEditComponent { } try { - const activeAccountId = (await firstValueFrom(this.accountSerivce.activeAccount$)).id; + const activeAccountId = await firstValueFrom(this.activeUserId$); const userKey = await this.keyService.getUserKeyWithLegacySupport(activeAccountId); const folder = await this.folderService.encrypt(this.folder, userKey); - this.formPromise = this.folderApiService.save(folder); + this.formPromise = this.folderApiService.save(folder, activeAccountId); await this.formPromise; this.platformUtilsService.showToast( "success", diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.spec.ts b/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.spec.ts index 0386a20adbb..47003d51cae 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.spec.ts +++ b/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.spec.ts @@ -63,7 +63,7 @@ describe("vault filter service", () => { singleOrgPolicy = new ReplaySubject(1); organizationService.memberOrganizations$ = organizations; - folderService.folderViews$ = folderViews; + folderService.folderViews$.mockReturnValue(folderViews); collectionService.decryptedCollections$ = collectionViews; policyService.policyAppliesToActiveUser$ .calledWith(PolicyType.PersonalOwnership) @@ -81,6 +81,7 @@ describe("vault filter service", () => { i18nService, stateProvider, collectionService, + accountService, ); collapsedGroupingsState = stateProvider.activeUser.getFake(COLLAPSED_GROUPINGS); }); diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.ts b/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.ts index c4ac3dc2d70..97b44132e60 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.ts +++ b/apps/web/src/app/vault/individual-vault/vault-filter/services/vault-filter.service.ts @@ -21,6 +21,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ActiveUserState, StateProvider } from "@bitwarden/common/platform/state"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -45,6 +46,8 @@ const NestingDelimiter = "/"; @Injectable() export class VaultFilterService implements VaultFilterServiceAbstraction { + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + organizationTree$: Observable> = combineLatest([ this.organizationService.memberOrganizations$, this.policyService.policyAppliesToActiveUser$(PolicyType.SingleOrg), @@ -57,8 +60,14 @@ export class VaultFilterService implements VaultFilterServiceAbstraction { protected _organizationFilter = new BehaviorSubject(null); - filteredFolders$: Observable = this.folderService.folderViews$.pipe( - combineLatestWith(this.cipherService.cipherViews$, this._organizationFilter), + filteredFolders$: Observable = this.activeUserId$.pipe( + switchMap((userId) => + combineLatest([ + this.folderService.folderViews$(userId), + this.cipherService.cipherViews$, + this._organizationFilter, + ]), + ), switchMap(([folders, ciphers, org]) => { return this.filterFolders(folders, ciphers, org); }), @@ -95,6 +104,7 @@ export class VaultFilterService implements VaultFilterServiceAbstraction { protected i18nService: I18nService, protected stateProvider: StateProvider, protected collectionService: CollectionService, + protected accountService: AccountService, ) {} async getCollectionNodeFromTree(id: string) { diff --git a/apps/web/src/app/vault/individual-vault/view.component.spec.ts b/apps/web/src/app/vault/individual-vault/view.component.spec.ts index b26c55d46e8..bde9f564c4a 100644 --- a/apps/web/src/app/vault/individual-vault/view.component.spec.ts +++ b/apps/web/src/app/vault/individual-vault/view.component.spec.ts @@ -5,11 +5,14 @@ import { mock } from "jest-mock-extended"; import { CollectionService } from "@bitwarden/admin-console/common"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; +import { mockAccountServiceWith } from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -63,6 +66,7 @@ describe("ViewComponent", () => { useValue: mock(), }, { provide: ConfigService, useValue: mock() }, + { provide: AccountService, useValue: mockAccountServiceWith("UserId" as UserId) }, { provide: CipherAuthorizationService, useValue: { diff --git a/apps/web/src/app/vault/org-vault/vault-filter/vault-filter.service.ts b/apps/web/src/app/vault/org-vault/vault-filter/vault-filter.service.ts index c4ac9d73df7..e2d713649f5 100644 --- a/apps/web/src/app/vault/org-vault/vault-filter/vault-filter.service.ts +++ b/apps/web/src/app/vault/org-vault/vault-filter/vault-filter.service.ts @@ -4,6 +4,7 @@ import { map, Observable, ReplaySubject, Subject } from "rxjs"; import { CollectionAdminView, CollectionService } from "@bitwarden/admin-console/common"; 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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { StateProvider } from "@bitwarden/common/platform/state"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; @@ -32,6 +33,7 @@ export class VaultFilterService extends BaseVaultFilterService implements OnDest i18nService: I18nService, stateProvider: StateProvider, collectionService: CollectionService, + accountService: AccountService, ) { super( organizationService, @@ -41,6 +43,7 @@ export class VaultFilterService extends BaseVaultFilterService implements OnDest i18nService, stateProvider, collectionService, + accountService, ); } diff --git a/libs/angular/src/vault/components/add-edit.component.ts b/libs/angular/src/vault/components/add-edit.component.ts index 3a9d0289971..4bd3e9710fb 100644 --- a/libs/angular/src/vault/components/add-edit.component.ts +++ b/libs/angular/src/vault/components/add-edit.component.ts @@ -102,6 +102,8 @@ export class AddEditComponent implements OnInit, OnDestroy { private personalOwnershipPolicyAppliesToActiveUser: boolean; private previousCipherId: string; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + get fido2CredentialCreationDateValue(): string { const dateCreated = this.i18nService.t("dateCreated"); const creationDate = this.datePipe.transform( @@ -259,12 +261,10 @@ export class AddEditComponent implements OnInit, OnDestroy { const loadedAddEditCipherInfo = await this.loadAddEditCipherInfo(); + const activeUserId = await firstValueFrom(this.activeUserId$); if (this.cipher == null) { if (this.editMode) { const cipher = await this.loadCipher(); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); this.cipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); @@ -323,7 +323,7 @@ export class AddEditComponent implements OnInit, OnDestroy { this.cipher.login.fido2Credentials = null; } - this.folders$ = this.folderService.folderViews$; + this.folders$ = this.folderService.folderViews$(activeUserId); if (this.editMode && this.previousCipherId !== this.cipherId) { void this.eventCollectionService.collectMany(EventType.Cipher_ClientViewed, [this.cipher]); diff --git a/libs/angular/src/vault/components/folder-add-edit.component.ts b/libs/angular/src/vault/components/folder-add-edit.component.ts index 6d9ae53cc66..205733ba48d 100644 --- a/libs/angular/src/vault/components/folder-add-edit.component.ts +++ b/libs/angular/src/vault/components/folder-add-edit.component.ts @@ -2,7 +2,7 @@ // @ts-strict-ignore import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core"; import { Validators, FormBuilder } from "@angular/forms"; -import { firstValueFrom } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -27,6 +27,8 @@ export class FolderAddEditComponent implements OnInit { deletePromise: Promise; protected componentName = ""; + protected activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + formGroup = this.formBuilder.group({ name: ["", [Validators.required]], }); @@ -59,10 +61,10 @@ export class FolderAddEditComponent implements OnInit { } try { - const activeAccountId = await firstValueFrom(this.accountService.activeAccount$); - const userKey = await this.keyService.getUserKeyWithLegacySupport(activeAccountId.id); + const activeUserId = await firstValueFrom(this.activeUserId$); + const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const folder = await this.folderService.encrypt(this.folder, userKey); - this.formPromise = this.folderApiService.save(folder); + this.formPromise = this.folderApiService.save(folder, activeUserId); await this.formPromise; this.platformUtilsService.showToast( "success", @@ -90,7 +92,8 @@ export class FolderAddEditComponent implements OnInit { } try { - this.deletePromise = this.folderApiService.delete(this.folder.id); + const activeUserId = await firstValueFrom(this.activeUserId$); + this.deletePromise = this.folderApiService.delete(this.folder.id, activeUserId); await this.deletePromise; this.platformUtilsService.showToast("success", null, this.i18nService.t("deletedFolder")); this.onDeletedFolder.emit(this.folder); @@ -107,8 +110,10 @@ export class FolderAddEditComponent implements OnInit { if (this.editMode) { this.editMode = true; this.title = this.i18nService.t("editFolder"); - const folder = await this.folderService.get(this.folderId); - this.folder = await folder.decrypt(); + const activeUserId = await firstValueFrom(this.activeUserId$); + this.folder = await firstValueFrom( + this.folderService.getDecrypted$(this.folderId, activeUserId), + ); } else { this.title = this.i18nService.t("addFolder"); } diff --git a/libs/angular/src/vault/components/view.component.ts b/libs/angular/src/vault/components/view.component.ts index a6b9a571730..6bea4cd6150 100644 --- a/libs/angular/src/vault/components/view.component.ts +++ b/libs/angular/src/vault/components/view.component.ts @@ -79,6 +79,8 @@ export class ViewComponent implements OnDestroy, OnInit { private previousCipherId: string; private passwordReprompted = false; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + get fido2CredentialCreationDateValue(): string { const dateCreated = this.i18nService.t("dateCreated"); const creationDate = this.datePipe.transform( @@ -141,9 +143,7 @@ export class ViewComponent implements OnDestroy, OnInit { this.cleanUp(); const cipher = await this.cipherService.get(this.cipherId); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); + const activeUserId = await firstValueFrom(this.activeUserId$); this.cipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); @@ -158,7 +158,7 @@ export class ViewComponent implements OnDestroy, OnInit { if (this.cipher.folderId) { this.folder = await ( - await firstValueFrom(this.folderService.folderViews$) + await firstValueFrom(this.folderService.folderViews$(activeUserId)) ).find((f) => f.id == this.cipher.folderId); } diff --git a/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts b/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts index a2b624876be..dd0b49f356a 100644 --- a/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts +++ b/libs/angular/src/vault/vault-filter/services/vault-filter.service.ts @@ -1,7 +1,7 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Injectable } from "@angular/core"; -import { firstValueFrom, from, map, mergeMap, Observable } from "rxjs"; +import { firstValueFrom, from, map, mergeMap, Observable, switchMap } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; import { @@ -11,6 +11,7 @@ import { 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 { ActiveUserState, StateProvider } from "@bitwarden/common/platform/state"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; @@ -32,6 +33,8 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti private readonly collapsedGroupings$: Observable> = this.collapsedGroupingsState.state$.pipe(map((c) => new Set(c))); + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( protected organizationService: OrganizationService, protected folderService: FolderService, @@ -39,6 +42,7 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti protected collectionService: CollectionService, protected policyService: PolicyService, protected stateProvider: StateProvider, + protected accountService: AccountService, ) {} async storeCollapsedFilterNodes(collapsedFilterNodes: Set): Promise { @@ -81,7 +85,8 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti }); }; - return this.folderService.folderViews$.pipe( + return this.activeUserId$.pipe( + switchMap((userId) => this.folderService.folderViews$(userId)), mergeMap((folders) => from(transformation(folders))), ); } @@ -126,8 +131,9 @@ export class VaultFilterService implements DeprecatedVaultFilterServiceAbstracti } async getFolderNested(id: string): Promise> { + const activeUserId = await firstValueFrom(this.activeUserId$); const folders = await this.getAllFoldersNested( - await firstValueFrom(this.folderService.folderViews$), + await firstValueFrom(this.folderService.folderViews$(activeUserId)), ); return ServiceUtils.getTreeNodeObjectFromList(folders, id) as TreeNode; } diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index ce9eb5a15c0..1ed5227cb13 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -150,6 +150,9 @@ export const COLLECTION_DATA = new StateDefinition("collection", "disk", { web: "memory", }); export const FOLDER_DISK = new StateDefinition("folder", "disk", { web: "memory" }); +export const FOLDER_MEMORY = new StateDefinition("decryptedFolders", "memory", { + browser: "memory-large-object", +}); export const VAULT_FILTER_DISK = new StateDefinition("vaultFilter", "disk", { web: "disk-local", }); diff --git a/libs/common/src/platform/sync/core-sync.service.ts b/libs/common/src/platform/sync/core-sync.service.ts index 180767ccd16..cfa9030c9de 100644 --- a/libs/common/src/platform/sync/core-sync.service.ts +++ b/libs/common/src/platform/sync/core-sync.service.ts @@ -85,18 +85,25 @@ export abstract class CoreSyncService implements SyncService { await this.stateProvider.getUser(userId, LAST_SYNC_DATE).update(() => date); } - async syncUpsertFolder(notification: SyncFolderNotification, isEdit: boolean): Promise { + async syncUpsertFolder( + notification: SyncFolderNotification, + isEdit: boolean, + userId: UserId, + ): Promise { this.syncStarted(); - if (await this.stateService.getIsAuthenticated()) { + + const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId)); + + if (authStatus >= AuthenticationStatus.Locked) { try { - const localFolder = await this.folderService.get(notification.id); + const localFolder = await this.folderService.get(notification.id, userId); if ( (!isEdit && localFolder == null) || (isEdit && localFolder != null && localFolder.revisionDate < notification.revisionDate) ) { const remoteFolder = await this.folderApiService.get(notification.id); if (remoteFolder != null) { - await this.folderService.upsert(new FolderData(remoteFolder)); + await this.folderService.upsert(new FolderData(remoteFolder), userId); this.messageSender.send("syncedUpsertedFolder", { folderId: notification.id }); return this.syncCompleted(true); } @@ -108,10 +115,13 @@ export abstract class CoreSyncService implements SyncService { return this.syncCompleted(false); } - async syncDeleteFolder(notification: SyncFolderNotification): Promise { + async syncDeleteFolder(notification: SyncFolderNotification, userId: UserId): Promise { this.syncStarted(); - if (await this.stateService.getIsAuthenticated()) { - await this.folderService.delete(notification.id); + + const authStatus = await firstValueFrom(this.authService.authStatusFor$(userId)); + + if (authStatus >= AuthenticationStatus.Locked) { + await this.folderService.delete(notification.id, userId); this.messageSender.send("syncedDeletedFolder", { folderId: notification.id }); this.syncCompleted(true); return true; diff --git a/libs/common/src/platform/sync/sync.service.ts b/libs/common/src/platform/sync/sync.service.ts index 733b7beaff5..6763e01cab7 100644 --- a/libs/common/src/platform/sync/sync.service.ts +++ b/libs/common/src/platform/sync/sync.service.ts @@ -56,8 +56,9 @@ export abstract class SyncService { abstract syncUpsertFolder( notification: SyncFolderNotification, isEdit: boolean, + userId: UserId, ): Promise; - abstract syncDeleteFolder(notification: SyncFolderNotification): Promise; + abstract syncDeleteFolder(notification: SyncFolderNotification, userId: UserId): Promise; abstract syncUpsertCipher( notification: SyncCipherNotification, isEdit: boolean, diff --git a/libs/common/src/services/notifications.service.ts b/libs/common/src/services/notifications.service.ts index 6f7c5c9f262..4a14332af8a 100644 --- a/libs/common/src/services/notifications.service.ts +++ b/libs/common/src/services/notifications.service.ts @@ -168,10 +168,14 @@ export class NotificationsService implements NotificationsServiceAbstraction { await this.syncService.syncUpsertFolder( notification.payload as SyncFolderNotification, notification.type === NotificationType.SyncFolderUpdate, + payloadUserId, ); break; case NotificationType.SyncFolderDelete: - await this.syncService.syncDeleteFolder(notification.payload as SyncFolderNotification); + await this.syncService.syncDeleteFolder( + notification.payload as SyncFolderNotification, + payloadUserId, + ); break; case NotificationType.SyncVault: case NotificationType.SyncCiphers: diff --git a/libs/common/src/services/vault-timeout/vault-timeout.service.spec.ts b/libs/common/src/services/vault-timeout/vault-timeout.service.spec.ts index 71341a98a62..1350010f849 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout.service.spec.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout.service.spec.ts @@ -334,7 +334,7 @@ describe("VaultTimeoutService", () => { // Active users should have additional steps ran expect(searchService.clearIndex).toHaveBeenCalled(); - expect(folderService.clearCache).toHaveBeenCalled(); + expect(folderService.clearDecryptedFolderState).toHaveBeenCalled(); expectUserToHaveLoggedOut("3"); // They have chosen logout as their action and it's available, log them out expectUserToHaveLoggedOut("4"); // They may have had lock as their chosen action but it's not available to them so logout diff --git a/libs/common/src/services/vault-timeout/vault-timeout.service.ts b/libs/common/src/services/vault-timeout/vault-timeout.service.ts index f6ad0f17e9a..f465174bf40 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout.service.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout.service.ts @@ -135,10 +135,10 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { if (userId == null || userId === currentUserId) { await this.searchService.clearIndex(); - await this.folderService.clearCache(); await this.collectionService.clearActiveUserCache(); } + await this.folderService.clearDecryptedFolderState(userId); await this.masterPasswordService.clearMasterKey(lockingUserId); await this.stateService.setUserKeyAutoUnlock(null, { userId: lockingUserId }); diff --git a/libs/common/src/vault/abstractions/folder/folder-api.service.abstraction.ts b/libs/common/src/vault/abstractions/folder/folder-api.service.abstraction.ts index a732acfa991..859f2183edb 100644 --- a/libs/common/src/vault/abstractions/folder/folder-api.service.abstraction.ts +++ b/libs/common/src/vault/abstractions/folder/folder-api.service.abstraction.ts @@ -1,11 +1,13 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore +import { UserId } from "@bitwarden/common/types/guid"; + import { Folder } from "../../models/domain/folder"; import { FolderResponse } from "../../models/response/folder.response"; export class FolderApiServiceAbstraction { - save: (folder: Folder) => Promise; - delete: (id: string) => Promise; + save: (folder: Folder, userId: UserId) => Promise; + delete: (id: string, userId: UserId) => Promise; get: (id: string) => Promise; - deleteAll: () => Promise; + deleteAll: (userId: UserId) => Promise; } diff --git a/libs/common/src/vault/abstractions/folder/folder.service.abstraction.ts b/libs/common/src/vault/abstractions/folder/folder.service.abstraction.ts index c5722e0f57b..b7241e3ae37 100644 --- a/libs/common/src/vault/abstractions/folder/folder.service.abstraction.ts +++ b/libs/common/src/vault/abstractions/folder/folder.service.abstraction.ts @@ -13,23 +13,27 @@ import { FolderWithIdRequest } from "../../models/request/folder-with-id.request import { FolderView } from "../../models/view/folder.view"; export abstract class FolderService implements UserKeyRotationDataProvider { - folders$: Observable; - folderViews$: Observable; + folders$: (userId: UserId) => Observable; + folderViews$: (userId: UserId) => Observable; - clearCache: () => Promise; + clearDecryptedFolderState: (userId: UserId) => Promise; encrypt: (model: FolderView, key: SymmetricCryptoKey) => Promise; - get: (id: string) => Promise; - getDecrypted$: (id: string) => Observable; - getAllFromState: () => Promise; + get: (id: string, userId: UserId) => Promise; + getDecrypted$: (id: string, userId: UserId) => Observable; + /** + * @deprecated Use firstValueFrom(folders$) directly instead + * @param userId The user id + * @returns Promise of folders array + */ + getAllFromState: (userId: UserId) => Promise; /** * @deprecated Only use in CLI! */ - getFromState: (id: string) => Promise; + getFromState: (id: string, userId: UserId) => Promise; /** * @deprecated Only use in CLI! */ - getAllDecryptedFromState: () => Promise; - decryptFolders: (folders: Folder[]) => Promise; + getAllDecryptedFromState: (userId: UserId) => Promise; /** * Returns user folders re-encrypted with the new user key. * @param originalUserKey the original user key @@ -46,8 +50,8 @@ export abstract class FolderService implements UserKeyRotationDataProvider Promise; + upsert: (folder: FolderData | FolderData[], userId: UserId) => Promise; replace: (folders: { [id: string]: FolderData }, userId: UserId) => Promise; - clear: (userId?: string) => Promise; - delete: (id: string | string[]) => Promise; + clear: (userId: UserId) => Promise; + delete: (id: string | string[], userId: UserId) => Promise; } diff --git a/libs/common/src/vault/services/folder/folder-api.service.ts b/libs/common/src/vault/services/folder/folder-api.service.ts index e46df37c176..24831393668 100644 --- a/libs/common/src/vault/services/folder/folder-api.service.ts +++ b/libs/common/src/vault/services/folder/folder-api.service.ts @@ -1,3 +1,5 @@ +import { UserId } from "@bitwarden/common/types/guid"; + import { ApiService } from "../../../abstractions/api.service"; import { FolderApiServiceAbstraction } from "../../../vault/abstractions/folder/folder-api.service.abstraction"; import { InternalFolderService } from "../../../vault/abstractions/folder/folder.service.abstraction"; @@ -12,7 +14,7 @@ export class FolderApiService implements FolderApiServiceAbstraction { private apiService: ApiService, ) {} - async save(folder: Folder): Promise { + async save(folder: Folder, userId: UserId): Promise { const request = new FolderRequest(folder); let response: FolderResponse; @@ -24,17 +26,17 @@ export class FolderApiService implements FolderApiServiceAbstraction { } const data = new FolderData(response); - await this.folderService.upsert(data); + await this.folderService.upsert(data, userId); } - async delete(id: string): Promise { + async delete(id: string, userId: UserId): Promise { await this.deleteFolder(id); - await this.folderService.delete(id); + await this.folderService.delete(id, userId); } - async deleteAll(): Promise { + async deleteAll(userId: UserId): Promise { await this.apiService.send("DELETE", "/folders/all", null, true, false); - await this.folderService.clear(); + await this.folderService.clear(userId); } async get(id: string): Promise { diff --git a/libs/common/src/vault/services/folder/folder.service.spec.ts b/libs/common/src/vault/services/folder/folder.service.spec.ts index 193d0e85e61..612cd83d99b 100644 --- a/libs/common/src/vault/services/folder/folder.service.spec.ts +++ b/libs/common/src/vault/services/folder/folder.service.spec.ts @@ -1,10 +1,10 @@ import { mock, MockProxy } from "jest-mock-extended"; -import { firstValueFrom } from "rxjs"; +import { BehaviorSubject, firstValueFrom } from "rxjs"; import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; -import { makeStaticByteArray } from "../../../../spec"; +import { makeEncString } from "../../../../spec"; import { FakeAccountService, mockAccountServiceWith } from "../../../../spec/fake-account-service"; -import { FakeActiveUserState } from "../../../../spec/fake-state"; +import { FakeSingleUserState } from "../../../../spec/fake-state"; import { FakeStateProvider } from "../../../../spec/fake-state-provider"; import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; @@ -17,7 +17,7 @@ import { CipherService } from "../../abstractions/cipher.service"; import { FolderData } from "../../models/data/folder.data"; import { FolderView } from "../../models/view/folder.view"; import { FolderService } from "../../services/folder/folder.service"; -import { FOLDER_ENCRYPTED_FOLDERS } from "../key-state/folder.state"; +import { FOLDER_DECRYPTED_FOLDERS, FOLDER_ENCRYPTED_FOLDERS } from "../key-state/folder.state"; describe("Folder Service", () => { let folderService: FolderService; @@ -30,7 +30,7 @@ describe("Folder Service", () => { const mockUserId = Utils.newGuid() as UserId; let accountService: FakeAccountService; - let folderState: FakeActiveUserState>; + let folderState: FakeSingleUserState>; beforeEach(() => { keyService = mock(); @@ -42,11 +42,9 @@ describe("Folder Service", () => { stateProvider = new FakeStateProvider(accountService); i18nService.collator = new Intl.Collator("en"); + i18nService.t.mockReturnValue("No Folder"); - keyService.hasUserKey.mockResolvedValue(true); - keyService.getUserKeyWithLegacySupport.mockResolvedValue( - new SymmetricCryptoKey(makeStaticByteArray(32)) as UserKey, - ); + keyService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any)); encryptService.decryptToUtf8.mockResolvedValue("DEC"); folderService = new FolderService( @@ -57,10 +55,53 @@ describe("Folder Service", () => { stateProvider, ); - folderState = stateProvider.activeUser.getFake(FOLDER_ENCRYPTED_FOLDERS); + folderState = stateProvider.singleUser.getFake(mockUserId, FOLDER_ENCRYPTED_FOLDERS); // Initial state - folderState.nextState({ "1": folderData("1", "test") }); + folderState.nextState({ "1": folderData("1") }); + }); + + describe("folders$", () => { + it("emits encrypted folders from state", async () => { + const folder1 = folderData("1"); + const folder2 = folderData("2"); + + await stateProvider.setUserState( + FOLDER_ENCRYPTED_FOLDERS, + Object.fromEntries([folder1, folder2].map((f) => [f.id, f])), + mockUserId, + ); + + const result = await firstValueFrom(folderService.folders$(mockUserId)); + + expect(result.length).toBe(2); + expect(result).toIncludeAllPartialMembers([ + { id: "1", name: makeEncString("ENC_STRING_1") }, + { id: "2", name: makeEncString("ENC_STRING_2") }, + ]); + }); + }); + + describe("folderView$", () => { + it("emits decrypted folders from state", async () => { + const folder1 = folderData("1"); + const folder2 = folderData("2"); + + await stateProvider.setUserState( + FOLDER_ENCRYPTED_FOLDERS, + Object.fromEntries([folder1, folder2].map((f) => [f.id, f])), + mockUserId, + ); + + const result = await firstValueFrom(folderService.folderViews$(mockUserId)); + + expect(result.length).toBe(3); + expect(result).toIncludeAllPartialMembers([ + { id: "1", name: "DEC" }, + { id: "2", name: "DEC" }, + { name: "No Folder" }, + ]); + }); }); it("encrypt", async () => { @@ -83,105 +124,83 @@ describe("Folder Service", () => { describe("get", () => { it("exists", async () => { - const result = await folderService.get("1"); + const result = await folderService.get("1", mockUserId); expect(result).toEqual({ id: "1", - name: { - encryptedString: "test", - encryptionType: 0, - }, + name: makeEncString("ENC_STRING_" + 1), revisionDate: null, }); }); it("not exists", async () => { - const result = await folderService.get("2"); + const result = await folderService.get("2", mockUserId); expect(result).toBe(undefined); }); }); it("upsert", async () => { - await folderService.upsert(folderData("2", "test 2")); + await folderService.upsert(folderData("2"), mockUserId); - expect(await firstValueFrom(folderService.folders$)).toEqual([ + expect(await firstValueFrom(folderService.folders$(mockUserId))).toEqual([ { id: "1", - name: { - encryptedString: "test", - encryptionType: 0, - }, + name: makeEncString("ENC_STRING_" + 1), revisionDate: null, }, { id: "2", - name: { - encryptedString: "test 2", - encryptionType: 0, - }, + name: makeEncString("ENC_STRING_" + 2), revisionDate: null, }, ]); }); it("replace", async () => { - await folderService.replace({ "2": folderData("2", "test 2") }, mockUserId); + await folderService.replace({ "4": folderData("4") }, mockUserId); - expect(await firstValueFrom(folderService.folders$)).toEqual([ + expect(await firstValueFrom(folderService.folders$(mockUserId))).toEqual([ { - id: "2", - name: { - encryptedString: "test 2", - encryptionType: 0, - }, + id: "4", + name: makeEncString("ENC_STRING_" + 4), revisionDate: null, }, ]); }); it("delete", async () => { - await folderService.delete("1"); + await folderService.delete("1", mockUserId); - expect((await firstValueFrom(folderService.folders$)).length).toBe(0); + expect((await firstValueFrom(folderService.folders$(mockUserId))).length).toBe(0); }); - it("clearCache", async () => { - await folderService.clearCache(); + describe("clearDecryptedFolderState", () => { + it("null userId", async () => { + await expect(folderService.clearDecryptedFolderState(null)).rejects.toThrow( + "User ID is required.", + ); + }); + + it("userId provided", async () => { + await folderService.clearDecryptedFolderState(mockUserId); - expect((await firstValueFrom(folderService.folders$)).length).toBe(1); - expect((await firstValueFrom(folderService.folderViews$)).length).toBe(0); + expect((await firstValueFrom(folderService.folders$(mockUserId))).length).toBe(1); + expect( + (await firstValueFrom(stateProvider.getUserState$(FOLDER_DECRYPTED_FOLDERS, mockUserId))) + .length, + ).toBe(0); + }); }); - describe("clear", () => { - it("null userId", async () => { - await folderService.clear(); + it("clear", async () => { + await folderService.clear(mockUserId); - expect((await firstValueFrom(folderService.folders$)).length).toBe(0); - expect((await firstValueFrom(folderService.folderViews$)).length).toBe(0); - }); + expect((await firstValueFrom(folderService.folders$(mockUserId))).length).toBe(0); - /** - * TODO: Fix this test to address the problem where the fakes for the active user state is not - * updated as expected - */ - // it("matching userId", async () => { - // stateService.getUserId.mockResolvedValue("1"); - // await folderService.clear("1" as UserId); - - // expect((await firstValueFrom(folderService.folders$)).length).toBe(0); - // }); - - /** - * TODO: Fix this test to address the problem where the fakes for the active user state is not - * updated as expected - */ - // it("mismatching userId", async () => { - // await folderService.clear("12" as UserId); - - // expect((await firstValueFrom(folderService.folders$)).length).toBe(1); - // expect((await firstValueFrom(folderService.folderViews$)).length).toBe(2); - // }); + const folderViews = await firstValueFrom(folderService.folderViews$(mockUserId)); + expect(folderViews.length).toBe(1); + expect(folderViews[0].id).toBeNull(); // Should be the "No Folder" folder }); describe("getRotatedData", () => { @@ -207,10 +226,10 @@ describe("Folder Service", () => { }); }); - function folderData(id: string, name: string) { + function folderData(id: string) { const data = new FolderData({} as any); data.id = id; - data.name = name; + data.name = makeEncString("ENC_STRING_" + data.id).encryptedString; return data; } diff --git a/libs/common/src/vault/services/folder/folder.service.ts b/libs/common/src/vault/services/folder/folder.service.ts index 07b162b4f14..3aac5374fcb 100644 --- a/libs/common/src/vault/services/folder/folder.service.ts +++ b/libs/common/src/vault/services/folder/folder.service.ts @@ -1,14 +1,14 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Observable, firstValueFrom, map, shareReplay } from "rxjs"; +import { Observable, Subject, firstValueFrom, map, shareReplay, switchMap, merge } from "rxjs"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; -import { Utils } from "../../../platform/misc/utils"; import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; -import { ActiveUserState, DerivedState, StateProvider } from "../../../platform/state"; +import { StateProvider } from "../../../platform/state"; import { UserId } from "../../../types/guid"; import { UserKey } from "../../../types/key"; import { CipherService } from "../../../vault/abstractions/cipher.service"; @@ -21,11 +21,18 @@ import { FolderWithIdRequest } from "../../models/request/folder-with-id.request import { FOLDER_DECRYPTED_FOLDERS, FOLDER_ENCRYPTED_FOLDERS } from "../key-state/folder.state"; export class FolderService implements InternalFolderServiceAbstraction { - folders$: Observable; - folderViews$: Observable; + /** + * Ensures we reuse the same observable stream for each userId rather than + * creating a new one on each folderViews$ call. + */ + private folderViewCache = new Map>(); - private encryptedFoldersState: ActiveUserState>; - private decryptedFoldersState: DerivedState; + /** + * Used to force the folderviews$ Observable to re-emit with a provided value. + * Required because shareReplay with refCount: false maintains last emission. + * Used during cleanup to force emit empty arrays, ensuring stale data isn't retained. + */ + private forceFolderViews: Record> = {}; constructor( private keyService: KeyService, @@ -33,23 +40,44 @@ export class FolderService implements InternalFolderServiceAbstraction { private i18nService: I18nService, private cipherService: CipherService, private stateProvider: StateProvider, - ) { - this.encryptedFoldersState = this.stateProvider.getActive(FOLDER_ENCRYPTED_FOLDERS); - this.decryptedFoldersState = this.stateProvider.getDerived( - this.encryptedFoldersState.state$, - FOLDER_DECRYPTED_FOLDERS, - { folderService: this, keyService: this.keyService }, - ); + ) {} - this.folders$ = this.encryptedFoldersState.state$.pipe( - map((folderData) => Object.values(folderData).map((f) => new Folder(f))), - ); + folders$(userId: UserId): Observable { + return this.encryptedFoldersState(userId).state$.pipe( + map((folders) => { + if (folders == null) { + return []; + } - this.folderViews$ = this.decryptedFoldersState.state$; + return Object.values(folders).map((f) => new Folder(f)); + }), + ); } - async clearCache(): Promise { - await this.decryptedFoldersState.forceValue([]); + /** + * Returns an Observable of decrypted folder views for the given userId. + * Uses folderViewCache to maintain a single Observable instance per user, + * combining normal folder state updates with forced updates. + */ + folderViews$(userId: UserId): Observable { + if (!this.folderViewCache.has(userId)) { + if (!this.forceFolderViews[userId]) { + this.forceFolderViews[userId] = new Subject(); + } + + const observable = merge( + this.forceFolderViews[userId], + this.encryptedFoldersState(userId).state$.pipe( + switchMap((folderData) => { + return this.decryptFolders(userId, folderData); + }), + ), + ).pipe(shareReplay({ refCount: false, bufferSize: 1 })); + + this.folderViewCache.set(userId, observable); + } + + return this.folderViewCache.get(userId); } // TODO: This should be moved to EncryptService or something @@ -60,29 +88,29 @@ export class FolderService implements InternalFolderServiceAbstraction { return folder; } - async get(id: string): Promise { - const folders = await firstValueFrom(this.folders$); + async get(id: string, userId: UserId): Promise { + const folders = await firstValueFrom(this.folders$(userId)); return folders.find((folder) => folder.id === id); } - getDecrypted$(id: string): Observable { - return this.folderViews$.pipe( + getDecrypted$(id: string, userId: UserId): Observable { + return this.folderViews$(userId).pipe( map((folders) => folders.find((folder) => folder.id === id)), shareReplay({ refCount: true, bufferSize: 1 }), ); } - async getAllFromState(): Promise { - return await firstValueFrom(this.folders$); + async getAllFromState(userId: UserId): Promise { + return await firstValueFrom(this.folders$(userId)); } /** * @deprecated For the CLI only * @param id id of the folder */ - async getFromState(id: string): Promise { - const folder = await this.get(id); + async getFromState(id: string, userId: UserId): Promise { + const folder = await this.get(id, userId); if (!folder) { return null; } @@ -93,12 +121,13 @@ export class FolderService implements InternalFolderServiceAbstraction { /** * @deprecated Only use in CLI! */ - async getAllDecryptedFromState(): Promise { - return await firstValueFrom(this.folderViews$); + async getAllDecryptedFromState(userId: UserId): Promise { + return await firstValueFrom(this.folderViews$(userId)); } - async upsert(folderData: FolderData | FolderData[]): Promise { - await this.encryptedFoldersState.update((folders) => { + async upsert(folderData: FolderData | FolderData[], userId: UserId): Promise { + await this.clearDecryptedFolderState(userId); + await this.encryptedFoldersState(userId).update((folders) => { if (folders == null) { folders = {}; } @@ -120,24 +149,31 @@ export class FolderService implements InternalFolderServiceAbstraction { if (!folders) { return; } - + await this.clearDecryptedFolderState(userId); await this.stateProvider.getUser(userId, FOLDER_ENCRYPTED_FOLDERS).update(() => { const newFolders: Record = { ...folders }; return newFolders; }); } - async clear(userId?: UserId): Promise { + async clearDecryptedFolderState(userId: UserId): Promise { if (userId == null) { - await this.encryptedFoldersState.update(() => ({})); - await this.decryptedFoldersState.forceValue([]); - } else { - await this.stateProvider.getUser(userId, FOLDER_ENCRYPTED_FOLDERS).update(() => ({})); + throw new Error("User ID is required."); } + + await this.setDecryptedFolders([], userId); + } + + async clear(userId: UserId): Promise { + this.forceFolderViews[userId]?.next([]); + + await this.encryptedFoldersState(userId).update(() => ({})); + await this.clearDecryptedFolderState(userId); } - async delete(id: string | string[]): Promise { - await this.encryptedFoldersState.update((folders) => { + async delete(id: string | string[], userId: UserId): Promise { + await this.clearDecryptedFolderState(userId); + await this.encryptedFoldersState(userId).update((folders) => { if (folders == null) { return; } @@ -164,25 +200,11 @@ export class FolderService implements InternalFolderServiceAbstraction { } } if (updates.length > 0) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.cipherService.upsert(updates.map((c) => c.toCipherData())); + await this.cipherService.upsert(updates.map((c) => c.toCipherData())); } } } - async decryptFolders(folders: Folder[]) { - const decryptFolderPromises = folders.map((f) => f.decrypt()); - const decryptedFolders = await Promise.all(decryptFolderPromises); - - decryptedFolders.sort(Utils.getSortFunction(this.i18nService, "name")); - - const noneFolder = new FolderView(); - noneFolder.name = this.i18nService.t("noneFolder"); - decryptedFolders.push(noneFolder); - return decryptedFolders; - } - async getRotatedData( originalUserKey: UserKey, newUserKey: UserKey, @@ -193,7 +215,7 @@ export class FolderService implements InternalFolderServiceAbstraction { } let encryptedFolders: FolderWithIdRequest[] = []; - const folders = await firstValueFrom(this.folderViews$); + const folders = await firstValueFrom(this.folderViews$(userId)); if (!folders) { return encryptedFolders; } @@ -205,4 +227,63 @@ export class FolderService implements InternalFolderServiceAbstraction { ); return encryptedFolders; } + + /** + * Decrypts the folders for a user. + * @param userId the user id + * @param folderData encrypted folders + * @returns a list of decrypted folders + */ + private async decryptFolders( + userId: UserId, + folderData: Record, + ): Promise { + // Check if the decrypted folders are already cached + const decrypted = await firstValueFrom( + this.stateProvider.getUser(userId, FOLDER_DECRYPTED_FOLDERS).state$, + ); + if (decrypted?.length) { + return decrypted; + } + + if (folderData == null) { + return []; + } + + const folders = Object.values(folderData).map((f) => new Folder(f)); + const userKey = await firstValueFrom(this.keyService.userKey$(userId)); + if (!userKey) { + return []; + } + + const decryptFolderPromises = folders.map((f) => + f.decryptWithKey(userKey, this.encryptService), + ); + const decryptedFolders = await Promise.all(decryptFolderPromises); + decryptedFolders.sort(Utils.getSortFunction(this.i18nService, "name")); + + const noneFolder = new FolderView(); + noneFolder.name = this.i18nService.t("noneFolder"); + decryptedFolders.push(noneFolder); + + // Cache the decrypted folders + await this.setDecryptedFolders(decryptedFolders, userId); + return decryptedFolders; + } + + /** + * @returns a SingleUserState for the encrypted folders. + */ + private encryptedFoldersState(userId: UserId) { + return this.stateProvider.getUser(userId, FOLDER_ENCRYPTED_FOLDERS); + } + + /** + * Sets the decrypted folders state for a user. + * @param folders the decrypted folders + * @param userId the user id + */ + private async setDecryptedFolders(folders: FolderView[], userId: UserId): Promise { + await this.stateProvider.setUserState(FOLDER_DECRYPTED_FOLDERS, folders, userId); + } } diff --git a/libs/common/src/vault/services/key-state/folder.state.spec.ts b/libs/common/src/vault/services/key-state/folder.state.spec.ts index ece66b5d451..217a200ea88 100644 --- a/libs/common/src/vault/services/key-state/folder.state.spec.ts +++ b/libs/common/src/vault/services/key-state/folder.state.spec.ts @@ -1,11 +1,3 @@ -import { mock } from "jest-mock-extended"; - -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; -import { FolderService } from "../../abstractions/folder/folder.service.abstraction"; -import { FolderData } from "../../models/data/folder.data"; -import { Folder } from "../../models/domain/folder"; -import { FolderView } from "../../models/view/folder.view"; - import { FOLDER_DECRYPTED_FOLDERS, FOLDER_ENCRYPTED_FOLDERS } from "./folder.state"; describe("encrypted folders", () => { @@ -31,48 +23,32 @@ describe("encrypted folders", () => { }); describe("derived decrypted folders", () => { - const keyService = mock(); - const folderService = mock(); const sut = FOLDER_DECRYPTED_FOLDERS; - let data: FolderData; - - beforeEach(() => { - data = { - id: "id", - name: "encName", - revisionDate: "2024-01-31T12:00:00.000Z", - }; - }); - afterEach(() => { - jest.resetAllMocks(); - }); - - it("should deserialize encrypted folders", async () => { - const inputObj = [data]; + it("should deserialize decrypted folders", async () => { + const inputObj = [ + { + id: "id", + name: "encName", + revisionDate: "2024-01-31T12:00:00.000Z", + }, + ]; - const expectedFolderView = { - id: "id", - name: "encName", - revisionDate: new Date("2024-01-31T12:00:00.000Z"), - }; + const expectedFolderView = [ + { + id: "id", + name: "encName", + revisionDate: new Date("2024-01-31T12:00:00.000Z"), + }, + ]; - const result = sut.deserialize(JSON.parse(JSON.stringify(inputObj))); + const result = sut.deserializer(JSON.parse(JSON.stringify(inputObj))); - expect(result).toEqual([expectedFolderView]); + expect(result).toEqual(expectedFolderView); }); - it("should derive encrypted folders", async () => { - const folderViewMock = new FolderView(new Folder(data)); - keyService.hasUserKey.mockResolvedValue(true); - folderService.decryptFolders.mockResolvedValue([folderViewMock]); - - const encryptedFoldersState = { id: data }; - const derivedStateResult = await sut.derive(encryptedFoldersState, { - folderService, - keyService, - }); - - expect(derivedStateResult).toEqual([folderViewMock]); + it("should handle null input", async () => { + const result = sut.deserializer(null); + expect(result).toEqual([]); }); }); diff --git a/libs/common/src/vault/services/key-state/folder.state.ts b/libs/common/src/vault/services/key-state/folder.state.ts index 7262d72d58e..99ad8e5ae35 100644 --- a/libs/common/src/vault/services/key-state/folder.state.ts +++ b/libs/common/src/vault/services/key-state/folder.state.ts @@ -1,34 +1,23 @@ import { Jsonify } from "type-fest"; -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; -import { DeriveDefinition, FOLDER_DISK, UserKeyDefinition } from "../../../platform/state"; -import { FolderService } from "../../abstractions/folder/folder.service.abstraction"; +import { FOLDER_DISK, FOLDER_MEMORY, UserKeyDefinition } from "../../../platform/state"; import { FolderData } from "../../models/data/folder.data"; -import { Folder } from "../../models/domain/folder"; import { FolderView } from "../../models/view/folder.view"; export const FOLDER_ENCRYPTED_FOLDERS = UserKeyDefinition.record( FOLDER_DISK, - "folders", + "folder", { deserializer: (obj: Jsonify) => FolderData.fromJSON(obj), clearOn: ["logout"], }, ); -export const FOLDER_DECRYPTED_FOLDERS = DeriveDefinition.from< - Record, - FolderView[], - { folderService: FolderService; keyService: KeyService } ->(FOLDER_ENCRYPTED_FOLDERS, { - deserializer: (obj) => obj.map((f) => FolderView.fromJSON(f)), - derive: async (from, { folderService, keyService }) => { - const folders = Object.values(from || {}).map((f) => new Folder(f)); - - if (await keyService.hasUserKey()) { - return await folderService.decryptFolders(folders); - } else { - return []; - } +export const FOLDER_DECRYPTED_FOLDERS = new UserKeyDefinition( + FOLDER_MEMORY, + "decryptedFolders", + { + deserializer: (obj: Jsonify) => obj?.map((f) => FolderView.fromJSON(f)) ?? [], + clearOn: ["logout", "lock"], }, -}); +); diff --git a/libs/importer/src/components/import.component.ts b/libs/importer/src/components/import.component.ts index 0035fbdf10d..f2bf7471d44 100644 --- a/libs/importer/src/components/import.component.ts +++ b/libs/importer/src/components/import.component.ts @@ -16,7 +16,7 @@ import { import { FormBuilder, ReactiveFormsModule, Validators } from "@angular/forms"; import * as JSZip from "jszip"; import { concat, Observable, Subject, lastValueFrom, combineLatest, firstValueFrom } from "rxjs"; -import { filter, map, takeUntil } from "rxjs/operators"; +import { filter, map, switchMap, takeUntil } from "rxjs/operators"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -153,6 +153,8 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { private _importBlockedByPolicy = false; protected isFromAC = false; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + formGroup = this.formBuilder.group({ vaultSelector: [ "myVault", @@ -206,6 +208,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { @Optional() protected importCollectionService: ImportCollectionServiceAbstraction, protected toastService: ToastService, + protected accountService: AccountService, ) {} protected get importBlockedByPolicy(): boolean { @@ -257,7 +260,10 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { private handleImportInit() { // Filter out the no folder-item from folderViews$ - this.folders$ = this.folderService.folderViews$.pipe( + this.folders$ = this.activeUserId$.pipe( + switchMap((userId) => { + return this.folderService.folderViews$(userId); + }), map((folders) => folders.filter((f) => f.id != null)), ); diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts index 9d58bcbf559..069df8606bf 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts @@ -1,5 +1,5 @@ import { mock, MockProxy } from "jest-mock-extended"; -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject, of } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -178,8 +178,8 @@ describe("VaultExportService", () => { const activeAccount = { id: userId, ...accountInfo }; accountService.activeAccount$ = new BehaviorSubject(activeAccount); - folderService.getAllDecryptedFromState.mockResolvedValue(UserFolderViews); - folderService.getAllFromState.mockResolvedValue(UserFolders); + folderService.folderViews$.mockReturnValue(of(UserFolderViews)); + folderService.folders$.mockReturnValue(of(UserFolders)); kdfConfigService.getKdfConfig.mockResolvedValue(DEFAULT_KDF_CONFIG); encryptService.encrypt.mockResolvedValue(new EncString("encrypted")); @@ -295,7 +295,7 @@ describe("VaultExportService", () => { it("exported unencrypted object contains folders", async () => { cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1)); - await folderService.getAllDecryptedFromState(); + folderService.folderViews$.mockReturnValue(of(UserFolderViews)); const actual = await exportService.getExport("json"); expectEqualFolderViews(UserFolderViews, actual); @@ -303,7 +303,7 @@ describe("VaultExportService", () => { it("exported encrypted json contains folders", async () => { cipherService.getAll.mockResolvedValue(UserCipherDomains.slice(0, 1)); - await folderService.getAllFromState(); + folderService.folders$.mockReturnValue(of(UserFolders)); const actual = await exportService.getExport("encrypted_json"); expectEqualFolders(UserFolders, actual); diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts index dbd2024d3ad..f9df9c7057f 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts @@ -32,6 +32,8 @@ export class IndividualVaultExportService extends BaseVaultExportService implements IndividualVaultExportServiceAbstraction { + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + constructor( private folderService: FolderService, private cipherService: CipherService, @@ -61,9 +63,10 @@ export class IndividualVaultExportService let decFolders: FolderView[] = []; let decCiphers: CipherView[] = []; const promises = []; + const activeUserId = await firstValueFrom(this.activeUserId$); promises.push( - this.folderService.getAllDecryptedFromState().then((folders) => { + firstValueFrom(this.folderService.folderViews$(activeUserId)).then((folders) => { decFolders = folders; }), ); @@ -87,9 +90,10 @@ export class IndividualVaultExportService let folders: Folder[] = []; let ciphers: Cipher[] = []; const promises = []; + const activeUserId = await firstValueFrom(this.activeUserId$); promises.push( - this.folderService.getAllFromState().then((f) => { + firstValueFrom(this.folderService.folders$(activeUserId)).then((f) => { folders = f; }), ); @@ -102,10 +106,9 @@ export class IndividualVaultExportService await Promise.all(promises); - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), + const userKey = await this.keyService.getUserKeyWithLegacySupport( + await firstValueFrom(this.activeUserId$), ); - const userKey = await this.keyService.getUserKeyWithLegacySupport(activeUserId); const encKeyValidation = await this.encryptService.encrypt(Utils.newGuid(), userKey); const jsonDoc: BitwardenEncryptedIndividualJsonExport = { diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts index 6bf05796070..7e04972f8ab 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts @@ -1,5 +1,5 @@ import { mock, MockProxy } from "jest-mock-extended"; -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject, of } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -168,8 +168,8 @@ describe("VaultExportService", () => { kdfConfigService = mock(); - folderService.getAllDecryptedFromState.mockResolvedValue(UserFolderViews); - folderService.getAllFromState.mockResolvedValue(UserFolders); + folderService.folderViews$.mockReturnValue(of(UserFolderViews)); + folderService.folders$.mockReturnValue(of(UserFolders)); kdfConfigService.getKdfConfig.mockResolvedValue(DEFAULT_KDF_CONFIG); encryptService.encrypt.mockResolvedValue(new EncString("encrypted")); keyService.userKey$.mockReturnValue(new BehaviorSubject("mockOriginalUserKey" as any)); @@ -294,7 +294,7 @@ describe("VaultExportService", () => { it("exported unencrypted object contains folders", async () => { cipherService.getAllDecrypted.mockResolvedValue(UserCipherViews.slice(0, 1)); - await folderService.getAllDecryptedFromState(); + const actual = await exportService.getExport("json"); expectEqualFolderViews(UserFolderViews, actual); @@ -302,7 +302,7 @@ describe("VaultExportService", () => { it("exported encrypted json contains folders", async () => { cipherService.getAll.mockResolvedValue(UserCipherDomains.slice(0, 1)); - await folderService.getAllFromState(); + const actual = await exportService.getExport("encrypted_json"); expectEqualFolders(UserFolders, actual); diff --git a/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts b/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts index c2fbd024aa8..93a53345d3a 100644 --- a/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts +++ b/libs/vault/src/cipher-form/services/default-cipher-form-config.service.ts @@ -7,6 +7,7 @@ import { CollectionService } from "@bitwarden/admin-console/common"; 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 { OrganizationUserStatusType, PolicyType } from "@bitwarden/common/admin-console/enums"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { CipherId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; @@ -31,12 +32,17 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService { private cipherService: CipherService = inject(CipherService); private folderService: FolderService = inject(FolderService); private collectionService: CollectionService = inject(CollectionService); + private accountService = inject(AccountService); + + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); async buildConfig( mode: CipherFormMode, cipherId?: CipherId, cipherType?: CipherType, ): Promise { + const activeUserId = await firstValueFrom(this.activeUserId$); + const [organizations, collections, allowPersonalOwnership, folders, cipher] = await firstValueFrom( combineLatest([ @@ -49,9 +55,9 @@ export class DefaultCipherFormConfigService implements CipherFormConfigService { ), ), this.allowPersonalOwnership$, - this.folderService.folders$.pipe( + this.folderService.folders$(activeUserId).pipe( switchMap((f) => - this.folderService.folderViews$.pipe( + this.folderService.folderViews$(activeUserId).pipe( filter((d) => d.length - 1 === f.length), // -1 for "No Folder" in folderViews$ ), ), diff --git a/libs/vault/src/cipher-view/cipher-view.component.ts b/libs/vault/src/cipher-view/cipher-view.component.ts index 57af96258fa..4bd87a7869d 100644 --- a/libs/vault/src/cipher-view/cipher-view.component.ts +++ b/libs/vault/src/cipher-view/cipher-view.component.ts @@ -1,11 +1,12 @@ import { CommonModule } from "@angular/common"; import { Component, Input, OnChanges, OnDestroy } from "@angular/core"; -import { firstValueFrom, Observable, Subject, takeUntil } from "rxjs"; +import { firstValueFrom, map, Observable, Subject, takeUntil } from "rxjs"; import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { isCardExpired } from "@bitwarden/common/autofill/utils"; import { CollectionId } from "@bitwarden/common/types/guid"; import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; @@ -48,6 +49,8 @@ import { ViewIdentitySectionsComponent } from "./view-identity-sections/view-ide export class CipherViewComponent implements OnChanges, OnDestroy { @Input({ required: true }) cipher: CipherView | null = null; + private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); + /** * Optional list of collections the cipher is assigned to. If none are provided, they will be fetched using the * `CipherService` and the `collectionIds` property of the cipher. @@ -66,6 +69,7 @@ export class CipherViewComponent implements OnChanges, OnDestroy { private organizationService: OrganizationService, private collectionService: CollectionService, private folderService: FolderService, + private accountService: AccountService, ) {} async ngOnChanges() { @@ -136,8 +140,14 @@ export class CipherViewComponent implements OnChanges, OnDestroy { } if (this.cipher.folderId) { + const activeUserId = await firstValueFrom(this.activeUserId$); + + if (!activeUserId) { + return; + } + this.folder$ = this.folderService - .getDecrypted$(this.cipher.folderId) + .getDecrypted$(this.cipher.folderId, activeUserId) .pipe(takeUntil(this.destroyed$)); } } From 9807b33181172c59ac5d52a3189f3d82c40147c3 Mon Sep 17 00:00:00 2001 From: Evan Bassler Date: Thu, 2 Jan 2025 16:17:47 -0600 Subject: [PATCH 30/65] add field type to show correct new cipher popup form (#12433) Co-authored-by: Evan Bassler --- apps/browser/src/autofill/background/overlay.background.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index fd16bfcf16a..8b577ccccf5 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -2275,6 +2275,7 @@ export class OverlayBackground implements OverlayBackgroundInterface { card, identity, sender, + addNewCipherType, }: CurrentAddNewItemData) { const cipherView: CipherView = this.buildNewVaultItemCipherView({ login, @@ -2294,7 +2295,10 @@ export class OverlayBackground implements OverlayBackgroundInterface { collectionIds: cipherView.collectionIds, }); - await this.openAddEditVaultItemPopout(sender.tab, { cipherId: cipherView.id }); + await this.openAddEditVaultItemPopout(sender.tab, { + cipherId: cipherView.id, + cipherType: addNewCipherType, + }); await BrowserApi.sendMessage("inlineAutofillMenuRefreshAddEditCipher"); } catch (error) { this.logService.error("Error building cipher and opening add/edit vault item popout", error); From b370787239415e50b50b000b933d408f0493c4b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 18:24:57 -0500 Subject: [PATCH 31/65] [deps] BRE: Update gh minor (#11941) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-browser.yml | 6 +- .github/workflows/build-cli.yml | 16 ++-- .github/workflows/build-desktop.yml | 82 ++++++++++----------- .github/workflows/build-web.yml | 8 +- .github/workflows/chromatic.yml | 4 +- .github/workflows/crowdin-pull.yml | 2 +- .github/workflows/release-desktop-beta.yml | 60 +++++++-------- .github/workflows/repository-management.yml | 6 +- .github/workflows/scan.yml | 4 +- .github/workflows/version-auto-bump.yml | 2 +- 10 files changed, 95 insertions(+), 95 deletions(-) diff --git a/.github/workflows/build-browser.yml b/.github/workflows/build-browser.yml index 68d1f10a51a..aa62d602ad8 100644 --- a/.github/workflows/build-browser.yml +++ b/.github/workflows/build-browser.yml @@ -169,7 +169,7 @@ jobs: zip -r browser-source.zip browser-source - name: Upload browser source - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: browser-source-${{ env._BUILD_NUMBER }}.zip path: browser-source.zip @@ -272,7 +272,7 @@ jobs: working-directory: browser-source/apps/browser - name: Upload extension artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ matrix.artifact_name }}-${{ env._BUILD_NUMBER }}.zip path: browser-source/apps/browser/dist/${{ matrix.archive_name }} @@ -409,7 +409,7 @@ jobs: ls -la - name: Upload Safari artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: dist-safari-${{ env._BUILD_NUMBER }}.zip path: apps/browser/dist/dist-safari.zip diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index d480879fb15..02432e0a5f4 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -163,14 +163,14 @@ jobs: matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt - name: Upload unix zip asset - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-${{ env._PACKAGE_VERSION }}.zip if-no-files-found: error - name: Upload unix checksum asset - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-${{ env.LOWER_RUNNER_OS }}-sha256-${{ env._PACKAGE_VERSION }}.txt @@ -324,14 +324,14 @@ jobs: -t sha256 | Out-File -Encoding ASCII ./dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${env:_PACKAGE_VERSION}.txt - name: Upload windows zip asset - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-${{ env._PACKAGE_VERSION }}.zip if-no-files-found: error - name: Upload windows checksum asset - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt path: apps/cli/dist/bw${{ matrix.license_type.artifact_prefix }}-windows-sha256-${{ env._PACKAGE_VERSION }}.txt @@ -339,7 +339,7 @@ jobs: - name: Upload Chocolatey asset if: matrix.license_type.build_prefix == 'bit' - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg path: apps/cli/dist/chocolatey/bitwarden-cli.${{ env._PACKAGE_VERSION }}.nupkg @@ -350,7 +350,7 @@ jobs: - name: Upload NPM Build Directory asset if: matrix.license_type.build_prefix == 'bit' - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip path: apps/cli/bitwarden-cli-${{ env._PACKAGE_VERSION }}-npm-build.zip @@ -421,14 +421,14 @@ jobs: run: sudo snap remove bw - name: Upload snap asset - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bw_${{ env._PACKAGE_VERSION }}_amd64.snap path: apps/cli/dist/snap/bw_${{ env._PACKAGE_VERSION }}_amd64.snap if-no-files-found: error - name: Upload snap checksum asset - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt path: apps/cli/dist/snap/bw-snap-sha256-${{ env._PACKAGE_VERSION }}.txt diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 2a59dc28fc9..63453b93838 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -207,7 +207,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 id: cache with: path: | @@ -232,42 +232,42 @@ jobs: run: npm run dist:lin - name: Upload .deb artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb if-no-files-found: error - name: Upload .rpm artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm if-no-files-found: error - name: Upload .freebsd artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd if-no-files-found: error - name: Upload .snap artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap if-no-files-found: error - name: Upload .AppImage artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ needs.setup.outputs.release_channel }}-linux.yml path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml @@ -280,7 +280,7 @@ jobs: sudo npm run pack:lin:flatpak - name: Upload flatpak artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: com.bitwarden.desktop.flatpak path: apps/desktop/dist/com.bitwarden.desktop.flatpak @@ -373,7 +373,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 id: cache with: path: | @@ -428,91 +428,91 @@ jobs: -NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z - name: Upload portable exe artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload installer exe artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload appx ia32 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx if-no-files-found: error - name: Upload store appx ia32 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx if-no-files-found: error - name: Upload NSIS ia32 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z if-no-files-found: error - name: Upload appx x64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx if-no-files-found: error - name: Upload store appx x64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx if-no-files-found: error - name: Upload NSIS x64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z if-no-files-found: error - name: Upload appx ARM64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx if-no-files-found: error - name: Upload store appx ARM64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx if-no-files-found: error - name: Upload NSIS ARM64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z if-no-files-found: error - name: Upload nupkg artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ needs.setup.outputs.release_channel }}.yml path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release_channel }}.yml @@ -561,14 +561,14 @@ jobs: - name: Cache Build id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Cache Safari id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -681,7 +681,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 id: cache with: path: | @@ -749,14 +749,14 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -869,7 +869,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 id: cache with: path: | @@ -918,28 +918,28 @@ jobs: run: npm run pack:mac - name: Upload .zip artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip if-no-files-found: error - name: Upload .dmg artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg if-no-files-found: error - name: Upload .dmg blockmap artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ needs.setup.outputs.release_channel }}-mac.yml path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-mac.yml @@ -990,14 +990,14 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -1117,7 +1117,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 id: cache with: path: | @@ -1166,7 +1166,7 @@ jobs: run: npm run pack:mac:mas - name: Upload .pkg artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg @@ -1193,7 +1193,7 @@ jobs: if: | github.event_name != 'pull_request_target' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-desktop') - uses: slackapi/slack-github-action@37ebaef184d7626c5f204ab8d3baff4262dd30f0 # v1.27.0 + uses: slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3 # v1.27.1 with: channel-id: C074F5UESQ0 payload: | @@ -1252,14 +1252,14 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -1372,7 +1372,7 @@ jobs: npm link ../sdk-internal - name: Cache Native Module - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 id: cache with: path: | @@ -1424,7 +1424,7 @@ jobs: zip -r Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip Bitwarden.app - name: Upload masdev artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip path: apps/desktop/dist/mas-dev-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml index c686b46d51a..73ae0e14962 100644 --- a/.github/workflows/build-web.yml +++ b/.github/workflows/build-web.yml @@ -164,7 +164,7 @@ jobs: run: zip -r web-${{ env._VERSION }}-${{ matrix.name }}.zip build - name: Upload ${{ matrix.name }} artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: web-${{ env._VERSION }}-${{ matrix.name }}.zip path: apps/web/web-${{ env._VERSION }}-${{ matrix.name }}.zip @@ -274,7 +274,7 @@ jobs: - name: Build Docker image id: build-docker - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 + uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 # v6.10.0 with: context: apps/web file: apps/web/Dockerfile @@ -303,14 +303,14 @@ jobs: - name: Scan Docker image id: container-scan - uses: anchore/scan-action@5ed195cc06065322983cae4bb31e2a751feb86fd # v5.2.0 + uses: anchore/scan-action@869c549e657a088dc0441b08ce4fc0ecdac2bb65 # v5.3.0 with: image: ${{ steps.image-name.outputs.name }} fail-build: false output-format: sarif - name: Upload Grype results to GitHub - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 with: sarif_file: ${{ steps.container-scan.outputs.sarif }} diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml index 0efd9d22f17..a5ebd363f63 100644 --- a/.github/workflows/chromatic.yml +++ b/.github/workflows/chromatic.yml @@ -43,7 +43,7 @@ jobs: - name: Cache NPM id: npm-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: "~/.npm" key: ${{ runner.os }}-npm-chromatic-${{ hashFiles('**/package-lock.json') }} @@ -56,7 +56,7 @@ jobs: run: npm run build-storybook:ci - name: Publish to Chromatic - uses: chromaui/action@dd2eecb9bef44f54774581f4163b0327fd8cf607 # v11.16.3 + uses: chromaui/action@64a9c0ca3bfb724389b0d536e544f56b7b5ff5b3 # v11.20.2 with: token: ${{ secrets.GITHUB_TOKEN }} projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} diff --git a/.github/workflows/crowdin-pull.yml b/.github/workflows/crowdin-pull.yml index 1ac6dd9113f..027a2f11e55 100644 --- a/.github/workflows/crowdin-pull.yml +++ b/.github/workflows/crowdin-pull.yml @@ -22,7 +22,7 @@ jobs: crowdin_project_id: "308189" steps: - name: Generate GH App token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} diff --git a/.github/workflows/release-desktop-beta.yml b/.github/workflows/release-desktop-beta.yml index a940ce289ff..3ec11c77852 100644 --- a/.github/workflows/release-desktop-beta.yml +++ b/.github/workflows/release-desktop-beta.yml @@ -158,42 +158,42 @@ jobs: run: npm run dist:lin - name: Upload .deb artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-amd64.deb if-no-files-found: error - name: Upload .rpm artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.rpm if-no-files-found: error - name: Upload .freebsd artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.freebsd if-no-files-found: error - name: Upload .snap artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap path: apps/desktop/dist/bitwarden_${{ env._PACKAGE_VERSION }}_amd64.snap if-no-files-found: error - name: Upload .AppImage artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x86_64.AppImage if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ needs.setup.outputs.release-channel }}-linux.yml path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-linux.yml @@ -299,91 +299,91 @@ jobs: -NewName bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z - name: Upload portable exe artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/Bitwarden-Portable-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload installer exe artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe path: apps/desktop/dist/nsis-web/Bitwarden-Installer-${{ env._PACKAGE_VERSION }}.exe if-no-files-found: error - name: Upload appx ia32 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32.appx if-no-files-found: error - name: Upload store appx ia32 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-ia32-store.appx if-no-files-found: error - name: Upload NSIS ia32 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-ia32.nsis.7z if-no-files-found: error - name: Upload appx x64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64.appx if-no-files-found: error - name: Upload store appx x64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-x64-store.appx if-no-files-found: error - name: Upload NSIS x64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-x64.nsis.7z if-no-files-found: error - name: Upload appx ARM64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64.appx if-no-files-found: error - name: Upload store appx ARM64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-arm64-store.appx if-no-files-found: error - name: Upload NSIS ARM64 artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z path: apps/desktop/dist/nsis-web/bitwarden-${{ env._PACKAGE_VERSION }}-arm64.nsis.7z if-no-files-found: error - name: Upload nupkg artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: bitwarden.${{ env._PACKAGE_VERSION }}.nupkg path: apps/desktop/dist/chocolatey/bitwarden.${{ env._PACKAGE_VERSION }}.nupkg if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ needs.setup.outputs.release-channel }}.yml path: apps/desktop/dist/nsis-web/${{ needs.setup.outputs.release-channel }}.yml @@ -426,14 +426,14 @@ jobs: - name: Cache Build id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Cache Safari id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -560,14 +560,14 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -707,28 +707,28 @@ jobs: run: npm run pack:mac - name: Upload .zip artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal-mac.zip if-no-files-found: error - name: Upload .dmg artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg if-no-files-found: error - name: Upload .dmg blockmap artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap path: apps/desktop/dist/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.dmg.blockmap if-no-files-found: error - name: Upload auto-update artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: ${{ needs.setup.outputs.release-channel }}-mac.yml path: apps/desktop/dist/${{ needs.setup.outputs.release-channel }}-mac.yml @@ -773,14 +773,14 @@ jobs: - name: Get Build Cache id: build-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/desktop/build key: ${{ runner.os }}-${{ github.run_id }}-build - name: Setup Safari Cache id: safari-cache - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0 with: path: apps/browser/dist/Safari key: ${{ runner.os }}-${{ github.run_id }}-safari-extension @@ -915,7 +915,7 @@ jobs: APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} - name: Upload .pkg artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b # v4.5.0 with: name: Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-universal.pkg diff --git a/.github/workflows/repository-management.yml b/.github/workflows/repository-management.yml index aeafe17e5e0..a914a2c4a7a 100644 --- a/.github/workflows/repository-management.yml +++ b/.github/workflows/repository-management.yml @@ -66,7 +66,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Generate GH App token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} @@ -115,7 +115,7 @@ jobs: version: ${{ inputs.version_number_override }} - name: Generate GH App token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} @@ -452,7 +452,7 @@ jobs: - setup steps: - name: Generate GH App token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 6166ac79b1a..b0874b38cbf 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -31,7 +31,7 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: Scan with Checkmarx - uses: checkmarx/ast-github-action@f0869bd1a37fddc06499a096101e6c900e815d81 # 2.0.36 + uses: checkmarx/ast-github-action@184bf2f64f55d1c93fd6636d539edf274703e434 # 2.0.41 env: INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}" with: @@ -46,7 +46,7 @@ jobs: --output-path . ${{ env.INCREMENTAL }} - name: Upload Checkmarx results to GitHub - uses: github/codeql-action/upload-sarif@662472033e021d55d94146f66f6058822b0b39fd # v3.27.0 + uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 # v3.28.0 with: sarif_file: cx_result.sarif diff --git a/.github/workflows/version-auto-bump.yml b/.github/workflows/version-auto-bump.yml index f41261cb39a..ef46dbc867d 100644 --- a/.github/workflows/version-auto-bump.yml +++ b/.github/workflows/version-auto-bump.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Generate GH App token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1 id: app-token with: app-id: ${{ secrets.BW_GHAPP_ID }} From aeba2b3c73e953111c0907eba68d06596a5f6a12 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 22:29:53 -0500 Subject: [PATCH 32/65] [deps] Platform: Update webpack-cli to v6 (#12552) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 122 +++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 73 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index 197b7cb0093..ba7953d0faf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -179,7 +179,7 @@ "util": "0.12.5", "wait-on": "8.0.1", "webpack": "5.97.1", - "webpack-cli": "5.1.4", + "webpack-cli": "6.0.1", "webpack-dev-server": "5.2.0", "webpack-node-externals": "3.0.0" }, @@ -10338,45 +10338,45 @@ "license": "BSD-3-Clause" }, "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", + "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" } }, "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", + "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" } }, "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", + "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", "dev": true, "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" }, "peerDependenciesMeta": { "webpack-dev-server": { @@ -18831,6 +18831,16 @@ "node": ">= 0.4" } }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/into-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", @@ -27431,6 +27441,19 @@ "node": ">=0.10.0" } }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -31919,43 +31942,40 @@ } }, "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", + "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", "dev": true, "license": "MIT", "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", + "@discoveryjs/json-ext": "^0.6.1", + "@webpack-cli/configtest": "^3.0.1", + "@webpack-cli/info": "^3.0.1", + "@webpack-cli/serve": "^3.0.1", "colorette": "^2.0.14", - "commander": "^10.0.1", + "commander": "^12.1.0", "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", + "envinfo": "^7.14.0", "fastest-levenshtein": "^1.0.12", "import-local": "^3.0.2", "interpret": "^3.1.1", "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" + "webpack-merge": "^6.0.1" }, "bin": { "webpack-cli": "bin/cli.js" }, "engines": { - "node": ">=14.15.0" + "node": ">=18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "5.x.x" + "webpack": "^5.82.0" }, "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, "webpack-bundle-analyzer": { "optional": true }, @@ -31964,37 +31984,39 @@ } } }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=14" + "node": ">=14.17.0" } }, - "node_modules/webpack-cli/node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "node_modules/webpack-cli/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, "license": "MIT", "engines": { - "node": ">=10.13.0" + "node": ">=18" } }, - "node_modules/webpack-cli/node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "node_modules/webpack-cli/node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, "license": "MIT", "dependencies": { - "resolve": "^1.20.0" + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" }, "engines": { - "node": ">= 10.13.0" + "node": ">=18.0.0" } }, "node_modules/webpack-dev-middleware": { diff --git a/package.json b/package.json index 907723c3a02..843e9f34bb6 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "util": "0.12.5", "wait-on": "8.0.1", "webpack": "5.97.1", - "webpack-cli": "5.1.4", + "webpack-cli": "6.0.1", "webpack-dev-server": "5.2.0", "webpack-node-externals": "3.0.0" }, From b0f597128720331d7d0e19dcf08256be539f4d09 Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Fri, 3 Jan 2025 10:30:25 +0100 Subject: [PATCH 33/65] [PM-16664] Fix annual pricing for billable providers (#12662) --- .../provider-subscription.component.html | 13 +++++++------ .../provider-subscription.component.ts | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html index 50db2cb6a36..d23216cf7c1 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html @@ -38,12 +38,14 @@ }} - {{ ((100 - subscription.discountPercentage) / 100) * i.cost | currency: "$" }} /{{ - "month" | i18n + {{ + ((100 - subscription.discountPercentage) / 100) * getMonthlyCost(i) + | currency: "$" }} + / {{ "month" | i18n }}
- {{ i.cost | currency: "$" }} /{{ "month" | i18n }} + {{ getMonthlyCost(i) | currency: "$" }} / {{ "month" | i18n }}
@@ -52,9 +54,8 @@ - Total: {{ totalCost | currency: "$" }} /{{ - "month" | i18n - }} + Total: + {{ getTotalMonthlyCost() | currency: "$" }} / {{ "month" | i18n }} diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts index a6b27b9f3dd..8d222ec42bd 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts @@ -113,4 +113,20 @@ export class ProviderSubscriptionComponent implements OnInit, OnDestroy { } }); } + + protected getMonthlyCost(plan: ProviderPlanResponse): number { + return plan.cadence === "Monthly" ? plan.cost : plan.cost / 12; + } + + protected getDiscountedMonthlyCost(plan: ProviderPlanResponse): number { + return ((100 - this.subscription.discountPercentage) / 100) * this.getMonthlyCost(plan); + } + + protected getTotalMonthlyCost(): number { + let totalCost: number = 0; + for (const plan of this.subscription.plans) { + totalCost += this.getDiscountedMonthlyCost(plan); + } + return totalCost; + } } From 27e3f72e048c228b29b0770aed1fd6a2ab59e18d Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Fri, 3 Jan 2025 10:46:35 +0100 Subject: [PATCH 34/65] Revert "[PM-16664] Fix annual pricing for billable providers (#12662)" (#12677) This reverts commit b0f597128720331d7d0e19dcf08256be539f4d09. --- .../provider-subscription.component.html | 13 ++++++------- .../provider-subscription.component.ts | 16 ---------------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html index d23216cf7c1..50db2cb6a36 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.html @@ -38,14 +38,12 @@ }} - {{ - ((100 - subscription.discountPercentage) / 100) * getMonthlyCost(i) - | currency: "$" + {{ ((100 - subscription.discountPercentage) / 100) * i.cost | currency: "$" }} /{{ + "month" | i18n }} - / {{ "month" | i18n }}
- {{ getMonthlyCost(i) | currency: "$" }} / {{ "month" | i18n }} + {{ i.cost | currency: "$" }} /{{ "month" | i18n }}
@@ -54,8 +52,9 @@ - Total: - {{ getTotalMonthlyCost() | currency: "$" }} / {{ "month" | i18n }} + Total: {{ totalCost | currency: "$" }} /{{ + "month" | i18n + }} diff --git a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts index 8d222ec42bd..a6b27b9f3dd 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/subscription/provider-subscription.component.ts @@ -113,20 +113,4 @@ export class ProviderSubscriptionComponent implements OnInit, OnDestroy { } }); } - - protected getMonthlyCost(plan: ProviderPlanResponse): number { - return plan.cadence === "Monthly" ? plan.cost : plan.cost / 12; - } - - protected getDiscountedMonthlyCost(plan: ProviderPlanResponse): number { - return ((100 - this.subscription.discountPercentage) / 100) * this.getMonthlyCost(plan); - } - - protected getTotalMonthlyCost(): number { - let totalCost: number = 0; - for (const plan of this.subscription.plans) { - totalCost += this.getDiscountedMonthlyCost(plan); - } - return totalCost; - } } From 1f00eb1bfb7703db9e9686c62084274f57617c60 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 11:05:20 +0100 Subject: [PATCH 35/65] Autosync the updated translations (#12671) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/hr/messages.json | 2 +- apps/browser/src/_locales/nl/messages.json | 186 +++++++++--------- apps/browser/src/_locales/pl/messages.json | 2 +- apps/browser/src/_locales/pt_PT/messages.json | 2 +- apps/browser/src/_locales/sr/messages.json | 34 ++-- apps/browser/src/_locales/uk/messages.json | 2 +- apps/browser/src/_locales/zh_CN/messages.json | 18 +- apps/browser/store/locales/nl/copy.resx | 58 +++--- 8 files changed, 152 insertions(+), 152 deletions(-) diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 3b60cfe45c8..c93922cb913 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -1005,7 +1005,7 @@ "message": "Prikazuj identitete za jednostavnu auto-ispunu." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Klikni stavke za auto-ispunu na prikazu trezora" }, "clearClipboard": { "message": "Očisti međuspremnik", diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 7a252ee3ddb..d167ba220c1 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -181,7 +181,7 @@ "description": "This string is used on the vault page to indicate autofilling. Horizontal space is limited in the interface here so try and keep translations as concise as possible." }, "autoFill": { - "message": "Auto-invullen" + "message": "Automatisch invullen" }, "autoFillLogin": { "message": "Login automatisch invullen" @@ -688,7 +688,7 @@ "message": "Nu vergrendelen" }, "lockAll": { - "message": "Vergrendel alles" + "message": "Alles vergrendelen" }, "immediately": { "message": "Onmiddellijk" @@ -1043,7 +1043,7 @@ "message": "Ja, nu bijwerken" }, "notificationUnlockDesc": { - "message": "Ontgrendel je Bitwarden-kluis om het auto-invulverzoek te voltooien." + "message": "Ontgrendel je Bitwarden-kluis om het automatisch invullen verzoek te voltooien." }, "notificationUnlock": { "message": "Ontgrendelen" @@ -1200,7 +1200,7 @@ "message": "Geen bijlagen." }, "attachmentSaved": { - "message": "De bijlage is opgeslagen." + "message": "Bijlage opgeslagen" }, "file": { "message": "Bestand" @@ -1209,7 +1209,7 @@ "message": "Bestand om te delen" }, "selectFile": { - "message": "Selecteer een bestand." + "message": "Selecteer een bestand" }, "maxFileSize": { "message": "Maximale bestandsgrootte is 500 MB." @@ -1242,7 +1242,7 @@ "message": "1 GB versleutelde opslag voor bijlagen." }, "premiumSignUpEmergency": { - "message": "Noodtoegang" + "message": "Noodtoegang." }, "premiumSignUpTwoStepOptions": { "message": "Eigen opties voor tweestapsaanmelding zoals YubiKey en Duo." @@ -1425,10 +1425,10 @@ "message": "Specificeer de basis-URL van je zelfgehoste Bitwarden-installatie. Bijvoorbeeld: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Voor geavanceerde configuratie kun je de basis URL van elke service onafhankelijk opgeven." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Je moet de basis URL van de server of ten minste één aangepaste omgeving toevoegen." }, "customEnvironment": { "message": "Aangepaste omgeving" @@ -1459,14 +1459,14 @@ "message": "Pictogrammenserver-URL" }, "environmentSaved": { - "message": "De omgeving-URL's zijn opgeslagen." + "message": "Omgeving-URL's opgeslagen" }, "showAutoFillMenuOnFormFields": { - "message": "Auto-invulmenu op formuliervelden weergeven", + "message": "Automatisch invullen menu op formuliervelden weergeven", "description": "Represents the message for allowing the user to enable the autofill overlay" }, "autofillSuggestionsSectionTitle": { - "message": "Suggesties voor automatisch invullen" + "message": "Suggesties automatisch invullen" }, "showInlineMenuLabel": { "message": "Suggesties voor automatisch invullen op formuliervelden weergeven" @@ -1511,7 +1511,7 @@ "message": "Als een inlogformulier wordt gedetecteerd, dan worden de inloggegevens automatisch ingevuld." }, "experimentalFeature": { - "message": "Gehackte of onbetrouwbare websites kunnen auto-invullen tijdens het laden van de pagina misbruiken." + "message": "Gehackte of onbetrouwbare websites kunnen automatisch invullen tijdens het laden van de pagina misbruiken." }, "learnMoreAboutAutofillOnPageLoadLinkText": { "message": "Meer over risico's lezen" @@ -1535,7 +1535,7 @@ "message": "Automatisch invullen bij laden van pagina" }, "autoFillOnPageLoadNo": { - "message": "Niet Automatisch invullen bij laden van pagina" + "message": "Niet automatisch invullen bij laden van pagina" }, "commandOpenPopup": { "message": "Open kluis in pop-up" @@ -1606,7 +1606,7 @@ "message": "Een herkenbare afbeelding naast iedere login weergeven." }, "faviconDescAlt": { - "message": "Show a recognizable image next to each login. Applies to all logged in accounts." + "message": "Toon een herkenbare afbeelding naast elke login. Geldt voor alle ingelogde accounts." }, "enableBadgeCounter": { "message": "Teller weergeven" @@ -1690,7 +1690,7 @@ "message": "Dr." }, "mx": { - "message": "Mx" + "message": "Mx." }, "firstName": { "message": "Voornaam" @@ -1993,10 +1993,10 @@ "message": "Ontgrendelen met PIN" }, "setYourPinTitle": { - "message": "PIN-code instellen" + "message": "PIN instellen" }, "setYourPinButton": { - "message": "PIN-code instellen" + "message": "PIN instellen" }, "setYourPinCode": { "message": "Stel je PIN-code in voor het ontgrendelen van Bitwarden. Je PIN-code wordt opnieuw ingesteld als je je ooit volledig afmeldt bij de applicatie." @@ -2111,10 +2111,10 @@ "message": "Invullen en opslaan" }, "autoFillSuccessAndSavedUri": { - "message": "Automatisch gevuld item en opgeslagen URI" + "message": "Automatisch ingevuld item en opgeslagen URI" }, "autoFillSuccess": { - "message": "Automatisch gevuld item" + "message": "Item automatisch ingevuld " }, "insecurePageWarning": { "message": "Waarschuwing: Dit is een onbeveiligde HTTP-pagina waardoor anderen alle informatie die je verstuurt kunnen zien en wijzigen. Deze login is oorspronkelijk opgeslagen op een beveiligde (HTTPS) pagina." @@ -2225,7 +2225,7 @@ "message": "Fout bij vernieuwen toegangstoken" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Geen verversingstoken of API-sleutels gevonden. Probeer uit te loggen en weer in te loggen." }, "desktopSyncVerificationTitle": { "message": "Desktopsynchronisatieverificatie" @@ -2282,10 +2282,10 @@ "message": "Dit apparaat ondersteunt geen browserbiometrie." }, "biometricsNotUnlockedTitle": { - "message": "User locked or logged out" + "message": "Gebruiker vergrendeld of uitgelogd" }, "biometricsNotUnlockedDesc": { - "message": "Please unlock this user in the desktop application and try again." + "message": "Ontgrendel deze gebruiker in de desktopapplicatie en probeer het opnieuw." }, "biometricsNotAvailableTitle": { "message": "Biometrisch ontgrendelen niet beschikbaar" @@ -2623,11 +2623,11 @@ "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { - "message": "Your organization permissions were updated, requiring you to set a master password.", + "message": "De machtigingen van je organisatie zijn bijgewerkt, waardoor je een hoofdwachtwoord moet instellen.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "orgRequiresYouToSetPassword": { - "message": "Your organization requires you to set a master password.", + "message": "Je organisatie vereist dat je een hoofdwachtwoord instelt.", "description": "Used as a card title description on the set password page to explain why the user is there" }, "cardMetrics": { @@ -2766,7 +2766,7 @@ "message": "Persoonlijke kluis exporteren" }, "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.", + "message": "Alleen de individuele kluisitems die gekoppeld zijn aan $EMAIL$ worden geëxporteerd. Kluisitems van organisaties worden niet meegenomen. Alleen de informatie over het kluisitem wordt geëxporteerd en niet de bijbehorende bijlagen.", "placeholders": { "email": { "content": "$1", @@ -2869,7 +2869,7 @@ "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "$SERVICENAME$ fout: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -2887,7 +2887,7 @@ "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Website: $WEBSITE$. Gegenereerd door Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -2897,7 +2897,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Ongeldig $SERVICENAME$ API token", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -2907,7 +2907,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Ongeldige $SERVICENAME$ API token: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -2921,7 +2921,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "Kan $SERVICENAME$ gemaskeerde e-mailaccount-ID niet verkrijgen.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -2931,7 +2931,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Ongeldig $SERVICENAME$ domein.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -2941,7 +2941,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Ongeldige $SERVICENAME$ url.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -2951,7 +2951,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Onbekende $SERVICENAME$ fout opgetreden.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -2961,7 +2961,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Onbekende doorstuurder: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -3017,7 +3017,7 @@ "message": "zelfgehost" }, "thirdParty": { - "message": "van derden" + "message": "Derde partij" }, "thirdPartyServerMessage": { "message": "Verbonden met server implementatie van derden, $SERVERNAME$. Reproduceer bugs via de officiële server, of meld ze bij het serverproject.", @@ -3071,7 +3071,7 @@ "message": "Alle inlogopties bekijken" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "Alle inlogopties weergeven" }, "notificationSentDevice": { "message": "Er is een melding naar je apparaat verzonden." @@ -3125,10 +3125,10 @@ "message": "Je organisatiebeleid heeft het automatisch invullen bij laden van pagina ingeschakeld." }, "howToAutofill": { - "message": "Hoe automatisch aanvullen" + "message": "Hoe automatisch invullen" }, "autofillSelectInfoWithCommand": { - "message": "Select an item from this screen, use the shortcut $COMMAND$, or explore other options in settings.", + "message": "Selecteer een item in dit scherm, gebruik de sneltoets $COMMAND$ of verken andere opties in de instellingen.", "placeholders": { "command": { "content": "$1", @@ -3137,16 +3137,16 @@ } }, "autofillSelectInfoWithoutCommand": { - "message": "Select an item from this screen, or explore other options in settings." + "message": "Selecteer een item in dit scherm of verken andere opties in de instellingen." }, "gotIt": { - "message": "Ik snap het" + "message": "Oké" }, "autofillSettings": { "message": "Instellingen automatisch invullen" }, "autofillKeyboardShortcutSectionTitle": { - "message": "Shortcut voor automatisch invullen" + "message": "Snelkoppeling automatisch invullen" }, "autofillKeyboardShortcutUpdateLabel": { "message": "Snelkoppeling wijzigen" @@ -3243,7 +3243,7 @@ "message": "Algemeen" }, "display": { - "message": "Display" + "message": "Weergave" }, "accountSuccessfullyCreated": { "message": "Account succesvol aangemaakt!" @@ -3372,7 +3372,7 @@ "message": "-- Type om te filteren --" }, "multiSelectLoading": { - "message": "Opties ophalen..." + "message": "Opties ophalen…" }, "multiSelectNotFound": { "message": "Geen items gevonden" @@ -3413,7 +3413,7 @@ "description": "Notification button text for starting a fileless import." }, "importing": { - "message": "Importeren...", + "message": "Importeren…", "description": "Notification message for when an import is in progress." }, "dataSuccessfullyImported": { @@ -3432,33 +3432,33 @@ "message": "Aliasdomein" }, "passwordRepromptDisabledAutofillOnPageLoad": { - "message": "Items with master password re-prompt cannot be autofilled on page load. Autofill on page load turned off.", + "message": "Items met hoofdwachtwoord re-prompt kunnen niet automatisch worden ingevuld bij het laden van de pagina. Automatisch invullen bij laden van pagina uitgeschakeld.", "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": "Automatisch invullen bij het laden van een pagina ingesteld op de standaardinstelling.", "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": "Hoofdwachtwoord herhaalprompt uitschakelen om dit veld te bewerken", "description": "Message appearing below the autofill on load message when master password reprompt is set for a vault item." }, "toggleSideNavigation": { "message": "Zijnavigatie schakelen" }, "skipToContent": { - "message": "Skip to content" + "message": "Overslaan naar inhoud" }, "bitwardenOverlayButton": { "message": "Menuknop Bitwarden automatisch invullen", "description": "Page title for the iframe containing the overlay button" }, "toggleBitwardenVaultOverlay": { - "message": "Bitwarden auto-invulmenu in- en uitschakelen", + "message": "Bitwarden automatisch invullen menu in- en uitschakelen", "description": "Screen reader and tool tip label for the overlay button" }, "bitwardenVault": { - "message": "Bitwarden auto-invulmenu", + "message": "Bitwarden automatisch invullen menu", "description": "Page title in overlay" }, "unlockYourAccountToViewMatchingLogins": { @@ -3486,7 +3486,7 @@ "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { - "message": "Inloggegevens invullen voor", + "message": "Referenties invullen voor", "description": "Screen reader text for when overlay item is in focused" }, "partialUsername": { @@ -3530,7 +3530,7 @@ "description": "Screen reader text (aria-label) for new identity button within inline menu" }, "bitwardenOverlayMenuAvailable": { - "message": "Bitwarden auto-invulmenu beschikbaar. Druk op de pijltjestoets omlaag om te selecteren.", + "message": "Bitwarden automatisch invullen menu beschikbaar. Druk op de pijltjestoets omlaag om te selecteren.", "description": "Screen reader text for announcing when the overlay opens on the page" }, "turnOn": { @@ -3574,7 +3574,7 @@ "message": "Deze actie vereist verificatie actie. Stel een pincode in om door te gaan." }, "setPin": { - "message": "Pincode instellen" + "message": "PIN instellen" }, "verifyWithBiometrics": { "message": "Biometrisch ontgrendelen" @@ -3619,7 +3619,7 @@ "message": "Fout bij het verbinden met de Duo-service. Gebruik een andere tweestapsaanmeldingsmethode of neem contact op met Duo voor hulp." }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Start Duo en volg de stappen om het inloggen te voltooien." }, "duoRequiredForAccount": { "message": "Jouw account vereist Duo-tweestapsaanmelding." @@ -3628,10 +3628,10 @@ "message": "Open de extensie om in te loggen." }, "popoutExtension": { - "message": "Popout extension" + "message": "Pop-out extensie" }, "launchDuo": { - "message": "Launch Duo" + "message": "Duo starten" }, "importFormatError": { "message": "De gegevens zijn niet correct opgemaakt. Controleer je importbestand en probeer het opnieuw." @@ -3759,7 +3759,7 @@ "message": "Kies een passkey om mee in te loggen" }, "passkeyItem": { - "message": "Passkey-Item" + "message": "Passkey item" }, "overwritePasskey": { "message": "Passkey overschrijven?" @@ -3801,7 +3801,7 @@ "message": "LastPass Email" }, "importingYourAccount": { - "message": "Account impoteren..." + "message": "Account impoteren…" }, "lastPassMFARequired": { "message": "LastPass multifactor-authenticatie vereist" @@ -3825,10 +3825,10 @@ "message": "Wacht op SSO-authenticatie" }, "awaitingSSODesc": { - "message": "Ga door met inloggen met de inloggegevens van je bedrijf." + "message": "Ga door met inloggen met de referenties van je bedrijf." }, "seeDetailedInstructions": { - "message": "See detailed instructions on our help site at", + "message": "Zie gedetailleerde instructies op onze helpsite op", "description": "This is followed a by a hyperlink to the help website." }, "importDirectlyFromLastPass": { @@ -3844,52 +3844,52 @@ "message": "Collectie" }, "lastPassYubikeyDesc": { - "message": "Insert the YubiKey associated with your LastPass account into your computer's USB port, then touch its button." + "message": "Steek de YubiKey die bij je LastPass account hoort in de USB poort van je computer en druk dan op de knop." }, "switchAccount": { - "message": "Switch account" + "message": "Account wisselen" }, "switchAccounts": { - "message": "Switch accounts" + "message": "Accounts wisselen" }, "switchToAccount": { - "message": "Switch to account" + "message": "Wisselen naar account" }, "activeAccount": { - "message": "Active account" + "message": "Actief account" }, "availableAccounts": { "message": "Beschikbare accounts" }, "accountLimitReached": { - "message": "Account limit reached. Log out of an account to add another." + "message": "Accountlimiet bereikt. Log uit bij een account om een andere toe te voegen." }, "active": { - "message": "active" + "message": "actief" }, "locked": { - "message": "locked" + "message": "vergrendeld" }, "unlocked": { - "message": "unlocked" + "message": "ontgrendeld" }, "server": { "message": "server" }, "hostedAt": { - "message": "hosted at" + "message": "gehost op" }, "useDeviceOrHardwareKey": { - "message": "Use your device or hardware key" + "message": "Gebruik je apparaat of hardwaresleutel" }, "justOnce": { - "message": "Just once" + "message": "Eenmalig" }, "alwaysForThisSite": { - "message": "Always for this site" + "message": "Altijd voor deze site" }, "domainAddedToExcludedDomains": { - "message": "$DOMAIN$ added to excluded domains.", + "message": "$DOMAIN$ toegevoegd aan uitgesloten domeinen.", "placeholders": { "domain": { "content": "$1", @@ -3950,7 +3950,7 @@ "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "Referenties succesvol opgeslagen!", "description": "Notification message for when saving credentials has succeeded." }, "passwordSaved": { @@ -3958,7 +3958,7 @@ "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "Referenties succesvol bijgewerkt!", "description": "Notification message for when updating credentials has succeeded." }, "passwordUpdated": { @@ -3966,7 +3966,7 @@ "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "Fout bij het opslaan van referenties. Controleer console voor details.", "description": "Notification message for when saving credentials has failed." }, "success": { @@ -3979,7 +3979,7 @@ "message": "Passkey verwijderd" }, "autofillSuggestions": { - "message": "Suggesties voor automatisch invullen" + "message": "Suggesties automatisch invullen" }, "autofillSuggestionsTip": { "message": "Inlogitem opslaan voor automatisch invullen op deze site" @@ -3994,7 +3994,7 @@ "message": "Wis filters of probeer een andere zoekterm" }, "copyInfoTitle": { - "message": "Copy info - $ITEMNAME$", + "message": "Info kopiëren - $ITEMNAME$", "description": "Title for a button that opens a menu with options to copy information from an item.", "placeholders": { "itemname": { @@ -4004,7 +4004,7 @@ } }, "copyNoteTitle": { - "message": "Copy Note - $ITEMNAME$", + "message": "Notitie kopiëren - $ITEMNAME$", "description": "Title for a button copies a note to the clipboard.", "placeholders": { "itemname": { @@ -4014,7 +4014,7 @@ } }, "moreOptionsLabel": { - "message": "More options, $ITEMNAME$", + "message": "Meer opties, $ITEMNAME$", "description": "Aria label for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4024,7 +4024,7 @@ } }, "moreOptionsTitle": { - "message": "More options - $ITEMNAME$", + "message": "Meer opties - $ITEMNAME$", "description": "Title for a button that opens a menu with more options for an item.", "placeholders": { "itemname": { @@ -4034,7 +4034,7 @@ } }, "viewItemTitle": { - "message": "View item - $ITEMNAME$", + "message": "Item bekijken - $ITEMNAME$", "description": "Title for a link that opens a view for an item.", "placeholders": { "itemname": { @@ -4060,22 +4060,22 @@ "message": "Aan collecties toewijzen" }, "copyEmail": { - "message": "Copy email" + "message": "E-mail kopiëren" }, "copyPhone": { - "message": "Copy phone" + "message": "Telefoon kopiëren" }, "copyAddress": { - "message": "Copy address" + "message": "Adres kopiëren" }, "adminConsole": { - "message": "Admin Console" + "message": "Beheerconsole" }, "accountSecurity": { "message": "Accountbeveiliging" }, "notifications": { - "message": "Notifications" + "message": "Meldingen" }, "appearance": { "message": "Uiterlijk" @@ -4107,7 +4107,7 @@ } }, "new": { - "message": "New" + "message": "Nieuw" }, "removeItem": { "message": "Verwijder $NAME$", @@ -4245,7 +4245,7 @@ "description": "Used within the inline menu to provide an aria description when users are attempting to fill a card cipher." }, "loginCredentials": { - "message": "Inloggegevens" + "message": "Login referenties" }, "authenticatorKey": { "message": "Authenticatiesleutel" @@ -4546,10 +4546,10 @@ "message": "Itemlocatie" }, "fileSend": { - "message": "Bestand-Sends" + "message": "Bestand verzenden" }, "fileSends": { - "message": "Bestand-Sends" + "message": "Bestanden verzenden" }, "textSend": { "message": "Tekst-Sends" @@ -4567,7 +4567,7 @@ "message": "Accountacties" }, "showNumberOfAutofillSuggestions": { - "message": "Aantal login-autofill-suggesties op het extensie-pictogram weergeven" + "message": "Aantal login automatisch invullen suggesties op het extensie-pictogram weergeven" }, "showQuickCopyActions": { "message": "Toon snelle kopieeracties in de kluis" diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index 5d1cd22c9ef..a429059ea7d 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -1005,7 +1005,7 @@ "message": "Pokaż elementy tożsamości na stronie głównej, aby ułatwić autouzupełnianie." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Kliknij na dane logowania, aby autouzupełnić w widoku Sejfu" }, "clearClipboard": { "message": "Wyczyść schowek", diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 24caa7e813d..def50289ae6 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -803,7 +803,7 @@ "message": "Código de verificação inválido" }, "valueCopied": { - "message": "$VALUE$ copiado", + "message": "$VALUE$ copiado(a)", "description": "Value has been copied to the clipboard.", "placeholders": { "value": { diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 1a1ebf69794..d515c2a0c6b 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -193,10 +193,10 @@ "message": "Ауто-пуњење идентитета" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Пуни верификациони кôд" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "Пуни верификациони кôд", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -1005,7 +1005,7 @@ "message": "Прикажи ставке идентитета на страници за лакше аутоматско допуњавање." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Кликните на ставке за ауто-попуњавање у приказу сефа" }, "clearClipboard": { "message": "Обриши привремену меморију", @@ -3071,7 +3071,7 @@ "message": "Погледајте сав извештај у опције" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "Погледајте сав извештај у опције" }, "notificationSentDevice": { "message": "Обавештење је послато на ваш уређај." @@ -3478,11 +3478,11 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Једнократни верификациони кôд заснован на времену", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "Преостало време до истека актуелног ТОТП-а", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { @@ -4570,7 +4570,7 @@ "message": "Прикажи број предлога за ауто-попуњавање пријаве на икони додатка" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Приказати брзе радње копирања у Сефу" }, "systemDefault": { "message": "Системски подразумевано" @@ -4804,22 +4804,22 @@ "message": "Бета" }, "importantNotice": { - "message": "Important notice" + "message": "Важно обавештење" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Поставити дво-степенску пријаву" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden ће послати кôд на имејл вашег налога за верификовање пријављивања са нових уређаја почевши од фебруара 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Можете да подесите пријаву у два корака као алтернативни начин да заштитите свој налог или да промените свој имејл у један који можете да приступите." }, "remindMeLater": { - "message": "Remind me later" + "message": "Подсети ме касније" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Да ли имате поуздан приступ својим имејлом, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4828,16 +4828,16 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Не, ненам" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Да, могу поуздано да приступим овим имејлом" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Упалити дво-степенску пријаву" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Променити имејл налога" }, "extensionWidth": { "message": "Ширина додатка" diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index c817b55dab3..8e20bc56ff5 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -1005,7 +1005,7 @@ "message": "Показувати список посвідчень на сторінці вкладки для легкого автозаповнення." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Натисніть на запис у режимі перегляду сховища для автозаповнення" }, "clearClipboard": { "message": "Очистити буфер обміну", diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 39a945360f8..9af42f75e08 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -284,7 +284,7 @@ "message": "前往网页 App 吗?" }, "continueToWebAppDesc": { - "message": "在网页应用上探索 Bitwarden 账户的更多功能。" + "message": "在网页 App 上探索 Bitwarden 账户的更多功能。" }, "continueToHelpCenter": { "message": "前往帮助中心吗?" @@ -299,7 +299,7 @@ "message": "帮助别人了解 Bitwarden 是否适合他们。立即访问浏览器的扩展程序商店并留下评分。" }, "changeMasterPasswordOnWebConfirmation": { - "message": "您可以在 Bitwarden 网页应用上更改您的主密码。" + "message": "您可以在 Bitwarden 网页 App 上更改您的主密码。" }, "fingerprintPhrase": { "message": "指纹短语", @@ -597,7 +597,7 @@ "message": "前往" }, "launchWebsite": { - "message": "启动网站" + "message": "打开网站" }, "launchWebsiteName": { "message": "前往 $ITEMNAME$ 的网站", @@ -763,7 +763,7 @@ "message": "必须填写确认主密码。" }, "masterPasswordMinlength": { - "message": "主密码必须至少 $VALUE$ 个字符长度。", + "message": "主密码长度必须至少为 $VALUE$ 个字符。", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -1071,7 +1071,7 @@ "message": "主题" }, "themeDesc": { - "message": "更改本应用程序的颜色主题。" + "message": "更改应用程序的颜色主题。" }, "themeDescAlt": { "message": "更改应用程序的颜色主题。适用于所有已登录的账户。" @@ -1133,7 +1133,7 @@ "message": "确认密码库导出" }, "exportWarningDesc": { - "message": "导出的密码库数据包含未加密格式。您不应该通过不安全的渠道(例如电子邮件)来存储或发送导出的文件。用完后请立即将其删除。" + "message": "此导出包含未加密格式的密码库数据。您不应该通过不安全的渠道(例如电子邮件)来存储或发送此导出文件。使用完后请立即将其删除。" }, "encExportKeyWarningDesc": { "message": "此导出将使用您账户的加密密钥来加密您的数据。如果您曾经轮换过账户的加密密钥,您应将其重新导出,否则您将无法解密导出的文件。" @@ -4810,7 +4810,7 @@ "message": "设置两步登录" }, "newDeviceVerificationNoticeContentPage1": { - "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮箱发送一个代码,以验证来自新设备的登录。" + "message": "从 2025 年 02 月起,当有来自新设备的登录时,Bitwarden 将向您的账户电子邮箱发送验证码。" }, "newDeviceVerificationNoticeContentPage2": { "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" @@ -4819,7 +4819,7 @@ "message": "稍后提醒我" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "您能可靠地访问您的电子邮箱 $EMAIL$ 吗?", + "message": "您能可正常访问您的电子邮箱 $EMAIL$ 吗?", "placeholders": { "email": { "content": "$1", @@ -4831,7 +4831,7 @@ "message": "不,我不能" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "是的,我可以可靠地访问我的电子邮箱" + "message": "是的,我可以正常访问我的电子邮箱" }, "turnOnTwoStepLogin": { "message": "开启两步登录" diff --git a/apps/browser/store/locales/nl/copy.resx b/apps/browser/store/locales/nl/copy.resx index 6e646d5ece8..17720f54f4c 100644 --- a/apps/browser/store/locales/nl/copy.resx +++ b/apps/browser/store/locales/nl/copy.resx @@ -118,58 +118,58 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden - wachtwoordbeheerder + Bitwarden Wachtwoordbeheerder - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Thuis, op het werk of onderweg, Bitwarden beveiligt eenvoudig al je wachtwoorden, sleutels en gevoelige informatie. - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + Erkend als de beste wachtwoordmanager door PCMag, WIRED, The Verge, CNET, G2 en meer! -SECURE YOUR DIGITAL LIFE -Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. +BEVEILIG JE DIGITALE LEVEN +Beveilig je digitale leven en bescherm je tegen datalekken door unieke, sterke wachtwoorden te genereren en op te slaan voor elke account. Bewaar alles in een end-to-end versleutelde wachtwoordkluis waar alleen jij toegang toe hebt. -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +OVERAL EN ALTIJD TOEGANG TOT JE GEGEVENS, OP ELK APPARAAT +Beheer, bewaar, beveilig en deel een onbeperkt aantal wachtwoorden op een onbeperkt aantal apparaten zonder beperkingen. -EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE -Utilize Bitwarden for free with no ads or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. +IEDEREEN ZOU DE MIDDELEN MOETEN HEBBEN OM VEILIG ONLINE TE BLIJVEN +Gebruik Bitwarden gratis, zonder advertenties of verkoop van gegevens. Bitwarden vindt dat iedereen de mogelijkheid moet hebben om veilig online te zijn. Premium abonnementen bieden toegang tot geavanceerde functies. -EMPOWER YOUR TEAMS WITH BITWARDEN -Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. +VERSTERK JE TEAMS MET BITWARDEN +Abonnementen voor Teams en Enterprise worden geleverd met professionele zakelijke functies. Enkele voorbeelden zijn SSO-integratie, zelf hosten, directory-integratie en SCIM provisioning, globaal beleid, API-toegang, gebeurtenislogboeken en meer. -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +Gebruik Bitwarden om je medewerkers te beveiligen en gevoelige informatie te delen met collega's. -More reasons to choose Bitwarden: +Meer redenen om voor Bitwarden te kiezen: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Encryptie van wereldklasse +Wachtwoorden worden beschermd met geavanceerde end-to-end versleuteling (AES-256 bit, salted hashtag en PBKDF2 SHA-256) zodat je gegevens veilig en privé blijven. -3rd-party Audits -Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. +Audits door derde partijen +Bitwarden voert regelmatig uitgebreide beveiligingsaudits uit bij gerenommeerde beveiligingsbedrijven. Deze jaarlijkse audits omvatten broncodebeoordelingen en penetratietests voor Bitwarden IP's, servers en webapplicaties. -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +Geavanceerde 2FA +Beveilig je login met een authenticator van derden, codes per e-mail of FIDO2 WebAuthn referenties zoals een hardware beveiligingssleutel of passkey. Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +Verstuur gegevens rechtstreeks naar anderen met behoud van end-to-end versleutelde beveiliging en beperking van blootstelling. -Built-in Generator -Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. +Ingebouwde generator +Maak lange, complexe en duidelijke wachtwoorden en unieke gebruikersnamen voor elke site die je bezoekt. Integreer met e-mail alias providers voor extra privacy. -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +Wereldwijde vertalingen +Bitwarden vertalingen bestaan voor meer dan 60 talen, vertaald door de wereldwijde gemeenschap via Crowdin. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Platformoverkoepelende applicaties +Beveilig en deel gevoelige gegevens in je Bitwarden Vault vanuit elke browser, mobiel apparaat of desktop OS, en meer. -Bitwarden secures more than just passwords -End-to-end encrypted credential management solutions from Bitwarden empower organizations to secure everything, including developer secrets and passkey experiences. Visit Bitwarden.com to learn more about Bitwarden Secrets Manager and Bitwarden Passwordless.dev! +Bitwarden beveiligt meer dan alleen wachtwoorden +Met de end-to-end versleutelde oplossingen voor referentiebeheer van Bitwarden kunnen organisaties alles beveiligen, inclusief ontwikkelaarsgeheimen en ervaringen met wachtwoorden. Bezoek Bitwarden.com voor meer informatie over Bitwarden Secrets Manager en Bitwarden Passwordless.dev! - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Thuis, op het werk of onderweg, Bitwarden beveiligt eenvoudig al je wachtwoorden, sleutels en gevoelige informatie. Synchroniseer en gebruik je kluis op meerdere apparaten From 654eef1de27ffd45798e8a9694a6a529e373381f Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Fri, 3 Jan 2025 11:11:12 +0100 Subject: [PATCH 36/65] Remove v1 account switcher (#12577) Remove conditional rendering for extensionRefresh feature flag Co-authored-by: Daniel James Smith --- .../account-switcher.component.html | 236 +++++------------- .../account-switcher.component.ts | 9 - .../account-switching/account.component.html | 123 +++------ .../account-switching/account.component.ts | 1 - 4 files changed, 95 insertions(+), 274 deletions(-) diff --git a/apps/browser/src/auth/popup/account-switching/account-switcher.component.html b/apps/browser/src/auth/popup/account-switching/account-switcher.component.html index f0723d75ff8..0152cd1c7ff 100644 --- a/apps/browser/src/auth/popup/account-switching/account-switcher.component.html +++ b/apps/browser/src/auth/popup/account-switching/account-switcher.component.html @@ -1,182 +1,78 @@ - - - - - - - - + + + + + + + - - - -
- -
+ + + +
+ +
- - -

{{ "availableAccounts" | i18n }}

-
+ + +

{{ "availableAccounts" | i18n }}

+
-
- -
-
+
+ +
+
- -

- {{ "accountLimitReached" | i18n }} -

-
-
+

+ {{ "accountLimitReached" | i18n }} +

+
+
-
- - -

- {{ "options" | i18n }} -

-
+
+ + +

+ {{ "options" | i18n }} +

+
- - - - - - - - - -
-
- - - - - -
- -
-
{{ "switchAccounts" | i18n }}
-
- -
- -
-
-
-
-
    - -
  • - -
  • - -
    - {{ "availableAccounts" | i18n }} -
    -
  • - -
  • -
    -
    -
- -

+

- -
-
{{ "options" | i18n }}
-
- - - -
-
-
-
-
+ + {{ "lockNow" | i18n }} + + + + + + + + +
+
+
diff --git a/apps/browser/src/auth/popup/account-switching/account-switcher.component.ts b/apps/browser/src/auth/popup/account-switching/account-switcher.component.ts index fb636ecaf6d..25e1b2ae83f 100644 --- a/apps/browser/src/auth/popup/account-switching/account-switcher.component.ts +++ b/apps/browser/src/auth/popup/account-switching/account-switcher.component.ts @@ -10,9 +10,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeou import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { UserId } from "@bitwarden/common/types/guid"; import { AvatarModule, @@ -25,7 +23,6 @@ import { import { enableAccountSwitching } from "../../../platform/flags"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; -import { HeaderComponent } from "../../../platform/popup/header.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; @@ -44,7 +41,6 @@ import { AccountSwitcherService } from "./services/account-switcher.service"; AvatarModule, PopupPageComponent, PopupHeaderComponent, - HeaderComponent, PopOutComponent, CurrentAccountComponent, AccountComponent, @@ -58,7 +54,6 @@ export class AccountSwitcherComponent implements OnInit, OnDestroy { loading = false; activeUserCanLock = false; - extensionRefreshFlag = false; enableAccountSwitching = true; constructor( @@ -70,7 +65,6 @@ export class AccountSwitcherComponent implements OnInit, OnDestroy { private router: Router, private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private authService: AuthService, - private configService: ConfigService, private lockService: LockService, ) {} @@ -109,9 +103,6 @@ export class AccountSwitcherComponent implements OnInit, OnDestroy { async ngOnInit() { this.enableAccountSwitching = enableAccountSwitching(); - this.extensionRefreshFlag = await this.configService.getFeatureFlag( - FeatureFlag.ExtensionRefresh, - ); const availableVaultTimeoutActions = await firstValueFrom( this.vaultTimeoutSettingsService.availableVaultTimeoutActions$(), diff --git a/apps/browser/src/auth/popup/account-switching/account.component.html b/apps/browser/src/auth/popup/account-switching/account.component.html index d062c67a2e3..d2e15d31899 100644 --- a/apps/browser/src/auth/popup/account-switching/account.component.html +++ b/apps/browser/src/auth/popup/account-switching/account.component.html @@ -1,109 +1,44 @@ - - - - - - - - - - - - + - - + diff --git a/apps/browser/src/auth/popup/account-switching/account.component.ts b/apps/browser/src/auth/popup/account-switching/account.component.ts index 5c4132e491c..104241e9c7b 100644 --- a/apps/browser/src/auth/popup/account-switching/account.component.ts +++ b/apps/browser/src/auth/popup/account-switching/account.component.ts @@ -19,7 +19,6 @@ import { AccountSwitcherService, AvailableAccount } from "./services/account-swi }) export class AccountComponent { @Input() account: AvailableAccount; - @Input() extensionRefreshFlag: boolean = false; @Output() loading = new EventEmitter(); constructor( From c07454342d020bb8b9c775dbabf3dbad89eb047e Mon Sep 17 00:00:00 2001 From: Victoria League Date: Fri, 3 Jan 2025 09:41:18 -0500 Subject: [PATCH 37/65] [PM-16675] Prevent scrollbar from appearing on each send item (#12666) --- libs/components/src/item/item.component.ts | 2 +- .../send-list-items-container.component.html | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libs/components/src/item/item.component.ts b/libs/components/src/item/item.component.ts index 833949ddb96..97a80484373 100644 --- a/libs/components/src/item/item.component.ts +++ b/libs/components/src/item/item.component.ts @@ -20,7 +20,7 @@ import { ItemActionComponent } from "./item-action.component"; providers: [{ provide: A11yRowDirective, useExisting: ItemComponent }], host: { class: - "tw-block tw-box-border tw-overflow-auto tw-flex tw-bg-background [&:has(.item-main-content_button:hover,.item-main-content_a:hover)]:tw-cursor-pointer [&:has(.item-main-content_button:hover,.item-main-content_a:hover)]:tw-bg-primary-100 tw-text-main tw-border-solid tw-border-b tw-border-0 [&:not(bit-layout_*)]:tw-rounded-lg bit-compact:[&:not(bit-layout_*)]:tw-rounded-none bit-compact:[&:not(bit-layout_*)]:last-of-type:tw-rounded-b-lg bit-compact:[&:not(bit-layout_*)]:first-of-type:tw-rounded-t-lg tw-min-h-9 tw-mb-1.5 bit-compact:tw-mb-0", + "tw-block tw-box-border tw-overflow-hidden tw-flex tw-bg-background [&:has(.item-main-content_button:hover,.item-main-content_a:hover)]:tw-cursor-pointer [&:has(.item-main-content_button:hover,.item-main-content_a:hover)]:tw-bg-primary-100 tw-text-main tw-border-solid tw-border-b tw-border-0 [&:not(bit-layout_*)]:tw-rounded-lg bit-compact:[&:not(bit-layout_*)]:tw-rounded-none bit-compact:[&:not(bit-layout_*)]:last-of-type:tw-rounded-b-lg bit-compact:[&:not(bit-layout_*)]:first-of-type:tw-rounded-t-lg tw-min-h-9 tw-mb-1.5 bit-compact:tw-mb-0", }, }) export class ItemComponent extends A11yRowDirective { diff --git a/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.html b/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.html index a0f6c09f83e..d7755546365 100644 --- a/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.html +++ b/libs/tools/send/send-ui/src/send-list-items-container/send-list-items-container.component.html @@ -14,7 +14,6 @@

[queryParams]="{ sendId: send.id, type: send.type }" appStopClick type="button" - class="tw-pb-1" > Date: Fri, 3 Jan 2025 11:39:01 -0500 Subject: [PATCH 38/65] [deps] BRE: Update slackapi/slack-github-action action to v2 (#12140) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-desktop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 63453b93838..3221c7eef2f 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -1193,7 +1193,7 @@ jobs: if: | github.event_name != 'pull_request_target' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/rc' || github.ref == 'refs/heads/hotfix-rc-desktop') - uses: slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3 # v1.27.1 + uses: slackapi/slack-github-action@485a9d42d3a73031f12ec201c457e2162c45d02d # v2.0.0 with: channel-id: C074F5UESQ0 payload: | From 1e6471bb1d92a461dde935fd769c4a4bb41ec5e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 12:57:54 -0500 Subject: [PATCH 39/65] [deps] Platform: Update Rust crate cc to 1.2.4 (#12297) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- apps/desktop/desktop_native/Cargo.lock | 4 ++-- apps/desktop/desktop_native/objc/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 86c33d34843..384ee30b1c3 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -567,9 +567,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.4" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9157bbaa6b165880c27a4293a474c91cdcf265cc68cc829bf10be0964a391caf" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] diff --git a/apps/desktop/desktop_native/objc/Cargo.toml b/apps/desktop/desktop_native/objc/Cargo.toml index 1299e34a657..04e332b8db3 100644 --- a/apps/desktop/desktop_native/objc/Cargo.toml +++ b/apps/desktop/desktop_native/objc/Cargo.toml @@ -17,5 +17,5 @@ tokio = "1.39.1" core-foundation = "=0.10.0" [build-dependencies] -cc = "1.0.104" +cc = "1.2.4" glob = "0.3.1" From c69278e7616f4d15f42b62070bfb2a4264daa6aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 14:28:44 -0500 Subject: [PATCH 40/65] [deps] Platform: Update Rust crate uniffi to 0.28.3 (#12549) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- apps/desktop/desktop_native/Cargo.lock | 8 ++++---- apps/desktop/desktop_native/macos_provider/Cargo.toml | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 384ee30b1c3..1933eefd224 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -1134,7 +1134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -1519,7 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -2836,7 +2836,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3340,7 +3340,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] diff --git a/apps/desktop/desktop_native/macos_provider/Cargo.toml b/apps/desktop/desktop_native/macos_provider/Cargo.toml index 28cc6372c62..ff7408d6d44 100644 --- a/apps/desktop/desktop_native/macos_provider/Cargo.toml +++ b/apps/desktop/desktop_native/macos_provider/Cargo.toml @@ -21,10 +21,10 @@ serde = { version = "1.0.205", features = ["derive"] } serde_json = "1.0.122" tokio = { version = "1.39.2", features = ["sync"] } tokio-util = "0.7.11" -uniffi = { version = "0.28.0", features = ["cli"] } +uniffi = { version = "0.28.3", features = ["cli"] } [target.'cfg(target_os = "macos")'.dependencies] oslog = "0.2.0" [build-dependencies] -uniffi = { version = "0.28.0", features = ["build"] } +uniffi = { version = "0.28.3", features = ["build"] } From 05d373d070bb25a882d1ed8de6ee6c5e3b18f58e Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 3 Jan 2025 14:51:54 -0500 Subject: [PATCH 41/65] turn off autocomplete for browser search input (#12679) --- .../vault-v2/vault-search/vault-v2-search.component.html | 1 + libs/components/src/search/search.component.html | 1 + libs/components/src/search/search.component.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.html index 7cf154c0ee8..224eaccd93c 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-search/vault-v2-search.component.html @@ -1,4 +1,5 @@

diff --git a/libs/components/src/search/search.component.ts b/libs/components/src/search/search.component.ts index 6ec79eaa84e..9a811ce6777 100644 --- a/libs/components/src/search/search.component.ts +++ b/libs/components/src/search/search.component.ts @@ -46,6 +46,7 @@ export class SearchComponent implements ControlValueAccessor, FocusableElement { @Input() disabled: boolean; @Input() placeholder: string; + @Input() autocomplete: string; getFocusTarget() { return this.input.nativeElement; From dac23db9524d1c5cc8385018479bbf6bc5afd1c2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 15:15:32 -0500 Subject: [PATCH 42/65] [deps] Platform: Update Rust crate napi-build to v2.1.4 (#12546) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- apps/desktop/desktop_native/Cargo.lock | 4 ++-- apps/desktop/desktop_native/napi/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index 1933eefd224..b40246fca2d 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -1667,9 +1667,9 @@ dependencies = [ [[package]] name = "napi-build" -version = "2.1.3" +version = "2.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1c0f5d67ee408a4685b61f5ab7e58605c8ae3f2b4189f0127d804ff13d5560a" +checksum = "db836caddef23662b94e16bf1f26c40eceb09d6aee5d5b06a7ac199320b69b19" [[package]] name = "napi-derive" diff --git a/apps/desktop/desktop_native/napi/Cargo.toml b/apps/desktop/desktop_native/napi/Cargo.toml index 6a656cdc574..8e19d62c1e6 100644 --- a/apps/desktop/desktop_native/napi/Cargo.toml +++ b/apps/desktop/desktop_native/napi/Cargo.toml @@ -30,4 +30,4 @@ tokio-stream = "=0.1.15" windows-registry = "=0.3.0" [build-dependencies] -napi-build = "=2.1.3" +napi-build = "=2.1.4" From 196c1e1fa4189946d14b5aea468fb7d6aa94ed6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Tom=C3=A9?= <108268980+r-tome@users.noreply.github.com> Date: Fri, 3 Jan 2025 20:36:43 +0000 Subject: [PATCH 43/65] Fix installation ID missing in events by returning an object with the 'name' property instead of a string (#12463) --- .../admin-console/organizations/manage/events.component.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/web/src/app/admin-console/organizations/manage/events.component.ts b/apps/web/src/app/admin-console/organizations/manage/events.component.ts index c9fb1cb08f0..ab7306d9140 100644 --- a/apps/web/src/app/admin-console/organizations/manage/events.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/events.component.ts @@ -131,7 +131,9 @@ export class EventsComponent extends BaseEventsComponent implements OnInit, OnDe protected getUserName(r: EventResponse, userId: string) { if (r.installationId != null) { - return `Installation: ${r.installationId}`; + return { + name: `Installation: ${r.installationId}`, + }; } if (userId != null) { From d34888a5683d91d9c0c4dccedf44447cda82789a Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:31:19 +0100 Subject: [PATCH 44/65] Autosync the updated translations (#12672) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 55 +++++ apps/web/src/locales/ar/messages.json | 55 +++++ apps/web/src/locales/az/messages.json | 55 +++++ apps/web/src/locales/be/messages.json | 55 +++++ apps/web/src/locales/bg/messages.json | 55 +++++ apps/web/src/locales/bn/messages.json | 55 +++++ apps/web/src/locales/bs/messages.json | 55 +++++ apps/web/src/locales/ca/messages.json | 55 +++++ apps/web/src/locales/cs/messages.json | 55 +++++ apps/web/src/locales/cy/messages.json | 55 +++++ apps/web/src/locales/da/messages.json | 55 +++++ apps/web/src/locales/de/messages.json | 55 +++++ apps/web/src/locales/el/messages.json | 55 +++++ apps/web/src/locales/en_GB/messages.json | 55 +++++ apps/web/src/locales/en_IN/messages.json | 55 +++++ apps/web/src/locales/eo/messages.json | 55 +++++ apps/web/src/locales/es/messages.json | 55 +++++ apps/web/src/locales/et/messages.json | 55 +++++ apps/web/src/locales/eu/messages.json | 55 +++++ apps/web/src/locales/fa/messages.json | 55 +++++ apps/web/src/locales/fi/messages.json | 55 +++++ apps/web/src/locales/fil/messages.json | 55 +++++ apps/web/src/locales/fr/messages.json | 55 +++++ apps/web/src/locales/gl/messages.json | 55 +++++ apps/web/src/locales/he/messages.json | 55 +++++ apps/web/src/locales/hi/messages.json | 55 +++++ apps/web/src/locales/hr/messages.json | 55 +++++ apps/web/src/locales/hu/messages.json | 55 +++++ apps/web/src/locales/id/messages.json | 55 +++++ apps/web/src/locales/it/messages.json | 55 +++++ apps/web/src/locales/ja/messages.json | 55 +++++ apps/web/src/locales/ka/messages.json | 55 +++++ apps/web/src/locales/km/messages.json | 55 +++++ apps/web/src/locales/kn/messages.json | 55 +++++ apps/web/src/locales/ko/messages.json | 55 +++++ apps/web/src/locales/lv/messages.json | 55 +++++ apps/web/src/locales/ml/messages.json | 55 +++++ apps/web/src/locales/mr/messages.json | 55 +++++ apps/web/src/locales/my/messages.json | 55 +++++ apps/web/src/locales/nb/messages.json | 55 +++++ apps/web/src/locales/ne/messages.json | 55 +++++ apps/web/src/locales/nl/messages.json | 255 ++++++++++++++--------- apps/web/src/locales/nn/messages.json | 55 +++++ apps/web/src/locales/or/messages.json | 55 +++++ apps/web/src/locales/pl/messages.json | 55 +++++ apps/web/src/locales/pt_BR/messages.json | 55 +++++ apps/web/src/locales/pt_PT/messages.json | 55 +++++ apps/web/src/locales/ro/messages.json | 55 +++++ apps/web/src/locales/ru/messages.json | 55 +++++ apps/web/src/locales/si/messages.json | 55 +++++ apps/web/src/locales/sk/messages.json | 55 +++++ apps/web/src/locales/sl/messages.json | 55 +++++ apps/web/src/locales/sr/messages.json | 101 +++++++-- apps/web/src/locales/sr_CS/messages.json | 55 +++++ apps/web/src/locales/sv/messages.json | 55 +++++ apps/web/src/locales/te/messages.json | 55 +++++ apps/web/src/locales/th/messages.json | 55 +++++ apps/web/src/locales/tr/messages.json | 69 +++++- apps/web/src/locales/uk/messages.json | 55 +++++ apps/web/src/locales/vi/messages.json | 55 +++++ apps/web/src/locales/zh_CN/messages.json | 87 ++++++-- apps/web/src/locales/zh_TW/messages.json | 55 +++++ 62 files changed, 3556 insertions(+), 146 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 2e8c1fdea10..f86b6ab497b 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 91a223bc83f..ed843a62cd1 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 1b3685420ce..09785738464 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Güncəlllənən vergi məlumatı" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Doğrulanmayıb" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Təşkilat adı 50 xarakterdən çox ola bilməz." + }, + "resellerRenewalWarning": { + "message": "Abunəliyiniz tezliklə yenilənəcək. Kəsintisiz xidməti təmin etmək və yeniləməni $RENEWAL_DATE$ tarixindən əvvəl təsdiqləmək üçün $RESELLER$ ilə əlaqə saxlayın.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Abunəliyinizə aid faktura $ISSUED_DATE$ tarixində təqdim edildi. Kəsintisiz xidməti təmin etmək və yeniləməni $DUE_DATE$ tarixindən əvvəl təsdiqləmək üçün $RESELLER$ ilə əlaqə saxlayın.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Abunəliyinizə aid faktura üzrə ödəniş edilmədi. Kəsintisiz xidməti təmin etmək və yeniləməni $GRACE_PERIOD_END$ tarixindən əvvəl təsdiqləmək üçün $RESELLER$ ilə əlaqə saxlayın.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 335dcbbe650..ea705b38b4e 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 4a0f650bd3f..1f5fb8d8c7e 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Обновена данъчна информация" }, + "billingInvalidTaxIdError": { + "message": "Неправилен данъчен идентификатор. Ако смятате, че това е грешка, свържете се с поддръжката." + }, + "billingTaxIdTypeInferenceError": { + "message": "Не успяхме да потвърдим Вашия данъчен идентификатор. Ако смятате, че това е грешка, свържете се с поддръжката." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Неправилен данъчен идентификатор. Ако смятате, че това е грешка, свържете се с поддръжката." + }, + "billingPreviewInvoiceError": { + "message": "Възникна грешка при преглеждането на фактурата. Опитайте отново по-късно." + }, "unverified": { "message": "Непотвърден" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Името на организацията не може да бъде по-дълго от 50 знака." + }, + "resellerRenewalWarning": { + "message": "Вашият абонамент ще бъде подновен скоро. За да подсигурите, че услугата няма да има прекъсвания, свържете се с $RESELLER$ и потвърдете подновяването преди $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Фактура за абонамента Ви беше издадена на $ISSUED_DATE$. За да подсигурите, че услугата няма да има прекъсвания, свържете се с $RESELLER$ и потвърдете подновяването преди $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Фактурата за абонамента Ви не е била платена. За да подсигурите, че услугата няма да има прекъсвания, свържете се с $RESELLER$ и потвърдете подновяването преди $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 3860a66b925..56a04f3d870 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 1604eb20677..3e9c4525b04 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index 38684e8aefa..1cf16dcc0fd 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 0fdac8e60f3..64ce764de82 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Aktualizované daňové údaje" }, + "billingInvalidTaxIdError": { + "message": "Neplatné DIČ. Pokud se domníváte, že se jedná o chybu, kontaktujte podporu." + }, + "billingTaxIdTypeInferenceError": { + "message": "Nebyli jsme schopni ověřit Vaše DIČ. Pokud se domníváte, že se jedná o chybu, kontaktujte podporu." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Neplatné DIČ. Pokud se domníváte, že se jedná o chybu, kontaktujte podporu." + }, + "billingPreviewInvoiceError": { + "message": "Při náhledu faktury došlo k chybě. Opakujte akci později." + }, "unverified": { "message": "Neověřeno" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Název organizace nesmí přesáhnout 50 znaků." + }, + "resellerRenewalWarning": { + "message": "Vaše předplatné se brzy obnoví. Chcete-li zajistit nepřerušenou službu, kontaktujte $RESELLER$ pro potvrzení obnovení před $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Faktura pro Vaše předplatné byla vystavena dne $ISSUED_DATE$. Chcete-li zajistit nepřerušovanou službu, kontaktujte $RESELLER$ pro potvrzení obnovení před $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Faktura za Vaše předplatné nebyla zaplacena. Chcete-li zajistit nepřerušovanou službu, kontaktujte $RESELLER$ pro potvrzení obnovení před $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index c774497eae2..c0c39c91d30 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index 86bb1145217..b2b3b0491c3 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Opdaterede momsoplysninger" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Ubekræftet" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organisationsnavn må ikke overstige 50 tegn." + }, + "resellerRenewalWarning": { + "message": "Abonnementet fornyes snart. For at sikre uafbrudt tjeneste, kontakt $RESELLER$ for at bekræfte fornyelsen inden $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "En faktura for abonnementet er udstedt pr. $ISSUED_DATE$. For at sikre uafbrudt tjeneste, kontakt $RESELLER$ for at bekræfte fornyelsen inden $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Fakturaen for abonnementet er ikke blevet betalt. For at sikre uafbrudt tjeneste, kontakt $RESELLER$ for at bekræfte fornyelsen inden $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 4ed75be054f..4596dd88b3a 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Steuerinformationen aktualisiert" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Nicht verifiziert" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Der Name der Organisation darf 50 Zeichen nicht überschreiten." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index 50a327b1fa1..42d24fae72d 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Τα φορολογικά στοιχεία ενημερώθηκαν" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index 3da937ec266..f37aa8150cf 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organisation name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index dd507896e56..131b6b36383 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organisation name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index 06225dba76f..0170c225c03 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index f2548036c2a..3c3d7bb135d 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index 21096b3f710..700c748add8 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index 19de255284b..4c7719ada13 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index bb422bf70ae..fe0ba063a7b 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index a5d576d349d..234cfb0ee3e 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Verotiedot muutettiin" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Vahvistamaton" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 6257f2b5eaf..f5a9b078984 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index c9f87b19267..e6c402293f8 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Informations sur les taxes mises à jour" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Non vérifié" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Le nom de l'organisation ne doit pas dépasser 50 caractères." + }, + "resellerRenewalWarning": { + "message": "Votre abonnement sera renouvelé bientôt. Pour assurer un service sans interruption, contactez $RESELLER$ pour confirmer votre renouvellement avant $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Une facture pour votre abonnement a été émise sur $ISSUED_DATE$. Pour assurer un service sans interruption, contactez $RESELLER$ pour confirmer votre renouvellement avant $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "La facture de votre abonnement n'a pas été payée. Pour assurer un service sans interruption, contactez $RESELLER$ pour confirmer votre renouvellement avant $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 7fd7be8395d..986350b0637 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 32e51d6a037..9c4ef530721 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 3f2bd5897e6..82a0c12a390 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 5a397cd4b14..7b77ae9d58f 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Ažurirane porezne informacije" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Nepotvrđeno" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Naziv organizacije ne može biti duži od 50 znakova." + }, + "resellerRenewalWarning": { + "message": "Tvoja će se pretplata uskoro obnoviti. Za neprekinutu uslugu, kontaktiraj $RESELLER$ za potvrdu obnove prije $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Za tvoju je pretplatu $ISSUED_DATE$ izdana faktura. Za neprekinutu uslugu, kontaktiraj $RESELLER$ za potvrdu obnove prije $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Faktura za tvoju pretplatu nije plaćena. Za neprekinutu uslugu, kontaktiraj $RESELLER$ za potvrdu obnovu prije $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 682f080fb87..ecd7db04ca1 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Frissített adó információ" }, + "billingInvalidTaxIdError": { + "message": "Érvénytelen az adóazonosító. Ha úgy gondoljuk, hogy ez hiba, forduljunk az ügyfélszolgálathoz." + }, + "billingTaxIdTypeInferenceError": { + "message": "Nem lehetett ellenőrizni az adóazonosítót. Ha úgy gondoljuk, hogy ez hiba, forduljunk az ügyfélszolgálathoz." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Érvénytelen az adóazonosító. Ha úgy gondoljuk, hogy ez hiba, forduljunk az ügyfélszolgálathoz." + }, + "billingPreviewInvoiceError": { + "message": "Hiba történt a számla előnézete közben. Próbáljuk újra később." + }, "unverified": { "message": "Nem ellenőrzött" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "A szervezet neve nem haladhatja meg az 50 karaktert." + }, + "resellerRenewalWarning": { + "message": "Az előfizetés hamarosan megújul. A folyamatos szolgáltatás biztosítása érdekében lépjünk kapcsolatba $RESELLER$ viszonteladóval és erősítsük meg a megújítást $RENEWAL_DATE$ előtt.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Az előfizetésről szóló számla kiállítása $ISSUED_DATE$ napon történt. A megszakítás nélküli szolgáltatás biztosítása érdekében lépjünk kapcsolatba $RESELLER$ viszonteladóval és erősítsük meg a megújítást $DUE_DATE$ előtt.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Az előfizetésről szóló számla nem lett kfizetve. A folyamatos szolgáltatás biztosítása érdekében lépjünk kapcsolatba $RESELLER$ viszonteladóval és erősítsük meg a megújítást $GRACE_PERIOD_END$ előtt.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 877a6b21261..7517cac5ae5 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 36bcc07a023..0154a3c8c78 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Informazioni fiscali aggiornate" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Non verificato" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 343818e3ad4..1383ce49170 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "更新された税情報" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "未認証" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index 2a61cd89766..cc4dc222103 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index c5a77826c9e..36ab0050700 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index ec7241be790..e1fd4cc9ac9 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 59c0e15ee33..7966191f530 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 8f8ae16320c..6546b248914 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Atjaunināta nodokļu informācija" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Neapliecināts" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Apvienības nosaukums nevar pārsniegt 50 rakstzīmes." + }, + "resellerRenewalWarning": { + "message": "Abonements drīz tiks atjaunots. Lai nodrošinātu nepārtrauktu pakalpojumu, pirms $RENEWAL_DATE$ jāsazinās ar $RESELLER$, lai apstiprinātu atjaunošanu.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Rēķins par abonementu tika izdots $ISSUED_DATE$. Lai nodrošinātu nepārtrauktu pakalpojumu, pirms $DUE_DATE$ jāsazinās ar $RESELLER$, lai apstiprinātu atjaunošanu.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Rēķins par abonementu nav apmaksāts. Lai nodrošinātu nepārtrauktu pakalpojumu, pirms $GRACE_PERIOD_END$ jāsazināš ar $RESELLER$, lai apstiprinātu atjaunošanu.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index bca6a172b62..c6f9aa8d853 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index c5a77826c9e..36ab0050700 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index c5a77826c9e..36ab0050700 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index caf22428259..af26fc4df94 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index 345b8945460..e51fb3ced67 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 4e6e29704b6..cd72a94251c 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -952,7 +952,7 @@ "message": "Uitgelogd" }, "loggedOutDesc": { - "message": "You have been logged out of your account." + "message": "Je bent afgemeld bij je account." }, "loginExpired": { "message": "Je inlogsessie is verlopen." @@ -1126,7 +1126,7 @@ "message": "De verificatiesessie is verlopen. Start het inlogproces opnieuw op." }, "verifyIdentity": { - "message": "Verify your Identity" + "message": "Controleer je identiteit" }, "logInInitiated": { "message": "Inloggen gestart" @@ -1254,7 +1254,7 @@ "message": "E-mailadres" }, "yourVaultIsLockedV2": { - "message": "Je kluis is vergrendeld." + "message": "Je kluis is vergrendeld" }, "yourAccountIsLocked": { "message": "Je account is vergrendeld" @@ -1450,7 +1450,7 @@ "message": "Wijzig de verzamelingen waarmee dit item gedeeld is. Alleen organisatiegebruikers met toegang tot deze verzamelingen kunnen dit item inzien." }, "deleteSelectedItemsDesc": { - "message": "Je hebt $COUNT$ item(s) geselecteerd om te verwijderen. Weet je zeker dat je al deze items wilt verwijderen?", + "message": "$COUNT$ item(s) worden naar de prullenbak gestuurd.", "placeholders": { "count": { "content": "$1", @@ -1471,7 +1471,7 @@ "message": "Weet je zeker dat je wilt doorgaan?" }, "moveSelectedItemsDesc": { - "message": "Choose a folder that you would like to add the $COUNT$ selected item(s) to.", + "message": "Kies een map waaraan je de $COUNT$ geselecteerde item(s) wilt toevoegen.", "placeholders": { "count": { "content": "$1", @@ -1506,10 +1506,10 @@ "message": "UUID kopiëren" }, "errorRefreshingAccessToken": { - "message": "Access Token Refresh Error" + "message": "Fout bij vernieuwen toegangstoken" }, "errorRefreshingAccessTokenDesc": { - "message": "No refresh token or API keys found. Please try logging out and logging back in." + "message": "Geen verversingstoken of API-sleutels gevonden. Probeer uit te loggen en weer in te loggen." }, "warning": { "message": "Waarschuwing" @@ -1590,7 +1590,7 @@ "message": "Dit bestand is beveiligd met een wachtwoord. Voer het bestandswachtwoord in om gegevens te importeren." }, "exportSuccess": { - "message": "Je kluisgegevens zijn geëxporteerd." + "message": "Kluisgegevens geëxporteerd" }, "passwordGenerator": { "message": "Wachtwoordgenerator" @@ -1870,11 +1870,11 @@ "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new login instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { - "message": " aanmaken.", + "message": " in plaats daarvan.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead." }, "onboardingImportDataDetailsPartTwoWithOrgs": { - "message": " aanmaken. Je moet misschien wachten tot je beheerder je organisatielidmaatschap bevestigt.", + "message": " in plaats daarvan. Je moet misschien wachten tot je beheerder je organisatielidmaatschap bevestigt.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "importError": { @@ -1884,7 +1884,7 @@ "message": "Er was een probleem met de data die je probeerde te importeren. Los de onderstaande fouten op in het bronbestand en probeer het opnieuw." }, "importSuccess": { - "message": "De gegevens zijn in je kluis geïmporteerd." + "message": "Gegevens succesvol geïmporteerd" }, "importSuccessNumberOfItems": { "message": "Een totaal van $AMOUNT$ items zijn geïmporteerd.", @@ -2752,7 +2752,7 @@ "message": "Weet je zeker dat je wilt opzeggen? Je verliest toegang tot alle functionaliteiten van dit abonnement aan het einde van deze betalingscyclus." }, "canceledSubscription": { - "message": "Het abonnement is opgezegd." + "message": "Abonnement geannuleerd" }, "neverExpires": { "message": "Vervalt nooit" @@ -3138,7 +3138,7 @@ "message": "Je nieuwe organisatie is klaar voor gebruik!" }, "organizationUpgraded": { - "message": "Je organisatie is bijgewerkt." + "message": "Organisatie bijgewerkt" }, "leave": { "message": "Verlaten" @@ -3147,7 +3147,7 @@ "message": "Weet je zeker dat je deze organisatie wilt verlaten?" }, "leftOrganization": { - "message": "Je hebt de organisatie verlaten." + "message": "Je hebt de organisatie verlaten" }, "defaultCollection": { "message": "Standaardverzameling" @@ -3285,7 +3285,7 @@ "message": "Eigenaar" }, "ownerDesc": { - "message": "De gebruiker met de hoogste toegangsrechten. Deze gebruiker kan alle aspecten van je organisatie beheren." + "message": "De gebruiker met de hoogste toegangsrechten. Deze gebruiker kan alle aspecten van je organisatie beheren" }, "clientOwnerDesc": { "message": "Deze gebruiker moet onafhankelijk zijn van de provider. Als de provider is losgekoppeld van de organisatie, blijft deze gebruiker eigenaar van de organisatie." @@ -3294,22 +3294,22 @@ "message": "Beheerder" }, "adminDesc": { - "message": "Beheerders hebben toegang tot alle items, verzamelingen en gebruikers binnen je organisatie en kunnen deze ook beheren." + "message": "Beheerders hebben toegang tot alle items, verzamelingen en gebruikers binnen je organisatie en kunnen deze ook beheren" }, "user": { "message": "Gebruiker" }, "userDesc": { - "message": "Een standaardgebruiker met toegang tot de verzamelingen van je organisatie." + "message": "Items openen en toevoegen aan toegewezen collecties" }, "all": { "message": "Alle" }, "addAccess": { - "message": "Add Access" + "message": "Toegang toevoegen" }, "addAccessFilter": { - "message": "Add Access Filter" + "message": "Toegangsfilter toevoegen" }, "refresh": { "message": "Verversen" @@ -3351,16 +3351,16 @@ "message": "Bitwarden Secrets Manager" }, "loggedIn": { - "message": "Ingelogd." + "message": "Ingelogd" }, "changedPassword": { - "message": "Accountwachtwoord veranderd." + "message": "Accountwachtwoord veranderd" }, "enabledUpdated2fa": { - "message": "Tweestapsaanmelding geactiveerd/bijgewerkt." + "message": "Inloggen in twee stappen opgeslagen" }, "disabled2fa": { - "message": "Tweestapsaanmelding uitgeschakeld." + "message": "Inloggen in twee stappen uitgeschakeld" }, "recovered2fa": { "message": "Account hersteld van tweestapsaanmelding." @@ -3385,7 +3385,7 @@ "description": "PIN code. Ex. The short code (often numeric) that you use to unlock a device." }, "exportedVault": { - "message": "Kluis geëxporteerd." + "message": "Kluis geëxporteerd" }, "exportedOrganizationVault": { "message": "Organisatiekluis geëxporteerd." @@ -3808,7 +3808,7 @@ "message": "Wijzig de groep waar deze gebruiker bij hoort." }, "invitedUsers": { - "message": "Gebruiker(s) uitgenodigd." + "message": "Gebruiker(s) uitgenodigd" }, "resendInvitation": { "message": "Uitnodiging opnieuw versturen" @@ -3817,7 +3817,7 @@ "message": "E-mail opnieuw versturen" }, "hasBeenReinvited": { - "message": "$USER$ is opnieuw uitgenodigd.", + "message": "$USER$ opnieuw uitgenodigd", "placeholders": { "user": { "content": "$1", @@ -3865,7 +3865,7 @@ "message": "Kijk in het postvak IN van je e-mail voor een verificatielink." }, "emailVerified": { - "message": "Je e-mailadres is geverifieerd." + "message": "Account e-mail geverifieerd" }, "emailVerifiedV2": { "message": "E-mailadres geverifieerd" @@ -4089,7 +4089,7 @@ "message": "Als je de bankrekening niet verifieert mis je een betaling waardoor je abonnement wordt uitgeschakeld." }, "verifiedBankAccount": { - "message": "Bankrekening geverifieerd." + "message": "Bankrekening geverifieerd" }, "bankAccount": { "message": "Bankrekening" @@ -4181,10 +4181,10 @@ "message": "Aanpassingen aan je abonnement leiden tot evenredige wijzigingen in je factuurtotaal. Als nieuwe gebruikers je gebruikersplaatsen overschrijden, ontvang je onmiddellijk een afschrijving voor de extra gebruikers." }, "smStandaloneTrialSeatCountUpdateMessageFragment1": { - "message": "If you want to add additional" + "message": "Als je aanvullende" }, "smStandaloneTrialSeatCountUpdateMessageFragment2": { - "message": "seats without the bundled offer, please contact" + "message": "plaatsen zonder de gebundelde aanbieding, neem dan contact op met" }, "subscriptionUserSeatsLimitedAutoscale": { "message": "Aanpassingen aan je abonnement leiden tot evenredige wijzigingen in je factuurtotaal. Als nieuwe gebruikers je gebruikersplaatsen overschrijden, ontvang je onmiddellijk een afschrijving voor de extra gebruikers tot het aantal van $MAX$ gebruikersplaatsen is bereikt.", @@ -4394,7 +4394,7 @@ "description": "ex. Date this password was updated" }, "organizationIsDisabled": { - "message": "Organisatie uitgeschakeld." + "message": "Organisatie opgeschort" }, "secretsAccessSuspended": { "message": "Opgeschorte organisaties zijn niet toegankelijk. Neem contact op met de eigenaar van je organisatie voor hulp." @@ -4662,7 +4662,7 @@ } }, "permanentlyDeletedItemId": { - "message": "Definitief verwijderd item $ID$.", + "message": "Item $ID$ permanent verwijderd", "placeholders": { "id": { "content": "$1", @@ -4683,7 +4683,7 @@ "message": "Herstelde items" }, "restoredItemId": { - "message": "Hersteld item $ID$.", + "message": "Item $ID$ hersteld", "placeholders": { "id": { "content": "$1", @@ -5102,7 +5102,7 @@ } }, "emergencyApproved": { - "message": "Noodtoegang goedgekeurd." + "message": "Noodtoegang goedgekeurd" }, "emergencyRejected": { "message": "Noodtoegang afgewezen" @@ -5194,7 +5194,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Custom roles is an enterprise feature. Contact our support team to upgrade your subscription'" }, "customDescNonEnterpriseLink": { - "message": "Enterprise feature", + "message": "enterprise functie", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Custom roles is an enterprise feature. Contact our support team to upgrade your subscription'" }, "customDescNonEnterpriseEnd": { @@ -5533,7 +5533,7 @@ "message": "Wachtwoord opnieuw ingesteld!" }, "resetPasswordEnrollmentWarning": { - "message": "Inschrijving stelt organisatiebeheerders in staat om je hoofdwachtwoord te wijzigen. Weet je zeker dat je wilt inschrijven?" + "message": "Registratie geeft organisatiebeheerders de mogelijkheid om je hoofdwachtwoord te wijzigen" }, "accountRecoveryPolicy": { "message": "Accountherstel-administratie" @@ -5617,10 +5617,10 @@ "message": "Bulkactie status" }, "bulkConfirmMessage": { - "message": "Succesvol bevestigd." + "message": "Succesvol bevestigd" }, "bulkReinviteMessage": { - "message": "Succesvol opnieuw uitgenodigd." + "message": "Succesvol opnieuw uitgenodigd" }, "bulkRemovedMessage": { "message": "Succesvol verwijderd" @@ -5632,7 +5632,7 @@ "message": "Toegang tot de organisatie hersteld" }, "bulkFilteredMessage": { - "message": "Uitgezonderd, niet van toepassing voor deze actie." + "message": "Uitgesloten, niet van toepassing op deze actie" }, "nonCompliantMembersTitle": { "message": "Niet-conforme leden" @@ -5671,7 +5671,7 @@ "message": "Providernaam" }, "providerSetup": { - "message": "De provider is ingesteld." + "message": "Provider succesvol ingesteld" }, "clients": { "message": "Apparaten" @@ -5757,7 +5757,7 @@ } }, "providerIsDisabled": { - "message": "Provider is uitgeschakeld." + "message": "Aanbieder geschorst" }, "providerUpdated": { "message": "Provider bijgewerkt" @@ -5835,7 +5835,7 @@ "message": "Minuten" }, "vaultTimeoutPolicyInEffect": { - "message": "Het beleid van je organisatie heeft invloed op de time-out van je kluis. De maximaal toegestane time-out voor je kluis is $HOURS$ uur en $MINUTES$ minuten", + "message": "Het beleid van je organisatie heeft invloed op de time-out van je kluis. De maximaal toegestane time-out voor je kluis is $HOURS$ uur en $MINUTES$ minuten.", "placeholders": { "hours": { "content": "$1", @@ -6037,7 +6037,7 @@ "message": "Onderteken authenticatie aanvragen" }, "ssoSettingsSaved": { - "message": "Single Sign-On configuratie is opgeslagen." + "message": "Single sign-on configuratie opgeslagen" }, "sponsoredFamilies": { "message": "Gratis Bitwarden Families" @@ -6196,7 +6196,7 @@ "message": "Hoofdwachtwoord verwijderen" }, "removedMasterPassword": { - "message": "Hoofdwachtwoord verwijderd." + "message": "Hoofdwachtwoord verwijderd" }, "allowSso": { "message": "SSO-authenticatie toestaan" @@ -6319,37 +6319,37 @@ "message": "Het roteren van het factureringssynchronisatietoken maakt het vorige token ongeldig." }, "selfHostedServer": { - "message": "self-hosted" + "message": "zelf gehost" }, "customEnvironment": { - "message": "Custom environment" + "message": "Aangepaste omgeving" }, "selfHostedBaseUrlHint": { - "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com" + "message": "Geef de basis URL op van je on-premises gehoste Bitwarden installatie. Voorbeeld: https://bitwarden.company.com" }, "selfHostedCustomEnvHeader": { - "message": "For advanced configuration, you can specify the base URL of each service independently." + "message": "Voor geavanceerde configuratie kun je de basis URL van elke service onafhankelijk opgeven." }, "selfHostedEnvFormInvalid": { - "message": "You must add either the base Server URL or at least one custom environment." + "message": "Je moet de basis URL van de server of ten minste één aangepaste omgeving toevoegen." }, "apiUrl": { - "message": "API server URL" + "message": "API-server URL" }, "webVaultUrl": { - "message": "Web vault server URL" + "message": "Webkluisserver URL" }, "identityUrl": { - "message": "Identity server URL" + "message": "Identiteitsserver URL" }, "notificationsUrl": { - "message": "Notifications server URL" + "message": "Meldingen server URL" }, "iconsUrl": { - "message": "Icons server URL" + "message": "Pictogrammen server URL" }, "environmentSaved": { - "message": "Environment URLs saved" + "message": "Omgevings-URL's opgeslagen" }, "selfHostingTitle": { "message": "Zelfgehost" @@ -6358,7 +6358,7 @@ "message": "Voor het instellen van je organisatie op je eigen server, moet je je licentiebestand uploaden. Om gratis Families-plannen en geavanceerde factureringsmogelijkheden voor je zelfgehoste organisatie te ondersteunen, moet je factureringssynchronisatie instellen." }, "billingSyncApiKeyRotated": { - "message": "Token geroteerd." + "message": "Token geroteerd" }, "billingSyncKeyDesc": { "message": "Er is een factureringssynchronisatietoken van de abonnementsinstellingen van je cloudorganisatie vereist voor het afronden van dit formulier." @@ -6679,7 +6679,7 @@ "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { - "message": "$SERVICENAME$ error: $ERRORMESSAGE$", + "message": "$SERVICENAME$ fout: $ERRORMESSAGE$", "description": "Reports an error returned by a forwarding service to the user.", "placeholders": { "servicename": { @@ -6693,11 +6693,11 @@ } }, "forwarderGeneratedBy": { - "message": "Generated by Bitwarden.", + "message": "Gegenereerd door Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen." }, "forwarderGeneratedByWithWebsite": { - "message": "Website: $WEBSITE$. Generated by Bitwarden.", + "message": "Website: $WEBSITE$. Gegenereerd door Bitwarden.", "description": "Displayed with the address on the forwarding service's configuration screen.", "placeholders": { "WEBSITE": { @@ -6707,7 +6707,7 @@ } }, "forwaderInvalidToken": { - "message": "Invalid $SERVICENAME$ API token", + "message": "Ongeldig $SERVICENAME$ API token", "description": "Displayed when the user's API token is empty or rejected by the forwarding service.", "placeholders": { "servicename": { @@ -6717,7 +6717,7 @@ } }, "forwaderInvalidTokenWithMessage": { - "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$", + "message": "Ongeldige $SERVICENAME$ API token: $ERRORMESSAGE$", "description": "Displayed when the user's API token is rejected by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -6731,7 +6731,7 @@ } }, "forwarderNoAccountId": { - "message": "Unable to obtain $SERVICENAME$ masked email account ID.", + "message": "Kan $SERVICENAME$ gemaskeerde e-mailaccount-ID niet verkrijgen.", "description": "Displayed when the forwarding service fails to return an account ID.", "placeholders": { "servicename": { @@ -6741,7 +6741,7 @@ } }, "forwarderNoDomain": { - "message": "Invalid $SERVICENAME$ domain.", + "message": "Ongeldig $SERVICENAME$ domein.", "description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.", "placeholders": { "servicename": { @@ -6751,7 +6751,7 @@ } }, "forwarderNoUrl": { - "message": "Invalid $SERVICENAME$ url.", + "message": "Ongeldige $SERVICENAME$ url.", "description": "Displayed when the url of the forwarding service wasn't supplied.", "placeholders": { "servicename": { @@ -6761,7 +6761,7 @@ } }, "forwarderUnknownError": { - "message": "Unknown $SERVICENAME$ error occurred.", + "message": "Onbekende $SERVICENAME$ fout opgetreden.", "description": "Displayed when the forwarding service failed due to an unknown error.", "placeholders": { "servicename": { @@ -6771,7 +6771,7 @@ } }, "forwarderUnknownForwarder": { - "message": "Unknown forwarder: '$SERVICENAME$'.", + "message": "Onbekende doorstuurder: '$SERVICENAME$'.", "description": "Displayed when the forwarding service is not supported.", "placeholders": { "servicename": { @@ -7478,7 +7478,7 @@ "message": "Geef toegang tot collecties door ze aan deze groep toe te voegen." }, "restrictedCollectionAssignmentDesc": { - "message": "You can only assign collections you manage." + "message": "Je kunt alleen verzamelingen toewijzen die je beheert." }, "selectMembers": { "message": "Leden selecteren" @@ -7700,7 +7700,7 @@ "message": "Groepen selecteren" }, "userPermissionOverrideHelperDesc": { - "message": "Permissions set for a member will replace permissions set by that member's group." + "message": "Rechten ingesteld voor een lid vervangen de rechten ingesteld door de groep van dat lid." }, "noMembersOrGroupsAdded": { "message": "Geen leden of groepen toegevoegd" @@ -7904,7 +7904,7 @@ "message": "Werk je versleutelingsinstellingen bij om aan de nieuwe beveiligingsaanbevelingen te voldoen en de bescherming van je account te verbeteren." }, "kdfSettingsChangeLogoutWarning": { - "message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login, if any. We recommend exporting your vault before changing your encryption settings to prevent data loss." + "message": "Als je doorgaat, log je uit van alle actieve sessies. Je zult opnieuw moeten inloggen en, indien van toepassing, tweestapsverificatie moeten voltooien. We raden aan om je kluis te exporteren voordat je je versleutelingsinstellingen wijzigt om gegevensverlies te voorkomen." }, "secretsManager": { "message": "Secrets Manager" @@ -8559,10 +8559,10 @@ "message": "Je hebt geen toegang om deze collectie te beheren." }, "grantAddAccessCollectionWarningTitle": { - "message": "Missing Can Manage Permissions" + "message": "Ontbrekende Kan beheren machtigingen" }, "grantAddAccessCollectionWarning": { - "message": "Grant Can manage permissions to allow full collection management including deletion of collection." + "message": "Kan beheren machtigingen verlenen voor volledig verzamelingsbeheer, inclusief het verwijderen van verzamelingen." }, "grantCollectionAccess": { "message": "Groepen of mensen toegang tot deze collectie geven." @@ -8660,7 +8660,7 @@ "message": "Het is niet mogelijk om jezelf toe te voegen aan groepen." }, "cannotAddYourselfToCollections": { - "message": "You cannot add yourself to collections." + "message": "Je kunt jezelf niet toevoegen aan verzamelingen." }, "assign": { "message": "Toewijzen" @@ -9112,25 +9112,25 @@ } }, "createNewClientToManageAsProvider": { - "message": "Create a new client organization to manage as a Provider. Additional seats will be reflected in the next billing cycle." + "message": "Maak een nieuwe clientorganisatie aan om te beheren als Aanbieder. Extra plaatsen worden weergegeven in de volgende factureringscyclus." }, "selectAPlan": { - "message": "Select a plan" + "message": "Selecteer een plan" }, "thirtyFivePercentDiscount": { - "message": "35% Discount" + "message": "35% korting" }, "monthPerMember": { - "message": "month per member" + "message": "maand per lid" }, "seats": { - "message": "Seats" + "message": "Personen" }, "addOrganization": { - "message": "Add organization" + "message": "Organisatie toevoegen" }, "createdNewClient": { - "message": "Successfully created new client" + "message": "Nieuwe klant succesvol aangemaakt" }, "noAccess": { "message": "Geen toegang" @@ -9139,16 +9139,16 @@ "message": "Deze collectie is alleen toegankelijk vanaf de admin console" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Organisatiemenu togglen" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Kluisitem selecteren" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Verzamelitem selecteren" }, "manageBillingFromProviderPortalMessage": { - "message": "Manage billing from the Provider Portal" + "message": "Facturering beheren vanuit het aanbiederportaal" }, "continueSettingUpFreeTrial": { "message": "Doorgaan met het instellen van je gratis proefperiode van Bitwarden" @@ -9169,7 +9169,7 @@ "message": "Voer je organisatie-informatie voor Enterprise in" }, "viewItemsIn": { - "message": "View items in $NAME$", + "message": "Bekijk items in $NAME$", "description": "Button to view the contents of a folder or collection", "placeholders": { "name": { @@ -9179,7 +9179,7 @@ } }, "backTo": { - "message": "Back to $NAME$", + "message": "Terug naar $NAME$", "description": "Navigate back to a previous folder or collection", "placeholders": { "name": { @@ -9189,11 +9189,11 @@ } }, "back": { - "message": "Back", + "message": "Terug", "description": "Button text to navigate back" }, "removeItem": { - "message": "Remove $NAME$", + "message": "$NAME$ verwijderen", "description": "Remove a selected option, such as a folder or collection", "placeholders": { "name": { @@ -9203,13 +9203,13 @@ } }, "viewInfo": { - "message": "View info" + "message": "Bekijk info" }, "viewAccess": { - "message": "View access" + "message": "Toegang bekijken" }, "noCollectionsSelected": { - "message": "You have not selected any collections." + "message": "Je hebt geen verzamelingen geselecteerd." }, "updateName": { "message": "Naam bijwerken" @@ -9218,7 +9218,7 @@ "message": "Organisatienaam bijgewerkt" }, "providerPlan": { - "message": "Managed Service Provider" + "message": "Beheerde dienstaanbieder" }, "managedServiceProvider": { "message": "Managed service provider" @@ -9227,10 +9227,10 @@ "message": "Multi-organisatie onderneming" }, "orgSeats": { - "message": "Organization Seats" + "message": "Organisatie plaatsen" }, "providerDiscount": { - "message": "$AMOUNT$% Discount", + "message": "$AMOUNT$% korting", "placeholders": { "amount": { "content": "$1", @@ -9239,7 +9239,7 @@ } }, "lowKDFIterationsBanner": { - "message": "Laag aantal KDF-iteraties. Verhoog je iteraties om de veiligheid van je account te verbeteren," + "message": "Laag aantal KDF-iteraties. Verhoog je iteraties om de veiligheid van je account te verbeteren." }, "changeKDFSettings": { "message": "KDF-instellingen wijzigen" @@ -9251,10 +9251,10 @@ "message": "Bescherm je gezin of bedrijf" }, "upgradeOrganizationCloseSecurityGaps": { - "message": "Close security gaps with monitoring reports" + "message": "Beveiligingslekken dichten met bewakingsrapporten" }, "upgradeOrganizationCloseSecurityGapsDesc": { - "message": "Stay ahead of security vulnerabilities by upgrading to a paid plan for enhanced monitoring." + "message": "Blijf kwetsbaarheden in de beveiliging voor door te upgraden naar een betaald plan voor verbeterde monitoring." }, "approveAllRequests": { "message": "Alle verzoeken goedkeuren" @@ -9269,13 +9269,25 @@ "message": "Bitcoin" }, "updatedTaxInformation": { - "message": "Updated tax information" + "message": "Bijgewerkte belastinggegevens" + }, + "billingInvalidTaxIdError": { + "message": "Ongeldig btw-nummer, als je denkt dat dit een fout is, neem dan contact op met support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We konden je btw-nummer niet valideren, als je denkt dat dit een fout is, neem dan contact op met support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Ongeldig btw-nummer, als je denkt dat dit een fout is, neem dan contact op met support." + }, + "billingPreviewInvoiceError": { + "message": "Er is een fout opgetreden met het weergeven van de factuur. Probeer het later nog eens." }, "unverified": { - "message": "Unverified" + "message": "Niet-geverifieerd" }, "verified": { - "message": "Verified" + "message": "Geverifieerd" }, "viewSecret": { "message": "Geheim weergeven" @@ -9698,7 +9710,7 @@ "message": "Je Secrets Manager-abonnement zal upgraden naar het geselecteerde abonnement" }, "bitwardenPasswordManager": { - "message": "Bitwarden Password Manager" + "message": "Bitwarden Wachtwoordbeheerder" }, "secretsManagerComplimentaryPasswordManager": { "message": "Je gratis eenjarige Password Manager-abonnement zal veranderen naar het geselecteerde abonnement. Er worden pas kosten in rekening gebracht als de gratis periode voorbij is." @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organisatienaam mag niet langer zijn dan 50 tekens." + }, + "resellerRenewalWarning": { + "message": "Je abonnement wordt binnenkort verlengd. Neem voor $RENEWAL_DATE$ contact op met $RESELLER$ om je verlenging te bevestigen en een ononderbroken service te verzekeren.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Er is een factuur voor je abonnement aangemaakt op $ISSUED_DATE$. Neem contact op met $RESELLER$ voor $DUE_DATE$ om je verlenging te bevestigen en een ononderbroken service te verzekeren.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "De factuur voor je abonnement is niet betaald. Neem contact op met $RESELLER$ voor $GRACE_PERIOD_END$ om je verlenging te bevestigen en een ononderbroken service te verzekeren.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 7951e875fe8..0e3c134ba4d 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index c5a77826c9e..36ab0050700 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 67d63ce9b33..58e4de95317 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Zaktualizowane informacje podatkowe" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Niezweryfikowane" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 5461370c663..463b7f5e060 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Informações fiscais atualizadas" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Não verificado" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 28b65826f02..57a2eee7cf5 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Informações fiscais atualizadas" }, + "billingInvalidTaxIdError": { + "message": "Número de identificação fiscal inválido. Se considerar que se trata de um erro, contacte a assistência." + }, + "billingTaxIdTypeInferenceError": { + "message": "Não foi possível validar o seu número de identificação fiscal. Se considerar que se trata de um erro, contacte a assistência." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Número de identificação fiscal inválido. Se considerar que se trata de um erro, contacte a assistência." + }, + "billingPreviewInvoiceError": { + "message": "Ocorreu um erro ao pré-visualizar a fatura. Por favor, tente novamente mais tarde." + }, "unverified": { "message": "Não verificado" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "O nome da organização não pode exceder 50 caracteres." + }, + "resellerRenewalWarning": { + "message": "A sua subscrição será renovada em breve. Para garantir um serviço ininterrupto, contacte a $RESELLER$ para confirmar a sua renovação antes de $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "A fatura da sua subscrição foi emitida a $ISSUED_DATE$. Para garantir um serviço ininterrupto, contacte a $RESELLER$ para confirmar a sua renovação antes de $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "A fatura da sua subscrição não foi paga. Para garantir um serviço ininterrupto, contacte a $RESELLER$ para confirmar a sua renovação antes de $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index 5fdb6ab5e68..18ff0b2158f 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index fd309722f46..89209f2fa52 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Обновление сведений о налогах" }, + "billingInvalidTaxIdError": { + "message": "Недействительный ID, если вы считаете, что это ошибка, обратитесь в службу поддержки." + }, + "billingTaxIdTypeInferenceError": { + "message": "Мы не смогли подтвердить ваш ID, если вы считаете, что это ошибка, обратитесь в службу поддержки." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Недействительный ID, если вы считаете, что это ошибка, обратитесь в службу поддержки." + }, + "billingPreviewInvoiceError": { + "message": "При подготовке счета произошла ошибка. Пожалуйста, повторите попытку позже." + }, "unverified": { "message": "Неверифицирован" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Название организации не может превышать 50 символов." + }, + "resellerRenewalWarning": { + "message": "Ваша подписка скоро будет продлена. Чтобы гарантировать непрерывность сервиса, свяжитесь с $RESELLER$ для подтверждения продления до $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Счет за вашу подписку был выставлен $ISSUED_DATE$. Чтобы гарантировать непрерывность сервиса, свяжитесь с $RESELLER$, чтобы подтвердить продление подписки до $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Счет за вашу подписку не был оплачен. Чтобы гарантировать непрерывность сервиса, свяжитесь с $RESELLER$ для подтверждения продления до $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index 3dfac52754f..0649f83f519 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 947e459b8fd..4c47afaa63d 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Aktualizované daňové informácie" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Neoverený" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Meno organizácie nemôže mať viac ako 50 znakov." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 55aceaecf2b..9a9535aebaa 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 17e82485f8c..e15d6d66653 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -3889,7 +3889,7 @@ "message": "Користите неподржани веб прегледач. Веб сеф можда неће правилно функционисати." }, "freeTrialEndPromptCount": { - "message": "Your free trial ends in $COUNT$ days.", + "message": "Ваша проба се завршава за $COUNT$ дана.", "placeholders": { "count": { "content": "$1", @@ -3898,7 +3898,7 @@ } }, "freeTrialEndPromptMultipleDays": { - "message": "$ORGANIZATION$, your free trial ends in $COUNT$ days.", + "message": "$ORGANIZATION$, Ваша проба са завршава за $COUNT$ дана.", "placeholders": { "count": { "content": "$2", @@ -3911,7 +3911,7 @@ } }, "freeTrialEndPromptTomorrow": { - "message": "$ORGANIZATION$, your free trial ends tomorrow.", + "message": "$ORGANIZATION$, Ваша проба са завршава сутра.", "placeholders": { "organization": { "content": "$1", @@ -3920,10 +3920,10 @@ } }, "freeTrialEndPromptTomorrowNoOrgName": { - "message": "Your free trial ends tomorrow." + "message": "Ваша бесплатна пробна се завршава сутра." }, "freeTrialEndPromptToday": { - "message": "$ORGANIZATION$, your free trial ends today.", + "message": "$ORGANIZATION$, Ваша проба са завршава данас.", "placeholders": { "organization": { "content": "$1", @@ -3932,10 +3932,10 @@ } }, "freeTrialEndingTodayWithoutOrgName": { - "message": "Your free trial ends today." + "message": "Ваша бесплатна пробна се завршава данас." }, "clickHereToAddPaymentMethod": { - "message": "Click here to add a payment method." + "message": "Кликните овде да додате начин плаћања." }, "joinOrganization": { "message": "Придружи Организацију" @@ -4492,7 +4492,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": "Бићете обавештени када захтев буде одобрен" }, "free": { "message": "Бесплатно", @@ -6529,7 +6529,7 @@ "message": "Генериши име" }, "generateEmail": { - "message": "Generate email" + "message": "Генеришите имејл" }, "spinboxBoundariesHint": { "message": "Value must be between $MIN$ and $MAX$.", @@ -9018,7 +9018,7 @@ "message": "Употребите Bitwarden Secrets Manager SDK на следећим програмским језицима да направите сопствене апликације." }, "ssoDescStart": { - "message": "Configure", + "message": "Подеси", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure single sign-on for Bitwarden using the implementation guide for your Identity Provider." }, "ssoDescEnd": { @@ -9032,7 +9032,7 @@ "message": "SCIM" }, "scimIntegrationDescStart": { - "message": "Configure ", + "message": "Подеси ", "description": "This represents the beginning of a sentence, broken up to include links. The full sentence will be 'Configure SCIM (System for Cross-domain Identity Management) to automatically provision users and groups to Bitwarden using the implementation guide for your Identity Provider" }, "scimIntegrationDescEnd": { @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Ажуриране пореске информације" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Непроверено" }, @@ -9885,22 +9897,22 @@ "message": "Descriptor code" }, "importantNotice": { - "message": "Important notice" + "message": "Важно обавештење" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Поставити дво-степенску пријаву" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden ће послати кôд на имејл вашег налога за верификовање пријављивања са нових уређаја почевши од фебруара 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Можете да подесите пријаву у два корака као алтернативни начин да заштитите свој налог или да промените свој имејл у један који можете да приступите." }, "remindMeLater": { - "message": "Remind me later" + "message": "Подсети ме касније" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Да ли имате поуздан приступ својим имејлом, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -9909,19 +9921,19 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "Не, ненам" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Да, могу поуздано да приступим овим имејлом" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Упалити дво-степенску пријаву" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Променити имејл налога" }, "removeMembers": { - "message": "Remove members" + "message": "Уклони чланове" }, "claimedDomains": { "message": "Claimed domains" @@ -9954,7 +9966,7 @@ "message": "Claimed" }, "domainStatusUnderVerification": { - "message": "Under verification" + "message": "Под провером" }, "claimedDomainsDesc": { "message": "Claim a domain to own all member accounts whose email address matches the domain. Members will be able to skip the SSO identifier when logging in. Administrators will also be able to delete member accounts." @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index 6dd5fed6736..b2cd3a877d4 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index b4d2fb7aa8d..14d7bc4572c 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index c5a77826c9e..36ab0050700 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index 5d2da786d83..c731b9ff87e 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index fb821407a16..ba53ebe7dd4 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -3,22 +3,22 @@ "message": "Tüm uygulamalar" }, "criticalApplications": { - "message": "Critical applications" + "message": "Kritik uygulamalar" }, "accessIntelligence": { "message": "Access Intelligence" }, "riskInsights": { - "message": "Risk Insights" + "message": "Risk İçgörüleri" }, "passwordRisk": { - "message": "Password Risk" + "message": "Parola Riski" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "Uygulamalar genelinde risk altındaki parolaları (zayıf, açık veya yeniden kullanılan) gözden geçirin. Kullanıcılarınız için risk altındaki parolalara yönelik güvenlik eylemlerine öncelik vermek üzere en kritik uygulamalarınızı seçin." }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "Veri son güncellenme tarihi: $DATE$", "placeholders": { "date": { "content": "$1", @@ -30,10 +30,10 @@ "message": "Bildirilen üyeler" }, "revokeMembers": { - "message": "Revoke members" + "message": "Üyeleri iptal et" }, "restoreMembers": { - "message": "Restore members" + "message": "Üyeleri geri yükle" }, "cannotRestoreAccessError": { "message": "Cannot restore organization access" @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Doğrulanmadı" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 89d538e1a2a..c17befc27ce 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Податкову інформацію оновлено" }, + "billingInvalidTaxIdError": { + "message": "Недійсний ІПН. Якщо ви вважаєте це помилкою, зверніться до служби підтримки." + }, + "billingTaxIdTypeInferenceError": { + "message": "Не вдалося перевірити ваш ІПН. Якщо ви вважаєте це помилкою, зверніться до служби підтримки." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Недійсний ІПН. Якщо ви вважаєте це помилкою, зверніться до служби підтримки." + }, + "billingPreviewInvoiceError": { + "message": "Під час перегляду рахунку виникла помилка. Повторіть спробу пізніше." + }, "unverified": { "message": "Не перевірений" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Назва організації не може перевищувати 50 символів." + }, + "resellerRenewalWarning": { + "message": "Ваша передплата невдовзі поновиться. Щоб забезпечити безперебійну роботу, зверніться до $RESELLER$ для підтвердження поновлення до $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "Рахунок за вашу передплату випущено $ISSUED_DATE$. Щоб забезпечити безперебійну роботу, зверніться до $RESELLER$ для підтвердження поновлення до $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "Рахунок за вашу передплату ще не сплачено. Щоб забезпечити безперебійну роботу, зверніться до $RESELLER$ для підтвердження поновлення до $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index c8300de6fbf..9f4156014c6 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "Updated tax information" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "Unverified" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index e0856dc4350..a7d73801372 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1521,7 +1521,7 @@ "message": "确认机密导出" }, "exportWarningDesc": { - "message": "本次导出包含未加密格式的密码库数据。您不应该通过不安全的渠道(例如电子邮件)来存储或发送此导出文件。用完后请立即将其删除。" + "message": "此导出包含未加密格式的密码库数据。您不应该通过不安全的渠道(例如电子邮件)来存储或发送此导出文件。使用完后请立即将其删除。" }, "exportSecretsWarningDesc": { "message": "本次导出包含未加密格式的机密数据。您不应该通过不安全的渠道(例如电子邮件)来存储或发送此导出文件。用完后请立即将其删除。" @@ -1716,7 +1716,7 @@ "message": "请重新登录。" }, "logBackInOthersToo": { - "message": "请重新登录。如果您还在使用其他 Bitwarden 应用,也请注销并重新登陆。" + "message": "请重新登录。如果您还在使用其他 Bitwarden 应用程序,也请注销并重新登陆。" }, "changeMasterPassword": { "message": "修改主密码" @@ -2018,7 +2018,7 @@ "message": "添加自定义域名" }, "newCustomDomainDesc": { - "message": "输入用逗号分隔的域名列表。只能输入「基础」域名,不要输入子域名。例如,输入「google.com」而不是「www.google.com」。您也可以输入「androidapp://package.name」以将 Android 应用程序与其他网站域名关联。" + "message": "输入用逗号分隔的域名列表。只能输入「基础」域名,不要输入子域名。例如,输入「google.com」而不是「www.google.com」。您也可以输入「androidapp://package.name」以将 Android App 与其他网站域名关联。" }, "customDomainX": { "message": "自定义域名 $INDEX$", @@ -2135,7 +2135,7 @@ } }, "continueToExternalUrlDesc": { - "message": "您将离开 Bitwarden 并将在新窗口中启动一个外部网站。" + "message": "您将离开 Bitwarden 并将在新窗口中打开一个外部网站。" }, "twoStepContinueToBitwardenUrlTitle": { "message": "前往 bitwarden.com 吗?" @@ -2180,13 +2180,13 @@ "message": "保存表单。" }, "twoFactorYubikeyWarning": { - "message": "由于平台的限制,YubiKey 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 YubiKey 时可以访问您的账户。支持的平台:" + "message": "由于平台限制,YubiKey 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 YubiKey 时可以访问您的账户。支持的平台:" }, "twoFactorYubikeySupportUsb": { "message": "具有可使用 YubiKey 的 USB 端口的设备上的网页版密码库、桌面应用程序、CLI 以及浏览器扩展。" }, "twoFactorYubikeySupportMobile": { - "message": "具有 NFC 功能或可使用 YubiKey 的数据端口的设备上的移动应用程序。" + "message": "具有 NFC 功能或可使用 YubiKey 的数据端口的设备上的移动 App。" }, "yubikeyX": { "message": "YubiKey $INDEX$", @@ -2231,7 +2231,7 @@ "message": "禁用全部钥匙" }, "twoFactorDuoDesc": { - "message": "输入 Duo 管理面板提供的 Bitwarden 应用信息。" + "message": "输入 Duo 管理面板提供的 Bitwarden 应用程序信息。" }, "twoFactorDuoClientId": { "message": "Client ID" @@ -2282,7 +2282,7 @@ "message": "保存表单。" }, "twoFactorU2fWarning": { - "message": "由于平台的限制,FIDO U2F 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 FIDO U2F 时可以访问您的账户。支持的平台:" + "message": "由于平台限制,FIDO U2F 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在无法使用 FIDO U2F 时可以访问您的账户。支持的平台:" }, "twoFactorU2fSupportWeb": { "message": "桌面/笔记本电脑上支持 U2F 的浏览器(启用了 FIDO U2F 的 Chrome、Opera、Vivaldi 或 Firefox)中的网页版密码库和浏览器扩展。" @@ -2297,7 +2297,7 @@ "message": "读取安全钥匙时出现问题,请重试。" }, "twoFactorWebAuthnWarning": { - "message": "由于平台限制,无法在所有 Bitwarden 应用程序中使用 WebAuthn。您应该启用另一个两步登录提供程序,以便在 WebAuthn 无法使用时可以访问您的账户。支持的平台有:" + "message": "由于平台限制,WebAuthn 不能在所有 Bitwarden 应用程序上使用。您应该启用另一个两步登录提供程序,以便在 WebAuthn 无法使用时可以访问您的账户。支持的平台有:" }, "twoFactorWebAuthnSupportWeb": { "message": "桌面/笔记本电脑上支持 WebAuthn 的浏览器(启用了 FIDO U2F 的 Chrome、Opera、Vivaldi 或 Firefox)中的网页密码库和浏览器扩展。" @@ -4286,7 +4286,7 @@ "message": "为了提高安全性,我们更改了加密方案。请在下方输入您的主密码以立即更新您的加密密钥。" }, "updateEncryptionKeyWarning": { - "message": "更新加密密钥后,您需要注销所有正在使用的 Bitwarden 应用(比如移动 App 或者浏览器扩展)后重新登录。注销或者重新登录(这将下载新的加密密钥)失败可能会导致数据损坏。我们会尝试自动为您注销,但是,可能会有所延迟。" + "message": "更新加密密钥后,您需要注销所有正在使用的 Bitwarden 应用程序(比如移动 App 或者浏览器扩展)后重新登录。注销或者重新登录(这将下载新的加密密钥)失败可能会导致数据损坏。我们会尝试自动为您注销,但是,可能会有所延迟。" }, "updateEncryptionKeyExportWarning": { "message": "您保存的任何已加密导出也将变为无效。" @@ -4707,7 +4707,7 @@ "message": "包括 VAT/GST 信息(可选)" }, "taxIdNumber": { - "message": "VAT/GST 税号" + "message": "VAT/GST 税务 ID" }, "taxInfoUpdated": { "message": "税务信息已更新。" @@ -8061,7 +8061,7 @@ } }, "masterPasswordMinimumlength": { - "message": "主密码长度最少为 $LENGTH$ 个字符。", + "message": "主密码长度必须至少为 $LENGTH$ 个字符。", "placeholders": { "length": { "content": "$1", @@ -9058,7 +9058,7 @@ "message": "使用适合您平台的实施指南为 Bitwarden 配置设备管理。" }, "integrationCardTooltip": { - "message": "启动 $INTEGRATION$ 实施指南。", + "message": "打开 $INTEGRATION$ 实施指南。", "placeholders": { "integration": { "content": "$1", @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "更新了税务信息" }, + "billingInvalidTaxIdError": { + "message": "无效的税务 ID,如有疑问,请联系支持。" + }, + "billingTaxIdTypeInferenceError": { + "message": "我们无法验证您的税务 ID,如有疑问,请联系支持。" + }, + "billingPreviewInvalidTaxIdError": { + "message": "无效的税务 ID,如有疑问,请联系支持。" + }, + "billingPreviewInvoiceError": { + "message": "预览账单时出错。请稍后再试。" + }, "unverified": { "message": "未验证" }, @@ -9891,7 +9903,7 @@ "message": "设置两步登录" }, "newDeviceVerificationNoticeContentPage1": { - "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮箱发送一个代码,以验证来自新设备的登录。" + "message": "从 2025 年 02 月起,当有来自新设备的登录时,Bitwarden 将向您的账户电子邮箱发送验证码。" }, "newDeviceVerificationNoticeContentPage2": { "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" @@ -9900,7 +9912,7 @@ "message": "稍后提醒我" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "您能可靠地访问您的电子邮箱 $EMAIL$ 吗?", + "message": "您能正常访问您的电子邮箱 $EMAIL$ 吗?", "placeholders": { "email": { "content": "$1", @@ -9912,7 +9924,7 @@ "message": "不,我不能" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "是的,我可以可靠地访问我的电子邮箱" + "message": "是的,我可以正常访问我的电子邮箱" }, "turnOnTwoStepLogin": { "message": "开启两步登录" @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "组织名称不能超过 50 个字符。" + }, + "resellerRenewalWarning": { + "message": "您的订阅即将续订。为确保服务不中断,请在 $RENEWAL_DATE$ 之前联系 $RESELLER$ 确认您的续订。", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "您的订阅账单已于 $ISSUED_DATE$ 开具。为确保服务不中断,请在 $DUE_DATE$ 之前联系 $RESELLER$ 确认您的续订。", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "您的订阅账单尚未支付。为确保服务不中断,请在 $GRACE_PERIOD_END$ 之前联系 $RESELLER$ 确认您的续订。", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index bf15ea2a20a..ae60ea3cdb7 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -9271,6 +9271,18 @@ "updatedTaxInformation": { "message": "已更新稅務資訊" }, + "billingInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingTaxIdTypeInferenceError": { + "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvalidTaxIdError": { + "message": "Invalid tax ID, if you believe this is an error please contact support." + }, + "billingPreviewInvoiceError": { + "message": "An error occurred while previewing the invoice. Please try again later." + }, "unverified": { "message": "未驗證" }, @@ -10007,5 +10019,48 @@ }, "organizationNameMaxLength": { "message": "Organization name cannot exceed 50 characters." + }, + "resellerRenewalWarning": { + "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "renewal_date": { + "content": "$2", + "example": "01/01/2024" + } + } + }, + "resellerOpenInvoiceWarning": { + "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "issued_date": { + "content": "$2", + "example": "01/01/2024" + }, + "due_date": { + "content": "$3", + "example": "01/15/2024" + } + } + }, + "resellerPastDueWarning": { + "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "placeholders": { + "reseller": { + "content": "$1", + "example": "Reseller Name" + }, + "grace_period_end": { + "content": "$2", + "example": "02/14/2024" + } + } } } From 534e42b9f0692b55d026dda71908ee27e4a5343f Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:31:16 +0100 Subject: [PATCH 45/65] [PM-16432] Remove v1 account security settings (#12578) * Remove v1 account security settings Delete v1 component Remove conditional routing based on extension refresh feature flag * Remove unused import --------- Co-authored-by: Daniel James Smith --- .../account-security-v1.component.html | 140 ----- .../settings/account-security-v1.component.ts | 499 ------------------ .../settings/account-security.component.ts | 2 - apps/browser/src/popup/app-routing.module.ts | 6 +- apps/browser/src/popup/app.module.ts | 2 - 5 files changed, 3 insertions(+), 646 deletions(-) delete mode 100644 apps/browser/src/auth/popup/settings/account-security-v1.component.html delete mode 100644 apps/browser/src/auth/popup/settings/account-security-v1.component.ts diff --git a/apps/browser/src/auth/popup/settings/account-security-v1.component.html b/apps/browser/src/auth/popup/settings/account-security-v1.component.html deleted file mode 100644 index dff9675743f..00000000000 --- a/apps/browser/src/auth/popup/settings/account-security-v1.component.html +++ /dev/null @@ -1,140 +0,0 @@ - -
- -
-

- {{ "accountSecurity" | i18n }} -

-
- -
-
-
-
-

{{ "unlockMethods" | i18n }}

-
-
- - -
-
- - -
-
- - -
-
-
-
-

{{ "sessionTimeoutHeader" | i18n }}

-
- - - {{ - "vaultTimeoutPolicyWithActionInEffect" - | i18n: policy.timeout.hours : policy.timeout.minutes : (policy.action | i18n) - }} - - - {{ "vaultTimeoutPolicyInEffect" | i18n: policy.timeout.hours : policy.timeout.minutes }} - - - {{ "vaultTimeoutActionPolicyInEffect" | i18n: (policy.action | i18n) }} - - - - -
- - -
- -
-
-
-

{{ "otherOptions" | i18n }}

-
- - - - - -
-
-
diff --git a/apps/browser/src/auth/popup/settings/account-security-v1.component.ts b/apps/browser/src/auth/popup/settings/account-security-v1.component.ts deleted file mode 100644 index d06724bf657..00000000000 --- a/apps/browser/src/auth/popup/settings/account-security-v1.component.ts +++ /dev/null @@ -1,499 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from "@angular/core"; -import { FormBuilder } from "@angular/forms"; -import { - BehaviorSubject, - combineLatest, - concatMap, - distinctUntilChanged, - filter, - firstValueFrom, - map, - Observable, - pairwise, - startWith, - Subject, - switchMap, - takeUntil, -} from "rxjs"; - -import { FingerprintDialogComponent } from "@bitwarden/auth/angular"; -import { PinServiceAbstraction } from "@bitwarden/auth/common"; -import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; -import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout.service"; -import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { PolicyType } from "@bitwarden/common/admin-console/enums"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; -import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { - VaultTimeout, - VaultTimeoutOption, - VaultTimeoutStringType, -} from "@bitwarden/common/types/vault-timeout.type"; -import { DialogService } from "@bitwarden/components"; -import { KeyService, BiometricStateService, BiometricsService } from "@bitwarden/key-management"; - -import { BiometricErrors, BiometricErrorTypes } from "../../../models/biometricErrors"; -import { BrowserApi } from "../../../platform/browser/browser-api"; -import { enableAccountSwitching } from "../../../platform/flags"; -import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; -import { SetPinComponent } from "../components/set-pin.component"; - -import { AwaitDesktopDialogComponent } from "./await-desktop-dialog.component"; - -@Component({ - selector: "auth-account-security", - templateUrl: "account-security-v1.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class AccountSecurityComponent implements OnInit, OnDestroy { - protected readonly VaultTimeoutAction = VaultTimeoutAction; - - availableVaultTimeoutActions: VaultTimeoutAction[] = []; - vaultTimeoutOptions: VaultTimeoutOption[]; - vaultTimeoutPolicyCallout: Observable<{ - timeout: { hours: string; minutes: string }; - action: VaultTimeoutAction; - }>; - supportsBiometric: boolean; - showChangeMasterPass = true; - accountSwitcherEnabled = false; - - form = this.formBuilder.group({ - vaultTimeout: [null as VaultTimeout | null], - vaultTimeoutAction: [VaultTimeoutAction.Lock], - pin: [null as boolean | null], - biometric: false, - enableAutoBiometricsPrompt: true, - }); - - private refreshTimeoutSettings$ = new BehaviorSubject(undefined); - private destroy$ = new Subject(); - - constructor( - private accountService: AccountService, - private pinService: PinServiceAbstraction, - private policyService: PolicyService, - private formBuilder: FormBuilder, - private platformUtilsService: PlatformUtilsService, - private i18nService: I18nService, - private vaultTimeoutService: VaultTimeoutService, - private vaultTimeoutSettingsService: VaultTimeoutSettingsService, - public messagingService: MessagingService, - private environmentService: EnvironmentService, - private keyService: KeyService, - private stateService: StateService, - private userVerificationService: UserVerificationService, - private dialogService: DialogService, - private changeDetectorRef: ChangeDetectorRef, - private biometricStateService: BiometricStateService, - private biometricsService: BiometricsService, - ) { - this.accountSwitcherEnabled = enableAccountSwitching(); - } - - async ngOnInit() { - const maximumVaultTimeoutPolicy = this.policyService.get$(PolicyType.MaximumVaultTimeout); - this.vaultTimeoutPolicyCallout = maximumVaultTimeoutPolicy.pipe( - filter((policy) => policy != null), - map((policy) => { - let timeout; - if (policy.data?.minutes) { - timeout = { - hours: Math.floor(policy.data?.minutes / 60).toString(), - minutes: (policy.data?.minutes % 60).toString(), - }; - } - return { timeout: timeout, action: policy.data?.action }; - }), - ); - - const showOnLocked = - !this.platformUtilsService.isFirefox() && !this.platformUtilsService.isSafari(); - - this.vaultTimeoutOptions = [ - { name: this.i18nService.t("immediately"), value: 0 }, - { name: this.i18nService.t("oneMinute"), value: 1 }, - { name: this.i18nService.t("fiveMinutes"), value: 5 }, - { name: this.i18nService.t("fifteenMinutes"), value: 15 }, - { name: this.i18nService.t("thirtyMinutes"), value: 30 }, - { name: this.i18nService.t("oneHour"), value: 60 }, - { name: this.i18nService.t("fourHours"), value: 240 }, - ]; - - if (showOnLocked) { - this.vaultTimeoutOptions.push({ - name: this.i18nService.t("onLocked"), - value: VaultTimeoutStringType.OnLocked, - }); - } - - this.vaultTimeoutOptions.push({ - name: this.i18nService.t("onRestart"), - value: VaultTimeoutStringType.OnRestart, - }); - this.vaultTimeoutOptions.push({ - name: this.i18nService.t("never"), - value: VaultTimeoutStringType.Never, - }); - - const activeAccount = await firstValueFrom(this.accountService.activeAccount$); - - let timeout = await firstValueFrom( - this.vaultTimeoutSettingsService.getVaultTimeoutByUserId$(activeAccount.id), - ); - if (timeout === VaultTimeoutStringType.OnLocked && !showOnLocked) { - timeout = VaultTimeoutStringType.OnRestart; - } - - const initialValues = { - vaultTimeout: timeout, - vaultTimeoutAction: await firstValueFrom( - this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(activeAccount.id), - ), - pin: await this.pinService.isPinSet(activeAccount.id), - biometric: await this.vaultTimeoutSettingsService.isBiometricLockSet(), - enableAutoBiometricsPrompt: await firstValueFrom( - this.biometricStateService.promptAutomatically$, - ), - }; - this.form.patchValue(initialValues, { emitEvent: false }); - - this.supportsBiometric = await this.biometricsService.supportsBiometric(); - this.showChangeMasterPass = await this.userVerificationService.hasMasterPassword(); - - this.form.controls.vaultTimeout.valueChanges - .pipe( - startWith(initialValues.vaultTimeout), // emit to init pairwise - pairwise(), - concatMap(async ([previousValue, newValue]) => { - await this.saveVaultTimeout(previousValue, newValue); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - - this.form.controls.vaultTimeoutAction.valueChanges - .pipe( - startWith(initialValues.vaultTimeoutAction), // emit to init pairwise - pairwise(), - concatMap(async ([previousValue, newValue]) => { - await this.saveVaultTimeoutAction(previousValue, newValue); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - - this.form.controls.pin.valueChanges - .pipe( - concatMap(async (value) => { - await this.updatePin(value); - this.refreshTimeoutSettings$.next(); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - - this.form.controls.biometric.valueChanges - .pipe( - distinctUntilChanged(), - concatMap(async (enabled) => { - await this.updateBiometric(enabled); - if (enabled) { - this.form.controls.enableAutoBiometricsPrompt.enable(); - } else { - this.form.controls.enableAutoBiometricsPrompt.disable(); - } - this.refreshTimeoutSettings$.next(); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - - this.refreshTimeoutSettings$ - .pipe( - switchMap(() => - combineLatest([ - this.vaultTimeoutSettingsService.availableVaultTimeoutActions$(), - this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(activeAccount.id), - ]), - ), - takeUntil(this.destroy$), - ) - .subscribe(([availableActions, action]) => { - this.availableVaultTimeoutActions = availableActions; - this.form.controls.vaultTimeoutAction.setValue(action, { emitEvent: false }); - // NOTE: The UI doesn't properly update without detect changes. - // I've even tried using an async pipe, but it still doesn't work. I'm not sure why. - // Using an async pipe means that we can't call `detectChanges` AFTER the data has change - // meaning that we are forced to use regular class variables instead of observables. - this.changeDetectorRef.detectChanges(); - }); - - this.refreshTimeoutSettings$ - .pipe( - switchMap(() => - combineLatest([ - this.vaultTimeoutSettingsService.availableVaultTimeoutActions$(), - maximumVaultTimeoutPolicy, - ]), - ), - takeUntil(this.destroy$), - ) - .subscribe(([availableActions, policy]) => { - if (policy?.data?.action || availableActions.length <= 1) { - this.form.controls.vaultTimeoutAction.disable({ emitEvent: false }); - } else { - this.form.controls.vaultTimeoutAction.enable({ emitEvent: false }); - } - }); - } - - async saveVaultTimeout(previousValue: VaultTimeout, newValue: VaultTimeout) { - if (newValue === VaultTimeoutStringType.Never) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: { key: "warning" }, - content: { key: "neverLockWarning" }, - type: "warning", - }); - - if (!confirmed) { - this.form.controls.vaultTimeout.setValue(previousValue, { emitEvent: false }); - return; - } - } - - // The minTimeoutError does not apply to browser because it supports Immediately - // So only check for the policyError - if (this.form.controls.vaultTimeout.hasError("policyError")) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("vaultTimeoutTooLarge"), - ); - return; - } - - const activeAccount = await firstValueFrom(this.accountService.activeAccount$); - - const vaultTimeoutAction = await firstValueFrom( - this.vaultTimeoutSettingsService.getVaultTimeoutActionByUserId$(activeAccount.id), - ); - - await this.vaultTimeoutSettingsService.setVaultTimeoutOptions( - activeAccount.id, - newValue, - vaultTimeoutAction, - ); - if (newValue === VaultTimeoutStringType.Never) { - this.messagingService.send("bgReseedStorage"); - } - } - - async saveVaultTimeoutAction(previousValue: VaultTimeoutAction, newValue: VaultTimeoutAction) { - if (newValue === VaultTimeoutAction.LogOut) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: { key: "vaultTimeoutLogOutConfirmationTitle" }, - content: { key: "vaultTimeoutLogOutConfirmation" }, - type: "warning", - }); - - if (!confirmed) { - this.form.controls.vaultTimeoutAction.setValue(previousValue, { - emitEvent: false, - }); - return; - } - } - - if (this.form.controls.vaultTimeout.hasError("policyError")) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("vaultTimeoutTooLarge"), - ); - return; - } - - const activeAccount = await firstValueFrom(this.accountService.activeAccount$); - - await this.vaultTimeoutSettingsService.setVaultTimeoutOptions( - activeAccount.id, - this.form.value.vaultTimeout, - newValue, - ); - this.refreshTimeoutSettings$.next(); - } - - async updatePin(value: boolean) { - if (value) { - const dialogRef = SetPinComponent.open(this.dialogService); - - if (dialogRef == null) { - this.form.controls.pin.setValue(false, { emitEvent: false }); - return; - } - - const userHasPinSet = await firstValueFrom(dialogRef.closed); - this.form.controls.pin.setValue(userHasPinSet, { emitEvent: false }); - } else { - await this.vaultTimeoutSettingsService.clear(); - } - } - - async updateBiometric(enabled: boolean) { - if (enabled && this.supportsBiometric) { - let granted; - try { - granted = await BrowserApi.requestPermission({ permissions: ["nativeMessaging"] }); - } catch (e) { - // eslint-disable-next-line - console.error(e); - - if (this.platformUtilsService.isFirefox() && BrowserPopupUtils.inSidebar(window)) { - await this.dialogService.openSimpleDialog({ - title: { key: "nativeMessaginPermissionSidebarTitle" }, - content: { key: "nativeMessaginPermissionSidebarDesc" }, - acceptButtonText: { key: "ok" }, - cancelButtonText: null, - type: "info", - }); - - this.form.controls.biometric.setValue(false); - return; - } - } - - if (!granted) { - await this.dialogService.openSimpleDialog({ - title: { key: "nativeMessaginPermissionErrorTitle" }, - content: { key: "nativeMessaginPermissionErrorDesc" }, - acceptButtonText: { key: "ok" }, - cancelButtonText: null, - type: "danger", - }); - - this.form.controls.biometric.setValue(false); - return; - } - - const awaitDesktopDialogRef = AwaitDesktopDialogComponent.open(this.dialogService); - const awaitDesktopDialogClosed = firstValueFrom(awaitDesktopDialogRef.closed); - - await this.keyService.refreshAdditionalKeys(); - - await Promise.race([ - awaitDesktopDialogClosed.then(async (result) => { - if (result !== true) { - this.form.controls.biometric.setValue(false); - } - }), - this.biometricsService - .authenticateBiometric() - .then((result) => { - this.form.controls.biometric.setValue(result); - if (!result) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorEnableBiometricTitle"), - this.i18nService.t("errorEnableBiometricDesc"), - ); - } - }) - .catch((e) => { - // Handle connection errors - this.form.controls.biometric.setValue(false); - - const error = BiometricErrors[e.message as BiometricErrorTypes]; - - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.dialogService.openSimpleDialog({ - title: { key: error.title }, - content: { key: error.description }, - acceptButtonText: { key: "ok" }, - cancelButtonText: null, - type: "danger", - }); - }) - .finally(() => { - awaitDesktopDialogRef.close(true); - }), - ]); - } else { - await this.biometricStateService.setBiometricUnlockEnabled(false); - await this.biometricStateService.setFingerprintValidated(false); - } - } - - async updateAutoBiometricsPrompt() { - await this.biometricStateService.setPromptAutomatically( - this.form.value.enableAutoBiometricsPrompt, - ); - } - - async changePassword() { - const confirmed = await this.dialogService.openSimpleDialog({ - title: { key: "continueToWebApp" }, - content: { key: "changeMasterPasswordOnWebConfirmation" }, - type: "info", - acceptButtonText: { key: "continue" }, - }); - if (confirmed) { - const env = await firstValueFrom(this.environmentService.environment$); - await BrowserApi.createNewTab(env.getWebVaultUrl()); - } - } - - async twoStep() { - const confirmed = await this.dialogService.openSimpleDialog({ - title: { key: "twoStepLogin" }, - content: { key: "twoStepLoginConfirmation" }, - type: "info", - }); - if (confirmed) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserApi.createNewTab("https://bitwarden.com/help/setup-two-step-login/"); - } - } - - async fingerprint() { - const fingerprint = await this.keyService.getFingerprint(await this.stateService.getUserId()); - - const dialogRef = FingerprintDialogComponent.open(this.dialogService, { - fingerprint, - }); - - return firstValueFrom(dialogRef.closed); - } - - async lock() { - await this.vaultTimeoutService.lock(); - } - - async logOut() { - const confirmed = await this.dialogService.openSimpleDialog({ - title: { key: "logOut" }, - content: { key: "logOutConfirmation" }, - type: "info", - }); - - const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; - if (confirmed) { - this.messagingService.send("logout", { userId: userId }); - } - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } -} diff --git a/apps/browser/src/auth/popup/settings/account-security.component.ts b/apps/browser/src/auth/popup/settings/account-security.component.ts index cf923ac74b5..86eea889fdd 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.ts +++ b/apps/browser/src/auth/popup/settings/account-security.component.ts @@ -60,7 +60,6 @@ import { BrowserApi } from "../../../platform/browser/browser-api"; import { enableAccountSwitching } from "../../../platform/flags"; import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; -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 { SetPinComponent } from "../components/set-pin.component"; @@ -82,7 +81,6 @@ import { AwaitDesktopDialogComponent } from "./await-desktop-dialog.component"; JslibModule, LinkModule, PopOutComponent, - PopupFooterComponent, PopupHeaderComponent, PopupPageComponent, RouterModule, diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index b7bc5643ac4..49d680cd752 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -65,7 +65,6 @@ import { LoginViaAuthRequestComponentV1 } from "../auth/popup/login-via-auth-req import { RegisterComponent } from "../auth/popup/register.component"; import { RemovePasswordComponent } from "../auth/popup/remove-password.component"; import { SetPasswordComponent } from "../auth/popup/set-password.component"; -import { AccountSecurityComponent as AccountSecurityV1Component } from "../auth/popup/settings/account-security-v1.component"; import { AccountSecurityComponent } from "../auth/popup/settings/account-security.component"; import { SsoComponentV1 } from "../auth/popup/sso-v1.component"; import { TwoFactorAuthComponent } from "../auth/popup/two-factor-auth.component"; @@ -351,11 +350,12 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, }), - ...extensionRefreshSwap(AccountSecurityV1Component, AccountSecurityComponent, { + { path: "account-security", + component: AccountSecurityComponent, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, - }), + }, ...extensionRefreshSwap(NotificationsSettingsV1Component, NotificationsSettingsComponent, { path: "notifications", canActivate: [authGuard], diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index 04d681812fe..83475a661c9 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -29,7 +29,6 @@ import { LoginViaAuthRequestComponentV1 } from "../auth/popup/login-via-auth-req import { RegisterComponent } from "../auth/popup/register.component"; import { RemovePasswordComponent } from "../auth/popup/remove-password.component"; import { SetPasswordComponent } from "../auth/popup/set-password.component"; -import { AccountSecurityComponent as AccountSecurityComponentV1 } from "../auth/popup/settings/account-security-v1.component"; import { AccountSecurityComponent } from "../auth/popup/settings/account-security.component"; import { VaultTimeoutInputComponent } from "../auth/popup/settings/vault-timeout-input.component"; import { SsoComponentV1 } from "../auth/popup/sso-v1.component"; @@ -165,7 +164,6 @@ import "../platform/popup/locales"; TwoFactorOptionsComponent, UpdateTempPasswordComponent, UserVerificationComponent, - AccountSecurityComponentV1, VaultTimeoutInputComponent, ViewComponent, ViewCustomFieldsComponent, From 9f670c68208b24a886add9ea97f14aca3dd35e67 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:34:03 +0000 Subject: [PATCH 46/65] Autosync the updated translations (#12673) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/ar/messages.json | 6 +- apps/desktop/src/locales/fi/messages.json | 4 +- apps/desktop/src/locales/fr/messages.json | 24 +-- apps/desktop/src/locales/it/messages.json | 140 +++++++++--------- apps/desktop/src/locales/ja/messages.json | 148 +++++++++---------- apps/desktop/src/locales/nl/messages.json | 14 +- apps/desktop/src/locales/sk/messages.json | 2 +- apps/desktop/src/locales/sr/messages.json | 52 +++---- apps/desktop/src/locales/tr/messages.json | 4 +- apps/desktop/src/locales/zh_CN/messages.json | 26 ++-- 10 files changed, 210 insertions(+), 210 deletions(-) diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index d9c702b19d8..a15dbb5f078 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -3399,10 +3399,10 @@ "message": "ملاحظة هامة" }, "setupTwoStepLogin": { - "message": "إعداد المصادقة الثنائية" + "message": "إعداد تسجيل الدخول بخطوتين" }, "newDeviceVerificationNoticeContentPage1": { - "message": "سيقوم Bitwarden بإرسال رمز إلى البريد الإلكتروني الخاص بحسابك للتحقق من تسجيلات الدخول من الأجهزة الجديدة ابتداء من فبراير 2025." + "message": "سيقوم Bitwarden بإرسال رمز إلى البريد الإلكتروني الخاص بحسابك للتحقق من تسجيلات الدخول من الأجهزة الجديدة ابتداءً من فبراير 2025." }, "newDeviceVerificationNoticeContentPage2": { "message": "يمكنك إعداد المصادقة الثنائية كطريقة بديلة لحماية حسابك أو تغيير بريدك الإلكتروني إلى بريد يمكنك الوصول إليه." @@ -3426,7 +3426,7 @@ "message": "نعم، يمكنني الوصول بشكل موثوق إلى بريدي الإلكتروني" }, "turnOnTwoStepLogin": { - "message": "تفعيل المصادقة الثنائية" + "message": "تشغيل تسجيل الدخول بخطوتين" }, "changeAcctEmail": { "message": "تغيير البريد الإلكتروني الخاص بالحساب" diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 226c44bc352..69092054f28 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -2729,7 +2729,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" }, "needAnotherOptionV1": { "message": "Tarvitsetko toisen vaihtoehdon?" @@ -3402,7 +3402,7 @@ "message": "Määritä kaksivaiheinen kirjautuminen" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden lähettää tilisi sähköpostiosoitteeseen koodin, jolla voit vahvistaa kirjautumiset uusista laitteista helmikuusta 2025 alkaen." }, "newDeviceVerificationNoticeContentPage2": { "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index d387cbb20a0..a353653e1e3 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -323,7 +323,7 @@ "message": "Générer un mot de passe" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Générer une phrase de passe" }, "type": { "message": "Type" @@ -467,7 +467,7 @@ "message": "Copier la clé privée SSH" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "Copier la phrase de passe", "description": "Copy passphrase to clipboard" }, "copyUri": { @@ -926,7 +926,7 @@ "message": "La session d'authentification a expiré. Veuillez redémarrer le processus de connexion." }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL du serveur auto-hébergé", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1951,7 +1951,7 @@ "message": "Votre nouveau mot de passe principal ne répond pas aux exigences de politique de sécurité." }, "receiveMarketingEmailsV2": { - "message": "Get advice, announcements, and research opportunities from Bitwarden in your inbox." + "message": "Obtenez des conseils, des annonces et des opportunités de recherche de la part de Bitwarden dans votre boîte de réception." }, "unsubscribe": { "message": "Se désabonner" @@ -2478,10 +2478,10 @@ "message": "Générer le nom d'utilisateur" }, "generateEmail": { - "message": "Generate email" + "message": "Générer un courriel" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "La valeur doit être comprise entre $MIN$ et $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2495,7 +2495,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Utilisez $RECOMMENDED$ caractères ou plus pour générer un mot de passe fort.", "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": { @@ -2505,7 +2505,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Utilisez $RECOMMENDED$ mots ou plus pour générer une phrase de passe forte.", "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": { @@ -2729,10 +2729,10 @@ "message": "A notification was sent to your device" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Assurez-vous que votre compte est déverrouillé et que la phrase d'empreinte digitale correspond à celle de l'autre appareil" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Besoin d'une autre option ?" }, "fingerprintMatchInfo": { "message": "Veuillez vous assurer que votre coffre est déverrouillé et que la phrase d'empreinte correspond à celle de l'autre appareil." @@ -2741,13 +2741,13 @@ "message": "Phrase d'empreinte" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Vous serez notifié une fois que la demande sera approuvée" }, "needAnotherOption": { "message": "La connexion avec l'appareil doit être configurée dans les paramètres de l'application Bitwarden. Besoin d'une autre option ?" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Afficher toutes les options de connexion" }, "viewAllLoginOptions": { "message": "Afficher toutes les options de connexion" diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index e8c0a3d1a39..e035a13606d 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -27,7 +27,7 @@ "message": "Nota sicura" }, "typeSshKey": { - "message": "SSH key" + "message": "Chiave SSH" }, "folders": { "message": "Cartelle" @@ -64,7 +64,7 @@ } }, "welcomeBack": { - "message": "Welcome back" + "message": "Bentornato" }, "moveToOrgDesc": { "message": "Scegli un'organizzazione in cui vuoi spostare questo elemento. Spostarlo in un'organizzazione trasferisce la proprietà dell'elemento all'organizzazione. Una volta spostato, non sarai più il proprietario diretto di questo elemento." @@ -181,61 +181,61 @@ "message": "Indirizzo" }, "sshPrivateKey": { - "message": "Private key" + "message": "Chiave privata" }, "sshPublicKey": { - "message": "Public key" + "message": "Chiave pubblica" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Impronta digitale" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Tipo di chiave" }, "sshKeyAlgorithmED25519": { "message": "ED25519" }, "sshKeyAlgorithmRSA2048": { - "message": "RSA 2048-Bit" + "message": "RSA a 2048 bit" }, "sshKeyAlgorithmRSA3072": { - "message": "RSA 3072-Bit" + "message": "RSA a 3072 bit" }, "sshKeyAlgorithmRSA4096": { - "message": "RSA 4096-Bit" + "message": "RSA a 4096 bit" }, "sshKeyGenerated": { - "message": "A new SSH key was generated" + "message": "È stata generata una nuova chiave SSH" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "La password inserita non è corretta." }, "importSshKey": { - "message": "Import" + "message": "Importa" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Conferma password" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Inserisci la password per la chiave SSH." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Inserisci password" }, "sshAgentUnlockRequired": { - "message": "Please unlock your vault to approve the SSH key request." + "message": "Sbloccare la cassaforte per approvare la richiesta di chiave SSH." }, "sshAgentUnlockTimeout": { - "message": "SSH key request timed out." + "message": "Richiesta chiave SSH scaduta." }, "enableSshAgent": { - "message": "Enable SSH agent" + "message": "Abilita agente SSH" }, "enableSshAgentDesc": { - "message": "Enable the SSH agent to sign SSH requests right from your Bitwarden vault." + "message": "Abilita l'agente SSH per firmare le richieste SSH direttamente dalla tua cassaforte Bitwarden." }, "enableSshAgentHelp": { - "message": "The SSH agent is a service targeted at developers that allows you to sign SSH requests directly from your Bitwarden vault." + "message": "L'agente SSH è un servizio rivolto agli sviluppatori che consente di firmare le richieste SSH direttamente dalla tua cassaforte Bitwarden." }, "premiumRequired": { "message": "Premium necessario" @@ -461,10 +461,10 @@ "message": "Copia password" }, "regenerateSshKey": { - "message": "Regenerate SSH key" + "message": "Rigenera la chiave SSH" }, "copySshPrivateKey": { - "message": "Copy SSH private key" + "message": "Copia chiave privata SSH" }, "copyPassphrase": { "message": "Copia passphrase", @@ -624,7 +624,7 @@ "message": "Crea account" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Nuovo in Bitwarden?" }, "setAStrongPassword": { "message": "Imposta una password robusta" @@ -636,16 +636,16 @@ "message": "Accedi" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Accedi a Bitwarden" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Accedi con passkey" }, "loginWithDevice": { - "message": "Log in with device" + "message": "Accedi con dispositivo" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Usa il Single Sign-On" }, "submit": { "message": "Invia" @@ -920,10 +920,10 @@ "message": "URL del server" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Timeout autenticazione" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "La sessione di autenticazione è scaduta. Accedi di nuovo." }, "selfHostBaseUrl": { "message": "URL server autogestito", @@ -1393,13 +1393,13 @@ "message": "Cronologia delle password" }, "generatorHistory": { - "message": "Generator history" + "message": "Cronologia generatore" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Cancella cronologia generatore" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Se continui, tutte le voci verranno eliminate definitivamente dalla cronologia del generatore. Vuoi continuare?" }, "clear": { "message": "Cancella", @@ -1409,13 +1409,13 @@ "message": "Non ci sono password da mostrare." }, "clearHistory": { - "message": "Clear history" + "message": "Cancella cronologia" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Niente da mostrare" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Non hai generato niente di recente" }, "undo": { "message": "Annulla" @@ -1771,10 +1771,10 @@ "message": "L'eliminazione del tuo account è permanente. Non può essere annullata." }, "cannotDeleteAccount": { - "message": "Cannot delete account" + "message": "Impossibile eliminare account" }, "cannotDeleteAccountDesc": { - "message": "This action cannot be completed because your account is owned by an organization. Contact your organization administrator for additional details." + "message": "Questa azione non può essere completata perché il tuo account è di proprietà di un'organizzazione. Contatta l'amministratore della tua organizzazione per dettagli." }, "accountDeleted": { "message": "Account eliminato" @@ -2481,7 +2481,7 @@ "message": "Genera e-mail" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Il valore deve essere compreso tra $MIN$ e $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2495,7 +2495,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Usa $RECOMMENDED$ caratteri o più per generare una password forte.", "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": { @@ -2505,7 +2505,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Usa $RECOMMENDED$ parole o più per generare una passphrase forte.", "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": { @@ -2726,13 +2726,13 @@ "message": "Una notifica è stata inviata al tuo dispositivo." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Una notifica è stata inviata al tuo dispositivo" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Assicurati che il tuo account sia sbloccato e che la frase dell'impronta digitale corrisponda nell'altro dispositivo" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Bisogno di un'altra opzione?" }, "fingerprintMatchInfo": { "message": "Assicurati che la tua cassaforte sia sbloccata e che la frase impronta corrisponda sull'altro dispositivo." @@ -2741,13 +2741,13 @@ "message": "Frase impronta" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Sarai notificato una volta che la richiesta sarà approvata" }, "needAnotherOption": { "message": "L'accesso con dispositivo deve essere abilitato nelle impostazioni dell'app Bitwarden. Ti serve un'altra opzione?" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Visualizza tutte le opzioni di accesso" }, "viewAllLoginOptions": { "message": "Visualizza tutte le opzioni di accesso" @@ -2869,7 +2869,7 @@ "message": "Controlla se la tua password è presente in una violazione dei dati" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Accesso effettuato!" }, "important": { "message": "Importante:" @@ -2902,16 +2902,16 @@ "message": "Aggiornamento delle impostazioni consigliato" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Ricorda questo dispositivo per rendere immediati i futuri accessi" }, "deviceApprovalRequired": { "message": "Approvazione del dispositivo obbligatoria. Seleziona un'opzione di approvazione:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Approvazione dispositivo richiesta" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Seleziona un'opzione di approvazione sotto" }, "rememberThisDevice": { "message": "Ricorda questo dispositivo" @@ -2966,7 +2966,7 @@ "message": "Email utente mancante" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Email utente attiva non trovata. Logout in corso." }, "deviceTrusted": { "message": "Dispositivo fidato" @@ -3363,55 +3363,55 @@ "message": "Non è stato possibile trovare nessuna porta libera per il login Sso." }, "authorize": { - "message": "Authorize" + "message": "Autorizza" }, "deny": { - "message": "Deny" + "message": "Nega" }, "sshkeyApprovalTitle": { - "message": "Confirm SSH key usage" + "message": "Conferma l'uso della chiave SSH" }, "sshkeyApprovalMessageInfix": { - "message": "is requesting access to" + "message": "richiede l'accesso a" }, "unknownApplication": { - "message": "An application" + "message": "Un'applicazione" }, "sshKeyPasswordUnsupported": { - "message": "Importing password protected SSH keys is not yet supported" + "message": "L'importazione di chiavi SSH protette da password non è ancora supportata" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "La chiave SSH non è valida" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "Il tipo di chiave SSH non è supportato" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "Importa chiave dagli Appunti" }, "sshKeyPasted": { - "message": "SSH key imported successfully" + "message": "Chiave SSH importata correttamente" }, "fileSavedToDevice": { "message": "File salvato sul dispositivo. Gestisci dai download del dispositivo." }, "importantNotice": { - "message": "Important notice" + "message": "Notifica importante" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Imposta accesso in due passaggi" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden invierà un codice all'e-mail del tuo account per verificare gli accessi da nuovi dispositivi a partire da febbraio 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Puoi impostare l'accesso in due passaggi come modo alternativo per proteggere il tuo account, o cambiare la tua e-mail in una alla quale puoi accedere." }, "remindMeLater": { - "message": "Remind me later" + "message": "Ricordamelo più tardi" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Hai accesso affidabile alla tua e-mail, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -3420,15 +3420,15 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "No, non ce l'ho" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Sì, posso accedere in modo affidabile alla mia e-mail" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Attiva accesso in due passaggi" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Cambia l'e-mail dell'account" } } diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index c146fb2404c..7315d74a70f 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -27,7 +27,7 @@ "message": "セキュアメモ" }, "typeSshKey": { - "message": "SSH key" + "message": "SSH キー" }, "folders": { "message": "フォルダー" @@ -64,7 +64,7 @@ } }, "welcomeBack": { - "message": "Welcome back" + "message": "ようこそ" }, "moveToOrgDesc": { "message": "このアイテムを移動する組織を選択してください。組織に移動すると、アイテムの所有権がその組織に移行します。 このアイテムが移動された後、あなたはこのアイテムの直接の所有者にはなりません。" @@ -181,16 +181,16 @@ "message": "住所" }, "sshPrivateKey": { - "message": "Private key" + "message": "秘密鍵" }, "sshPublicKey": { - "message": "Public key" + "message": "公開鍵" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "フィンガープリント" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "キーの種類" }, "sshKeyAlgorithmED25519": { "message": "ED25519" @@ -205,37 +205,37 @@ "message": "RSA 4096-Bit" }, "sshKeyGenerated": { - "message": "A new SSH key was generated" + "message": "新しい SSH 鍵が生成されました" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "入力されたパスワードが間違っています。" }, "importSshKey": { - "message": "Import" + "message": "インポート" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "パスワードを確認" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "SSH キーのパスワードを入力します。" }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "パスワードを入力" }, "sshAgentUnlockRequired": { - "message": "Please unlock your vault to approve the SSH key request." + "message": "SSH キーリクエストを承認するには、保管庫のロックを解除してください。" }, "sshAgentUnlockTimeout": { - "message": "SSH key request timed out." + "message": "SSH キーの要求がタイムアウトしました。" }, "enableSshAgent": { - "message": "Enable SSH agent" + "message": "SSH エージェントを有効にする" }, "enableSshAgentDesc": { - "message": "Enable the SSH agent to sign SSH requests right from your Bitwarden vault." + "message": "Bitwarden 保管庫から直接 SSH 要求に署名するために SSH エージェントを有効にします。" }, "enableSshAgentHelp": { - "message": "The SSH agent is a service targeted at developers that allows you to sign SSH requests directly from your Bitwarden vault." + "message": "SSH エージェントとは、Bitwarden 保管庫から直接 SSH リクエストに署名できる、開発者を対象としたサービスです。" }, "premiumRequired": { "message": "プレミアム会員専用" @@ -323,7 +323,7 @@ "message": "パスワードの自動生成" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "パスフレーズを生成" }, "type": { "message": "タイプ" @@ -461,13 +461,13 @@ "message": "パスワードのコピー" }, "regenerateSshKey": { - "message": "Regenerate SSH key" + "message": "SSH キーを再生成" }, "copySshPrivateKey": { - "message": "Copy SSH private key" + "message": "SSH 秘密鍵をコピー" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "パスフレーズをコピー", "description": "Copy passphrase to clipboard" }, "copyUri": { @@ -624,7 +624,7 @@ "message": "アカウントの作成" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Bitwarden は初めてですか?" }, "setAStrongPassword": { "message": "強力なパスワードを設定する" @@ -636,16 +636,16 @@ "message": "ログイン" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Bitwarden にログイン" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "パスキーでログイン" }, "loginWithDevice": { - "message": "Log in with device" + "message": "デバイスでログイン" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "シングルサインオンを使用する" }, "submit": { "message": "送信" @@ -920,13 +920,13 @@ "message": "サーバー URL" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "認証のタイムアウト" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "認証セッションの有効期限が切れました。ログイン操作を最初からやり直してください。" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "自己ホスト型サーバーの URL", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1320,7 +1320,7 @@ "description": "Copy credit card number" }, "copyEmail": { - "message": "Copy email" + "message": "メールアドレスをコピー" }, "copySecurityCode": { "message": "セキュリティコードのコピー", @@ -1393,13 +1393,13 @@ "message": "パスワードの履歴" }, "generatorHistory": { - "message": "Generator history" + "message": "生成履歴" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "生成履歴を消去" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "続行すると、すべてのエントリは生成履歴から完全に削除されます。続行してもよろしいですか?" }, "clear": { "message": "消去する", @@ -1409,13 +1409,13 @@ "message": "表示するパスワードがありません" }, "clearHistory": { - "message": "Clear history" + "message": "履歴を消去" }, "nothingToShow": { - "message": "Nothing to show" + "message": "表示するものがありません" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "最近生成したものはありません" }, "undo": { "message": "元に戻す" @@ -1771,10 +1771,10 @@ "message": "アカウントを恒久的に削除します。元に戻すことはできません。" }, "cannotDeleteAccount": { - "message": "Cannot delete account" + "message": "アカウントを削除できません" }, "cannotDeleteAccountDesc": { - "message": "This action cannot be completed because your account is owned by an organization. Contact your organization administrator for additional details." + "message": "このアカウントは組織が所有しているため、操作を完了できません。詳しくは組織の管理者へご確認ください。" }, "accountDeleted": { "message": "アカウントが削除されました" @@ -2478,10 +2478,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": { @@ -2495,7 +2495,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": { @@ -2505,7 +2505,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": { @@ -2558,11 +2558,11 @@ "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": { @@ -2726,13 +2726,13 @@ "message": "デバイスに通知を送信しました。" }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "お使いのデバイスに通知が送信されました" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "アカウントがロック解除されていることと、フィンガープリントフレーズが他の端末と一致していることを確認してください" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "別の選択肢が必要ですか?" }, "fingerprintMatchInfo": { "message": "保管庫がロックされていることと、パスフレーズが他のデバイスと一致していることを確認してください。" @@ -2741,13 +2741,13 @@ "message": "パスフレーズ" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "リクエストが承認されると通知されます" }, "needAnotherOption": { "message": "Bitwarden アプリの設定でデバイスでログインする必要があります。別のオプションが必要ですか?" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "すべてのログインオプションを表示" }, "viewAllLoginOptions": { "message": "すべてのログインオプションを表示" @@ -2869,7 +2869,7 @@ "message": "このパスワードの既知のデータ流出を確認" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "ログインしました!" }, "important": { "message": "重要" @@ -2902,16 +2902,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": "このデバイスを記憶する" @@ -2966,7 +2966,7 @@ "message": "ユーザーのメールアドレスがありません" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "アクティブなユーザーメールアドレスが見つかりません。ログアウトします。" }, "deviceTrusted": { "message": "信頼されたデバイス" @@ -3363,55 +3363,55 @@ "message": "SSO ログインのための空きポートが見つかりませんでした。" }, "authorize": { - "message": "Authorize" + "message": "認可" }, "deny": { - "message": "Deny" + "message": "拒否" }, "sshkeyApprovalTitle": { - "message": "Confirm SSH key usage" + "message": "SSH 鍵の使用を確認します" }, "sshkeyApprovalMessageInfix": { - "message": "is requesting access to" + "message": "がアクセスを要求しています: " }, "unknownApplication": { - "message": "An application" + "message": "アプリ" }, "sshKeyPasswordUnsupported": { - "message": "Importing password protected SSH keys is not yet supported" + "message": "パスワードで保護された SSH キーのインポートはまだサポートされていません" }, "invalidSshKey": { - "message": "The SSH key is invalid" + "message": "SSH キーが無効です" }, "sshKeyTypeUnsupported": { - "message": "The SSH key type is not supported" + "message": "サポートされていない種類の SSH キーです" }, "importSshKeyFromClipboard": { - "message": "Import key from clipboard" + "message": "クリップボードからキーをインポート" }, "sshKeyPasted": { - "message": "SSH key imported successfully" + "message": "SSH キーのインポートに成功しました" }, "fileSavedToDevice": { "message": "ファイルをデバイスに保存しました。デバイスのダウンロードで管理できます。" }, "importantNotice": { - "message": "Important notice" + "message": "重要なお知らせ" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "2段階認証によるログインを設定する" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden は2025年2月以降、新しいデバイスからのログイン時にアカウントのメールアドレスに確認コードを送信します。" }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "代わりに2段階認証によるログインでアカウントを保護するか、メールアドレスをあなたがアクセスできるものに変更できます。" }, "remindMeLater": { - "message": "Remind me later" + "message": "後で再通知" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "新しいメールアドレス $EMAIL$ はあなたが管理しているものですか?", "placeholders": { "email": { "content": "$1", @@ -3420,15 +3420,15 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "いいえ、違います" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "はい、メールアドレスには私が確実にアクセスできます" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "2段階認証によるログインを有効にする" }, "changeAcctEmail": { - "message": "Change account email" + "message": "アカウントのメールアドレスを変更する" } } diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 2cd0232e5d4..a23ef820ab7 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -945,7 +945,7 @@ "message": "Pictogrammenserver-URL" }, "environmentSaved": { - "message": "De omgevings-URL's zijn opgeslagen." + "message": "Omgevings-URL's opgeslagen" }, "ok": { "message": "Ok" @@ -1002,7 +1002,7 @@ "message": "Nieuwe map toevoegen" }, "view": { - "message": "Beeld" + "message": "Weergeven" }, "account": { "message": "Account" @@ -1268,7 +1268,7 @@ "description": "Copy to clipboard" }, "checkForUpdates": { - "message": "Controleren op updates" + "message": "Controleren op updates…" }, "version": { "message": "Versie $VERSION_NUM$", @@ -3026,7 +3026,7 @@ } }, "multipleInputEmails": { - "message": "Een of meer e-mailadressen zijn ongeldig" + "message": "Eén of meer e-mailadressen zijn ongeldig" }, "inputTrimValidator": { "message": "Invoer mag niet alleen witruimte bevatten.", @@ -3051,7 +3051,7 @@ "message": "-- Type om te filteren --" }, "multiSelectLoading": { - "message": "Opties ophalen..." + "message": "Opties ophalen…" }, "multiSelectNotFound": { "message": "Geen items gevonden" @@ -3243,7 +3243,7 @@ "message": "LastPass Email" }, "importingYourAccount": { - "message": "Account impoteren..." + "message": "Account impoteren…" }, "lastPassMFARequired": { "message": "LastPass multifactor-authenticatie vereist" @@ -3396,7 +3396,7 @@ "message": "Bestand op apparaat opgeslagen. Beheer vanaf de downloads op je apparaat." }, "importantNotice": { - "message": "Belangrijke mededeling" + "message": "Belangrijke melding" }, "setupTwoStepLogin": { "message": "Tweestapsaanmelding instellen" diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 6013b9b61e0..cec06c3c028 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -3399,7 +3399,7 @@ "message": "Dôležité upozornenie" }, "setupTwoStepLogin": { - "message": "Nastavenie dvojstupňového prihlásenia" + "message": "Nastaviť dvojstupňové prihlásenie" }, "newDeviceVerificationNoticeContentPage1": { "message": "Bitwarden vám od februára 2025 pošle na e-mail vášho účtu kód na overenie prihlásenia z nových zariadení." diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 3196f2c208b..9f9dec2dd68 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -208,19 +208,19 @@ "message": "Генерисан је нови SSH кључ" }, "sshKeyWrongPassword": { - "message": "The password you entered is incorrect." + "message": "Лозинка коју сте унели није тачна." }, "importSshKey": { - "message": "Import" + "message": "Увоз" }, "confirmSshKeyPassword": { - "message": "Confirm password" + "message": "Потврда лозинке" }, "enterSshKeyPasswordDesc": { - "message": "Enter the password for the SSH key." + "message": "Унети лозинку за SSH кључ." }, "enterSshKeyPassword": { - "message": "Enter password" + "message": "Унесите лозинку" }, "sshAgentUnlockRequired": { "message": "Откључајте свој сеф да бисте одобрили захтев за SSH кључ." @@ -920,10 +920,10 @@ "message": "УРЛ Сервера" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Истекло је време аутентификације" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "Истекло је време сесије за аутентификацију. Молим вас покрените процес пријаве поново." }, "selfHostBaseUrl": { "message": "УРЛ сервера који се самостално хостује", @@ -1393,13 +1393,13 @@ "message": "Историја Лозинке" }, "generatorHistory": { - "message": "Generator history" + "message": "Генератор историје" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Испразнити генератор историје" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Ако наставите, сви уноси ће бити трајно избрисани из генератора историје. Да ли сте сигурни да желите да наставите?" }, "clear": { "message": "Очисти", @@ -1409,13 +1409,13 @@ "message": "Нема лозинки за приказивање." }, "clearHistory": { - "message": "Clear history" + "message": "Обриши историју" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Ништа за приказ" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Недавно нисте ништа генерисали" }, "undo": { "message": "Опозови" @@ -2481,7 +2481,7 @@ "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": { @@ -2495,7 +2495,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": { @@ -2505,7 +2505,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": { @@ -2726,13 +2726,13 @@ "message": "Обавештење је послато на ваш уређај." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Обавештење је послато на ваш уређај" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Уверите се да је ваш налог откључан и да се фраза отиска подудара на другом уређају" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Треба Вам друга опција?" }, "fingerprintMatchInfo": { "message": "Уверите се да је ваш сеф откључан и да се фраза отиска прста подудара на другом уређају." @@ -2741,13 +2741,13 @@ "message": "Сигурносна фраза сефа" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Бићете обавештени када захтев буде одобрен" }, "needAnotherOption": { "message": "Пријава помоћу уређаја мора бити подешена у подешавањима Bitwarden апликације. Потребна је друга опција?" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Погледајте сав извештај у опције" }, "viewAllLoginOptions": { "message": "Погредајте све опције пријављивања" @@ -2869,7 +2869,7 @@ "message": "Проверите познате упада података за ову лозинку" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Пријављено!" }, "important": { "message": "Важно:" @@ -2902,16 +2902,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": "Запамти овај уређај" @@ -2966,7 +2966,7 @@ "message": "Недостаје имејл корисника" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Имејл активног корисника није пронађен. Одјављивање." }, "deviceTrusted": { "message": "Уређај поуздан" diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 9ff0efe6854..8357f8616bc 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -3363,10 +3363,10 @@ "message": "SSO girişi için açık port bulunamadı." }, "authorize": { - "message": "Authorize" + "message": "Yetkilendir" }, "deny": { - "message": "Deny" + "message": "Reddet" }, "sshkeyApprovalTitle": { "message": "Confirm SSH key usage" diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index dfcd104cf53..9bff79aa857 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -742,7 +742,7 @@ "message": "必须填写确认主密码。" }, "masterPasswordMinlength": { - "message": "主密码必须至少 $VALUE$ 个字符长度。", + "message": "主密码长度必须至少为 $VALUE$ 个字符。", "description": "The Master Password must be at least a specific number of characters long.", "placeholders": { "value": { @@ -1044,7 +1044,7 @@ "message": "前往网页 App 吗?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "您可以在 Bitwarden 网页应用上更改您的主密码。" + "message": "您可以在 Bitwarden 网页 App 上更改您的主密码。" }, "fingerprintPhrase": { "message": "指纹短语", @@ -1058,7 +1058,7 @@ "message": "转到网页版密码库" }, "getMobileApp": { - "message": "获取移动应用程序" + "message": "获取移动 App" }, "getBrowserExtension": { "message": "获取浏览器扩展" @@ -1247,13 +1247,13 @@ "message": "语言" }, "languageDesc": { - "message": "更改应用程序所使用的语言。重新启动后生效。" + "message": "更改应用程序所使用的语言。重启后生效。" }, "theme": { "message": "主题" }, "themeDesc": { - "message": "更改本应用程序的颜色主题。" + "message": "更改应用程序的颜色主题。" }, "dark": { "message": "深色", @@ -1665,7 +1665,7 @@ "message": "确认密码库导出" }, "exportWarningDesc": { - "message": "导出的密码库数据包含未加密格式。您不应该通过不安全的渠道(例如电子邮件)来存储或发送导出的文件。用完后请立即将其删除。" + "message": "此导出包含未加密格式的密码库数据。您不应该通过不安全的渠道(例如电子邮件)来存储或发送此导出文件。使用完后请立即将其删除。" }, "encExportKeyWarningDesc": { "message": "此导出将使用您账户的加密密钥来加密您的数据。如果您曾经轮换过账户的加密密钥,您应将其重新导出,否则您将无法解密导出的文件。" @@ -1711,7 +1711,7 @@ "message": "使用 PIN 码解锁" }, "setYourPinCode": { - "message": "设定您用来解锁 Bitwarden 的 PIN 码。您的 PIN 设置将在您完全注销本应用程序时被重置。" + "message": "设置用于解锁 Bitwarden 的 PIN 码。您的 PIN 设置将在您完全注销应用程序时被重置。" }, "pinRequired": { "message": "需要 PIN 码。" @@ -1753,7 +1753,7 @@ "message": "应用程序启动时要求使用触控 ID" }, "requirePasswordOnStart": { - "message": "应用程序启动时要求输入密码或 PIN 码" + "message": "App 启动时要求输入密码或 PIN 码" }, "recommendedForSecurity": { "message": "安全起见,推荐设置。" @@ -2402,7 +2402,7 @@ "message": "偏好设置" }, "appPreferences": { - "message": "应用设置(所有账户)" + "message": "应用程序设置(所有账户)" }, "accountSwitcherLimitReached": { "message": "已达到账户上限。请注销一个账户后再添加其他账户。" @@ -3369,7 +3369,7 @@ "message": "拒绝" }, "sshkeyApprovalTitle": { - "message": "确认 SSH 密钥的使用方式" + "message": "确认 SSH 密钥的使用" }, "sshkeyApprovalMessageInfix": { "message": "正在请求访问" @@ -3402,7 +3402,7 @@ "message": "设置两步登录" }, "newDeviceVerificationNoticeContentPage1": { - "message": "从 2025 年 02 月开始,Bitwarden 将向您的账户电子邮箱发送一个代码,以验证来自新设备的登录。" + "message": "从 2025 年 02 月起,当有来自新设备的登录时,Bitwarden 将向您的账户电子邮箱发送验证码。" }, "newDeviceVerificationNoticeContentPage2": { "message": "您可以设置两步登录作为保护账户的替代方法,或将您的电子邮箱更改为您可以访问的电子邮箱。" @@ -3411,7 +3411,7 @@ "message": "稍后提醒我" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "您能可靠地访问您的电子邮箱 $EMAIL$ 吗?", + "message": "您能可正常访问您的电子邮箱 $EMAIL$ 吗?", "placeholders": { "email": { "content": "$1", @@ -3423,7 +3423,7 @@ "message": "不,我不能" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "是的,我可以可靠地访问我的电子邮箱" + "message": "是的,我可以正常访问我的电子邮箱" }, "turnOnTwoStepLogin": { "message": "开启两步登录" From 860711337e461dc3c69c7444c32628c443ae3df5 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:34:23 +0000 Subject: [PATCH 47/65] Autosync the updated translations (#12712) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/fi/messages.json | 6 +- apps/browser/src/_locales/it/messages.json | 310 +++++++++--------- apps/browser/src/_locales/ja/messages.json | 12 +- apps/browser/src/_locales/tr/messages.json | 2 +- apps/browser/src/_locales/zh_CN/messages.json | 8 +- 5 files changed, 169 insertions(+), 169 deletions(-) diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 2c621dc4621..718c0631156 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -2105,7 +2105,7 @@ "message": "Aikakatkaisutoiminnon vahvistus" }, "autoFillAndSave": { - "message": "Täytä automaattisesti ja tallenna" + "message": "Automaattitäytä ja tallenna" }, "fillAndSave": { "message": "Täytä ja tallenna" @@ -3482,7 +3482,7 @@ "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "Aika jäljellä, ennen kuin nykyinen TOTP vanhenee", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { @@ -4810,7 +4810,7 @@ "message": "Määritä kaksivaiheinen kirjautuminen" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden lähettää tilisi sähköpostiosoitteeseen koodin, jolla voit vahvistaa kirjautumiset uusista laitteista helmikuusta 2025 alkaen." }, "newDeviceVerificationNoticeContentPage2": { "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 711f62f4dea..6490a441832 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -20,16 +20,16 @@ "message": "Crea account" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Nuovo in Bitwarden?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Accedi con passkey" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "Usa il Single Sign-On" }, "welcomeBack": { - "message": "Welcome back" + "message": "Bentornato" }, "setAStrongPassword": { "message": "Imposta una password robusta" @@ -120,7 +120,7 @@ "message": "Copia password" }, "copyPassphrase": { - "message": "Copy passphrase" + "message": "Copia passphrase" }, "copyNote": { "message": "Copia nota" @@ -153,13 +153,13 @@ "message": "Copia numero licenza" }, "copyPrivateKey": { - "message": "Copy private key" + "message": "Copia chiave privata" }, "copyPublicKey": { - "message": "Copy public key" + "message": "Copia chiave pubblica" }, "copyFingerprint": { - "message": "Copy fingerprint" + "message": "Copia impronta" }, "copyCustomField": { "message": "Copia $FIELD$", @@ -177,7 +177,7 @@ "message": "Copia note" }, "fill": { - "message": "Fill", + "message": "Riempi", "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": { @@ -193,10 +193,10 @@ "message": "Riempi automaticamente identità" }, "fillVerificationCode": { - "message": "Fill verification code" + "message": "Riempi codice di verifica" }, "fillVerificationCodeAria": { - "message": "Fill Verification Code", + "message": "Riempi Codice di Verifica", "description": "Aria label for the heading displayed the inline menu for totp code autofill" }, "generatePasswordCopied": { @@ -239,7 +239,7 @@ "message": "Aggiungi elemento" }, "accountEmail": { - "message": "Account email" + "message": "Email dell'account" }, "requestHint": { "message": "Richiedi suggerimento" @@ -443,7 +443,7 @@ "message": "Genera password" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "Genera passphrase" }, "regeneratePassword": { "message": "Rigenera password" @@ -530,7 +530,7 @@ "description": "Label for the avoid ambiguous characters checkbox." }, "generatorPolicyInEffect": { - "message": "Enterprise policy requirements have been applied to your generator options.", + "message": "I requisiti di politica aziendale sono stati applicati alle opzioni del generatore.", "description": "Indicates that a policy limits the credential generator screen." }, "searchVault": { @@ -576,7 +576,7 @@ "message": "Note" }, "privateNote": { - "message": "Private note" + "message": "Nota privata" }, "note": { "message": "Nota" @@ -600,7 +600,7 @@ "message": "Avvia il sito web" }, "launchWebsiteName": { - "message": "Launch website $ITEMNAME$", + "message": "Apri sito web $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -633,7 +633,7 @@ "message": "Timeout della sessione" }, "vaultTimeoutHeader": { - "message": "Vault timeout" + "message": "Timeout cassaforte" }, "otherOptions": { "message": "Altre opzioni" @@ -651,13 +651,13 @@ "message": "La tua cassaforte è bloccata. Verifica la tua identità per continuare." }, "yourVaultIsLockedV2": { - "message": "Your vault is locked" + "message": "Cassaforte bloccata" }, "yourAccountIsLocked": { - "message": "Your account is locked" + "message": "Il tuo account è bloccato" }, "or": { - "message": "or" + "message": "o" }, "unlock": { "message": "Sblocca" @@ -852,7 +852,7 @@ "message": "Accedi" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Accedi a Bitwarden" }, "restartRegistration": { "message": "Riprova la registrazione" @@ -888,10 +888,10 @@ "message": "La verifica in due passaggi rende il tuo account più sicuro richiedendoti di verificare il tuo login usando un altro dispositivo come una chiave di sicurezza, app di autenticazione, SMS, telefonata, o email. Può essere abilitata nella cassaforte web su bitwarden.com. Vuoi visitare il sito?" }, "twoStepLoginConfirmationContent": { - "message": "Make your account more secure by setting up two-step login in the Bitwarden web app." + "message": "Rendi il tuo account più sicuro impostando l'autenticazione a due fattori nell'app web di Bitwarden." }, "twoStepLoginConfirmationTitle": { - "message": "Continue to web app?" + "message": "Aprire web app?" }, "editedFolder": { "message": "Cartella salvata" @@ -1005,7 +1005,7 @@ "message": "Mostra le identità nella sezione Scheda per riempirle automaticamente." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Clicca gli oggetti da riempire dalla sezione Cassaforte" }, "clearClipboard": { "message": "Cancella appunti", @@ -1126,7 +1126,7 @@ "description": "WARNING (should stay in capitalized letters if the language permits)" }, "warningCapitalized": { - "message": "Warning", + "message": "Attenzione", "description": "Warning (should maintain locale-relevant capitalization)" }, "confirmVaultExport": { @@ -1206,7 +1206,7 @@ "message": "File" }, "fileToShare": { - "message": "File to share" + "message": "File da condividere" }, "selectFile": { "message": "Seleziona un file" @@ -1317,10 +1317,10 @@ "message": "Inserisci il codice di verifica a 6 cifre dalla tua app di autenticazione." }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "Timeout autenticazione" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "La sessione di autenticazione è scaduta. Accedi di nuovo." }, "enterVerificationCodeEmail": { "message": "Inserisci il codice di verifica a 6 cifre inviato a $EMAIL$.", @@ -1440,7 +1440,7 @@ "message": "URL del server" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "URL server autogestito", "description": "Label for field requesting a self-hosted integration service URL" }, "apiUrl": { @@ -1472,10 +1472,10 @@ "message": "Mostra suggerimenti di riempimento automatico nei campi del modulo" }, "showInlineMenuIdentitiesLabel": { - "message": "Display identities as suggestions" + "message": "Mostra identità come consigli" }, "showInlineMenuCardsLabel": { - "message": "Display cards as suggestions" + "message": "Mostra carte come consigli" }, "showInlineMenuOnIconSelectionLabel": { "message": "Mostra suggerimenti quando l'icona è selezionata" @@ -1768,7 +1768,7 @@ "message": "Identità" }, "typeSshKey": { - "message": "SSH key" + "message": "Chiave SSH" }, "newItemHeader": { "message": "Nuovo $TYPE$", @@ -1801,13 +1801,13 @@ "message": "Cronologia delle password" }, "generatorHistory": { - "message": "Generator history" + "message": "Cronologia generatore" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "Cancella cronologia generatore" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "Se continui, tutte le voci verranno eliminate definitivamente dalla cronologia del generatore. Vuoi continuare?" }, "back": { "message": "Indietro" @@ -1846,7 +1846,7 @@ "message": "Note sicure" }, "sshKeys": { - "message": "SSH Keys" + "message": "Chiavi SSH" }, "clear": { "message": "Cancella", @@ -1929,10 +1929,10 @@ "message": "Cancella cronologia" }, "nothingToShow": { - "message": "Nothing to show" + "message": "Niente da mostrare" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "Non hai generato niente di recente" }, "remove": { "message": "Rimuovi" @@ -1993,16 +1993,16 @@ "message": "Sblocca con PIN" }, "setYourPinTitle": { - "message": "Set PIN" + "message": "Imposta PIN" }, "setYourPinButton": { - "message": "Set PIN" + "message": "Imposta PIN" }, "setYourPinCode": { "message": "Imposta il tuo codice PIN per sbloccare Bitwarden. Le tue impostazioni PIN saranno resettate se esci completamente dall'app." }, "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": "Il tuo PIN sarà usato per sbloccare Bitwarden invece della password principale. Il PIN sarà ripristinato se ti disconnetterai completamente da Bitwarden." }, "pinRequired": { "message": "Codice PIN obbligatorio." @@ -2017,7 +2017,7 @@ "message": "Sblocca con i dati biometrici" }, "unlockWithMasterPassword": { - "message": "Unlock with master password" + "message": "Sblocca con password principale" }, "awaitDesktop": { "message": "In attesa di conferma dal desktop" @@ -2029,7 +2029,7 @@ "message": "Blocca con la password principale al riavvio del browser" }, "lockWithMasterPassOnRestart1": { - "message": "Require master password on browser restart" + "message": "Richiedi password principale al riavvio del browser" }, "selectOneCollection": { "message": "Devi selezionare almeno una raccolta." @@ -2067,7 +2067,7 @@ "message": "Azione timeout cassaforte" }, "vaultTimeoutAction1": { - "message": "Timeout action" + "message": "Azione al timeout" }, "lock": { "message": "Blocca", @@ -2355,14 +2355,14 @@ "message": "Modifiche del dominio escluso salvate" }, "limitSendViews": { - "message": "Limit views" + "message": "Limita visualizzazioni" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "Nessuno potrà vedere questo Send al raggiungimento del limite.", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "$ACCESSCOUNT$ visualizzazioni rimaste", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -2376,14 +2376,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendDetails": { - "message": "Send details", + "message": "Dettagli Send", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeText": { "message": "Testo" }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "Testo da condividere" }, "sendTypeFile": { "message": "File" @@ -2393,7 +2393,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": "Nascondi testo come default" }, "expired": { "message": "Scaduto" @@ -2440,7 +2440,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": "Sicuro di voler eliminare definitivamente questo Send?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "editSend": { @@ -2451,7 +2451,7 @@ "message": "Data di eliminazione" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "Il Send sarà cancellato definitivamente in questa data.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -2473,7 +2473,7 @@ "message": "Personalizzato" }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "Richiedi ai destinatari una password opzionale per aprire questo Send.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { @@ -2500,11 +2500,11 @@ "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": "Il Send sarà disponibile a chiunque con il link per la prossima ora.", "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": "Il Send sarà disponibile a chiunque con il link per le prossime $HOURS$ ore.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "hours": { @@ -2514,11 +2514,11 @@ } }, "sendExpiresInDaysSingle": { - "message": "The Send will be available to anyone with the link for the next 1 day.", + "message": "Il Send sarà disponibile a chiunque con il link per il prossimo giorno.", "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": "Il Send sarà disponibile a chiunque con il link per i prossimi $DAYS$ giorni.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated.", "placeholders": { "days": { @@ -2536,11 +2536,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": "Scollegare estensione?", "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": "Per creare un file Send, devi scollegare l'estensione in una nuova finestra.", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendLinuxChromiumFileWarning": { @@ -2553,7 +2553,7 @@ "message": "Per scegliere un file usando Safari, apri una nuova finestra cliccando questo banner." }, "popOut": { - "message": "Pop out" + "message": "Scollega" }, "sendFileCalloutHeader": { "message": "Prima di iniziare" @@ -2574,7 +2574,7 @@ "message": "Si è verificato un errore durante il salvataggio delle date di eliminazione e scadenza." }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "Nascondi il tuo indirizzo email ai visualizzatori." }, "passwordPrompt": { "message": "Richiedi di inserire la password principale di nuovo per visualizzare questo elemento" @@ -2631,7 +2631,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": "di $TOTAL$", "placeholders": { "total": { "content": "$1", @@ -2650,7 +2650,7 @@ "message": "Minuti" }, "vaultTimeoutPolicyAffectingOptions": { - "message": "Enterprise policy requirements have been applied to your timeout options" + "message": "I requisiti di politica aziendale sono stati applicati alle opzioni di timeout" }, "vaultTimeoutPolicyInEffect": { "message": "Le politiche della tua organizzazione hanno impostato il timeout massimo consentito della tua cassaforte su $HOURS$ ore e $MINUTES$ minuti.", @@ -2666,7 +2666,7 @@ } }, "vaultTimeoutPolicyInEffect1": { - "message": "$HOURS$ hour(s) and $MINUTES$ minute(s) maximum.", + "message": "Al massimo $HOURS$ ora/e e $MINUTES$ minuto/i.", "placeholders": { "hours": { "content": "$1", @@ -2679,7 +2679,7 @@ } }, "vaultTimeoutPolicyMaximumError": { - "message": "Timeout exceeds the restriction set by your organization: $HOURS$ hour(s) and $MINUTES$ minute(s) maximum", + "message": "Il timeout supera la restrizione impostata dalla tua organizzazione: massimo $HOURS$ ora/e e $MINUTES$ minuto/i", "placeholders": { "hours": { "content": "$1", @@ -2793,10 +2793,10 @@ "message": "Genera nome utente" }, "generateEmail": { - "message": "Generate email" + "message": "Genera email" }, "spinboxBoundariesHint": { - "message": "Value must be between $MIN$ and $MAX$.", + "message": "Il valore deve essere compreso tra $MIN$ e $MAX$.", "description": "Explains spin box minimum and maximum values to the user", "placeholders": { "min": { @@ -2810,7 +2810,7 @@ } }, "passwordLengthRecommendationHint": { - "message": " Use $RECOMMENDED$ characters or more to generate a strong password.", + "message": " Usa $RECOMMENDED$ caratteri o più per generare una password forte.", "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": { @@ -2820,7 +2820,7 @@ } }, "passphraseNumWordsRecommendationHint": { - "message": " Use $RECOMMENDED$ words or more to generate a strong passphrase.", + "message": " Usa $RECOMMENDED$ parole o più per generare una passphrase forte.", "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": { @@ -2861,11 +2861,11 @@ "message": "Genera un alias email con un servizio di inoltro esterno." }, "forwarderDomainName": { - "message": "Email domain", + "message": "Dominio email", "description": "Labels the domain name email forwarder service option" }, "forwarderDomainNameHint": { - "message": "Choose a domain that is supported by the selected service", + "message": "Scegli un dominio supportato dal servizio selezionato", "description": "Guidance provided for email forwarding services that support multiple email domains." }, "forwarderError": { @@ -3068,25 +3068,25 @@ "message": "Invia notifica di nuovo" }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "Visualizza tutte le opzioni di accesso" }, "viewAllLoginOptionsV1": { - "message": "View all log in options" + "message": "Visualizza tutte le opzioni di accesso" }, "notificationSentDevice": { "message": "Una notifica è stata inviata al tuo dispositivo." }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "Una notifica è stata inviata al tuo dispositivo" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "Assicurati che il tuo account sia sbloccato e che la frase dell'impronta digitale corrisponda nell'altro dispositivo" }, "youWillBeNotifiedOnceTheRequestIsApproved": { - "message": "You will be notified once the request is approved" + "message": "Sarai notificato una volta che la richiesta sarà approvata" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "Bisogno di un'altra opzione?" }, "loginInitiated": { "message": "Accesso avviato" @@ -3182,16 +3182,16 @@ "message": "Si apre in una nuova finestra" }, "rememberThisDeviceToMakeFutureLoginsSeamless": { - "message": "Remember this device to make future logins seamless" + "message": "Ricorda questo dispositivo per rendere immediati i futuri accessi" }, "deviceApprovalRequired": { "message": "Approvazione del dispositivo obbligatoria. Seleziona un'opzione di approvazione:" }, "deviceApprovalRequiredV2": { - "message": "Device approval required" + "message": "Approvazione dispositivo richiesta" }, "selectAnApprovalOptionBelow": { - "message": "Select an approval option below" + "message": "Seleziona un'opzione di approvazione sotto" }, "rememberThisDevice": { "message": "Ricorda questo dispositivo" @@ -3267,7 +3267,7 @@ "message": "Email utente mancante" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "Email utente attiva non trovata. Logout in corso." }, "deviceTrusted": { "message": "Dispositivo fidato" @@ -3478,11 +3478,11 @@ "description": "Screen reader text (aria-label) for unlock account button in overlay" }, "totpCodeAria": { - "message": "Time-based One-Time Password Verification Code", + "message": "Codice di Verifica One-Time a tempo", "description": "Aria label for the totp code displayed in the inline menu for autofill" }, "totpSecondsSpanAria": { - "message": "Time remaining before current TOTP expires", + "message": "Tempo rimasto prima che l'attuale TOTP scada", "description": "Aria label for the totp seconds displayed in the inline menu for autofill" }, "fillCredentialsFor": { @@ -3711,10 +3711,10 @@ "message": "Passkey" }, "accessing": { - "message": "Accessing" + "message": "Accedendo a" }, "loggedInExclamation": { - "message": "Logged in!" + "message": "Accesso effettuato!" }, "passkeyNotCopied": { "message": "La passkey non sarà copiata" @@ -3741,7 +3741,7 @@ "message": "Nessun login corrispondente per questo sito" }, "searchSavePasskeyNewLogin": { - "message": "Search or save passkey as new login" + "message": "Cerca o salva la passkey come nuovo login" }, "confirm": { "message": "Conferma" @@ -4208,13 +4208,13 @@ "message": "Filtri" }, "filterVault": { - "message": "Filter vault" + "message": "Filtra cassaforte" }, "filterApplied": { - "message": "One filter applied" + "message": "Un filtro applicato" }, "filterAppliedPlural": { - "message": "$COUNT$ filters applied", + "message": "$COUNT$ filtri applicati", "placeholders": { "count": { "content": "$1", @@ -4328,7 +4328,7 @@ "message": "Abilita animazioni" }, "showAnimations": { - "message": "Show animations" + "message": "Mostra animazioni" }, "addAccount": { "message": "Aggiungi account" @@ -4546,13 +4546,13 @@ "message": "Posizione elemento" }, "fileSend": { - "message": "File Send" + "message": "Send di File" }, "fileSends": { "message": "Send File" }, "textSend": { - "message": "Text Send" + "message": "Send di Testo" }, "textSends": { "message": "Send Testo" @@ -4570,7 +4570,7 @@ "message": "Mostra il numero di suggerimenti di riempimento automatico sull'icona dell'estensione" }, "showQuickCopyActions": { - "message": "Show quick copy actions on Vault" + "message": "Mostra azioni di copia rapida nella Cassaforte" }, "systemDefault": { "message": "Predefinito del sistema" @@ -4579,37 +4579,37 @@ "message": "I requisiti della policy aziendale sono stati applicati a questa impostazione" }, "sshPrivateKey": { - "message": "Private key" + "message": "Chiave privata" }, "sshPublicKey": { - "message": "Public key" + "message": "Chiave pubblica" }, "sshFingerprint": { - "message": "Fingerprint" + "message": "Impronta digitale" }, "sshKeyAlgorithm": { - "message": "Key type" + "message": "Tipo di chiave" }, "sshKeyAlgorithmED25519": { "message": "ED25519" }, "sshKeyAlgorithmRSA2048": { - "message": "RSA 2048-Bit" + "message": "RSA a 2048 bit" }, "sshKeyAlgorithmRSA3072": { - "message": "RSA 3072-Bit" + "message": "RSA a 3072 bit" }, "sshKeyAlgorithmRSA4096": { - "message": "RSA 4096-Bit" + "message": "RSA a 4096 bit" }, "retry": { - "message": "Retry" + "message": "Riprova" }, "vaultCustomTimeoutMinimum": { - "message": "Minimum custom timeout is 1 minute." + "message": "Il timeout personalizzato minimo è 1 minuto." }, "additionalContentAvailable": { - "message": "Additional content is available" + "message": "Sono disponibili ulteriori contenuti" }, "fileSavedToDevice": { "message": "File salvato sul dispositivo. Gestisci dai download del dispositivo." @@ -4642,22 +4642,22 @@ "message": "Non hai i permessi per modificare questo elemento" }, "authenticating": { - "message": "Authenticating" + "message": "Autenticazione" }, "fillGeneratedPassword": { - "message": "Fill generated password", + "message": "Riempi password generata", "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "Password rigenerata", "description": "Notification message for when a password has been regenerated" }, "saveLoginToBitwarden": { - "message": "Save login to Bitwarden?", + "message": "Salvare il login su Bitwarden?", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "Spazio", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { @@ -4669,157 +4669,157 @@ "description": "Represents the ` key in screen reader content as a readable word" }, "exclamationCharacterDescriptor": { - "message": "Exclamation mark", + "message": "Punto esclamativo", "description": "Represents the ! key in screen reader content as a readable word" }, "atSignCharacterDescriptor": { - "message": "At sign", + "message": "Chiocciola", "description": "Represents the @ key in screen reader content as a readable word" }, "hashSignCharacterDescriptor": { - "message": "Hash sign", + "message": "Cancelletto", "description": "Represents the # key in screen reader content as a readable word" }, "dollarSignCharacterDescriptor": { - "message": "Dollar sign", + "message": "Simbolo del dollaro", "description": "Represents the $ key in screen reader content as a readable word" }, "percentSignCharacterDescriptor": { - "message": "Percent sign", + "message": "Segno di percentuale", "description": "Represents the % key in screen reader content as a readable word" }, "caretCharacterDescriptor": { - "message": "Caret", + "message": "Accento circonflesso", "description": "Represents the ^ key in screen reader content as a readable word" }, "ampersandCharacterDescriptor": { - "message": "Ampersand", + "message": "E commerciale", "description": "Represents the & key in screen reader content as a readable word" }, "asteriskCharacterDescriptor": { - "message": "Asterisk", + "message": "Asterisco", "description": "Represents the * key in screen reader content as a readable word" }, "parenLeftCharacterDescriptor": { - "message": "Left parenthesis", + "message": "Parentesi sinistra", "description": "Represents the ( key in screen reader content as a readable word" }, "parenRightCharacterDescriptor": { - "message": "Right parenthesis", + "message": "Parentesi destra", "description": "Represents the ) key in screen reader content as a readable word" }, "hyphenCharacterDescriptor": { - "message": "Underscore", + "message": "Trattino basso", "description": "Represents the _ key in screen reader content as a readable word" }, "underscoreCharacterDescriptor": { - "message": "Hyphen", + "message": "Trattino", "description": "Represents the - key in screen reader content as a readable word" }, "plusCharacterDescriptor": { - "message": "Plus", + "message": "Più", "description": "Represents the + key in screen reader content as a readable word" }, "equalsCharacterDescriptor": { - "message": "Equals", + "message": "Uguale", "description": "Represents the = key in screen reader content as a readable word" }, "braceLeftCharacterDescriptor": { - "message": "Left brace", + "message": "Parentesi graffa aperta", "description": "Represents the { key in screen reader content as a readable word" }, "braceRightCharacterDescriptor": { - "message": "Right brace", + "message": "Parentesi graffa chiusa", "description": "Represents the } key in screen reader content as a readable word" }, "bracketLeftCharacterDescriptor": { - "message": "Left bracket", + "message": "Parentesi quadra aperta", "description": "Represents the [ key in screen reader content as a readable word" }, "bracketRightCharacterDescriptor": { - "message": "Right bracket", + "message": "Parentesi quadra chiusa", "description": "Represents the ] key in screen reader content as a readable word" }, "pipeCharacterDescriptor": { - "message": "Pipe", + "message": "Barra verticale", "description": "Represents the | key in screen reader content as a readable word" }, "backSlashCharacterDescriptor": { - "message": "Back slash", + "message": "Barra rovesciata", "description": "Represents the back slash key in screen reader content as a readable word" }, "colonCharacterDescriptor": { - "message": "Colon", + "message": "Due punti", "description": "Represents the : key in screen reader content as a readable word" }, "semicolonCharacterDescriptor": { - "message": "Semicolon", + "message": "Punto e virgola", "description": "Represents the ; key in screen reader content as a readable word" }, "doubleQuoteCharacterDescriptor": { - "message": "Double quote", + "message": "Doppi apici", "description": "Represents the double quote key in screen reader content as a readable word" }, "singleQuoteCharacterDescriptor": { - "message": "Single quote", + "message": "Apostrofo", "description": "Represents the ' key in screen reader content as a readable word" }, "lessThanCharacterDescriptor": { - "message": "Less than", + "message": "Minore", "description": "Represents the < key in screen reader content as a readable word" }, "greaterThanCharacterDescriptor": { - "message": "Greater than", + "message": "Maggiore", "description": "Represents the > key in screen reader content as a readable word" }, "commaCharacterDescriptor": { - "message": "Comma", + "message": "Virgola", "description": "Represents the , key in screen reader content as a readable word" }, "periodCharacterDescriptor": { - "message": "Period", + "message": "Punto", "description": "Represents the . key in screen reader content as a readable word" }, "questionCharacterDescriptor": { - "message": "Question mark", + "message": "Punto interrogativo", "description": "Represents the ? key in screen reader content as a readable word" }, "forwardSlashCharacterDescriptor": { - "message": "Forward slash", + "message": "Slash", "description": "Represents the / key in screen reader content as a readable word" }, "lowercaseAriaLabel": { - "message": "Lowercase" + "message": "Minuscolo" }, "uppercaseAriaLabel": { - "message": "Uppercase" + "message": "Maiuscolo" }, "generatedPassword": { - "message": "Generated password" + "message": "Password generata" }, "compactMode": { - "message": "Compact mode" + "message": "Modalità compatta" }, "beta": { "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Avviso importante" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Imposta accesso in due passaggi" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden invierà un codice all'email del tuo account per verificare gli accessi da nuovi dispositivi a partire da febbraio 2025." }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "Puoi impostare l'accesso in due passaggi come modo alternativo per proteggere il tuo account, o cambiare la tua e-mail in una alla quale puoi accedere." }, "remindMeLater": { - "message": "Remind me later" + "message": "Ricordamelo più tardi" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Riesci ancora ad accedere a questa email, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -4828,24 +4828,24 @@ } }, "newDeviceVerificationNoticePageOneEmailAccessNo": { - "message": "No, I do not" + "message": "No, non riesco" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "Sì, riesco ad accedere a questa email" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Attiva accesso in due passaggi" }, "changeAcctEmail": { - "message": "Change account email" + "message": "Cambia l'email dell'account" }, "extensionWidth": { - "message": "Extension width" + "message": "Larghezza estensione" }, "wide": { - "message": "Wide" + "message": "Larga" }, "extraWide": { - "message": "Extra wide" + "message": "Molto larga" } } diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index 0ffe01e7992..42dd73020ec 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -1005,7 +1005,7 @@ "message": "自動入力を簡単にするために、タブページに ID アイテムを表示します" }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "保管庫で、自動入力するアイテムをクリックしてください" }, "clearClipboard": { "message": "クリップボードの消去", @@ -4810,10 +4810,10 @@ "message": "2段階認証を設定する" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden は2025年2月以降、新しいデバイスからのログイン時にアカウントのメールアドレスに確認コードを送信します。" }, "newDeviceVerificationNoticeContentPage2": { - "message": "You can set up two-step login as an alternative way to protect your account or change your email to one you can access." + "message": "代わりに2段階認証によるログインでアカウントを保護するか、メールアドレスをあなたがアクセスできるものに変更できます。" }, "remindMeLater": { "message": "後で再通知" @@ -4831,13 +4831,13 @@ "message": "いいえ、違います。" }, "newDeviceVerificationNoticePageOneEmailAccessYes": { - "message": "Yes, I can reliably access my email" + "message": "はい、メールアドレスには私が確実にアクセスできます" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "2段階認証によるログインを有効にする" }, "changeAcctEmail": { - "message": "Change account email" + "message": "アカウントのメールアドレスを変更する" }, "extensionWidth": { "message": "拡張機能の幅" diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index a4c064e0394..e1236b3f86d 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -4154,7 +4154,7 @@ "message": "Ek bilgiler" }, "itemHistory": { - "message": "Öğe geçmişi" + "message": "Kayıt geçmişi" }, "lastEdited": { "message": "Son düzenlenme" diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index 9af42f75e08..69c1194af47 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -428,7 +428,7 @@ "description": "Short for 'credential generator'." }, "passGenInfo": { - "message": "自动生成安全可靠唯一的登录密码。" + "message": "自动为您的登录生成强大且唯一的密码。" }, "bitWebVaultApp": { "message": "Bitwarden 网页 App" @@ -888,7 +888,7 @@ "message": "两步登录要求您从其他设备(例如安全钥匙、验证器 App、短信、电话或者电子邮件)来验证您的登录,这能使您的账户更加安全。两步登录需要在 bitwarden.com 网页版密码库中设置。现在访问此网站吗?" }, "twoStepLoginConfirmationContent": { - "message": "通过在 Bitwarden 网页 App 中设置两步登录,可以使您的账户更加安全。" + "message": "在 Bitwarden 网页 App 中设置两步登录,让您的账户更加安全。" }, "twoStepLoginConfirmationTitle": { "message": "前往网页 App 吗?" @@ -2123,7 +2123,7 @@ "message": "您仍然想要填充此登录信息吗?" }, "autofillIframeWarning": { - "message": "该表单由不同于您保存的登录的 URI 域名托管。选择「确定」以自动填充,或选择「取消」停止填充。" + "message": "该表单由与您保存的登录 URI 不同的域名托管。选择「确定」继续自动填充,或选择「取消」停止自动填充。" }, "autofillIframeWarningTip": { "message": "要防止以后出现此警告,请将此站点的 URI $HOSTNAME$ 保存到您的 Bitwarden 登录项目中。", @@ -3982,7 +3982,7 @@ "message": "自动填充建议" }, "autofillSuggestionsTip": { - "message": "保存此站点的登录项目用来自动填充" + "message": "将此站点保存为登录项目以用于自动填充" }, "yourVaultIsEmpty": { "message": "您的密码库是空的" From e75a38c438270fd386e816bb4414b7cae630c30b Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 15:34:47 +0000 Subject: [PATCH 48/65] Autosync the updated translations (#12713) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/az/messages.json | 8 +- apps/web/src/locales/da/messages.json | 8 +- apps/web/src/locales/de/messages.json | 14 +-- apps/web/src/locales/en_IN/messages.json | 6 +- apps/web/src/locales/ja/messages.json | 146 +++++++++++------------ apps/web/src/locales/lv/messages.json | 8 +- apps/web/src/locales/sk/messages.json | 14 +-- apps/web/src/locales/zh_CN/messages.json | 26 ++-- 8 files changed, 115 insertions(+), 115 deletions(-) diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index 09785738464..b8111a0e997 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -9272,16 +9272,16 @@ "message": "Güncəlllənən vergi məlumatı" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Yararsız vergi kimliyi, bunun xəta olduğunu düşünürsünüzsə, dəstək komandası ilə əlaqə saxlayın." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Vergi kimliyi nömrənizi doğrulaya bilmədik, bunun xəta olduğunu düşünürsünüzsə, dəstək komandası ilə əlaqə saxlayın." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Yararsız vergi kimliyi, bunun xəta olduğunu düşünürsünüzsə, dəstək komandası ilə əlaqə saxlayın." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Faktura önizləməsi zamanı bir xəta baş verdi. Lütfən daha sonra yenidən sınayın." }, "unverified": { "message": "Doğrulanmayıb" diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index b2b3b0491c3..f71e1feeb3b 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -9272,16 +9272,16 @@ "message": "Opdaterede momsoplysninger" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Ugyldigt moms-ID. Mener man, at dette er en fejl, kontakt venligst supporten." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Moms-ID kan ikke bekræftes. Mener man, at dette er en fejl, kontakt venligst supporten." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Ugyldigt moms-ID. Mener man, at dette er en fejl, kontakt venligst supporten." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "En fejl opstod under forhåndsvisning af fakturaen. Forsøg igen senere." }, "unverified": { "message": "Ubekræftet" diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 4596dd88b3a..93422471457 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -9272,16 +9272,16 @@ "message": "Steuerinformationen aktualisiert" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Ungültige Steuer-ID. Wenn du glaubst, dass dies ein Fehler ist, wende dich bitte an den Support." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Wir konnten deine Steuer-ID nicht überprüfen. Wenn du glaubst, dass dies ein Fehler ist, kontaktiere bitte den Support." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Ungültige Steuer-ID. Wenn du glaubst, dass dies ein Fehler ist, wende dich bitte an den Support." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Bei der Vorschau der Rechnung ist ein Fehler aufgetreten. Bitte versuche es später erneut." }, "unverified": { "message": "Nicht verifiziert" @@ -10021,7 +10021,7 @@ "message": "Der Name der Organisation darf 50 Zeichen nicht überschreiten." }, "resellerRenewalWarning": { - "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "message": "Dein Abonnement wird bald verlängert. Um einen ununterbrochenen Betrieb zu gewährleisten, kontaktiere $RESELLER$ um deine Verlängerung vor dem $RENEWAL_DATE$ zu bestätigen.", "placeholders": { "reseller": { "content": "$1", @@ -10034,7 +10034,7 @@ } }, "resellerOpenInvoiceWarning": { - "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "message": "Eine Rechnung für dein Abonnement wurde am $ISSUED_DATE$ ausgestellt. Um einen ununterbrochenen Betrieb zu gewährleisten, kontaktiere $RESELLER$, um deine Verlängerung vor dem $DUE_DATE$ zu bestätigen.", "placeholders": { "reseller": { "content": "$1", @@ -10051,7 +10051,7 @@ } }, "resellerPastDueWarning": { - "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "message": "Die Rechnung für dein Abonnement wurde nicht bezahlt. Um einen ununterbrochenen Betrieb zu gewährleisten, kontaktiere $RESELLER$, um deine Verlängerung vor dem $GRACE_PERIOD_END$ zu bestätigen.", "placeholders": { "reseller": { "content": "$1", diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index 131b6b36383..ec67bb192c9 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -9272,13 +9272,13 @@ "message": "Updated tax information" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Invalid Aadhaar ID, if you believe this is an error please contact support." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "We were unable to validate your Aadhaar ID, if you believe this is an error please contact support." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Invalid Aadhaar ID, if you believe this is an error please contact support." }, "billingPreviewInvoiceError": { "message": "An error occurred while previewing the invoice. Please try again later." diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 1383ce49170..6b3b6f13b46 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -3,22 +3,22 @@ "message": "すべてのアプリ" }, "criticalApplications": { - "message": "Critical applications" + "message": "きわめて重要なアプリ" }, "accessIntelligence": { - "message": "Access Intelligence" + "message": "アクセス インテリジェンス" }, "riskInsights": { - "message": "Risk Insights" + "message": "リスク分析" }, "passwordRisk": { - "message": "Password Risk" + "message": "パスワードのリスク" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords (weak, exposed, or reused) across applications. Select your most critical applications to prioritize security actions for your users to address at-risk passwords." + "message": "危険なパスワード(強度が低い、流出済み、再利用)を、アプリをまたいで調査します。特に重要なアプリを選択して、危険なパスワードに優先対応するようユーザーに促しましょう。" }, "dataLastUpdated": { - "message": "Data last updated: $DATE$", + "message": "データの最終更新: $DATE$", "placeholders": { "date": { "content": "$1", @@ -33,10 +33,10 @@ "message": "メンバーを削除" }, "restoreMembers": { - "message": "Restore members" + "message": "メンバーを復元" }, "cannotRestoreAccessError": { - "message": "Cannot restore organization access" + "message": "組織へのアクセスを復元できません" }, "allApplicationsWithCount": { "message": "すべてのアプリ ($COUNT$)", @@ -48,10 +48,10 @@ } }, "createNewLoginItem": { - "message": "Create new login item" + "message": "新しいログインアイテムを作成" }, "criticalApplicationsWithCount": { - "message": "Critical applications ($COUNT$)", + "message": "特に重要なアプリ ($COUNT$)", "placeholders": { "count": { "content": "$1", @@ -69,7 +69,7 @@ } }, "noAppsInOrgTitle": { - "message": "No applications found in $ORG NAME$", + "message": "$ORG NAME$ にアプリが見つかりませんでした", "placeholders": { "org name": { "content": "$1", @@ -78,22 +78,22 @@ } }, "noAppsInOrgDescription": { - "message": "As users save logins, applications appear here, showing any at-risk passwords. Mark critical apps and notify users to update passwords." + "message": "ユーザーがログイン情報を保存すると、アプリがここに表示され、リスクの高いパスワードがあれば表示されます。特に重要なアプリはマークして、パスワードを更新するようにユーザーに通知しましょう。" }, "noCriticalAppsTitle": { - "message": "You haven't marked any applications as a Critical" + "message": "重要なアプリとしてマークしたものがありません" }, "noCriticalAppsDescription": { - "message": "Select your most critical applications to discover at-risk passwords, and notify users to change those passwords." + "message": "特に重要なアプリケーションを選択して、危険なパスワードを発見し、ユーザーにパスワードを変更するよう通知しましょう。" }, "markCriticalApps": { - "message": "Mark critical apps" + "message": "重要なアプリをマークする" }, "markAppAsCritical": { - "message": "Mark app as critical" + "message": "重要なアプリとしてマーク" }, "appsMarkedAsCritical": { - "message": "Apps marked as critical" + "message": "重要なアプリとしてマークされました" }, "application": { "message": "アプリ" @@ -102,13 +102,13 @@ "message": "リスクがあるパスワード" }, "requestPasswordChange": { - "message": "Request password change" + "message": "パスワードの変更を要求する" }, "totalPasswords": { "message": "合計パスワード数" }, "searchApps": { - "message": "Search applications" + "message": "アプリを検索" }, "atRiskMembers": { "message": "リスクがあるメンバー" @@ -469,7 +469,7 @@ "message": "パスワードの自動生成" }, "generatePassphrase": { - "message": "Generate passphrase" + "message": "パスフレーズを生成" }, "checkPassword": { "message": "パスワードが漏洩していないか確認する" @@ -572,7 +572,7 @@ "message": "セキュアメモ" }, "typeSshKey": { - "message": "SSH key" + "message": "SSH 鍵" }, "typeLoginPlural": { "message": "ログイン" @@ -733,11 +733,11 @@ "description": "Copy password to clipboard" }, "copyPassphrase": { - "message": "Copy passphrase", + "message": "パスフレーズをコピー", "description": "Copy passphrase to clipboard" }, "passwordCopied": { - "message": "Password copied" + "message": "パスワードをコピーしました" }, "copyUsername": { "message": "ユーザー名のコピー", @@ -994,7 +994,7 @@ "message": "Bitwarden アプリで「デバイスでログイン」の設定をする必要があります。別のオプションが必要ですか?" }, "needAnotherOptionV1": { - "message": "Need another option?" + "message": "別の選択肢が必要ですか?" }, "loginWithMasterPassword": { "message": "マスターパスワードでログイン" @@ -1009,13 +1009,13 @@ "message": "別のログイン方法を使用する" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "パスキーでログイン" }, "useSingleSignOn": { - "message": "Use single sign-on" + "message": "シングルサインオンを使用する" }, "welcomeBack": { - "message": "Welcome back" + "message": "ようこそ" }, "invalidPasskeyPleaseTryAgain": { "message": "無効なパスキーです。もう一度やり直してください。" @@ -1099,7 +1099,7 @@ "message": "アカウントの作成" }, "newToBitwarden": { - "message": "New to Bitwarden?" + "message": "Bitwarden は初めてですか?" }, "setAStrongPassword": { "message": "強力なパスワードを設定する" @@ -1117,13 +1117,13 @@ "message": "ログイン" }, "logInToBitwarden": { - "message": "Log in to Bitwarden" + "message": "Bitwarden にログイン" }, "authenticationTimeout": { - "message": "Authentication timeout" + "message": "認証のタイムアウト" }, "authenticationSessionTimedOut": { - "message": "The authentication session timed out. Please restart the login process." + "message": "認証セッションの有効期限が切れました。ログイン操作を最初からやり直してください。" }, "verifyIdentity": { "message": "本人確認" @@ -1294,7 +1294,7 @@ "message": "このコレクション内のアイテムをすべて表示する権限がありません。" }, "youDoNotHavePermissions": { - "message": "You do not have permissions to this collection" + "message": "このコレクションの利用権限がありません" }, "noCollectionsInList": { "message": "表示するコレクションがありません" @@ -1321,10 +1321,10 @@ "message": "デバイスに通知を送信しました。" }, "aNotificationWasSentToYourDevice": { - "message": "A notification was sent to your device" + "message": "お使いのデバイスに通知が送信されました" }, "makeSureYourAccountIsUnlockedAndTheFingerprintEtc": { - "message": "Make sure your account is unlocked and the fingerprint phrase matches on the other device" + "message": "アカウントがロック解除されていることと、フィンガープリントフレーズが他の端末と一致していることを確認してください" }, "versionNumber": { "message": "バージョン $VERSION_NUMBER$", @@ -1658,25 +1658,25 @@ "message": "パスワードの履歴" }, "generatorHistory": { - "message": "Generator history" + "message": "生成履歴" }, "clearGeneratorHistoryTitle": { - "message": "Clear generator history" + "message": "生成履歴を消去" }, "cleargGeneratorHistoryDescription": { - "message": "If you continue, all entries will be permanently deleted from generator's history. Are you sure you want to continue?" + "message": "続行すると、すべてのエントリは生成履歴から完全に削除されます。続行してもよろしいですか?" }, "noPasswordsInList": { "message": "表示するパスワードがありません" }, "clearHistory": { - "message": "Clear history" + "message": "履歴を消去" }, "nothingToShow": { - "message": "Nothing to show" + "message": "表示するものがありません" }, "nothingGeneratedRecently": { - "message": "You haven't generated anything recently" + "message": "最近生成したものはありません" }, "clear": { "message": "消去する", @@ -1786,7 +1786,7 @@ "message": "これらの操作はやり直せないため注意してください!" }, "dangerZoneDescSingular": { - "message": "Careful, this action is not reversible!" + "message": "この操作は元に戻せないため注意してください!" }, "deauthorizeSessions": { "message": "セッションの承認を取り消す" @@ -1801,7 +1801,7 @@ "message": "全てのセッションを無効化" }, "accountIsOwnedMessage": { - "message": "This account is owned by $ORGANIZATIONNAME$", + "message": "このアカウントは $ORGANIZATIONNAME$ が所有しています", "placeholders": { "organizationName": { "content": "$1", @@ -3430,7 +3430,7 @@ } }, "viewAllLogInOptions": { - "message": "View all log in options" + "message": "すべてのログインオプションを表示" }, "viewAllLoginOptions": { "message": "すべてのログインオプションを表示" @@ -3883,13 +3883,13 @@ "message": "ブラウザを更新" }, "generatingRiskInsights": { - "message": "Generating your risk insights..." + "message": "リスク分析を生成しています..." }, "updateBrowserDesc": { "message": "サポートされていないブラウザを使用しています。ウェブ保管庫が正しく動作しないかもしれません。" }, "freeTrialEndPromptCount": { - "message": "Your free trial ends in $COUNT$ days.", + "message": "無料体験はあと $COUNT$ 日で終了します。", "placeholders": { "count": { "content": "$1", @@ -3898,7 +3898,7 @@ } }, "freeTrialEndPromptMultipleDays": { - "message": "$ORGANIZATION$, your free trial ends in $COUNT$ days.", + "message": "$ORGANIZATION$ 様、無料体験はあと $COUNT$ 日で終了します。", "placeholders": { "count": { "content": "$2", @@ -3911,7 +3911,7 @@ } }, "freeTrialEndPromptTomorrow": { - "message": "$ORGANIZATION$, your free trial ends tomorrow.", + "message": "$ORGANIZATION$ 様、無料体験は明日で終了します。", "placeholders": { "organization": { "content": "$1", @@ -3920,10 +3920,10 @@ } }, "freeTrialEndPromptTomorrowNoOrgName": { - "message": "Your free trial ends tomorrow." + "message": "無料体験は明日終了します。" }, "freeTrialEndPromptToday": { - "message": "$ORGANIZATION$, your free trial ends today.", + "message": "$ORGANIZATION$ 様、無料体験は本日終了します。", "placeholders": { "organization": { "content": "$1", @@ -3932,16 +3932,16 @@ } }, "freeTrialEndingTodayWithoutOrgName": { - "message": "Your free trial ends today." + "message": "無料体験は本日で終了します。" }, "clickHereToAddPaymentMethod": { - "message": "Click here to add a payment method." + "message": "支払い方法を追加するにはここをクリックしてください。" }, "joinOrganization": { "message": "組織に参加" }, "joinOrganizationName": { - "message": "Join $ORGANIZATIONNAME$", + "message": "$ORGANIZATIONNAME$ に参加", "placeholders": { "organizationName": { "content": "$1", @@ -4492,7 +4492,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": "リクエストが承認されると通知されます" }, "free": { "message": "無料", @@ -4725,10 +4725,10 @@ "message": "組織のシングルサインオンポータルを使用してログインします。開始するには組織の識別子を入力してください。" }, "singleSignOnEnterOrgIdentifier": { - "message": "Enter your organization's SSO identifier to begin" + "message": "組織の SSO ID を入力して開始します" }, "singleSignOnEnterOrgIdentifierText": { - "message": "To log in with your SSO provider, enter your organization's SSO identifier to begin. You may need to enter this SSO identifier when you log in from a new device." + "message": "SSO プロバイダーでログインするには、組織の SSO ID を入力して開始します。新しいデバイスからログインする際に、この SSO ID を入力する必要がある場合があります。" }, "enterpriseSingleSignOn": { "message": "組織のシングルサインオン" @@ -4798,7 +4798,7 @@ "message": "ユーザーが他の組織に参加できないように制限します。" }, "singleOrgPolicyDesc": { - "message": "Restrict members from joining other organizations. This policy is required for organizations that have enabled domain verification." + "message": "メンバーに対し、他の組織への参加を制限します。ドメイン認証を有効にしている組織では、このポリシーは必須となります。" }, "singleOrgBlockCreateMessage": { "message": "現在の組織には、複数の組織に参加することを許可していないポリシーがあります。 組織の管理者に連絡するか、別の Bitwarden アカウントから登録してください。" @@ -4807,7 +4807,7 @@ "message": "オーナーまたは管理者でなく、すでに他の組織のメンバーであるメンバーは組織から削除されます。" }, "singleOrgPolicyMemberWarning": { - "message": "Non-compliant members will be placed in revoked status until they leave all other organizations. Administrators are exempt and can restore members once compliance is met." + "message": "ポリシーに準拠していないメンバーは、他のすべての組織から退出するまで失効状態になります。これは管理者には適用されず、管理者はコンプライアンスが満たされたメンバーを復元できます。" }, "requireSso": { "message": "シングルサインオン認証" @@ -5635,10 +5635,10 @@ "message": "除外します。このアクションには適用されません。" }, "nonCompliantMembersTitle": { - "message": "Non-compliant members" + "message": "非準拠のメンバー" }, "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" + "message": "単一組織ポリシーまたは2段階ログインポリシーに準拠していないメンバーは、ポリシー要件を遵守するまで復元できません。" }, "fingerprint": { "message": "指紋" @@ -6437,7 +6437,7 @@ "message": "エンティティ ID が URL でない場合は必須です。" }, "offerNoLongerValid": { - "message": "This offer is no longer valid. Contact your organization administrators for more information." + "message": "このオファーは無効になりました。詳しくは組織の管理者にお問い合わせください。" }, "openIdOptionalCustomizations": { "message": "オプションのカスタマイズ" @@ -6529,10 +6529,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": { @@ -6546,7 +6546,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": { @@ -6556,7 +6556,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": { @@ -6671,11 +6671,11 @@ "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": { @@ -8101,16 +8101,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": "このデバイスを記憶する" @@ -8342,7 +8342,7 @@ "message": "ユーザーのメールアドレスがありません" }, "activeUserEmailNotFoundLoggingYouOut": { - "message": "Active user email not found. Logging you out." + "message": "アクティブなユーザーメールアドレスが見つかりません。ログアウトします。" }, "deviceTrusted": { "message": "信頼されたデバイス" @@ -8440,10 +8440,10 @@ "message": "組織のコレクションに関する挙動を管理します" }, "limitCollectionCreationDesc": { - "message": "Limit collection creation to owners and admins" + "message": "コレクションの作成を所有者と管理者のみに制限" }, "limitCollectionDeletionDesc": { - "message": "Limit collection deletion to owners and admins" + "message": "コレクションの削除を所有者と管理者のみに制限" }, "allowAdminAccessToAllCollectionItemsDesc": { "message": "所有者と管理者はすべてのコレクションとアイテムを管理できます" @@ -8491,7 +8491,7 @@ "message": "サーバー URL" }, "selfHostBaseUrl": { - "message": "Self-host server URL", + "message": "自己ホスト型サーバー URL", "description": "Label for field requesting a self-hosted integration service URL" }, "aliasDomain": { diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 6546b248914..0b830e6dc9a 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -9272,16 +9272,16 @@ "message": "Atjaunināta nodokļu informācija" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Nederīgs nodokļu identifikators. Ja ir pārliecība, ka tā ir kļūda, lūgums sazināties ar atbalstu." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Mēs nevarējām pārbaudīt nodokļu identifikatoru. Ja ir pārliecība, ka tā ir kļūda, lūgums sazināties ar atbalstu." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Nederīgs nodokļu identifikators. Ja ir pārliecība, ka tā ir kļūda, lūgums sazināties ar atbalstu." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Rēķina priekšskatīšanas laikā atgadījās kļūda. Lūgums vēlāk mēģināt vēlreiz." }, "unverified": { "message": "Neapliecināts" diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 4c47afaa63d..dbffa25048c 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -9272,16 +9272,16 @@ "message": "Aktualizované daňové informácie" }, "billingInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Neplatne číslo pre DPH, ak myslíte že ide o chybu, kontaktujte prosím zákaznícku podporu." }, "billingTaxIdTypeInferenceError": { - "message": "We were unable to validate your tax ID, if you believe this is an error please contact support." + "message": "Nepodarilo sa nám overiť vaše číslo pre DPH, ak myslíte že ide o chybu, kontaktujte prosím zákaznícku podporu." }, "billingPreviewInvalidTaxIdError": { - "message": "Invalid tax ID, if you believe this is an error please contact support." + "message": "Neplatne číslo pre DPH, ak myslíte že ide o chybu, kontaktujte prosím zákaznícku podporu." }, "billingPreviewInvoiceError": { - "message": "An error occurred while previewing the invoice. Please try again later." + "message": "Pri vytváraní náhľadu faktúry nastala chyba. Prosím skúste to neskor." }, "unverified": { "message": "Neoverený" @@ -10021,7 +10021,7 @@ "message": "Meno organizácie nemôže mať viac ako 50 znakov." }, "resellerRenewalWarning": { - "message": "Your subscription will renew soon. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", + "message": "Vaše predplatné sa čoskoro obnoví. Aby ste si zabezpečili nepretržitú prevádzku, kontaktujte $RESELLER$ a potvrďte obnovenie pred $RENEWAL_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10034,7 +10034,7 @@ } }, "resellerOpenInvoiceWarning": { - "message": "An invoice for your subscription was issued on $ISSUED_DATE$. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $DUE_DATE$.", + "message": "Faktúra za vaše predplatné bola vystavená dňa $ISSUED_DATE$. Aby ste si zabezpečili nepretržitú prevádzku, kontaktujte $RESELLER$ a potvrďte obnovenie predplatného pred $DUE_DATE$.", "placeholders": { "reseller": { "content": "$1", @@ -10051,7 +10051,7 @@ } }, "resellerPastDueWarning": { - "message": "The invoice for your subscription has not been paid. To insure uninterrupted service, contact $RESELLER$ to confirm your renewal before $GRACE_PERIOD_END$.", + "message": "Faktúra za vaše predplatné nebola uhradená. Aby ste si zabezpečili nepretržitú prevádzku, kontaktujte $RESELLER$ a potvrďte obnovenie pred $GRACE_PERIOD_END$.", "placeholders": { "reseller": { "content": "$1", diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index a7d73801372..f293adcf62a 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -1006,7 +1006,7 @@ "message": "保持此窗口打开然后按照浏览器的提示操作。" }, "useADifferentLogInMethod": { - "message": "使用不同的登录方式" + "message": "使用其他登录方式" }, "logInWithPasskey": { "message": "使用通行密钥登录" @@ -1997,13 +1997,13 @@ "message": "域名规则" }, "domainRulesDesc": { - "message": "如果您在多个不同网站之间使用同一个登陆信息,您可以把这些网站标记为「通用」。Bitwarden 会为您设置「全局」域名。" + "message": "如果您在多个不同网站域名中使用同一个登录信息,您可以把这些网站标记为「等效」。「全局」域名是由 Bitwarden 为您预先创建的域名。" }, "globalEqDomains": { - "message": "全局通用域名" + "message": "全局等效域名" }, "customEqDomains": { - "message": "自定义通用域名" + "message": "自定义等效域名" }, "exclude": { "message": "排除" @@ -2039,7 +2039,7 @@ "message": "强制两步登录" }, "twoStepLoginDesc": { - "message": "在登录时要求使用额外的步骤来保护您的账户。" + "message": "在登录时要求执行额外的步骤来保护您的账户。" }, "twoStepLoginTeamsDesc": { "message": "为您的组织启用两步登录。" @@ -2055,7 +2055,7 @@ "message": "要实施 Duo 方式的两步登录,请使用下面的选项。" }, "twoStepLoginOrganizationSsoDesc": { - "message": "如果您已设置或计划设置 SSO,两步登录可能已经通过您的身份提供程序实施了。" + "message": "如果您已设置或计划设置 SSO,两步登录可能已经通过您的身份提供程序强制实施了。" }, "twoStepLoginRecoveryWarning": { "message": "启用两步登录可能会将您永久锁定在 Bitwarden 账户之外。如果您无法使用常规的两步登录提供程序(例如您丢失了设备),则可以使用恢复代码访问您的账户。如果您失去对您账户的访问,Bitwarden 支持也无法帮助您。我们建议您记下或打印恢复代码,并将其妥善保管。" @@ -3294,7 +3294,7 @@ "message": "管理员" }, "adminDesc": { - "message": "管理组织访问权限,所有集合,成员,报告以及安全设置" + "message": "管理组织的访问权限,所有集合、成员、报告,以及安全设置" }, "user": { "message": "用户" @@ -4304,7 +4304,7 @@ "message": "升级组织" }, "upgradeOrganizationDesc": { - "message": "本功能对免费组织不可用。切换到付费计划以解锁更多功能。" + "message": "此功能不适用于免费组织。请切换到付费计划以解锁更多功能。" }, "createOrganizationStep1": { "message": "创建组织:第一步" @@ -4514,7 +4514,7 @@ "message": "您的 API 密钥可用于在 Bitwarden CLI 中进行身份验证。" }, "userApiKeyWarning": { - "message": "您的 API 密钥是另一套等效的身份验证机制。请严格保密。" + "message": "您的 API 密钥是一种替代身份验证机制。请严格保密。" }, "oauth2ClientCredentials": { "message": "OAuth 2.0 客户端凭据", @@ -5998,16 +5998,16 @@ "message": "最小入站签名算法" }, "spWantAssertionsSigned": { - "message": "希望断言被签名" + "message": "要求使用签名的断言" }, "spValidateCertificates": { "message": "验证证书" }, "spUniqueEntityId": { - "message": "设置一个唯一的 SP 实体 ID" + "message": "设置专属的 SP 实体 ID" }, "spUniqueEntityIdDesc": { - "message": "生成您的组织独有的标识符" + "message": "为您的组织生成专属的标识符" }, "idpEntityId": { "message": "实体 ID" @@ -8077,7 +8077,7 @@ "message": "忽略" }, "notAvailableForFreeOrganization": { - "message": "免费组织不能使用此功能。请联系您的组织所有者寻求升级。" + "message": "此功能不适用于免费组织。请联系您的组织所有者寻求升级。" }, "smProjectSecretsNoItemsNoAccess": { "message": "请联系您的组织的管理员来管理此工程的机密。", From 828a7fe3396bad3ec04b013816d818d4e30da9c9 Mon Sep 17 00:00:00 2001 From: Shane Melton Date: Mon, 6 Jan 2025 08:42:38 -0800 Subject: [PATCH 49/65] [PM-15557] Log the Cipher_ClientViewed event when opening the VaultItemDialog (#12669) --- .../vault-item-dialog/vault-item-dialog.component.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts index 02dc5ef48bb..a9ff49c5791 100644 --- a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts +++ b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts @@ -9,9 +9,11 @@ import { map } from "rxjs/operators"; import { CollectionView } from "@bitwarden/admin-console/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +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 { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -237,6 +239,7 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { private premiumUpgradeService: PremiumUpgradePromptService, private cipherAuthorizationService: CipherAuthorizationService, private apiService: ApiService, + private eventCollectionService: EventCollectionService, ) { this.updateTitle(); } @@ -257,6 +260,13 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { [this.params.activeCollectionId], this.params.isAdminConsoleAction, ); + + await this.eventCollectionService.collect( + EventType.Cipher_ClientViewed, + this.cipher.id, + false, + this.cipher.organizationId, + ); } this.performingInitialLoad = false; From ec21e8db592d929f55dae2579dc48825d44b3028 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Mon, 6 Jan 2025 17:44:36 +0100 Subject: [PATCH 50/65] Add missing credit card number pipe (#12508) Co-authored-by: Daniel James Smith --- .../cipher-view/card-details/card-details-view.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/vault/src/cipher-view/card-details/card-details-view.component.html b/libs/vault/src/cipher-view/card-details/card-details-view.component.html index d805408b385..fff771b6465 100644 --- a/libs/vault/src/cipher-view/card-details/card-details-view.component.html +++ b/libs/vault/src/cipher-view/card-details/card-details-view.component.html @@ -22,7 +22,7 @@

{{ setSectionTitle }}

readonly bitInput type="password" - [value]="card.number" + [value]="card.number | creditCardNumber: cipher.card.brand" aria-readonly="true" data-testid="cardholder-number" class="tw-font-mono" From c349ea95c6a2608bee3296a60805a98e3d24348f Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:11:31 +0100 Subject: [PATCH 51/65] Remove v1 popout component (#12518) Co-authored-by: Daniel James Smith --- .../platform/popup/components/pop-out.component.html | 7 +------ .../src/platform/popup/components/pop-out.component.ts | 10 +--------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/apps/browser/src/platform/popup/components/pop-out.component.html b/apps/browser/src/platform/popup/components/pop-out.component.html index c3f1f8ca150..3097f6e30d3 100644 --- a/apps/browser/src/platform/popup/components/pop-out.component.html +++ b/apps/browser/src/platform/popup/components/pop-out.component.html @@ -1,9 +1,4 @@ - - - - + + + + + + + diff --git a/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts b/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts new file mode 100644 index 00000000000..abf74371912 --- /dev/null +++ b/apps/desktop/src/vault/app/vault/credential-generator-dialog.component.ts @@ -0,0 +1,69 @@ +import { DIALOG_DATA } from "@angular/cdk/dialog"; +import { CommonModule } from "@angular/common"; +import { Component, Inject } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + ButtonModule, + DialogModule, + DialogService, + ItemModule, + LinkModule, +} from "@bitwarden/components"; +import { + CredentialGeneratorHistoryDialogComponent, + GeneratorModule, +} from "@bitwarden/generator-components"; +import { CipherFormGeneratorComponent } from "@bitwarden/vault"; + +type CredentialGeneratorParams = { + onCredentialGenerated: (value?: string) => void; + type: "password" | "username"; +}; + +@Component({ + standalone: true, + selector: "credential-generator-dialog", + templateUrl: "credential-generator-dialog.component.html", + imports: [ + CipherFormGeneratorComponent, + CommonModule, + DialogModule, + ButtonModule, + JslibModule, + GeneratorModule, + ItemModule, + LinkModule, + ], +}) +export class CredentialGeneratorDialogComponent { + credentialValue?: string; + + constructor( + @Inject(DIALOG_DATA) protected data: CredentialGeneratorParams, + private dialogService: DialogService, + ) {} + + applyCredentials = () => { + this.data.onCredentialGenerated(this.credentialValue); + }; + + clearCredentials = () => { + this.data.onCredentialGenerated(); + }; + + onCredentialGenerated = (value: string) => { + this.credentialValue = value; + }; + + openHistoryDialog = () => { + // open history dialog + this.dialogService.open(CredentialGeneratorHistoryDialogComponent); + }; + + static open = (dialogService: DialogService, data: CredentialGeneratorParams) => { + dialogService.open(CredentialGeneratorDialogComponent, { + data, + }); + }; +} diff --git a/apps/desktop/src/vault/app/vault/vault.component.ts b/apps/desktop/src/vault/app/vault/vault.component.ts index 67b69be7d1b..f375b303024 100644 --- a/apps/desktop/src/vault/app/vault/vault.component.ts +++ b/apps/desktop/src/vault/app/vault/vault.component.ts @@ -20,7 +20,9 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EventType } from "@bitwarden/common/enums"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -40,6 +42,7 @@ import { invokeMenu, RendererMenuItem } from "../../../utils"; import { AddEditComponent } from "./add-edit.component"; import { AttachmentsComponent } from "./attachments.component"; import { CollectionsComponent } from "./collections.component"; +import { CredentialGeneratorDialogComponent } from "./credential-generator-dialog.component"; import { FolderAddEditComponent } from "./folder-add-edit.component"; import { PasswordHistoryComponent } from "./password-history.component"; import { ShareComponent } from "./share.component"; @@ -107,6 +110,7 @@ export class VaultComponent implements OnInit, OnDestroy { private apiService: ApiService, private dialogService: DialogService, private billingAccountProfileStateService: BillingAccountProfileStateService, + private configService: ConfigService, ) {} async ngOnInit() { @@ -622,11 +626,29 @@ export class VaultComponent implements OnInit, OnDestroy { } async openGenerator(comingFromAddEdit: boolean, passwordType = true) { - // FIXME: Will need to be extended to use the cipher-form-generator component introduced with https://github.com/bitwarden/clients/pull/11350 - if (this.modal != null) { - this.modal.close(); + const isGeneratorSwapEnabled = await this.configService.getFeatureFlag( + FeatureFlag.GeneratorToolsModernization, + ); + + if (isGeneratorSwapEnabled) { + CredentialGeneratorDialogComponent.open(this.dialogService, { + onCredentialGenerated: (value?: string) => { + if (this.addEditComponent != null) { + this.addEditComponent.markPasswordAsDirty(); + if (passwordType) { + this.addEditComponent.cipher.login.password = value ?? ""; + } else { + this.addEditComponent.cipher.login.username = value ?? ""; + } + } + }, + type: passwordType ? "password" : "username", + }); + return; } + // TODO: Legacy code below, remove once the new generator is fully implemented + // https://bitwarden.atlassian.net/browse/PM-7121 const cipher = this.addEditComponent?.cipher; const loginType = cipher != null && cipher.type === CipherType.Login && cipher.login != null; From ce07e408eaad52194ed53235a942cc24579de519 Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:46:59 -0800 Subject: [PATCH 53/65] [PM-13028] - add fixed width to vault list icon (#12644) * add fixed width to vault list icon * justify start * don't display totp capture when in popout * Revert "don't display totp capture when in popout" This reverts commit f50b0a6caf4cb23d2af8521f51b9c772336782ac. --- .../vault-list-items-container.component.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html index 72ac590c779..b5d92a386b3 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html @@ -34,7 +34,9 @@

" class="{{ itemHeightClass }}" > - +
+ +
{{ cipher.name }} Date: Mon, 6 Jan 2025 13:49:33 -0500 Subject: [PATCH 54/65] [CL-506] Upgrade to Angular 18 (#12218) --- apps/web/src/app/app.module.ts | 4 +- apps/web/src/app/shared/shared.module.ts | 6 +- apps/web/webpack.config.js | 2 +- .../bit-web/src/app/app.module.ts | 4 +- package-lock.json | 4132 +++++++++-------- package.json | 40 +- 6 files changed, 2192 insertions(+), 1996 deletions(-) diff --git a/apps/web/src/app/app.module.ts b/apps/web/src/app/app.module.ts index 2a67232e3db..22fd745eab8 100644 --- a/apps/web/src/app/app.module.ts +++ b/apps/web/src/app/app.module.ts @@ -3,7 +3,7 @@ import { LayoutModule } from "@angular/cdk/layout"; import { NgModule } from "@angular/core"; import { FormsModule } from "@angular/forms"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { InfiniteScrollModule } from "ngx-infinite-scroll"; +import { InfiniteScrollDirective } from "ngx-infinite-scroll"; import { AppComponent } from "./app.component"; import { CoreModule } from "./core"; @@ -23,7 +23,7 @@ import { WildcardRoutingModule } from "./wildcard-routing.module"; BrowserAnimationsModule, FormsModule, CoreModule, - InfiniteScrollModule, + InfiniteScrollDirective, DragDropModule, LayoutModule, OssRoutingModule, diff --git a/apps/web/src/app/shared/shared.module.ts b/apps/web/src/app/shared/shared.module.ts index 1b04583a395..8f44d8a4bf5 100644 --- a/apps/web/src/app/shared/shared.module.ts +++ b/apps/web/src/app/shared/shared.module.ts @@ -3,7 +3,7 @@ import { CommonModule, DatePipe } from "@angular/common"; import { NgModule } from "@angular/core"; import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { RouterModule } from "@angular/router"; -import { InfiniteScrollModule } from "ngx-infinite-scroll"; +import { InfiniteScrollDirective } from "ngx-infinite-scroll"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { @@ -49,7 +49,7 @@ import "./locales"; DragDropModule, FormsModule, ReactiveFormsModule, - InfiniteScrollModule, + InfiniteScrollDirective, RouterModule, JslibModule, @@ -86,7 +86,7 @@ import "./locales"; DragDropModule, FormsModule, ReactiveFormsModule, - InfiniteScrollModule, + InfiniteScrollDirective, RouterModule, JslibModule, diff --git a/apps/web/webpack.config.js b/apps/web/webpack.config.js index df325015aad..9373308c112 100644 --- a/apps/web/webpack.config.js +++ b/apps/web/webpack.config.js @@ -256,7 +256,7 @@ const devServer = 'sha256-JVRXyYPueLWdwGwY9m/7u4QlZ1xeQdqUj2t8OVIzZE4=' 'sha256-or0p3LaHetJ4FRq+flVORVFFNsOjQGWrDvX8Jf7ACWg=' 'sha256-jvLh2uL2/Pq/gpvNJMaEL4C+TNhBeGadLIUyPcVRZvY=' - 'sha256-Oca9ZYU1dwNscIhdNV7tFBsr4oqagBhZx9/p4w8GOcg=' + 'sha256-VZTcMoTEw3nbAHejvqlyyRm1Mdx+DVNgyKANjpWw0qg=' ;img-src 'self' data: diff --git a/bitwarden_license/bit-web/src/app/app.module.ts b/bitwarden_license/bit-web/src/app/app.module.ts index fd1a3b0b84c..3a78ae0ed01 100644 --- a/bitwarden_license/bit-web/src/app/app.module.ts +++ b/bitwarden_license/bit-web/src/app/app.module.ts @@ -4,7 +4,7 @@ import { NgModule } from "@angular/core"; import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { RouterModule } from "@angular/router"; -import { InfiniteScrollModule } from "ngx-infinite-scroll"; +import { InfiniteScrollDirective } from "ngx-infinite-scroll"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { CoreModule } from "@bitwarden/web-vault/app/core"; @@ -37,7 +37,7 @@ import { AccessIntelligenceModule } from "./tools/access-intelligence/access-int FormsModule, ReactiveFormsModule, CoreModule, - InfiniteScrollModule, + InfiniteScrollDirective, DragDropModule, AppRoutingModule, OssRoutingModule, diff --git a/package-lock.json b/package-lock.json index ba7953d0faf..c60d71881a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,22 +15,22 @@ "libs/*" ], "dependencies": { - "@angular/animations": "17.3.12", - "@angular/cdk": "17.3.10", - "@angular/common": "17.3.12", - "@angular/compiler": "17.3.12", - "@angular/core": "17.3.12", - "@angular/forms": "17.3.12", - "@angular/platform-browser": "17.3.12", - "@angular/platform-browser-dynamic": "17.3.12", - "@angular/router": "17.3.12", + "@angular/animations": "18.2.13", + "@angular/cdk": "18.2.14", + "@angular/common": "18.2.13", + "@angular/compiler": "18.2.13", + "@angular/core": "18.2.13", + "@angular/forms": "18.2.13", + "@angular/platform-browser": "18.2.13", + "@angular/platform-browser-dynamic": "18.2.13", + "@angular/router": "18.2.13", "@bitwarden/sdk-internal": "0.2.0-main.38", "@electron/fuses": "1.8.0", "@koa/multer": "3.0.2", "@koa/router": "13.1.0", "@microsoft/signalr": "8.0.7", "@microsoft/signalr-protocol-msgpack": "8.0.7", - "@ng-select/ng-select": "12.0.7", + "@ng-select/ng-select": "13.9.1", "argon2": "0.41.1", "argon2-browser": "1.18.0", "big-integer": "1.6.52", @@ -53,7 +53,7 @@ "lowdb": "1.0.0", "lunr": "2.3.9", "multer": "1.4.5-lts.1", - "ngx-infinite-scroll": "17.0.1", + "ngx-infinite-scroll": "18.0.0", "ngx-toastr": "19.0.0", "node-fetch": "2.6.12", "node-forge": "1.3.1", @@ -74,20 +74,20 @@ "zxcvbn": "4.4.2" }, "devDependencies": { - "@angular-devkit/build-angular": "17.3.11", - "@angular-eslint/eslint-plugin": "17.5.3", - "@angular-eslint/eslint-plugin-template": "17.5.3", - "@angular-eslint/schematics": "17.5.3", - "@angular-eslint/template-parser": "17.5.3", - "@angular/cli": "17.3.11", - "@angular/compiler-cli": "17.3.12", - "@angular/elements": "17.3.12", + "@angular-devkit/build-angular": "18.2.12", + "@angular-eslint/eslint-plugin": "18.4.3", + "@angular-eslint/eslint-plugin-template": "18.4.3", + "@angular-eslint/schematics": "18.4.3", + "@angular-eslint/template-parser": "18.4.3", + "@angular/cli": "18.2.12", + "@angular/compiler-cli": "18.2.13", + "@angular/elements": "18.2.13", "@babel/core": "7.24.9", "@babel/preset-env": "7.24.8", "@compodoc/compodoc": "1.1.26", "@electron/notarize": "2.5.0", "@electron/rebuild": "3.7.1", - "@ngtools/webpack": "17.3.11", + "@ngtools/webpack": "18.2.12", "@storybook/addon-a11y": "8.4.7", "@storybook/addon-actions": "8.4.7", "@storybook/addon-designs": "8.0.4", @@ -369,14 +369,12 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1802.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.11.tgz", - "integrity": "sha512-p+XIc/j51aI83ExNdeZwvkm1F4wkuKMGUUoj0MVUUi5E6NoiMlXYm6uU8+HbRvPBzGy5+3KOiGp3Fks0UmDSAA==", + "version": "0.1802.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.12.tgz", + "integrity": "sha512-bepVb2/GtJppYKaeW8yTGE6egmoWZ7zagFDsmBdbF+BYp+HmeoPsclARcdryBPVq68zedyTRdvhWSUTbw1AYuw==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { - "@angular-devkit/core": "18.2.11", + "@angular-devkit/core": "18.2.12", "rxjs": "7.8.1" }, "engines": { @@ -386,98 +384,96 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-17.3.11.tgz", - "integrity": "sha512-lHX5V2dSts328yvo/9E2u9QMGcvJhbEKKDDp9dBecwvIG9s+4lTOJgi9DPUE7W+AtmPcmbbhwC2JRQ/SLQhAoA==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.12.tgz", + "integrity": "sha512-quVUi7eqTq9OHumQFNl9Y8t2opm8miu4rlYnuF6rbujmmBDvdUvR6trFChueRczl2p5HWqTOr6NPoDGQm8AyNw==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1703.11", - "@angular-devkit/build-webpack": "0.1703.11", - "@angular-devkit/core": "17.3.11", - "@babel/core": "7.24.0", - "@babel/generator": "7.23.6", - "@babel/helper-annotate-as-pure": "7.22.5", - "@babel/helper-split-export-declaration": "7.22.6", - "@babel/plugin-transform-async-generator-functions": "7.23.9", - "@babel/plugin-transform-async-to-generator": "7.23.3", - "@babel/plugin-transform-runtime": "7.24.0", - "@babel/preset-env": "7.24.0", - "@babel/runtime": "7.24.0", - "@discoveryjs/json-ext": "0.5.7", - "@ngtools/webpack": "17.3.11", + "@angular-devkit/architect": "0.1802.12", + "@angular-devkit/build-webpack": "0.1802.12", + "@angular-devkit/core": "18.2.12", + "@angular/build": "18.2.12", + "@babel/core": "7.25.2", + "@babel/generator": "7.25.0", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.25.0", + "@babel/plugin-transform-async-to-generator": "7.24.7", + "@babel/plugin-transform-runtime": "7.24.7", + "@babel/preset-env": "7.25.3", + "@babel/runtime": "7.25.0", + "@discoveryjs/json-ext": "0.6.1", + "@ngtools/webpack": "18.2.12", "@vitejs/plugin-basic-ssl": "1.1.0", "ansi-colors": "4.1.3", - "autoprefixer": "10.4.18", + "autoprefixer": "10.4.20", "babel-loader": "9.1.3", - "babel-plugin-istanbul": "6.1.1", "browserslist": "^4.21.5", - "copy-webpack-plugin": "11.0.0", - "critters": "0.0.22", - "css-loader": "6.10.0", - "esbuild-wasm": "0.20.1", + "copy-webpack-plugin": "12.0.2", + "critters": "0.0.24", + "css-loader": "7.1.2", + "esbuild-wasm": "0.23.0", "fast-glob": "3.3.2", - "http-proxy-middleware": "2.0.7", - "https-proxy-agent": "7.0.4", - "inquirer": "9.2.15", - "jsonc-parser": "3.2.1", + "http-proxy-middleware": "3.0.3", + "https-proxy-agent": "7.0.5", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", "karma-source-map-support": "1.4.0", "less": "4.2.0", - "less-loader": "11.1.0", + "less-loader": "12.2.0", "license-webpack-plugin": "4.0.2", - "loader-utils": "3.2.1", - "magic-string": "0.30.8", - "mini-css-extract-plugin": "2.8.1", + "loader-utils": "3.3.1", + "magic-string": "0.30.11", + "mini-css-extract-plugin": "2.9.0", "mrmime": "2.0.0", - "open": "8.4.2", + "open": "10.1.0", "ora": "5.4.1", "parse5-html-rewriting-stream": "7.0.0", - "picomatch": "4.0.1", - "piscina": "4.4.0", - "postcss": "8.4.35", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "postcss": "8.4.41", "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.1", - "sass": "1.71.1", - "sass-loader": "14.1.1", - "semver": "7.6.0", + "sass": "1.77.6", + "sass-loader": "16.0.0", + "semver": "7.6.3", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", - "terser": "5.29.1", + "terser": "5.31.6", "tree-kill": "1.2.2", - "tslib": "2.6.2", - "undici": "6.11.1", - "vite": "5.1.8", - "watchpack": "2.4.0", + "tslib": "2.6.3", + "vite": "5.4.6", + "watchpack": "2.4.1", "webpack": "5.94.0", - "webpack-dev-middleware": "6.1.2", - "webpack-dev-server": "4.15.1", - "webpack-merge": "5.10.0", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.0.4", + "webpack-merge": "6.0.1", "webpack-subresource-integrity": "5.1.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.20.1" + "esbuild": "0.23.0" }, "peerDependencies": { - "@angular/compiler-cli": "^17.0.0", - "@angular/localize": "^17.0.0", - "@angular/platform-server": "^17.0.0", - "@angular/service-worker": "^17.0.0", + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", "@web/test-runner": "^0.18.0", "browser-sync": "^3.0.2", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "karma": "^6.3.0", - "ng-packagr": "^17.0.0", + "ng-packagr": "^18.0.0", "protractor": "^7.0.0", "tailwindcss": "^2.0.0 || ^3.0.0", - "typescript": ">=5.2 <5.5" + "typescript": ">=5.4 <5.6" }, "peerDependenciesMeta": { "@angular/localize": { @@ -515,87 +511,22 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/architect": { - "version": "0.1703.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.11.tgz", - "integrity": "sha512-YNasVZk4rYdcM6M+KRH8PUBhVyJfqzUYLpO98GgRokW+taIDgifckSlmfDZzQRbw45qiwei1IKCLqcpC8nM5Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "17.3.11", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/build-webpack": { - "version": "0.1703.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.11.tgz", - "integrity": "sha512-qbCiiHuoVkD7CtLyWoRi/Vzz6nrEztpF5XIyWUcQu67An1VlxbMTE4yoSQiURjCQMnB/JvS1GPVed7wOq3SJ/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/architect": "0.1703.11", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "webpack": "^5.30.0", - "webpack-dev-server": "^4.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", - "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, "node_modules/@angular-devkit/build-angular/node_modules/@babel/core": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", - "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.24.0", - "@babel/parser": "^7.24.0", - "@babel/template": "^7.24.0", - "@babel/traverse": "^7.24.0", - "@babel/types": "^7.24.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -621,27 +552,28 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@babel/preset-env": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz", - "integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==", + "version": "7.25.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.25.3.tgz", + "integrity": "sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.23.5", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-plugin-utils": "^7.24.0", - "@babel/helper-validator-option": "^7.23.5", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.23.7", + "@babel/compat-data": "^7.25.2", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-validator-option": "^7.24.8", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.3", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.0", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.0", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.7", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.0", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-class-properties": "^7.12.13", "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.23.3", - "@babel/plugin-syntax-import-attributes": "^7.23.3", + "@babel/plugin-syntax-import-assertions": "^7.24.7", + "@babel/plugin-syntax-import-attributes": "^7.24.7", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", @@ -653,59 +585,60 @@ "@babel/plugin-syntax-private-property-in-object": "^7.14.5", "@babel/plugin-syntax-top-level-await": "^7.14.5", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.23.3", - "@babel/plugin-transform-async-generator-functions": "^7.23.9", - "@babel/plugin-transform-async-to-generator": "^7.23.3", - "@babel/plugin-transform-block-scoped-functions": "^7.23.3", - "@babel/plugin-transform-block-scoping": "^7.23.4", - "@babel/plugin-transform-class-properties": "^7.23.3", - "@babel/plugin-transform-class-static-block": "^7.23.4", - "@babel/plugin-transform-classes": "^7.23.8", - "@babel/plugin-transform-computed-properties": "^7.23.3", - "@babel/plugin-transform-destructuring": "^7.23.3", - "@babel/plugin-transform-dotall-regex": "^7.23.3", - "@babel/plugin-transform-duplicate-keys": "^7.23.3", - "@babel/plugin-transform-dynamic-import": "^7.23.4", - "@babel/plugin-transform-exponentiation-operator": "^7.23.3", - "@babel/plugin-transform-export-namespace-from": "^7.23.4", - "@babel/plugin-transform-for-of": "^7.23.6", - "@babel/plugin-transform-function-name": "^7.23.3", - "@babel/plugin-transform-json-strings": "^7.23.4", - "@babel/plugin-transform-literals": "^7.23.3", - "@babel/plugin-transform-logical-assignment-operators": "^7.23.4", - "@babel/plugin-transform-member-expression-literals": "^7.23.3", - "@babel/plugin-transform-modules-amd": "^7.23.3", - "@babel/plugin-transform-modules-commonjs": "^7.23.3", - "@babel/plugin-transform-modules-systemjs": "^7.23.9", - "@babel/plugin-transform-modules-umd": "^7.23.3", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", - "@babel/plugin-transform-new-target": "^7.23.3", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4", - "@babel/plugin-transform-numeric-separator": "^7.23.4", - "@babel/plugin-transform-object-rest-spread": "^7.24.0", - "@babel/plugin-transform-object-super": "^7.23.3", - "@babel/plugin-transform-optional-catch-binding": "^7.23.4", - "@babel/plugin-transform-optional-chaining": "^7.23.4", - "@babel/plugin-transform-parameters": "^7.23.3", - "@babel/plugin-transform-private-methods": "^7.23.3", - "@babel/plugin-transform-private-property-in-object": "^7.23.4", - "@babel/plugin-transform-property-literals": "^7.23.3", - "@babel/plugin-transform-regenerator": "^7.23.3", - "@babel/plugin-transform-reserved-words": "^7.23.3", - "@babel/plugin-transform-shorthand-properties": "^7.23.3", - "@babel/plugin-transform-spread": "^7.23.3", - "@babel/plugin-transform-sticky-regex": "^7.23.3", - "@babel/plugin-transform-template-literals": "^7.23.3", - "@babel/plugin-transform-typeof-symbol": "^7.23.3", - "@babel/plugin-transform-unicode-escapes": "^7.23.3", - "@babel/plugin-transform-unicode-property-regex": "^7.23.3", - "@babel/plugin-transform-unicode-regex": "^7.23.3", - "@babel/plugin-transform-unicode-sets-regex": "^7.23.3", + "@babel/plugin-transform-arrow-functions": "^7.24.7", + "@babel/plugin-transform-async-generator-functions": "^7.25.0", + "@babel/plugin-transform-async-to-generator": "^7.24.7", + "@babel/plugin-transform-block-scoped-functions": "^7.24.7", + "@babel/plugin-transform-block-scoping": "^7.25.0", + "@babel/plugin-transform-class-properties": "^7.24.7", + "@babel/plugin-transform-class-static-block": "^7.24.7", + "@babel/plugin-transform-classes": "^7.25.0", + "@babel/plugin-transform-computed-properties": "^7.24.7", + "@babel/plugin-transform-destructuring": "^7.24.8", + "@babel/plugin-transform-dotall-regex": "^7.24.7", + "@babel/plugin-transform-duplicate-keys": "^7.24.7", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.0", + "@babel/plugin-transform-dynamic-import": "^7.24.7", + "@babel/plugin-transform-exponentiation-operator": "^7.24.7", + "@babel/plugin-transform-export-namespace-from": "^7.24.7", + "@babel/plugin-transform-for-of": "^7.24.7", + "@babel/plugin-transform-function-name": "^7.25.1", + "@babel/plugin-transform-json-strings": "^7.24.7", + "@babel/plugin-transform-literals": "^7.25.2", + "@babel/plugin-transform-logical-assignment-operators": "^7.24.7", + "@babel/plugin-transform-member-expression-literals": "^7.24.7", + "@babel/plugin-transform-modules-amd": "^7.24.7", + "@babel/plugin-transform-modules-commonjs": "^7.24.8", + "@babel/plugin-transform-modules-systemjs": "^7.25.0", + "@babel/plugin-transform-modules-umd": "^7.24.7", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.24.7", + "@babel/plugin-transform-new-target": "^7.24.7", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.24.7", + "@babel/plugin-transform-numeric-separator": "^7.24.7", + "@babel/plugin-transform-object-rest-spread": "^7.24.7", + "@babel/plugin-transform-object-super": "^7.24.7", + "@babel/plugin-transform-optional-catch-binding": "^7.24.7", + "@babel/plugin-transform-optional-chaining": "^7.24.8", + "@babel/plugin-transform-parameters": "^7.24.7", + "@babel/plugin-transform-private-methods": "^7.24.7", + "@babel/plugin-transform-private-property-in-object": "^7.24.7", + "@babel/plugin-transform-property-literals": "^7.24.7", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/plugin-transform-reserved-words": "^7.24.7", + "@babel/plugin-transform-shorthand-properties": "^7.24.7", + "@babel/plugin-transform-spread": "^7.24.7", + "@babel/plugin-transform-sticky-regex": "^7.24.7", + "@babel/plugin-transform-template-literals": "^7.24.7", + "@babel/plugin-transform-typeof-symbol": "^7.24.8", + "@babel/plugin-transform-unicode-escapes": "^7.24.7", + "@babel/plugin-transform-unicode-property-regex": "^7.24.7", + "@babel/plugin-transform-unicode-regex": "^7.24.7", + "@babel/plugin-transform-unicode-sets-regex": "^7.24.7", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", - "core-js-compat": "^3.31.0", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.4", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.37.1", "semver": "^6.3.1" }, "engines": { @@ -720,102 +653,17 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@angular-devkit/build-angular/node_modules/@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@angular-devkit/build-angular/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/autoprefixer": { - "version": "10.4.18", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.18.tgz", - "integrity": "sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g==", + "node_modules/@angular-devkit/build-angular/node_modules/@discoveryjs/json-ext": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.1.tgz", + "integrity": "sha512-boghen8F0Q8D+0/Q1/1r6DUEieUJ8w2a1gIknExMSHBsJFOr2+0KUfHiVYBvucPwl3+RU5PFBK833FjFCh3BhA==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001591", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=14.17.0" } }, "node_modules/@angular-devkit/build-angular/node_modules/babel-loader": { @@ -836,251 +684,137 @@ "webpack": ">=5" } }, - "node_modules/@angular-devkit/build-angular/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } + "license": "MIT" }, - "node_modules/@angular-devkit/build-angular/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/@angular-devkit/build-angular/node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular-devkit/build-angular/node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "node_modules/@angular-devkit/build-angular/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, "engines": { - "node": ">= 12" + "node": ">=8.0.0" } }, - "node_modules/@angular-devkit/build-angular/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/@angular-devkit/build-angular/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "MIT" + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } }, - "node_modules/@angular-devkit/build-angular/node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "node_modules/@angular-devkit/build-angular/node_modules/http-proxy-middleware": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz", + "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==", "dev": true, - "license": "MIT", "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@angular-devkit/build-angular/node_modules/css-loader": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.4", - "postcss-modules-scope": "^3.1.1", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/@angular-devkit/build-angular/node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "license": "BSD-2-Clause", "engines": { - "node": ">=4.0" + "node": ">= 10" } }, - "node_modules/@angular-devkit/build-angular/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "node_modules/@angular-devkit/build-angular/node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, - "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "is-inside-container": "^1.0.0" }, "engines": { - "node": "*" + "node": ">=16" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular-devkit/build-angular/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/@angular-devkit/build-angular/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "license": "ISC", "dependencies": { - "is-glob": "^4.0.3" + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" }, "engines": { - "node": ">=10.13.0" + "node": ">=10" } }, - "node_modules/@angular-devkit/build-angular/node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "node_modules/@angular-devkit/build-angular/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/@angular-devkit/build-angular/node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "node_modules/@angular-devkit/build-angular/node_modules/memfs": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.14.1.tgz", + "integrity": "sha512-Fq5CMEth+2iprLJ5mNizRcWuiwRZYjNkUD0zKk224jZunE9CRacTRDK8QLALbMBlNX2y3nY6lKZbesCwDwacig==", "dev": true, - "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" }, "engines": { - "node": ">= 14" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/inquirer": { - "version": "9.2.15", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", - "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ljharb/through": "^2.3.12", - "ansi-escapes": "^4.3.2", - "chalk": "^5.3.0", - "cli-cursor": "^3.1.0", - "cli-width": "^4.1.0", - "external-editor": "^3.1.0", - "figures": "^3.2.0", - "lodash": "^4.17.21", - "mute-stream": "1.0.0", - "ora": "^5.4.1", - "run-async": "^3.0.0", - "rxjs": "^7.8.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" + "node": ">= 4.0.0" }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" } }, - "node_modules/@angular-devkit/build-angular/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, "node_modules/@angular-devkit/build-angular/node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz", - "integrity": "sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", + "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", "dev": true, - "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", "tapable": "^2.2.1" @@ -1096,47 +830,28 @@ "webpack": "^5.0.0" } }, - "node_modules/@angular-devkit/build-angular/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@angular-devkit/build-angular/node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" }, "engines": { - "node": "*" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@angular-devkit/build-angular/node_modules/p-retry": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.0", - "retry": "^0.13.1" + "node": ">=18" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@angular-devkit/build-angular/node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "dev": true, "funding": [ { @@ -1152,59 +867,35 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" } }, - "node_modules/@angular-devkit/build-angular/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, - "license": "ISC", "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@angular-devkit/build-angular/node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/@angular-devkit/build-angular/node_modules/sass": { - "version": "1.71.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", - "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", + "version": "1.77.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", + "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", "dev": true, - "license": "MIT", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -1218,11 +909,10 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/sass-loader": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-14.1.1.tgz", - "integrity": "sha512-QX8AasDg75monlybel38BZ49JP5Z+uSKfKwF2rO7S74BywaRmGQMUBw9dtkS+ekyM/QnP+NOrRYq8ABMZ9G8jw==", + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.0.tgz", + "integrity": "sha512-n13Z+3rU9A177dk4888czcVFiC8CL9dii4qpXWUg3YIIgZEvi9TCFKjOQcbK0kJM7DJu9VucrZFddvNfYCPwtw==", "dev": true, - "license": "MIT", "dependencies": { "neo-async": "^2.6.2" }, @@ -1258,17 +948,16 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=10" } }, "node_modules/@angular-devkit/build-angular/node_modules/webpack": { @@ -1318,88 +1007,116 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-server": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", "dev": true, - "license": "MIT", "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/serve-static": "^1.13.10", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.5", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "launch-editor": "^2.6.0", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.1.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.13.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { "webpack": { "optional": true - }, - "webpack-cli": { - "optional": true } } }, - "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-server/node_modules/webpack-dev-middleware": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz", - "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==", + "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", "dev": true, - "license": "MIT", "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", "colorette": "^2.0.10", - "memfs": "^3.4.3", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } } }, "node_modules/@angular-devkit/build-angular/node_modules/webpack/node_modules/ajv": { @@ -1469,13 +1186,30 @@ "node": ">=10.13.0" } }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1802.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.12.tgz", + "integrity": "sha512-0Z3fdbZVRnjYWE2/VYyfy+uieY+6YZyEp4ylzklVkc+fmLNsnz4Zw6cK1LzzcBqAwKIyh1IdW20Cg7o8b0sONA==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1802.12", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, "node_modules/@angular-devkit/core": { - "version": "18.2.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.11.tgz", - "integrity": "sha512-H9P1shRGigORWJHUY2BRa2YurT+DVminrhuaYHsbhXBRsPmgB2Dx/30YLTnC1s5XmR9QIRUCsg/d3kyT1wd5Zg==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.12.tgz", + "integrity": "sha512-NtB6ypsaDyPE6/fqWOdfTmACs+yK5RqfH5tStEzWFeeDsIEDYKsJ06ypuRep7qTjYus5Rmttk0Ds+cFgz8JdUQ==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", @@ -1498,444 +1232,936 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@angular-devkit/core/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@angular-devkit/schematics": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.11.tgz", - "integrity": "sha512-I5wviiIqiFwar9Pdk30Lujk8FczEEc18i22A5c6Z9lbmhPQdTroDnEQdsfXjy404wPe8H62s0I15o4pmMGfTYQ==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.12.tgz", + "integrity": "sha512-mMea9txHbnCX5lXLHlo0RAgfhFHDio45/jMsREM2PA8UtVf2S8ltXz7ZwUrUyMQRv8vaSfn4ijDstF4hDMnRgQ==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "17.3.11", - "jsonc-parser": "3.2.1", - "magic-string": "0.30.8", + "@angular-devkit/core": "18.2.12", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.11", "ora": "5.4.1", "rxjs": "7.8.1" }, "engines": { - "node": "^18.13.0 || >=20.9.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", - "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-18.4.3.tgz", + "integrity": "sha512-zdrA8mR98X+U4YgHzUKmivRU+PxzwOL/j8G7eTOvBuq8GPzsP+hvak+tyxlgeGm9HsvpFj9ERHLtJ0xDUPs8fg==", + "dev": true }, - "node_modules/@angular-devkit/schematics/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/@angular-eslint/eslint-plugin": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-18.4.3.tgz", + "integrity": "sha512-AyJbupiwTBR81P6T59v+aULEnPpZBCBxL2S5QFWfAhNCwWhcof4GihvdK2Z87yhvzDGeAzUFSWl/beJfeFa+PA==", "dev": true, - "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "@angular-eslint/bundled-angular-compiler": "18.4.3", + "@angular-eslint/utils": "18.4.3" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" } }, - "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-18.4.3.tgz", + "integrity": "sha512-ijGlX2N01ayMXTpeQivOA31AszO8OEbu9ZQUCxnu9AyMMhxyi2q50bujRChAvN9YXQfdQtbxuajxV6+aiWb5BQ==", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "@angular-eslint/bundled-angular-compiler": "18.4.3", + "@angular-eslint/utils": "18.4.3", + "aria-query": "5.3.2", + "axobject-query": "4.1.0" }, "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "@typescript-eslint/types": "^7.11.0 || ^8.0.0", + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" } }, - "node_modules/@angular-eslint/bundled-angular-compiler": { - "version": "17.5.3", - "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.5.3.tgz", - "integrity": "sha512-x9jZ6mME9wxumErPGonWERXX/9TJ7mzEkQhOKt3BxBFm0sy9XQqLMAenp1PBSg3RF3rH7EEVdB2+jb75RtHp0g==", + "node_modules/@angular-eslint/eslint-plugin-template/node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, - "license": "MIT" + "engines": { + "node": ">= 0.4" + } }, - "node_modules/@angular-eslint/eslint-plugin": { - "version": "17.5.3", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-17.5.3.tgz", - "integrity": "sha512-2gMRZ+SkiygrPDtCJwMfjmwIFOcvxxC4NRX/MqRo6udsa0gtqPrc8acRbwrmAXlullmhzmaeUfkHpGDSzW8pFw==", + "node_modules/@angular-eslint/schematics": { + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-18.4.3.tgz", + "integrity": "sha512-D5maKn5e6n58+8n7jLFLD4g+RGPOPeDSsvPc1sqial5tEKLxAJQJS9WZ28oef3bhkob6C60D+1H0mMmEEVvyVA==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.5.3", - "@angular-eslint/utils": "17.5.3", - "@typescript-eslint/utils": "7.11.0" - }, - "peerDependencies": { - "eslint": "^7.20.0 || ^8.0.0", - "typescript": "*" + "@angular-devkit/core": ">= 18.0.0 < 19.0.0", + "@angular-devkit/schematics": ">= 18.0.0 < 19.0.0", + "@angular-eslint/eslint-plugin": "18.4.3", + "@angular-eslint/eslint-plugin-template": "18.4.3", + "ignore": "6.0.2", + "semver": "7.6.3", + "strip-json-comments": "3.1.1" } }, - "node_modules/@angular-eslint/eslint-plugin-template": { - "version": "17.5.3", - "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.5.3.tgz", - "integrity": "sha512-RkRFagxqBPV2xdNyeQQROUm6I1Izto1Z3Wy73lCk2zq1RhVgbznniH/epmOIE8PMkHmMKmZ765FV++J/90p4Ig==", + "node_modules/@angular-eslint/schematics/node_modules/ignore": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-6.0.2.tgz", + "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==", "dev": true, - "license": "MIT", - "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.5.3", - "@angular-eslint/utils": "17.5.3", - "@typescript-eslint/type-utils": "7.11.0", - "@typescript-eslint/utils": "7.11.0", - "aria-query": "5.3.0", - "axobject-query": "4.0.0" - }, - "peerDependencies": { - "eslint": "^7.20.0 || ^8.0.0", - "typescript": "*" + "engines": { + "node": ">= 4" } }, - "node_modules/@angular-eslint/schematics": { - "version": "17.5.3", - "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-17.5.3.tgz", - "integrity": "sha512-a0MlOjNLIM18l/66S+CzhANQR3QH3jDUa1MC50E4KBf1mwjQyfqd6RdfbOTMDjgFlPrfB+5JvoWOHHGj7FFM1A==", + "node_modules/@angular-eslint/schematics/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "MIT", - "dependencies": { - "@angular-eslint/eslint-plugin": "17.5.3", - "@angular-eslint/eslint-plugin-template": "17.5.3", - "ignore": "5.3.1", - "strip-json-comments": "3.1.1", - "tmp": "0.2.3" + "bin": { + "semver": "bin/semver.js" }, - "peerDependencies": { - "@angular/cli": ">= 17.0.0 < 18.0.0" + "engines": { + "node": ">=10" } }, "node_modules/@angular-eslint/template-parser": { - "version": "17.5.3", - "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-17.5.3.tgz", - "integrity": "sha512-NYybOsMkJUtFOW2JWALicipq0kK5+jGwA1MYyRoXjdbDlXltHUb9qkXj7p0fE6uRutBGXDl4288s8g/fZCnAIA==", + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-18.4.3.tgz", + "integrity": "sha512-JZMPtEB8yNip3kg4WDEWQyObSo2Hwf+opq2ElYuwe85GQkGhfJSJ2CQYo4FSwd+c5MUQAqESNRg9QqGYauDsiw==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.5.3", - "eslint-scope": "^8.0.0" + "@angular-eslint/bundled-angular-compiler": "18.4.3", + "eslint-scope": "^8.0.2" }, "peerDependencies": { - "eslint": "^7.20.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "node_modules/@angular-eslint/utils": { - "version": "17.5.3", - "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-17.5.3.tgz", - "integrity": "sha512-0nNm1FUOLhVHrdK2PP5dZCYYVmTIkEJ4CmlwpuC4JtCLbD5XAHQpY/ZW5Ff5n1b7KfJt1Zy//jlhkkIaw3LaBQ==", + "version": "18.4.3", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-18.4.3.tgz", + "integrity": "sha512-w0bJ9+ELAEiPBSTPPm9bvDngfu1d8JbzUhvs2vU+z7sIz/HMwUZT5S4naypj2kNN0gZYGYrW0lt+HIbW87zTAQ==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-eslint/bundled-angular-compiler": "17.5.3", - "@typescript-eslint/utils": "7.11.0" + "@angular-eslint/bundled-angular-compiler": "18.4.3" }, "peerDependencies": { - "eslint": "^7.20.0 || ^8.0.0", + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", "typescript": "*" } }, "node_modules/@angular/animations": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-17.3.12.tgz", - "integrity": "sha512-9hsdWF4gRRcVJtPcCcYLaX1CIyM9wUu6r+xRl6zU5hq8qhl35hig6ounz7CXFAzLf0WDBdM16bPHouVGaG76lg==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.13.tgz", + "integrity": "sha512-rG5J5Ek5Hg+Tz2NjkNOaG6PupiNK/lPfophXpsR1t/nWujqnMWX2krahD/i6kgD+jNWNKCJCYSOVvCx/BHOtKA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" - }, - "peerDependencies": { - "@angular/core": "17.3.12" - } - }, - "node_modules/@angular/cdk": { - "version": "17.3.10", - "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-17.3.10.tgz", - "integrity": "sha512-b1qktT2c1TTTe5nTji/kFAVW92fULK0YhYAvJ+BjZTPKu2FniZNe8o4qqQ0pUuvtMu+ZQxp/QqFYoidIVCjScg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" - }, - "optionalDependencies": { - "parse5": "^7.1.2" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "^17.0.0 || ^18.0.0", - "@angular/core": "^17.0.0 || ^18.0.0", - "rxjs": "^6.5.3 || ^7.4.0" - } - }, - "node_modules/@angular/cli": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-17.3.11.tgz", - "integrity": "sha512-8R9LwAGL8hGAWJ4mNG9ZPUrBUzIdmst0Ldua6RJJ+PrqgjX+8IbO+lNnfrOY/XY+Z3LXbCEJflL26f9czCvTPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/architect": "0.1703.11", - "@angular-devkit/core": "17.3.11", - "@angular-devkit/schematics": "17.3.11", - "@schematics/angular": "17.3.11", - "@yarnpkg/lockfile": "1.1.0", - "ansi-colors": "4.1.3", - "ini": "4.1.2", - "inquirer": "9.2.15", - "jsonc-parser": "3.2.1", - "npm-package-arg": "11.0.1", - "npm-pick-manifest": "9.0.0", - "open": "8.4.2", - "ora": "5.4.1", - "pacote": "17.0.6", - "resolve": "1.22.8", - "semver": "7.6.0", - "symbol-observable": "4.0.0", - "yargs": "17.7.2" - }, - "bin": { - "ng": "bin/ng.js" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular/cli/node_modules/@angular-devkit/architect": { - "version": "0.1703.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1703.11.tgz", - "integrity": "sha512-YNasVZk4rYdcM6M+KRH8PUBhVyJfqzUYLpO98GgRokW+taIDgifckSlmfDZzQRbw45qiwei1IKCLqcpC8nM5Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "17.3.11", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "@angular/core": "18.2.13" } }, - "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", - "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", + "node_modules/@angular/build": { + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.12.tgz", + "integrity": "sha512-4Ohz+OSILoL+cCAQ4UTiCT5v6pctu3fXNoNpTEUK46OmxELk9jDITO5rNyNS7TxBn9wY69kjX5VcDf7MenquFQ==", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1802.12", + "@babel/core": "7.25.2", + "@babel/helper-annotate-as-pure": "7.24.7", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.24.7", + "@inquirer/confirm": "3.1.22", + "@vitejs/plugin-basic-ssl": "1.1.0", + "browserslist": "^4.23.0", + "critters": "0.0.24", + "esbuild": "0.23.0", + "fast-glob": "3.3.2", + "https-proxy-agent": "7.0.5", + "listr2": "8.2.4", + "lmdb": "3.0.13", + "magic-string": "0.30.11", + "mrmime": "2.0.0", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.6.1", + "rollup": "4.22.4", + "sass": "1.77.6", + "semver": "7.6.3", + "vite": "5.4.6", + "watchpack": "2.4.1" }, "engines": { - "node": "^18.13.0 || >=20.9.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "peerDependencies": { - "chokidar": "^3.5.2" + "@angular/compiler-cli": "^18.0.0", + "@angular/localize": "^18.0.0", + "@angular/platform-server": "^18.0.0", + "@angular/service-worker": "^18.0.0", + "less": "^4.2.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0", + "typescript": ">=5.4 <5.6" }, "peerDependenciesMeta": { - "chokidar": { + "@angular/localize": { "optional": true - } - } - }, - "node_modules/@angular/cli/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/@babel/core": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@angular/cli/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "node_modules/@angular/build/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/build/node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", + "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "@babel/helper-plugin-utils": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "ajv": "^8.0.0" + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", + "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-android-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", + "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", + "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", + "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", + "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", + "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", + "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", + "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", + "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", + "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", + "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", + "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", + "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", + "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", + "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", + "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@angular/build/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@angular/build/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/build/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@angular/build/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/@angular/build/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/@angular/build/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/build/node_modules/listr2": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@angular/build/node_modules/rollup": { + "version": "4.22.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", + "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.22.4", + "@rollup/rollup-android-arm64": "4.22.4", + "@rollup/rollup-darwin-arm64": "4.22.4", + "@rollup/rollup-darwin-x64": "4.22.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", + "@rollup/rollup-linux-arm-musleabihf": "4.22.4", + "@rollup/rollup-linux-arm64-gnu": "4.22.4", + "@rollup/rollup-linux-arm64-musl": "4.22.4", + "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", + "@rollup/rollup-linux-riscv64-gnu": "4.22.4", + "@rollup/rollup-linux-s390x-gnu": "4.22.4", + "@rollup/rollup-linux-x64-gnu": "4.22.4", + "@rollup/rollup-linux-x64-musl": "4.22.4", + "@rollup/rollup-win32-arm64-msvc": "4.22.4", + "@rollup/rollup-win32-ia32-msvc": "4.22.4", + "@rollup/rollup-win32-x64-msvc": "4.22.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/@angular/build/node_modules/sass": { + "version": "1.77.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.6.tgz", + "integrity": "sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@angular/build/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular/build/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/build/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@angular/build/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@angular/cdk": { + "version": "18.2.14", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.14.tgz", + "integrity": "sha512-vDyOh1lwjfVk9OqoroZAP8pf3xxKUvyl+TVR8nJxL4c5fOfUFkD7l94HaanqKSRwJcI2xiztuu92IVoHn8T33Q==", + "dependencies": { + "tslib": "^2.3.0" + }, + "optionalDependencies": { + "parse5": "^7.1.2" + }, + "peerDependencies": { + "@angular/common": "^18.0.0 || ^19.0.0", + "@angular/core": "^18.0.0 || ^19.0.0", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/cli": { + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.12.tgz", + "integrity": "sha512-xhuZ/b7IhqNw1MgXf+arWf4x+GfUSt/IwbdWU4+CO8A7h0Y46zQywouP/KUK3cMQZfVdHdciTBvlpF3vFacA6Q==", + "dev": true, + "dependencies": { + "@angular-devkit/architect": "0.1802.12", + "@angular-devkit/core": "18.2.12", + "@angular-devkit/schematics": "18.2.12", + "@inquirer/prompts": "5.3.8", + "@listr2/prompt-adapter-inquirer": "2.0.15", + "@schematics/angular": "18.2.12", + "@yarnpkg/lockfile": "1.1.0", + "ini": "4.1.3", + "jsonc-parser": "3.3.1", + "listr2": "8.2.4", + "npm-package-arg": "11.0.3", + "npm-pick-manifest": "9.1.0", + "pacote": "18.0.6", + "resolve": "1.22.8", + "semver": "7.6.3", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/cli/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true + }, + "node_modules/@angular/cli/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true + }, + "node_modules/@angular/cli/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/listr2": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.4.tgz", + "integrity": "sha512-opevsywziHd3zHCVQGAj8zu+Z3yHNkkoYhWIGnq54RrCVwLz0MozotJEDnKsIBLvkfLGN6BLOyAeRrYI0pKA4g==", + "dev": true, + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@angular/cli/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "bin": { + "semver": "bin/semver.js" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "engines": { + "node": ">=10" } }, - "node_modules/@angular/cli/node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "node_modules/@angular/cli/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, - "license": "ISC", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, "engines": { - "node": ">= 12" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/inquirer": { - "version": "9.2.15", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", - "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", + "node_modules/@angular/cli/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "license": "MIT", "dependencies": { - "@ljharb/through": "^2.3.12", - "ansi-escapes": "^4.3.2", - "chalk": "^5.3.0", - "cli-cursor": "^3.1.0", - "cli-width": "^4.1.0", - "external-editor": "^3.1.0", - "figures": "^3.2.0", - "lodash": "^4.17.21", - "mute-stream": "1.0.0", - "ora": "^5.4.1", - "run-async": "^3.0.0", - "rxjs": "^7.8.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^6.2.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/cli/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "node_modules/@angular/cli/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "license": "ISC", + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/run-async": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", - "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "node_modules/@angular/cli/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, - "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=0.12.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/@angular/common": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-17.3.12.tgz", - "integrity": "sha512-vabJzvrx76XXFrm1RJZ6o/CyG32piTB/1sfFfKHdlH1QrmArb8It4gyk9oEjZ1IkAD0HvBWlfWmn+T6Vx3pdUw==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.13.tgz", + "integrity": "sha512-4ZqrNp1PoZo7VNvW+sbSc2CB2axP1sCH2wXl8B0wdjsj8JY1hF1OhuugwhpAHtGxqewed2kCXayE+ZJqSTV4jw==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "17.3.12", + "@angular/core": "18.2.13", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-17.3.12.tgz", - "integrity": "sha512-vwI8oOL/gM+wPnptOVeBbMfZYwzRxQsovojZf+Zol9szl0k3SZ3FycWlxxXZGFu3VIEfrP6pXplTmyODS/Lt1w==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.13.tgz", + "integrity": "sha512-TzWcrkopyjFF+WeDr2cRe8CcHjU72KfYV3Sm2TkBkcXrkYX5sDjGWrBGrG3hRB4e4okqchrOCvm1MiTdy2vKMA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "17.3.12" + "@angular/core": "18.2.13" }, "peerDependenciesMeta": { "@angular/core": { @@ -1944,15 +2170,14 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-17.3.12.tgz", - "integrity": "sha512-1F8M7nWfChzurb7obbvuE7mJXlHtY1UG58pcwcomVtpPb+kPavgAO8OEvJHYBMV+bzSxkXt5UIwL9lt9jHUxZA==", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.13.tgz", + "integrity": "sha512-DBSh4AQwkiJDSiVvJATRmjxf6wyUs9pwQLgaFdSlfuTRO+sdb0J2z1r3BYm8t0IqdoyXzdZq2YCH43EmyvD71g==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "7.23.9", + "@babel/core": "7.25.2", "@jridgewell/sourcemap-codec": "^1.4.14", - "chokidar": "^3.0.0", + "chokidar": "^4.0.0", "convert-source-map": "^1.5.1", "reflect-metadata": "^0.2.0", "semver": "^7.0.0", @@ -1965,30 +2190,29 @@ "ngcc": "bundles/ngcc/index.js" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/compiler": "17.3.12", - "typescript": ">=5.2 <5.5" + "@angular/compiler": "18.2.13", + "typescript": ">=5.4 <5.6" } }, "node_modules/@angular/compiler-cli/node_modules/@babel/core": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, - "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-compilation-targets": "^7.23.6", - "@babel/helper-module-transforms": "^7.23.3", - "@babel/helpers": "^7.23.9", - "@babel/parser": "^7.23.9", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -2007,85 +2231,107 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/core": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-17.3.12.tgz", - "integrity": "sha512-MuFt5yKi161JmauUta4Dh0m8ofwoq6Ino+KoOtkYMBGsSx+A7dSm+DUxxNwdj7+DNyg3LjVGCFgBFnq4g8z06A==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.13.tgz", + "integrity": "sha512-8mbWHMgO95OuFV1Ejy4oKmbe9NOJ3WazQf/f7wks8Bck7pcihd0IKhlPBNjFllbF5o+04EYSwFhEtvEgjMDClA==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.14.0" + "zone.js": "~0.14.10" } }, "node_modules/@angular/elements": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-17.3.12.tgz", - "integrity": "sha512-rUfEaV+Ol0bxtcEfNuf/7aVe+3/hAVJMNF/DHG71BSekCxPSH5WR6wE0zsXmVoTBadj+TUDlsyju9o9n3+C5Vg==", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-18.2.13.tgz", + "integrity": "sha512-yahRkXWgFolpWMeVsTIlWYwoq4Bsz6wrfS4b+TKHIZbTCyRUlJ5zBFecpYMwgmVuQDJZp+WkUWZV2Qg7kLJR5w==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/core": "17.3.12", + "@angular/core": "18.2.13", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/forms": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-17.3.12.tgz", - "integrity": "sha512-tV6r12Q3yEUlXwpVko4E+XscunTIpPkLbaiDn/MTL3Vxi2LZnsLgHyd/i38HaHN+e/H3B0a1ToSOhV5wf3ay4Q==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.13.tgz", + "integrity": "sha512-A67D867fu3DSBhdLWWZl/F5pr7v2+dRM2u3U7ZJ0ewh4a+sv+0yqWdJW+a8xIoiHxS+btGEJL2qAKJiH+MCFfg==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "17.3.12", - "@angular/core": "17.3.12", - "@angular/platform-browser": "17.3.12", + "@angular/common": "18.2.13", + "@angular/core": "18.2.13", + "@angular/platform-browser": "18.2.13", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/platform-browser": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-17.3.12.tgz", - "integrity": "sha512-DYY04ptWh/ulMHzd+y52WCE8QnEYGeIiW3hEIFjCN8z0kbIdFdUtEB0IK5vjNL3ejyhUmphcpeT5PYf3YXtqWQ==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.13.tgz", + "integrity": "sha512-tu7ZzY6qD3ATdWFzcTcsAKe7M6cJeWbT/4/bF9unyGO3XBPcNYDKoiz10+7ap2PUd0fmPwvuvTvSNJiFEBnB8Q==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/animations": "17.3.12", - "@angular/common": "17.3.12", - "@angular/core": "17.3.12" + "@angular/animations": "18.2.13", + "@angular/common": "18.2.13", + "@angular/core": "18.2.13" }, "peerDependenciesMeta": { "@angular/animations": { @@ -2094,38 +2340,36 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.12.tgz", - "integrity": "sha512-DQwV7B2x/DRLRDSisngZRdLqHdYbbrqZv2Hmu4ZbnNYaWPC8qvzgE/0CvY+UkDat3nCcsfwsMnlDeB6TL7/IaA==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.13.tgz", + "integrity": "sha512-kbQCf9+8EpuJC7buBxhSiwBtXvjAwAKh6MznD6zd2pyCYqfY6gfRCZQRtK59IfgVtKmEONWI9grEyNIRoTmqJg==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "17.3.12", - "@angular/compiler": "17.3.12", - "@angular/core": "17.3.12", - "@angular/platform-browser": "17.3.12" + "@angular/common": "18.2.13", + "@angular/compiler": "18.2.13", + "@angular/core": "18.2.13", + "@angular/platform-browser": "18.2.13" } }, "node_modules/@angular/router": { - "version": "17.3.12", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-17.3.12.tgz", - "integrity": "sha512-dg7PHBSW9fmPKTVzwvHEeHZPZdpnUqW/U7kj8D29HTP9ur8zZnx9QcnbplwPeYb8yYa62JMnZSEel2X4PxdYBg==", - "license": "MIT", + "version": "18.2.13", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.13.tgz", + "integrity": "sha512-VKmfgi/r/CkyBq9nChQ/ptmfu0JT/8ONnLVJ5H+SkFLRYJcIRyHLKjRihMCyVm6xM5yktOdCaW73NTQrFz7+bg==", "dependencies": { "tslib": "^2.3.0" }, "engines": { - "node": "^18.13.0 || >=20.9.0" + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" }, "peerDependencies": { - "@angular/common": "17.3.12", - "@angular/core": "17.3.12", - "@angular/platform-browser": "17.3.12", + "@angular/common": "18.2.13", + "@angular/core": "18.2.13", + "@angular/platform-browser": "18.2.13", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -2226,15 +2470,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", + "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { @@ -2242,13 +2485,12 @@ } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", + "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -2428,19 +2670,6 @@ "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", - "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", @@ -2584,13 +2813,12 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3097,16 +3325,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.0.tgz", + "integrity": "sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20", - "@babel/plugin-syntax-async-generators": "^7.8.4" + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/helper-remap-async-to-generator": "^7.25.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/traverse": "^7.25.0" }, "engines": { "node": ">=6.9.0" @@ -3116,15 +3343,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz", + "integrity": "sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/helper-remap-async-to-generator": "^7.22.20" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "@babel/helper-remap-async-to-generator": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -3781,17 +4007,16 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.0.tgz", - "integrity": "sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.7.tgz", + "integrity": "sha512-YqXjrk4C+a1kZjewqt+Mmu2UuV1s07y8kqcUf4qYLnoqemhR4gRQikhdAhSVJioMjVTu6Mo6pAbaypEA3jY6fw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.22.15", - "@babel/helper-plugin-utils": "^7.24.0", - "babel-plugin-polyfill-corejs2": "^0.4.8", - "babel-plugin-polyfill-corejs3": "^0.9.0", - "babel-plugin-polyfill-regenerator": "^0.5.5", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.7", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.1", + "babel-plugin-polyfill-regenerator": "^0.6.1", "semver": "^6.3.1" }, "engines": { @@ -3806,7 +4031,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -4091,33 +4315,6 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", - "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2", - "core-js-compat": "^3.38.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@babel/preset-env/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -4144,11 +4341,10 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", - "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz", + "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==", "dev": true, - "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -4696,33 +4892,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@compodoc/compodoc/node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", - "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2", - "core-js-compat": "^3.38.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/@compodoc/compodoc/node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", - "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, "node_modules/@compodoc/compodoc/node_modules/cheerio": { "version": "1.0.0-rc.12", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", @@ -4816,26 +4985,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@compodoc/compodoc/node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, "node_modules/@compodoc/compodoc/node_modules/jackspeak": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.0.2.tgz", @@ -4865,13 +5014,6 @@ "node": ">=6" } }, - "node_modules/@compodoc/compodoc/node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@compodoc/compodoc/node_modules/lru-cache": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", @@ -4882,16 +5024,6 @@ "node": "20 || >=22" } }, - "node_modules/@compodoc/compodoc/node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, "node_modules/@compodoc/compodoc/node_modules/minimatch": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", @@ -4919,23 +5051,10 @@ "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@compodoc/compodoc/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@compodoc/compodoc/node_modules/semver": { @@ -5095,16 +5214,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@electron/asar": { "version": "3.2.15", "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.15.tgz", @@ -5542,20 +5651,19 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", - "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", + "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -5834,6 +5942,252 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@inquirer/checkbox": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.5.0.tgz", + "integrity": "sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.3", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/confirm": { + "version": "3.1.22", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.22.tgz", + "integrity": "sha512-gsAKIOWBm2Q87CDfs9fEo7wJT3fwWIJfnDGMn9Qy74gBnNFOACDNfhUzovubbJjWnKLGBln7/NcSmZwj5DuEXg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.0.10", + "@inquirer/type": "^1.5.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz", + "integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==", + "dev": true, + "dependencies": { + "@inquirer/figures": "^1.0.6", + "@inquirer/type": "^2.0.0", + "@types/mute-stream": "^0.0.4", + "@types/node": "^22.5.5", + "@types/wrap-ansi": "^3.0.0", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^1.0.0", + "signal-exit": "^4.1.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/@inquirer/type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz", + "integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/core/node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@inquirer/core/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@inquirer/editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.2.0.tgz", + "integrity": "sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/expand": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-2.3.0.tgz", + "integrity": "sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-2.3.0.tgz", + "integrity": "sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-1.1.0.tgz", + "integrity": "sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/password": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-2.2.0.tgz", + "integrity": "sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/prompts": { + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-5.3.8.tgz", + "integrity": "sha512-b2BudQY/Si4Y2a0PdZZL6BeJtl8llgeZa7U2j47aaJSCeAl1e4UI7y8a9bSkO3o/ZbZrgT5muy/34JbsjfIWxA==", + "dev": true, + "dependencies": { + "@inquirer/checkbox": "^2.4.7", + "@inquirer/confirm": "^3.1.22", + "@inquirer/editor": "^2.1.22", + "@inquirer/expand": "^2.1.22", + "@inquirer/input": "^2.2.9", + "@inquirer/number": "^1.0.10", + "@inquirer/password": "^2.1.22", + "@inquirer/rawlist": "^2.2.4", + "@inquirer/search": "^1.0.7", + "@inquirer/select": "^2.4.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/rawlist": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-2.3.0.tgz", + "integrity": "sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/type": "^1.5.3", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/search": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-1.1.0.tgz", + "integrity": "sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.3", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/select": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-2.5.0.tgz", + "integrity": "sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==", + "dev": true, + "dependencies": { + "@inquirer/core": "^9.1.0", + "@inquirer/figures": "^1.0.5", + "@inquirer/type": "^1.5.3", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/type/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -5943,6 +6297,7 @@ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -5960,6 +6315,7 @@ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -5974,6 +6330,7 @@ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-locate": "^4.1.0" }, @@ -5987,6 +6344,7 @@ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-try": "^2.0.0" }, @@ -6003,6 +6361,7 @@ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-limit": "^2.2.0" }, @@ -6586,6 +6945,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.15", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.15.tgz", + "integrity": "sha512-MZrGem/Ujjd4cPTLYDfCZK2iKKeiO/8OX13S6jqxldLs0Prf2aGqVlJ77nMBqMv7fzqgXEgjrNHLXcKR8l9lOg==", + "dev": true, + "dependencies": { + "@inquirer/type": "^1.5.1" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 6" + } + }, "node_modules/@lit-labs/react": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-1.2.1.tgz", @@ -6610,18 +6984,83 @@ "@lit-labs/ssr-dom-shim": "^1.0.0" } }, - "node_modules/@ljharb/through": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", - "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.0.13.tgz", + "integrity": "sha512-uiKPB0Fv6WEEOZjruu9a6wnW/8jrjzlZbxXscMB8kuCJ1k6kHpcBnuvaAWcqhbI7rqX5GKziwWEdD+wi2gNLfA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - } + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.0.13.tgz", + "integrity": "sha512-bEVIIfK5mSQoG1R19qA+fJOvCB+0wVGGnXHT3smchBVahYBdlPn2OsZZKzlHWfb1E+PhLBmYfqB5zQXFP7hJig==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.0.13.tgz", + "integrity": "sha512-Yml1KlMzOnXj/tnW7yX8U78iAzTk39aILYvCPbqeewAq1kSzl+w59k/fiVkTBfvDi/oW/5YRxL+Fq+Y1Fr1r2Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.0.13.tgz", + "integrity": "sha512-afbVrsMgZ9dUTNUchFpj5VkmJRxvht/u335jUJ7o23YTbNbnpmXif3VKQGCtnjSh+CZaqm6N3CPG8KO3zwyZ1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.0.13.tgz", + "integrity": "sha512-vOtxu0xC0SLdQ2WRXg8Qgd8T32ak4SPqk5zjItRszrJk2BdeXqfGxBJbP7o4aOvSPSmSSv46Lr1EP4HXU8v7Kg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.0.13.tgz", + "integrity": "sha512-UCrMJQY/gJnOl3XgbWRZZUvGGBuKy6i0YNSptgMzHBjs+QYDYR1Mt/RLTOPy4fzzves65O1EDmlL//OzEqoLlA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@malept/cross-spawn-promise": { "version": "2.0.0", @@ -6755,14 +7194,92 @@ } } }, - "node_modules/@msgpack/msgpack": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz", - "integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==", - "license": "ISC", - "engines": { - "node": ">= 10" - } + "node_modules/@msgpack/msgpack": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-2.8.0.tgz", + "integrity": "sha512-h9u4u/jiIRKbq25PM+zymTyW6bhTzELvOoUd+AvYriWOAKpLGnIamaET3pnHYoI5iYphAHBI4ayx0MehR+VVPQ==", + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@napi-rs/cli": { "version": "2.18.4", @@ -6782,37 +7299,35 @@ } }, "node_modules/@ng-select/ng-select": { - "version": "12.0.7", - "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-12.0.7.tgz", - "integrity": "sha512-Eht1zlLP0DJxiXcKnq3aY/EJ8odomgU0hM0BJoPY6oX3XFHndtFtdPxlZfhVtQn+FwyDEh7306rRx6digxVssA==", - "license": "MIT", + "version": "13.9.1", + "resolved": "https://registry.npmjs.org/@ng-select/ng-select/-/ng-select-13.9.1.tgz", + "integrity": "sha512-+DzQkQp8coGWZREflJM/qx7BXipV6HEVpZCXoa6fJJRHJfmUMsxa5uV6kUVmClUE98Rkffk9CPHt6kZcj8PuqQ==", "dependencies": { "tslib": "^2.3.1" }, "engines": { - "node": ">= 16", + "node": ">= 18", "npm": ">= 8" }, "peerDependencies": { - "@angular/common": "^17.0.0-rc.0", - "@angular/core": "^17.0.0-rc.0", - "@angular/forms": "^17.0.0-rc.0" + "@angular/common": "^18.0.0", + "@angular/core": "^18.0.0", + "@angular/forms": "^18.0.0" } }, "node_modules/@ngtools/webpack": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-17.3.11.tgz", - "integrity": "sha512-SfTCbplt4y6ak5cf2IfqdoVOsnoNdh/j6Vu+wb8WWABKwZ5yfr2S/Gk6ithSKcdIZhAF8DNBOoyk1EJuf8Xkfg==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.12.tgz", + "integrity": "sha512-FFJAwtWbtpncMOVNuULPBwFJB7GSjiUwO93eGTzRp8O4EPQ8lCQeFbezQm/NP34+T0+GBLGzPSuQT+muob8YKw==", "dev": true, - "license": "MIT", "engines": { - "node": "^18.13.0 || >=20.9.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "peerDependencies": { - "@angular/compiler-cli": "^17.0.0", - "typescript": ">=5.2 <5.5", + "@angular/compiler-cli": "^18.0.0", + "typescript": ">=5.4 <5.6", "webpack": "^5.54.0" } }, @@ -6859,7 +7374,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", "dev": true, - "license": "ISC", "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", @@ -6876,7 +7390,6 @@ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", "dev": true, - "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -6889,7 +7402,6 @@ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -6902,15 +7414,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@npmcli/agent/node_modules/socks-proxy-agent": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", @@ -6939,7 +7449,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/promise-spawn": "^7.0.0", "ini": "^4.1.3", @@ -6955,22 +7464,11 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@npmcli/git/node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/@npmcli/git/node_modules/isexe": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -6979,15 +7477,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@npmcli/git/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -6997,7 +7493,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -7013,7 +7508,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", "dev": true, - "license": "ISC", "dependencies": { "npm-bundled": "^3.0.0", "npm-normalize-package-bin": "^3.0.0" @@ -7108,7 +7602,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -7118,7 +7611,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.1.tgz", "integrity": "sha512-f7zYC6kQautXHvNbLEWgD/uGu1+xCn9izgqBfgItWSx22U0ZDekxN08A1vM8cTxj/cRVe0Q94Ode+tdoYmIOOQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/git": "^5.0.0", "glob": "^10.2.2", @@ -7137,7 +7629,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -7149,15 +7640,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@npmcli/package-json/node_modules/proc-log": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -7167,7 +7656,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", "dev": true, - "license": "ISC", "dependencies": { "which": "^4.0.0" }, @@ -7180,7 +7668,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -7190,7 +7677,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -7202,26 +7688,25 @@ } }, "node_modules/@npmcli/redact": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-1.1.0.tgz", - "integrity": "sha512-PfnWuOkQgu7gCbnSsAisaX7hKOdZ4wSAhAzH3/ph5dSGau52kCRrMMGbiSQLwyTZpgldkZ49b0brkOr1AzGBHQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", "dev": true, - "license": "ISC", "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/@npmcli/run-script": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-7.0.4.tgz", - "integrity": "sha512-9ApYM/3+rBt9V80aYg6tZfzj3UWdiYyCt7gJUD1VJKvWF5nwKDSICXbYIQbspFTq6TOpbsEtIC0LArB8d9PFmg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", + "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^3.0.0", "@npmcli/package-json": "^5.0.0", "@npmcli/promise-spawn": "^7.0.0", "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", "which": "^4.0.0" }, "engines": { @@ -7233,17 +7718,24 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } }, + "node_modules/@npmcli/run-script/node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@npmcli/run-script/node_modules/which": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -7369,83 +7861,19 @@ ] }, "node_modules/@schematics/angular": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-17.3.11.tgz", - "integrity": "sha512-tvJpTgYC+hCnTyLszYRUZVyNTpPd+C44gh5CPTcG3qkqStzXQwynQAf6X/DjtwXbUiPQF0XfF0+0R489GpdZPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "17.3.11", - "@angular-devkit/schematics": "17.3.11", - "jsonc-parser": "3.2.1" - }, - "engines": { - "node": "^18.13.0 || >=20.9.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "17.3.11", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", - "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", + "version": "18.2.12", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.12.tgz", + "integrity": "sha512-sIoeipsisK5eTLW3XuNZYcal83AfslBbgI7LnV+3VrXwpasKPGHwo2ZdwhCd2IXAkuJ02Iyu7MyV0aQRM9i/3g==", "dev": true, - "license": "MIT", "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.1", - "picomatch": "4.0.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" + "@angular-devkit/core": "18.2.12", + "@angular-devkit/schematics": "18.2.12", + "jsonc-parser": "3.3.1" }, "engines": { - "node": "^18.13.0 || >=20.9.0", + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@schematics/angular/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@schematics/angular/node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } } }, "node_modules/@sideway/address": { @@ -7477,7 +7905,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.3.2" }, @@ -7490,7 +7917,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^16.14.0 || >=18.0.0" } @@ -7500,7 +7926,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^16.14.0 || >=18.0.0" } @@ -7510,7 +7935,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.0.0", @@ -7528,7 +7952,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -7541,7 +7964,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -7565,7 +7987,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -7577,15 +7998,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/@sigstore/sign/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -7609,7 +8028,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -7622,7 +8040,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -7640,7 +8057,6 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -7650,7 +8066,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -7663,7 +8078,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -7676,7 +8090,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -7689,7 +8102,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.3.2", "tuf-js": "^2.2.1" @@ -7703,7 +8115,6 @@ "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.1.0", @@ -8615,7 +9026,6 @@ "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", "dev": true, - "license": "MIT", "engines": { "node": "^16.14.0 || >=18.0.0" } @@ -8625,7 +9035,6 @@ "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", "dev": true, - "license": "MIT", "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^9.0.4" @@ -9207,6 +9616,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mute-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", + "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "22.10.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", @@ -9485,6 +9903,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/wrap-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", + "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "dev": true + }, "node_modules/@types/ws": { "version": "8.5.13", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", @@ -9772,102 +10196,10 @@ "license": "BSD-2-Clause", "dependencies": { "@typescript-eslint/scope-manager": "7.16.1", - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/typescript-estree": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.16.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", - "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.16.1", - "@typescript-eslint/visitor-keys": "7.16.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", - "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.11.0", - "@typescript-eslint/utils": "7.11.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", - "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", - "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.11.0", - "@typescript-eslint/visitor-keys": "7.11.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/typescript-estree": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1", + "debug": "^4.3.4" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -9876,21 +10208,24 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.56.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", - "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.16.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.16.1.tgz", + "integrity": "sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.11.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "7.16.1", + "@typescript-eslint/visitor-keys": "7.16.1" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -9949,6 +10284,7 @@ "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "7.11.0", @@ -9972,6 +10308,7 @@ "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "7.11.0", "@typescript-eslint/visitor-keys": "7.11.0" @@ -9990,6 +10327,7 @@ "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": "^18.18.0 || >=20.0.0" }, @@ -10004,6 +10342,7 @@ "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", "dev": true, "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/types": "7.11.0", "@typescript-eslint/visitor-keys": "7.11.0", @@ -10033,6 +10372,7 @@ "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "7.11.0", "eslint-visitor-keys": "^3.4.3" @@ -10525,19 +10865,6 @@ "node": ">=10" } }, - "node_modules/@yao-pkg/pkg/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/@yarnpkg/lockfile": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", @@ -11201,6 +11528,7 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "sprintf-js": "~1.0.2" } @@ -11549,13 +11877,12 @@ } }, "node_modules/axobject-query": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", - "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" + "engines": { + "node": ">= 0.4" } }, "node_modules/babel-jest": { @@ -11605,6 +11932,7 @@ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -11659,61 +11987,25 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0", - "core-js-compat": "^3.34.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-corejs3/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.10.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", + "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "@babel/helper-define-polyfill-provider": "^0.6.2", + "core-js-compat": "^3.38.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.5.0" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" - } - }, - "node_modules/babel-plugin-polyfill-regenerator/node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -12640,6 +12932,7 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -13877,11 +14170,11 @@ "license": "MIT" }, "node_modules/critters": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.22.tgz", - "integrity": "sha512-NU7DEcQZM2Dy8XTKFHxtdnIM/drE312j2T4PCVaSUcS0oBeyT/NImpRw/Ap0zOr/1SE7SgPK9tGPg1WK/sVakw==", + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz", + "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==", + "deprecated": "Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties", "dev": true, - "license": "Apache-2.0", "dependencies": { "chalk": "^4.1.0", "css-select": "^5.1.0", @@ -13892,26 +14185,6 @@ "postcss-media-query-parser": "^0.2.3" } }, - "node_modules/critters/node_modules/htmlparser2": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1", - "entities": "^4.4.0" - } - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -15454,42 +15727,42 @@ "license": "MIT" }, "node_modules/esbuild": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", - "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz", + "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.1", - "@esbuild/android-arm": "0.20.1", - "@esbuild/android-arm64": "0.20.1", - "@esbuild/android-x64": "0.20.1", - "@esbuild/darwin-arm64": "0.20.1", - "@esbuild/darwin-x64": "0.20.1", - "@esbuild/freebsd-arm64": "0.20.1", - "@esbuild/freebsd-x64": "0.20.1", - "@esbuild/linux-arm": "0.20.1", - "@esbuild/linux-arm64": "0.20.1", - "@esbuild/linux-ia32": "0.20.1", - "@esbuild/linux-loong64": "0.20.1", - "@esbuild/linux-mips64el": "0.20.1", - "@esbuild/linux-ppc64": "0.20.1", - "@esbuild/linux-riscv64": "0.20.1", - "@esbuild/linux-s390x": "0.20.1", - "@esbuild/linux-x64": "0.20.1", - "@esbuild/netbsd-x64": "0.20.1", - "@esbuild/openbsd-x64": "0.20.1", - "@esbuild/sunos-x64": "0.20.1", - "@esbuild/win32-arm64": "0.20.1", - "@esbuild/win32-ia32": "0.20.1", - "@esbuild/win32-x64": "0.20.1" + "@esbuild/aix-ppc64": "0.23.0", + "@esbuild/android-arm": "0.23.0", + "@esbuild/android-arm64": "0.23.0", + "@esbuild/android-x64": "0.23.0", + "@esbuild/darwin-arm64": "0.23.0", + "@esbuild/darwin-x64": "0.23.0", + "@esbuild/freebsd-arm64": "0.23.0", + "@esbuild/freebsd-x64": "0.23.0", + "@esbuild/linux-arm": "0.23.0", + "@esbuild/linux-arm64": "0.23.0", + "@esbuild/linux-ia32": "0.23.0", + "@esbuild/linux-loong64": "0.23.0", + "@esbuild/linux-mips64el": "0.23.0", + "@esbuild/linux-ppc64": "0.23.0", + "@esbuild/linux-riscv64": "0.23.0", + "@esbuild/linux-s390x": "0.23.0", + "@esbuild/linux-x64": "0.23.0", + "@esbuild/netbsd-x64": "0.23.0", + "@esbuild/openbsd-arm64": "0.23.0", + "@esbuild/openbsd-x64": "0.23.0", + "@esbuild/sunos-x64": "0.23.0", + "@esbuild/win32-arm64": "0.23.0", + "@esbuild/win32-ia32": "0.23.0", + "@esbuild/win32-x64": "0.23.0" } }, "node_modules/esbuild-register": { @@ -15506,16 +15779,15 @@ } }, "node_modules/esbuild-wasm": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.20.1.tgz", - "integrity": "sha512-6v/WJubRsjxBbQdz6izgvx7LsVFvVaGmSdwrFHmEzoVgfXL89hkKPoQHsnVI2ngOkcBUQT9kmAM1hVL1k/Av4A==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.23.0.tgz", + "integrity": "sha512-6jP8UmWy6R6TUUV8bMuC3ZyZ6lZKI56x0tkxyCIqWwRRJ/DgeQKneh/Oid5EoGoPFLrGNkz47ZEtWAYuiY/u9g==", "dev": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/escalade": { @@ -17595,6 +17867,7 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8.0.0" } @@ -18200,6 +18473,25 @@ "node": ">=12" } }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/http-assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", @@ -18570,7 +18862,6 @@ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", "dev": true, - "license": "ISC", "dependencies": { "minimatch": "^9.0.0" }, @@ -18602,8 +18893,7 @@ "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/import-fresh": { "version": "3.3.0", @@ -18775,11 +19065,10 @@ "license": "ISC" }, "node_modules/ini": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.2.tgz", - "integrity": "sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -19255,6 +19544,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -19456,6 +19754,7 @@ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", @@ -19473,6 +19772,7 @@ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", + "peer": true, "bin": { "semver": "bin/semver.js" } @@ -20298,6 +20598,16 @@ "fsevents": "^2.3.2" } }, + "node_modules/jest-haste-map/node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "peer": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, "node_modules/jest-junit": { "version": "16.0.0", "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-16.0.0.tgz", @@ -21078,6 +21388,7 @@ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -21205,7 +21516,6 @@ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", "dev": true, - "license": "MIT", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -21268,11 +21578,10 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true, - "license": "MIT" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true }, "node_modules/jsonfile": { "version": "6.1.0", @@ -21302,8 +21611,7 @@ "dev": true, "engines": [ "node >= 0.2.0" - ], - "license": "MIT" + ] }, "node_modules/jsqr": { "version": "1.4.0", @@ -21422,16 +21730,6 @@ "node": ">=6" } }, - "node_modules/klona": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", - "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/koa": { "version": "2.15.3", "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", @@ -21662,24 +21960,29 @@ } }, "node_modules/less-loader": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-11.1.0.tgz", - "integrity": "sha512-C+uDBV7kS7W5fJlUjq5mPBeBVhYpTIm5gB09APT9o3n/ILeaXVsiSFTbZpTJCJwQ/Crczfn3DmfQFwxYusWFug==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", "dev": true, - "license": "MIT", - "dependencies": { - "klona": "^2.0.4" - }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, "peerDependencies": { + "@rspack/core": "0.x || 1.x", "less": "^3.5.0 || ^4.0.0", "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, "node_modules/less/node_modules/make-dir": { @@ -22189,6 +22492,37 @@ "@types/trusted-types": "^2.0.2" } }, + "node_modules/lmdb": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.0.13.tgz", + "integrity": "sha512-UGe+BbaSUQtAMZobTb4nHvFMrmvuAQKSeaqAX2meTEQjfsbpl5sxdHD8T72OnwD4GU9uwNhYXIVe4QGs8N9Zyw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "msgpackr": "^1.10.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.4.1", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.0.13", + "@lmdb/lmdb-darwin-x64": "3.0.13", + "@lmdb/lmdb-linux-arm": "3.0.13", + "@lmdb/lmdb-linux-arm64": "3.0.13", + "@lmdb/lmdb-linux-x64": "3.0.13", + "@lmdb/lmdb-win32-x64": "3.0.13" + } + }, + "node_modules/lmdb/node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -22200,11 +22534,10 @@ } }, "node_modules/loader-utils": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 12.13.0" } @@ -22652,16 +22985,12 @@ } }, "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -23823,8 +24152,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/minimatch": { "version": "9.0.5", @@ -23965,37 +24293,6 @@ "dev": true, "license": "ISC" }, - "node_modules/minipass-json-stream": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz", - "integrity": "sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-json-stream/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", @@ -24183,12 +24480,43 @@ "node": ">=10" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz", + "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==", + "dev": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, "node_modules/multer": { "version": "1.4.5-lts.1", "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz", @@ -24354,16 +24682,15 @@ } }, "node_modules/ngx-infinite-scroll": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-17.0.1.tgz", - "integrity": "sha512-T+XseajbmT9YTMmPnFV/AfSlwjaV9m2gZtbIIZH3S+yg/rvvfbgkThqs54UWIu+pqcqNR4UhrXfw6mUjCVZD2A==", - "license": "MIT", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-18.0.0.tgz", + "integrity": "sha512-D183TDwpsd9Zl56UmItsl3RzHdN25srAISfg6lc3A8mEKkEgOq0s7ZzRAYcx8DHsAkMgtZqjIPEvMifD3DOB/g==", "dependencies": { "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/common": ">=17.0.0 <18.0.0", - "@angular/core": ">=17.0.0 <18.0.0" + "@angular/common": ">=18.0.0 <19.0.0", + "@angular/core": ">=18.0.0 <19.0.0" } }, "node_modules/ngx-toastr": { @@ -24386,7 +24713,6 @@ "integrity": "sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==", "dev": true, "hasInstallScript": true, - "license": "MIT", "optional": true, "os": [ "!win32" @@ -24401,7 +24727,6 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "dev": true, - "license": "MIT", "optional": true }, "node_modules/no-case": { @@ -24510,7 +24835,6 @@ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", "dev": true, - "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", @@ -24541,12 +24865,25 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/node-gyp/node_modules/@npmcli/fs": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -24559,7 +24896,6 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -24569,7 +24905,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -24593,7 +24928,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -24606,7 +24940,6 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "license": "ISC", "engines": { "node": ">=16" } @@ -24615,15 +24948,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/node-gyp/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -24647,7 +24978,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -24660,7 +24990,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -24678,7 +25007,6 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", "dev": true, - "license": "ISC", "dependencies": { "abbrev": "^2.0.0" }, @@ -24694,7 +25022,6 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -24704,7 +25031,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -24717,7 +25043,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -24730,7 +25055,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -24743,7 +25067,6 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, - "license": "ISC", "dependencies": { "isexe": "^3.1.1" }, @@ -24810,7 +25133,6 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", @@ -24825,7 +25147,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -24837,8 +25158,7 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -24878,7 +25198,6 @@ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", "dev": true, - "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^3.0.0" }, @@ -24891,7 +25210,6 @@ "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, @@ -24904,20 +25222,18 @@ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm-package-arg": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", - "integrity": "sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", "dev": true, - "license": "ISC", "dependencies": { "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", + "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" }, @@ -24930,7 +25246,6 @@ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", "dev": true, - "license": "ISC", "dependencies": { "lru-cache": "^10.0.1" }, @@ -24942,15 +25257,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/npm-package-arg/node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -24960,7 +25273,6 @@ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", "dev": true, - "license": "ISC", "dependencies": { "ignore-walk": "^6.0.4" }, @@ -24969,11 +25281,10 @@ } }, "node_modules/npm-pick-manifest": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz", - "integrity": "sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", "dev": true, - "license": "ISC", "dependencies": { "npm-install-checks": "^6.0.0", "npm-normalize-package-bin": "^3.0.0", @@ -24985,17 +25296,16 @@ } }, "node_modules/npm-registry-fetch": { - "version": "16.2.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-16.2.1.tgz", - "integrity": "sha512-8l+7jxhim55S85fjiDGJ1rZXBWGtRLi1OSb4Z3BPLObPuIaeKRlPRiYMSHU4/81ck3t71Z+UwDDl47gcpmfQQA==", + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", "dev": true, - "license": "ISC", "dependencies": { - "@npmcli/redact": "^1.1.0", + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", "make-fetch-happen": "^13.0.0", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", "minizlib": "^2.1.2", "npm-package-arg": "^11.0.0", "proc-log": "^4.0.0" @@ -25009,7 +25319,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -25022,7 +25331,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -25046,7 +25354,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -25058,15 +25365,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/npm-registry-fetch/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -25090,7 +25395,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -25103,7 +25407,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -25121,7 +25424,6 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -25131,7 +25433,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -25144,7 +25445,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -25157,7 +25457,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -25456,6 +25755,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ordered-binary": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.3.tgz", + "integrity": "sha512-oGFr3T+pYdTGJ+YFEILMpS3es+GiIbs9h/XQrclBXUtd44ey7XwfsMzM31f64I1SQOawDoDr/D823kNCADI8TA==", + "dev": true + }, "node_modules/os-name": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/os-name/-/os-name-4.0.1.tgz", @@ -25603,33 +25908,31 @@ "license": "BlueOak-1.0.0" }, "node_modules/pacote": { - "version": "17.0.6", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-17.0.6.tgz", - "integrity": "sha512-cJKrW21VRE8vVTRskJo78c/RCvwJCn1f4qgfxL4w77SOWrTCRcmfkYHlHtS0gqpgjv3zhXflRtgsrUCX5xwNnQ==", + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", + "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/git": "^5.0.0", "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", + "@npmcli/run-script": "^8.0.0", "cacache": "^18.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^11.0.0", "npm-packlist": "^8.0.0", "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", "sigstore": "^2.2.0", "ssri": "^10.0.0", "tar": "^6.1.11" }, "bin": { - "pacote": "lib/bin.js" + "pacote": "bin/index.js" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -25640,7 +25943,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -25653,7 +25955,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -25677,7 +25978,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -25689,15 +25989,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/pacote/node_modules/minipass-collect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -25706,11 +26004,10 @@ } }, "node_modules/pacote/node_modules/proc-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", - "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -25720,7 +26017,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -25733,7 +26029,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -25746,7 +26041,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -26157,11 +26451,10 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", - "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -26202,11 +26495,10 @@ } }, "node_modules/piscina": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.4.0.tgz", - "integrity": "sha512-+AQduEJefrOApE4bV7KRmp3N2JnnyErlVqq4P/jmko4FPz9Z877BCccl/iB3FdrWSUkvbGV9Kan/KllJgat3Vg==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.6.1.tgz", + "integrity": "sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==", "dev": true, - "license": "MIT", "optionalDependencies": { "nice-napi": "^1.0.2" } @@ -26582,8 +26874,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", @@ -27318,37 +27609,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/read-package-json": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-7.0.1.tgz", - "integrity": "sha512-8PcDiZ8DXUjLf687Ol4BR8Bpm2umR7vhoZOzNRt+uxD9GpBh/K+CAAALVIiYFknmvlmyg7hM7BSNUXPaCCqd0Q==", - "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/read-package-json-fast": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", - "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", - "dev": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -28947,7 +29207,6 @@ "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.0.0", @@ -29183,7 +29442,6 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -29193,15 +29451,13 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" + "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -29211,8 +29467,7 @@ "version": "3.0.20", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", - "dev": true, - "license": "CC0-1.0" + "dev": true }, "node_modules/spdy": { "version": "4.0.2", @@ -29264,7 +29519,8 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/ssri": { "version": "9.0.1", @@ -29975,11 +30231,10 @@ } }, "node_modules/terser": { - "version": "5.29.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", - "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -30125,6 +30380,7 @@ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -30140,6 +30396,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -30152,6 +30409,7 @@ "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -30173,6 +30431,7 @@ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -30264,19 +30523,6 @@ "node": ">=12.0.0" } }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/tinyrainbow": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", @@ -30652,10 +30898,9 @@ } }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "license": "0BSD" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/tsscmp": { "version": "1.0.6", @@ -30713,7 +30958,6 @@ "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", "dev": true, - "license": "MIT", "dependencies": { "@tufjs/models": "2.0.1", "debug": "^4.3.4", @@ -30728,7 +30972,6 @@ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", "dev": true, - "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -30741,7 +30984,6 @@ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/fs": "^3.1.0", "fs-minipass": "^3.0.0", @@ -30765,7 +31007,6 @@ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -30777,15 +31018,13 @@ "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/tuf-js/node_modules/make-fetch-happen": { "version": "13.0.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", "dev": true, - "license": "ISC", "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", @@ -30809,7 +31048,6 @@ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -30822,7 +31060,6 @@ "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, - "license": "MIT", "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", @@ -30840,7 +31077,6 @@ "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -30850,7 +31086,6 @@ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, - "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -30863,7 +31098,6 @@ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", "dev": true, - "license": "ISC", "dependencies": { "unique-slug": "^4.0.0" }, @@ -30876,7 +31110,6 @@ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", "dev": true, - "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4" }, @@ -31202,16 +31435,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/undici": { - "version": "6.11.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.11.1.tgz", - "integrity": "sha512-KyhzaLJnV1qa3BSHdj4AZ2ndqI0QWPxYzaIOio0WzcEJB9gvuysprJSLtpvc2D9mhR9jPDUk7xlJlZbH2KR5iw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0" - } - }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -31604,7 +31827,6 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "license": "Apache-2.0", "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -31615,7 +31837,6 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", "dev": true, - "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } @@ -31691,15 +31912,14 @@ } }, "node_modules/vite": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.8.tgz", - "integrity": "sha512-mB8ToUuSmzODSpENgvpFk2fTiU/YQ1tmcVJJ4WZbq4fPdGJkFNVcmVL5k7iDug6xzWjjuGDKAuSievIsD6H7Xw==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", + "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, - "license": "MIT", "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -31718,6 +31938,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -31735,6 +31956,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -31747,14 +31971,13 @@ } }, "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", - "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, - "license": "MIT", "optional": true, "os": [ "darwin" @@ -31764,12 +31987,11 @@ } }, "node_modules/vite/node_modules/esbuild": { - "version": "0.19.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", - "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, - "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -31777,29 +31999,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.12", - "@esbuild/android-arm": "0.19.12", - "@esbuild/android-arm64": "0.19.12", - "@esbuild/android-x64": "0.19.12", - "@esbuild/darwin-arm64": "0.19.12", - "@esbuild/darwin-x64": "0.19.12", - "@esbuild/freebsd-arm64": "0.19.12", - "@esbuild/freebsd-x64": "0.19.12", - "@esbuild/linux-arm": "0.19.12", - "@esbuild/linux-arm64": "0.19.12", - "@esbuild/linux-ia32": "0.19.12", - "@esbuild/linux-loong64": "0.19.12", - "@esbuild/linux-mips64el": "0.19.12", - "@esbuild/linux-ppc64": "0.19.12", - "@esbuild/linux-riscv64": "0.19.12", - "@esbuild/linux-s390x": "0.19.12", - "@esbuild/linux-x64": "0.19.12", - "@esbuild/netbsd-x64": "0.19.12", - "@esbuild/openbsd-x64": "0.19.12", - "@esbuild/sunos-x64": "0.19.12", - "@esbuild/win32-arm64": "0.19.12", - "@esbuild/win32-ia32": "0.19.12", - "@esbuild/win32-x64": "0.19.12" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/w3c-xmlserializer": { @@ -31841,23 +32063,11 @@ "dev": true, "license": "ISC" }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, - "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -31871,7 +32081,6 @@ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, - "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } @@ -31880,16 +32089,20 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -31899,7 +32112,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -31946,7 +32158,6 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", "dev": true, - "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "^0.6.1", "@webpack-cli/configtest": "^3.0.1", @@ -31999,32 +32210,15 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } }, - "node_modules/webpack-cli/node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/webpack-dev-middleware": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz", - "integrity": "sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz", + "integrity": "sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==", "dev": true, - "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.12", @@ -32053,7 +32247,6 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.0.tgz", "integrity": "sha512-90SqqYXA2SK36KcT6o1bvwvZfJFcmoamqeJY7+boioffX9g9C0wjjJRGUrQIuh43pb0ttX7+ssavmj/WN2RHtA==", "dev": true, - "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -32110,7 +32303,6 @@ "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" }, @@ -32123,7 +32315,6 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", "dev": true, - "license": "MIT", "engines": { "node": ">= 10" } @@ -32133,7 +32324,6 @@ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, - "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" }, @@ -32145,11 +32335,10 @@ } }, "node_modules/webpack-dev-server/node_modules/memfs": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.0.tgz", - "integrity": "sha512-q9MmZXd2rRWHS6GU3WEm3HyiXZyyoA1DqdOhEq0lxPBmKb5S7IAOwX0RgUCwJfqjelDCySa5h8ujOy24LqsWcw==", + "version": "4.15.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.3.tgz", + "integrity": "sha512-vR/g1SgqvKJgAyYla+06G4p/EOcEmwhYuVb1yc1ixcKf8o/sh7Zngv63957ZSNd1xrZJoinmNyDf2LzuP8WJXw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/json-pack": "^1.0.3", "@jsonjoy.com/util": "^1.3.0", @@ -32226,18 +32415,17 @@ } }, "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "dev": true, - "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", - "wildcard": "^2.0.0" + "wildcard": "^2.0.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, "node_modules/webpack-node-externals": { @@ -32294,7 +32482,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -32311,7 +32498,6 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, - "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } @@ -32368,7 +32554,6 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -32384,8 +32569,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", @@ -32826,6 +33010,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zip-stream": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", diff --git a/package.json b/package.json index 843e9f34bb6..9922b6d7bac 100644 --- a/package.json +++ b/package.json @@ -35,20 +35,20 @@ "libs/*" ], "devDependencies": { - "@angular-devkit/build-angular": "17.3.11", - "@angular-eslint/eslint-plugin": "17.5.3", - "@angular-eslint/eslint-plugin-template": "17.5.3", - "@angular-eslint/schematics": "17.5.3", - "@angular-eslint/template-parser": "17.5.3", - "@angular/cli": "17.3.11", - "@angular/compiler-cli": "17.3.12", - "@angular/elements": "17.3.12", + "@angular-devkit/build-angular": "18.2.12", + "@angular-eslint/eslint-plugin": "18.4.3", + "@angular-eslint/eslint-plugin-template": "18.4.3", + "@angular-eslint/schematics": "18.4.3", + "@angular-eslint/template-parser": "18.4.3", + "@angular/cli": "18.2.12", + "@angular/compiler-cli": "18.2.13", + "@angular/elements": "18.2.13", "@babel/core": "7.24.9", "@babel/preset-env": "7.24.8", "@compodoc/compodoc": "1.1.26", "@electron/notarize": "2.5.0", "@electron/rebuild": "3.7.1", - "@ngtools/webpack": "17.3.11", + "@ngtools/webpack": "18.2.12", "@storybook/addon-a11y": "8.4.7", "@storybook/addon-actions": "8.4.7", "@storybook/addon-designs": "8.0.4", @@ -145,22 +145,22 @@ "webpack-node-externals": "3.0.0" }, "dependencies": { - "@angular/animations": "17.3.12", - "@angular/cdk": "17.3.10", - "@angular/common": "17.3.12", - "@angular/compiler": "17.3.12", - "@angular/core": "17.3.12", - "@angular/forms": "17.3.12", - "@angular/platform-browser": "17.3.12", - "@angular/platform-browser-dynamic": "17.3.12", - "@angular/router": "17.3.12", + "@angular/animations": "18.2.13", + "@angular/cdk": "18.2.14", + "@angular/common": "18.2.13", + "@angular/compiler": "18.2.13", + "@angular/core": "18.2.13", + "@angular/forms": "18.2.13", + "@angular/platform-browser": "18.2.13", + "@angular/platform-browser-dynamic": "18.2.13", + "@angular/router": "18.2.13", "@bitwarden/sdk-internal": "0.2.0-main.38", "@electron/fuses": "1.8.0", "@koa/multer": "3.0.2", "@koa/router": "13.1.0", "@microsoft/signalr": "8.0.7", "@microsoft/signalr-protocol-msgpack": "8.0.7", - "@ng-select/ng-select": "12.0.7", + "@ng-select/ng-select": "13.9.1", "argon2": "0.41.1", "argon2-browser": "1.18.0", "big-integer": "1.6.52", @@ -183,7 +183,7 @@ "lowdb": "1.0.0", "lunr": "2.3.9", "multer": "1.4.5-lts.1", - "ngx-infinite-scroll": "17.0.1", + "ngx-infinite-scroll": "18.0.0", "ngx-toastr": "19.0.0", "node-fetch": "2.6.12", "node-forge": "1.3.1", From 26f086368b23f57925ecad244d659b5aa0f760dd Mon Sep 17 00:00:00 2001 From: Alec Rippberger <127791530+alec-livefront@users.noreply.github.com> Date: Mon, 6 Jan 2025 13:01:56 -0600 Subject: [PATCH 55/65] fix(auth): [PM-15987] improve email/master password entry back/forward navigation - Fix back button behavior in Safari to reliably return to email entry screen - Enable browser forward button after navigating back to email entry - Move email validation to input event instead of blur - Add continueClicked function to differentiate user clicks vs browser navigation - Add email verification gate to SSO route - Enhance master password validation logic - Fix strict typing errors Resolves PM-15987 --- .../src/angular/login/login.component.html | 37 +---- .../auth/src/angular/login/login.component.ts | 140 ++++++++++++------ 2 files changed, 102 insertions(+), 75 deletions(-) diff --git a/libs/auth/src/angular/login/login.component.html b/libs/auth/src/angular/login/login.component.html index 54a04d3de6c..c7837db74f2 100644 --- a/libs/auth/src/angular/login/login.component.html +++ b/libs/auth/src/angular/login/login.component.html @@ -20,8 +20,8 @@ formControlName="email" bitInput appAutofocus - (blur)="onEmailBlur($event)" - (keyup.enter)="continue()" + (input)="onEmailInput($event)" + (keyup.enter)="continuePressed()" /> @@ -33,7 +33,7 @@
- @@ -54,33 +54,10 @@ - - - - {{ "useSingleSignOn" | i18n }} - - - - - +

diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index 33c167dcaed..40f85e6d75c 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { CommonModule } from "@angular/common"; import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from "@angular/core"; import { FormBuilder, FormControl, ReactiveFormsModule, Validators } from "@angular/forms"; @@ -12,7 +10,6 @@ import { LoginStrategyServiceAbstraction, LoginSuccessHandlerService, PasswordLoginCredentials, - RegisterRouteService, } from "@bitwarden/auth/common"; import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; @@ -72,16 +69,15 @@ export enum LoginUiState { ], }) export class LoginComponent implements OnInit, OnDestroy { - @ViewChild("masterPasswordInputRef") masterPasswordInputRef: ElementRef; + @ViewChild("masterPasswordInputRef") masterPasswordInputRef: ElementRef | undefined; private destroy$ = new Subject(); - private enforcedMasterPasswordOptions: MasterPasswordPolicyOptions = undefined; + private enforcedMasterPasswordOptions: MasterPasswordPolicyOptions | undefined = undefined; readonly Icons = { WaveIcon, VaultIcon }; clientType: ClientType; ClientType = ClientType; LoginUiState = LoginUiState; - registerRoute$ = this.registerRouteService.registerRoute$(); // TODO: remove when email verification flag is removed isKnownDevice = false; loginUiState: LoginUiState = LoginUiState.EMAIL_ENTRY; @@ -97,13 +93,13 @@ export class LoginComponent implements OnInit, OnDestroy { { updateOn: "submit" }, ); - get emailFormControl(): FormControl { + get emailFormControl(): FormControl { return this.formGroup.controls.email; } // Web properties - enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions; - policies: Policy[]; + enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions | undefined; + policies: Policy[] | undefined; showResetPasswordAutoEnrollWarning = false; // Desktop properties @@ -125,7 +121,6 @@ export class LoginComponent implements OnInit, OnDestroy { private passwordStrengthService: PasswordStrengthServiceAbstraction, private platformUtilsService: PlatformUtilsService, private policyService: InternalPolicyService, - private registerRouteService: RegisterRouteService, private router: Router, private toastService: ToastService, private logService: LogService, @@ -200,12 +195,12 @@ export class LoginComponent implements OnInit, OnDestroy { return; } - const credentials = new PasswordLoginCredentials( - email, - masterPassword, - null, // captcha no longer used in new login / registration scenarios - null, - ); + if (!email || !masterPassword) { + this.logService.error("Email and master password are required"); + return; + } + + const credentials = new PasswordLoginCredentials(email, masterPassword); try { const authResult = await this.loginStrategyService.logIn(credentials); @@ -301,7 +296,12 @@ export class LoginComponent implements OnInit, OnDestroy { } protected async launchSsoBrowserWindow(clientId: "browser" | "desktop"): Promise { - await this.loginComponentService.launchSsoBrowserWindow(this.emailFormControl.value, clientId); + const email = this.emailFormControl.value; + if (!email) { + this.logService.error("Email is required for SSO login"); + return; + } + await this.loginComponentService.launchSsoBrowserWindow(email, clientId); } protected async evaluatePassword(): Promise { @@ -337,9 +337,14 @@ export class LoginComponent implements OnInit, OnDestroy { const masterPassword = this.formGroup.controls.masterPassword.value; + // Return false if masterPassword is null/undefined since this is only evaluated after successful login + if (!masterPassword) { + return false; + } + const passwordStrength = this.passwordStrengthService.getPasswordStrength( masterPassword, - this.formGroup.value.email, + this.formGroup.value.email ?? undefined, )?.score; return !this.policyService.evaluateMasterPassword( @@ -363,6 +368,7 @@ export class LoginComponent implements OnInit, OnDestroy { protected async validateEmail(): Promise { this.formGroup.controls.email.markAsTouched(); + this.formGroup.controls.email.updateValueAndValidity({ onlySelf: true, emitEvent: true }); return this.formGroup.controls.email.valid; } @@ -404,7 +410,10 @@ export class LoginComponent implements OnInit, OnDestroy { } // Check to see if the device is known so we can show the Login with Device option - await this.getKnownDevice(this.emailFormControl.value); + const email = this.emailFormControl.value; + if (email) { + await this.getKnownDevice(email); + } } } @@ -412,11 +421,10 @@ export class LoginComponent implements OnInit, OnDestroy { * Set the email value from the input field. * @param event The event object from the input field. */ - onEmailBlur(event: Event) { + onEmailInput(event: Event) { const emailInput = event.target as HTMLInputElement; this.formGroup.controls.email.setValue(emailInput.value); - // Call setLoginEmail so that the email is pre-populated when navigating to the "enter password" screen. - this.loginEmailService.setLoginEmail(this.formGroup.value.email); + this.loginEmailService.setLoginEmail(emailInput.value); } isLoginWithPasskeySupported() { @@ -428,28 +436,36 @@ export class LoginComponent implements OnInit, OnDestroy { await this.router.navigateByUrl("/hint"); } - protected async goToRegister(): Promise { - // TODO: remove when email verification flag is removed - const registerRoute = await firstValueFrom(this.registerRoute$); - - if (this.emailFormControl.valid) { - await this.router.navigate([registerRoute], { - queryParams: { email: this.emailFormControl.value }, - }); + protected async saveEmailSettings(): Promise { + const email = this.formGroup.value.email; + if (!email) { + this.logService.error("Email is required to save email settings."); return; } - await this.router.navigate([registerRoute]); + await this.loginEmailService.setLoginEmail(email); + this.loginEmailService.setRememberEmail(this.formGroup.value.rememberEmail ?? false); + await this.loginEmailService.saveEmailSettings(); } - protected async saveEmailSettings(): Promise { - await this.loginEmailService.setLoginEmail(this.formGroup.value.email); - this.loginEmailService.setRememberEmail(this.formGroup.value.rememberEmail); - await this.loginEmailService.saveEmailSettings(); + /** + * Continue button clicked (or enter key pressed). + * Adds the login url to the browser's history so that the back button can be used to go back to the email entry state. + * Needs to be separate from the continue() function because that can be triggered by the browser's forward button. + */ + protected async continuePressed() { + // Add a new entry to the browser's history so that there is a history entry to go back to + history.pushState({}, "", window.location.href); + await this.continue(); } + /** + * Continue to the master password entry state (only if email is validated) + */ protected async continue(): Promise { - if (await this.validateEmail()) { + const isEmailValid = await this.validateEmail(); + + if (isEmailValid) { await this.toggleLoginUiState(LoginUiState.MASTER_PASSWORD_ENTRY); } } @@ -460,6 +476,11 @@ export class LoginComponent implements OnInit, OnDestroy { * @param email - The user's email */ private async getKnownDevice(email: string): Promise { + if (!email) { + this.isKnownDevice = false; + return; + } + try { const deviceIdentifier = await this.appIdService.getAppId(); this.isKnownDevice = await this.devicesApiService.getKnownDevice(email, deviceIdentifier); @@ -503,7 +524,7 @@ export class LoginComponent implements OnInit, OnDestroy { const orgPolicies = await this.loginComponentService.getOrgPolicies(); this.policies = orgPolicies?.policies; - this.showResetPasswordAutoEnrollWarning = orgPolicies?.isPolicyAndAutoEnrollEnabled; + this.showResetPasswordAutoEnrollWarning = orgPolicies?.isPolicyAndAutoEnrollEnabled ?? false; let paramEmailIsSet = false; @@ -525,7 +546,9 @@ export class LoginComponent implements OnInit, OnDestroy { } // Check to see if the device is known so that we can show the Login with Device option - await this.getKnownDevice(this.emailFormControl.value); + if (this.emailFormControl.value) { + await this.getKnownDevice(this.emailFormControl.value); + } // Backup check to handle unknown case where activatedRoute is not available // This shouldn't happen under normal circumstances @@ -573,23 +596,50 @@ export class LoginComponent implements OnInit, OnDestroy { * Handle the back button click to transition back to the email entry state. */ protected async backButtonClicked() { - // Replace the history so the "forward" button doesn't show (which wouldn't do anything) - history.pushState(null, "", window.location.pathname); - await this.toggleLoginUiState(LoginUiState.EMAIL_ENTRY); + history.back(); } /** * Handle the popstate event to transition back to the email entry state when the back button is clicked. + * Also handles the case where the user clicks the forward button. * @param event - The popstate event. */ - private handlePopState = (event: PopStateEvent) => { + private handlePopState = async (event: PopStateEvent) => { if (this.loginUiState === LoginUiState.MASTER_PASSWORD_ENTRY) { - // Prevent default navigation + // Prevent default navigation when the browser's back button is clicked event.preventDefault(); - // Replace the history so the "forward" button doesn't show (which wouldn't do anything) - history.pushState(null, "", window.location.pathname); // Transition back to email entry state void this.toggleLoginUiState(LoginUiState.EMAIL_ENTRY); + } else if (this.loginUiState === LoginUiState.EMAIL_ENTRY) { + // Prevent default navigation when the browser's forward button is clicked + event.preventDefault(); + // Continue to the master password entry state + await this.continue(); } }; + + /** + * Handle the SSO button click. + * @param event - The event object. + */ + async handleSsoClick() { + const isEmailValid = await this.validateEmail(); + + if (!isEmailValid) { + return; + } + + await this.saveEmailSettings(); + + if (this.clientType === ClientType.Web) { + await this.router.navigate(["/sso"], { + queryParams: { email: this.formGroup.value.email }, + }); + return; + } + + await this.launchSsoBrowserWindow( + this.clientType === ClientType.Browser ? "browser" : "desktop", + ); + } } From 6aa5b1b953f30fd3dc54bfd424f5558ea15f7dc9 Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Mon, 6 Jan 2025 21:14:16 +0100 Subject: [PATCH 56/65] [PM-7105][PM-7242][PM-16256] Remove v1 code for Tab/Vault Part 2 (#12516) * Remove v1 code for Tab/Vault Part 2 * Removal conditional for assign-collections --------- Co-authored-by: Daniel James Smith --- apps/browser/src/popup/app-routing.module.ts | 89 +- apps/browser/src/popup/app.module.ts | 38 - .../vault/guards/clear-vault-state.guard.ts | 2 +- .../components/action-buttons.component.html | 102 --- .../components/action-buttons.component.ts | 108 --- .../components/cipher-row.component.html | 51 -- .../popup/components/cipher-row.component.ts | 31 - .../vault-v2.component.html | 0 .../{vault => vault-v2}/vault-v2.component.ts | 8 +- .../add-edit-custom-fields.component.html | 140 --- .../vault/add-edit-custom-fields.component.ts | 15 - .../components/vault/add-edit.component.html | 826 ------------------ .../components/vault/add-edit.component.ts | 417 --------- .../vault/attachments.component.html | 72 -- .../components/vault/attachments.component.ts | 82 -- .../vault/collections.component.html | 43 - .../components/vault/collections.component.ts | 61 -- .../vault/current-tab.component.html | 95 -- .../components/vault/current-tab.component.ts | 354 -------- .../vault/password-history.component.html | 40 - .../vault/password-history.component.ts | 44 - .../components/vault/share.component.html | 77 -- .../popup/components/vault/share.component.ts | 72 -- .../vault/vault-filter.component.html | 238 ----- .../vault/vault-filter.component.ts | 482 ---------- .../vault/vault-items.component.html | 123 --- .../components/vault/vault-items.component.ts | 316 ------- .../vault/vault-select.component.html | 82 -- .../vault/vault-select.component.ts | 227 ----- .../vault/view-custom-fields.component.html | 98 --- .../vault/view-custom-fields.component.ts | 14 - .../components/vault/view.component.html | 719 --------------- .../popup/components/vault/view.component.ts | 443 ---------- .../popup/settings/appearance.component.html | 80 -- .../popup/settings/appearance.component.ts | 75 -- .../settings/folder-add-edit.component.html | 49 -- .../settings/folder-add-edit.component.ts | 78 -- .../popup/settings/folders.component.html | 38 - .../vault/popup/settings/folders.component.ts | 48 - .../vault/popup/settings/sync.component.html | 35 - .../vault/popup/settings/sync.component.ts | 46 - .../settings/vault-settings.component.html | 56 -- .../settings/vault-settings.component.ts | 25 - 43 files changed, 31 insertions(+), 6008 deletions(-) delete mode 100644 apps/browser/src/vault/popup/components/action-buttons.component.html delete mode 100644 apps/browser/src/vault/popup/components/action-buttons.component.ts delete mode 100644 apps/browser/src/vault/popup/components/cipher-row.component.html delete mode 100644 apps/browser/src/vault/popup/components/cipher-row.component.ts rename apps/browser/src/vault/popup/components/{vault => vault-v2}/vault-v2.component.html (100%) rename apps/browser/src/vault/popup/components/{vault => vault-v2}/vault-v2.component.ts (95%) delete mode 100644 apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/add-edit.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/add-edit.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/attachments.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/attachments.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/collections.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/collections.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/current-tab.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/current-tab.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/password-history.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/password-history.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/share.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/share.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/vault-filter.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/vault-filter.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/vault-items.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/vault-items.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/vault-select.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/vault-select.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/view-custom-fields.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/view-custom-fields.component.ts delete mode 100644 apps/browser/src/vault/popup/components/vault/view.component.html delete mode 100644 apps/browser/src/vault/popup/components/vault/view.component.ts delete mode 100644 apps/browser/src/vault/popup/settings/appearance.component.html delete mode 100644 apps/browser/src/vault/popup/settings/appearance.component.ts delete mode 100644 apps/browser/src/vault/popup/settings/folder-add-edit.component.html delete mode 100644 apps/browser/src/vault/popup/settings/folder-add-edit.component.ts delete mode 100644 apps/browser/src/vault/popup/settings/folders.component.html delete mode 100644 apps/browser/src/vault/popup/settings/folders.component.ts delete mode 100644 apps/browser/src/vault/popup/settings/sync.component.html delete mode 100644 apps/browser/src/vault/popup/settings/sync.component.ts delete mode 100644 apps/browser/src/vault/popup/settings/vault-settings.component.html delete mode 100644 apps/browser/src/vault/popup/settings/vault-settings.component.ts diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 49d680cd752..161c4ca0524 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -93,28 +93,16 @@ import { ExportBrowserV2Component } from "../tools/popup/settings/export/export- import { ImportBrowserV2Component } from "../tools/popup/settings/import/import-browser-v2.component"; import { SettingsV2Component } from "../tools/popup/settings/settings-v2.component"; import { clearVaultStateGuard } from "../vault/guards/clear-vault-state.guard"; -import { AddEditComponent } from "../vault/popup/components/vault/add-edit.component"; -import { AttachmentsComponent } from "../vault/popup/components/vault/attachments.component"; -import { CollectionsComponent } from "../vault/popup/components/vault/collections.component"; -import { PasswordHistoryComponent } from "../vault/popup/components/vault/password-history.component"; -import { ShareComponent } from "../vault/popup/components/vault/share.component"; -import { VaultItemsComponent } from "../vault/popup/components/vault/vault-items.component"; -import { VaultV2Component } from "../vault/popup/components/vault/vault-v2.component"; -import { ViewComponent } from "../vault/popup/components/vault/view.component"; import { AddEditV2Component } from "../vault/popup/components/vault-v2/add-edit/add-edit-v2.component"; import { AssignCollections } from "../vault/popup/components/vault-v2/assign-collections/assign-collections.component"; import { AttachmentsV2Component } from "../vault/popup/components/vault-v2/attachments/attachments-v2.component"; import { PasswordHistoryV2Component } from "../vault/popup/components/vault-v2/vault-password-history-v2/vault-password-history-v2.component"; +import { VaultV2Component } from "../vault/popup/components/vault-v2/vault-v2.component"; import { ViewV2Component } from "../vault/popup/components/vault-v2/view-v2/view-v2.component"; import { AppearanceV2Component } from "../vault/popup/settings/appearance-v2.component"; -import { AppearanceComponent } from "../vault/popup/settings/appearance.component"; -import { FolderAddEditComponent } from "../vault/popup/settings/folder-add-edit.component"; import { FoldersV2Component } from "../vault/popup/settings/folders-v2.component"; -import { FoldersComponent } from "../vault/popup/settings/folders.component"; -import { SyncComponent } from "../vault/popup/settings/sync.component"; import { TrashComponent } from "../vault/popup/settings/trash.component"; import { VaultSettingsV2Component } from "../vault/popup/settings/vault-settings-v2.component"; -import { VaultSettingsComponent } from "../vault/popup/settings/vault-settings.component"; import { RouteElevation } from "./app-routing.animations"; import { debounceNavigationGuard } from "./services/debounce-navigation.service"; @@ -271,56 +259,43 @@ const routes: Routes = [ data: { elevation: 1 } satisfies RouteDataProperties, }, { - path: "ciphers", - component: VaultItemsComponent, - canActivate: [authGuard], - data: { elevation: 1 } satisfies RouteDataProperties, - }, - ...extensionRefreshSwap(ViewComponent, ViewV2Component, { path: "view-cipher", + component: ViewV2Component, canActivate: [authGuard], data: { // Above "trash" elevation: 3, } satisfies RouteDataProperties, - }), - ...extensionRefreshSwap(PasswordHistoryComponent, PasswordHistoryV2Component, { + }, + { path: "cipher-password-history", + component: PasswordHistoryV2Component, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, - }), - ...extensionRefreshSwap(AddEditComponent, AddEditV2Component, { + }, + { path: "add-cipher", + component: AddEditV2Component, canActivate: [authGuard, debounceNavigationGuard()], data: { elevation: 1 } satisfies RouteDataProperties, runGuardsAndResolvers: "always", - }), - ...extensionRefreshSwap(AddEditComponent, AddEditV2Component, { + }, + { path: "edit-cipher", + component: AddEditV2Component, canActivate: [authGuard, debounceNavigationGuard()], data: { // Above "trash" elevation: 3, } satisfies RouteDataProperties, runGuardsAndResolvers: "always", - }), - { - path: "share-cipher", - component: ShareComponent, - canActivate: [authGuard], - data: { elevation: 1 } satisfies RouteDataProperties, }, { - path: "collections", - component: CollectionsComponent, - canActivate: [authGuard], - data: { elevation: 1 } satisfies RouteDataProperties, - }, - ...extensionRefreshSwap(AttachmentsComponent, AttachmentsV2Component, { path: "attachments", + component: AttachmentsV2Component, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, - }), + }, { path: "generator", component: CredentialGeneratorComponent, @@ -361,33 +336,17 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, }), - ...extensionRefreshSwap(VaultSettingsComponent, VaultSettingsV2Component, { - path: "vault-settings", - canActivate: [authGuard], - data: { elevation: 1 } satisfies RouteDataProperties, - }), - ...extensionRefreshSwap(FoldersComponent, FoldersV2Component, { - path: "folders", - canActivate: [authGuard], - data: { elevation: 2 } satisfies RouteDataProperties, - }), - { - path: "add-folder", - component: FolderAddEditComponent, - canActivate: [authGuard], - data: { elevation: 1 } satisfies RouteDataProperties, - }, { - path: "edit-folder", - component: FolderAddEditComponent, + path: "vault-settings", + component: VaultSettingsV2Component, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, }, { - path: "sync", - component: SyncComponent, + path: "folders", + component: FoldersV2Component, canActivate: [authGuard], - data: { elevation: 1 } satisfies RouteDataProperties, + data: { elevation: 2 } satisfies RouteDataProperties, }, ...extensionRefreshSwap(ExcludedDomainsV1Component, ExcludedDomainsComponent, { path: "excluded-domains", @@ -400,16 +359,18 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, }, - ...extensionRefreshSwap(AppearanceComponent, AppearanceV2Component, { + { path: "appearance", + component: AppearanceV2Component, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, - }), - ...extensionRefreshSwap(AddEditComponent, AddEditV2Component, { + }, + { path: "clone-cipher", + component: AddEditV2Component, canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, - }), + }, { path: "add-send", component: SendAddEditV2Component, @@ -685,7 +646,7 @@ const routes: Routes = [ { path: "assign-collections", component: AssignCollections, - canActivate: [canAccessFeature(FeatureFlag.ExtensionRefresh, true, "/")], + canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, }, { diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index 83475a661c9..1fe8f1f18db 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -54,25 +54,6 @@ import { PopupHeaderComponent } from "../platform/popup/layout/popup-header.comp import { PopupPageComponent } from "../platform/popup/layout/popup-page.component"; import { PopupTabNavigationComponent } from "../platform/popup/layout/popup-tab-navigation.component"; import { FilePopoutCalloutComponent } from "../tools/popup/components/file-popout-callout.component"; -import { ActionButtonsComponent } from "../vault/popup/components/action-buttons.component"; -import { CipherRowComponent } from "../vault/popup/components/cipher-row.component"; -import { AddEditCustomFieldsComponent } from "../vault/popup/components/vault/add-edit-custom-fields.component"; -import { AddEditComponent } from "../vault/popup/components/vault/add-edit.component"; -import { AttachmentsComponent } from "../vault/popup/components/vault/attachments.component"; -import { CollectionsComponent } from "../vault/popup/components/vault/collections.component"; -import { CurrentTabComponent } from "../vault/popup/components/vault/current-tab.component"; -import { PasswordHistoryComponent } from "../vault/popup/components/vault/password-history.component"; -import { ShareComponent } from "../vault/popup/components/vault/share.component"; -import { VaultFilterComponent } from "../vault/popup/components/vault/vault-filter.component"; -import { VaultItemsComponent } from "../vault/popup/components/vault/vault-items.component"; -import { VaultSelectComponent } from "../vault/popup/components/vault/vault-select.component"; -import { ViewCustomFieldsComponent } from "../vault/popup/components/vault/view-custom-fields.component"; -import { ViewComponent } from "../vault/popup/components/vault/view.component"; -import { AppearanceComponent } from "../vault/popup/settings/appearance.component"; -import { FolderAddEditComponent } from "../vault/popup/settings/folder-add-edit.component"; -import { FoldersComponent } from "../vault/popup/settings/folders.component"; -import { SyncComponent } from "../vault/popup/settings/sync.component"; -import { VaultSettingsComponent } from "../vault/popup/settings/vault-settings.component"; import { AppRoutingModule } from "./app-routing.module"; import { AppComponent } from "./app.component"; @@ -127,48 +108,29 @@ import "../platform/popup/locales"; ExtensionAnonLayoutWrapperComponent, ], declarations: [ - ActionButtonsComponent, - AddEditComponent, - AddEditCustomFieldsComponent, AppComponent, - AttachmentsComponent, - CipherRowComponent, - VaultItemsComponent, - CollectionsComponent, ColorPasswordPipe, ColorPasswordCountPipe, - CurrentTabComponent, EnvironmentComponent, ExcludedDomainsV1Component, Fido2CipherRowV1Component, Fido2UseBrowserLinkV1Component, - FolderAddEditComponent, - FoldersComponent, - VaultFilterComponent, HintComponent, HomeComponent, LoginViaAuthRequestComponentV1, LoginComponentV1, LoginDecryptionOptionsComponentV1, NotificationsSettingsV1Component, - AppearanceComponent, - PasswordHistoryComponent, RegisterComponent, SetPasswordComponent, - VaultSettingsComponent, - ShareComponent, SsoComponentV1, - SyncComponent, TabsV2Component, TwoFactorComponent, TwoFactorOptionsComponent, UpdateTempPasswordComponent, UserVerificationComponent, VaultTimeoutInputComponent, - ViewComponent, - ViewCustomFieldsComponent, RemovePasswordComponent, - VaultSelectComponent, Fido2V1Component, AutofillV1Component, EnvironmentSelectorComponent, diff --git a/apps/browser/src/vault/guards/clear-vault-state.guard.ts b/apps/browser/src/vault/guards/clear-vault-state.guard.ts index 2b43f1ecbd3..b212c55d833 100644 --- a/apps/browser/src/vault/guards/clear-vault-state.guard.ts +++ b/apps/browser/src/vault/guards/clear-vault-state.guard.ts @@ -1,7 +1,7 @@ import { inject } from "@angular/core"; import { CanDeactivateFn } from "@angular/router"; -import { VaultV2Component } from "../popup/components/vault/vault-v2.component"; +import { VaultV2Component } from "../popup/components/vault-v2/vault-v2.component"; import { VaultPopupItemsService } from "../popup/services/vault-popup-items.service"; import { VaultPopupListFiltersService } from "../popup/services/vault-popup-list-filters.service"; diff --git a/apps/browser/src/vault/popup/components/action-buttons.component.html b/apps/browser/src/vault/popup/components/action-buttons.component.html deleted file mode 100644 index f63c1f1ac32..00000000000 --- a/apps/browser/src/vault/popup/components/action-buttons.component.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - diff --git a/apps/browser/src/vault/popup/components/action-buttons.component.ts b/apps/browser/src/vault/popup/components/action-buttons.component.ts deleted file mode 100644 index fd559aca817..00000000000 --- a/apps/browser/src/vault/popup/components/action-buttons.component.ts +++ /dev/null @@ -1,108 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; -import { Subject, takeUntil } from "rxjs"; - -import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { EventType } from "@bitwarden/common/enums"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/abstractions/totp.service"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; -import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { PasswordRepromptService } from "@bitwarden/vault"; - -@Component({ - selector: "app-action-buttons", - templateUrl: "action-buttons.component.html", -}) -export class ActionButtonsComponent implements OnInit, OnDestroy { - @Output() onView = new EventEmitter(); - @Output() launchEvent = new EventEmitter(); - @Input() cipher: CipherView; - @Input() showView = false; - - cipherType = CipherType; - userHasPremiumAccess = false; - - private componentIsDestroyed$ = new Subject(); - - constructor( - private i18nService: I18nService, - private platformUtilsService: PlatformUtilsService, - private eventCollectionService: EventCollectionService, - private totpService: TotpServiceAbstraction, - private passwordRepromptService: PasswordRepromptService, - private billingAccountProfileStateService: BillingAccountProfileStateService, - ) {} - - ngOnInit() { - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntil(this.componentIsDestroyed$)) - .subscribe((canAccessPremium: boolean) => { - this.userHasPremiumAccess = canAccessPremium; - }); - } - - ngOnDestroy() { - this.componentIsDestroyed$.next(true); - this.componentIsDestroyed$.complete(); - } - - launchCipher() { - this.launchEvent.emit(this.cipher); - } - - async copy(cipher: CipherView, value: string, typeI18nKey: string, aType: string) { - if ( - this.cipher.reprompt !== CipherRepromptType.None && - this.passwordRepromptService.protectedFields().includes(aType) && - !(await this.passwordRepromptService.showPasswordPrompt()) - ) { - return; - } - - if (value == null || (aType === "TOTP" && !this.displayTotpCopyButton(cipher))) { - return; - } else if (aType === "TOTP") { - value = await this.totpService.getCode(value); - } - - if (!cipher.viewPassword) { - return; - } - - this.platformUtilsService.copyToClipboard(value, { window: window }); - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("valueCopied", this.i18nService.t(typeI18nKey)), - ); - - if (typeI18nKey === "password") { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.eventCollectionService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id); - } else if (typeI18nKey === "verificationCodeTotp") { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.eventCollectionService.collect(EventType.Cipher_ClientCopiedHiddenField, cipher.id); - } else if (typeI18nKey === "securityCode") { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.eventCollectionService.collect(EventType.Cipher_ClientCopiedCardCode, cipher.id); - } - } - - displayTotpCopyButton(cipher: CipherView) { - return ( - (cipher?.login?.hasTotp ?? false) && (cipher.organizationUseTotp || this.userHasPremiumAccess) - ); - } - - view() { - this.onView.emit(this.cipher); - } -} diff --git a/apps/browser/src/vault/popup/components/cipher-row.component.html b/apps/browser/src/vault/popup/components/cipher-row.component.html deleted file mode 100644 index 8ac9147cb92..00000000000 --- a/apps/browser/src/vault/popup/components/cipher-row.component.html +++ /dev/null @@ -1,51 +0,0 @@ -
-
- - - -
-
diff --git a/apps/browser/src/vault/popup/components/cipher-row.component.ts b/apps/browser/src/vault/popup/components/cipher-row.component.ts deleted file mode 100644 index 6b71470a86b..00000000000 --- a/apps/browser/src/vault/popup/components/cipher-row.component.ts +++ /dev/null @@ -1,31 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, EventEmitter, Input, Output } from "@angular/core"; - -import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; - -@Component({ - selector: "app-cipher-row", - templateUrl: "cipher-row.component.html", -}) -export class CipherRowComponent { - @Output() onSelected = new EventEmitter(); - @Output() launchEvent = new EventEmitter(); - @Output() onView = new EventEmitter(); - @Input() cipher: CipherView; - @Input() last: boolean; - @Input() showView = false; - @Input() title: string; - - selectCipher(c: CipherView) { - this.onSelected.emit(c); - } - - launchCipher(c: CipherView) { - this.launchEvent.emit(c); - } - - viewCipher(c: CipherView) { - this.onView.emit(c); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/vault-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html similarity index 100% rename from apps/browser/src/vault/popup/components/vault/vault-v2.component.html rename to apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.html diff --git a/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts similarity index 95% rename from apps/browser/src/vault/popup/components/vault/vault-v2.component.ts rename to apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts index 68aa40cbf62..9970c115bb7 100644 --- a/apps/browser/src/vault/popup/components/vault/vault-v2.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/vault-v2.component.ts @@ -18,12 +18,14 @@ import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page import { VaultPopupItemsService } from "../../services/vault-popup-items.service"; import { VaultPopupListFiltersService } from "../../services/vault-popup-list-filters.service"; import { VaultUiOnboardingService } from "../../services/vault-ui-onboarding.service"; -import { AutofillVaultListItemsComponent, VaultListItemsContainerComponent } from "../vault-v2"; + import { NewItemDropdownV2Component, NewItemInitialValues, -} from "../vault-v2/new-item-dropdown/new-item-dropdown-v2.component"; -import { VaultHeaderV2Component } from "../vault-v2/vault-header/vault-header-v2.component"; +} from "./new-item-dropdown/new-item-dropdown-v2.component"; +import { VaultHeaderV2Component } from "./vault-header/vault-header-v2.component"; + +import { AutofillVaultListItemsComponent, VaultListItemsContainerComponent } from "."; enum VaultState { Empty, diff --git a/apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.html b/apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.html deleted file mode 100644 index 8464655c20b..00000000000 --- a/apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.html +++ /dev/null @@ -1,140 +0,0 @@ -
-

- {{ "customFields" | i18n }} -

-
- -
-
- - - -
- - - - - - - -
- - -
- -
-
- -
-
-
- -
- - - -
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.ts b/apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.ts deleted file mode 100644 index 6992455a8a6..00000000000 --- a/apps/browser/src/vault/popup/components/vault/add-edit-custom-fields.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component } from "@angular/core"; - -import { AddEditCustomFieldsComponent as BaseAddEditCustomFieldsComponent } from "@bitwarden/angular/vault/components/add-edit-custom-fields.component"; -import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; - -@Component({ - selector: "app-vault-add-edit-custom-fields", - templateUrl: "add-edit-custom-fields.component.html", -}) -export class AddEditCustomFieldsComponent extends BaseAddEditCustomFieldsComponent { - constructor(i18nService: I18nService, eventCollectionService: EventCollectionService) { - super(i18nService, eventCollectionService); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/add-edit.component.html b/apps/browser/src/vault/popup/components/vault/add-edit.component.html deleted file mode 100644 index fb1efbbbd79..00000000000 --- a/apps/browser/src/vault/popup/components/vault/add-edit.component.html +++ /dev/null @@ -1,826 +0,0 @@ -
-
-
- -
-

- {{ title }} -

-
- -
-
-
- - {{ "personalOwnershipPolicyInEffect" | i18n }} - -
-

- {{ "itemInformation" | i18n }} -

-
-
- - -
-
- - -
- -
-
-
- - -
-
- -
-
-
-
- - -
-
- - - -
-
- - -
-
-
- -
- {{ "typePasskey" | i18n }} - {{ "dateCreated" | i18n }} - {{ cipher.login.fido2Credentials[0].creationDate | date: "short" }} -
-
-
-
- -
-
- - -
-
- - - -
-
-
- - -
-
- - -
-
-
- - -
-
- -
-
-
- - - - - - - -
-
- - - - - - - -
-
- - -
-
-
- - -
-
- -
-
-
- -
-
- - - - - - - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- {{ "sshPrivateKey" | i18n }} - {{ cipher.sshKey.privateKey }} -
-
- {{ "sshPublicKey" | i18n }} - {{ cipher.sshKey.publicKey }} -
-
- {{ "sshKeyFingerprint" | i18n }} - {{ cipher.sshKey.keyFingerprint }} -
-
-
-
-
-
- -
- -
- - - - - - -
-
- - -
-
-
- -
-
-
-
-
- - -
-
- -
-
-
-
- - -
-
- - -
-
- - -
- - -
-
-
-

- -

-
-
- -
-
-
- - -
-

- {{ "ownership" | i18n }} -

-
-
- - -
-
-
-
-

- {{ "collections" | i18n }} -

-
-
- {{ "noCollectionsInList" | i18n }} -
-
-
-
- - -
-
-
-
-
- -
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/add-edit.component.ts b/apps/browser/src/vault/popup/components/vault/add-edit.component.ts deleted file mode 100644 index 39414217b0d..00000000000 --- a/apps/browser/src/vault/popup/components/vault/add-edit.component.ts +++ /dev/null @@ -1,417 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { DatePipe, Location } from "@angular/common"; -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import qrcodeParser from "qrcode-parser"; -import { firstValueFrom } from "rxjs"; -import { first } from "rxjs/operators"; - -import { CollectionService } from "@bitwarden/admin-console/common"; -import { AddEditComponent as BaseAddEditComponent } from "@bitwarden/angular/vault/components/add-edit.component"; -import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { normalizeExpiryYearFormat } from "@bitwarden/common/autofill/utils"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; -import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; -import { DialogService } from "@bitwarden/components"; -import { PasswordRepromptService } from "@bitwarden/vault"; - -import { BrowserFido2UserInterfaceSession } from "../../../../autofill/fido2/services/browser-fido2-user-interface.service"; -import { BrowserApi } from "../../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; -import { PopupCloseWarningService } from "../../../../popup/services/popup-close-warning.service"; -import { Fido2UserVerificationService } from "../../../services/fido2-user-verification.service"; -import { fido2PopoutSessionData$ } from "../../utils/fido2-popout-session-data"; -import { closeAddEditVaultItemPopout, VaultPopoutType } from "../../utils/vault-popout-window"; - -@Component({ - selector: "app-vault-add-edit", - templateUrl: "add-edit.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class AddEditComponent extends BaseAddEditComponent implements OnInit { - currentUris: string[]; - showAttachments = true; - openAttachmentsInPopup: boolean; - showAutoFillOnPageLoadOptions: boolean; - - private fido2PopoutSessionData$ = fido2PopoutSessionData$(); - - constructor( - cipherService: CipherService, - folderService: FolderService, - i18nService: I18nService, - platformUtilsService: PlatformUtilsService, - auditService: AuditService, - accountService: AccountService, - private autofillSettingsService: AutofillSettingsServiceAbstraction, - collectionService: CollectionService, - messagingService: MessagingService, - private route: ActivatedRoute, - private router: Router, - private location: Location, - eventCollectionService: EventCollectionService, - policyService: PolicyService, - private popupCloseWarningService: PopupCloseWarningService, - organizationService: OrganizationService, - passwordRepromptService: PasswordRepromptService, - logService: LogService, - dialogService: DialogService, - datePipe: DatePipe, - configService: ConfigService, - private fido2UserVerificationService: Fido2UserVerificationService, - cipherAuthorizationService: CipherAuthorizationService, - ) { - super( - cipherService, - folderService, - i18nService, - platformUtilsService, - auditService, - accountService, - collectionService, - messagingService, - eventCollectionService, - policyService, - logService, - passwordRepromptService, - organizationService, - dialogService, - window, - datePipe, - configService, - cipherAuthorizationService, - ); - } - - async ngOnInit() { - await super.ngOnInit(); - - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - if (params.cipherId) { - this.cipherId = params.cipherId; - } - if (params.folderId) { - this.folderId = params.folderId; - } - if (params.collectionId) { - this.collectionId = params.collectionId; - const collection = this.writeableCollections.find((c) => c.id === params.collectionId); - if (collection != null) { - this.collectionIds = [collection.id]; - this.organizationId = collection.organizationId; - } - } - if (params.type) { - const type = parseInt(params.type, null); - this.type = type; - } - this.editMode = !params.cipherId; - - if (params.cloneMode != null) { - this.cloneMode = params.cloneMode === "true"; - } - if (params.selectedVault) { - this.organizationId = params.selectedVault; - } - - await this.load(); - - if (!this.editMode || this.cloneMode) { - // Only allow setting username if there's no existing value - if ( - params.username && - (this.cipher.login.username == null || this.cipher.login.username === "") - ) { - this.cipher.login.username = params.username; - } - - if (params.name && (this.cipher.name == null || this.cipher.name === "")) { - this.cipher.name = params.name; - } - if ( - params.uri && - this.cipher.login.uris[0] && - (this.cipher.login.uris[0].uri == null || this.cipher.login.uris[0].uri === "") - ) { - this.cipher.login.uris[0].uri = params.uri; - } - } - - this.openAttachmentsInPopup = BrowserPopupUtils.inPopup(window); - - if (this.inAddEditPopoutWindow()) { - BrowserApi.messageListener("add-edit-popout", this.handleExtensionMessage.bind(this)); - } - }); - - if (!this.editMode) { - const tabs = await BrowserApi.tabsQuery({ windowType: "normal" }); - this.currentUris = - tabs == null - ? null - : tabs.filter((tab) => tab.url != null && tab.url !== "").map((tab) => tab.url); - } - - this.setFocus(); - - if (BrowserPopupUtils.inPopout(window)) { - this.popupCloseWarningService.enable(); - } - } - - async load() { - await super.load(); - this.showAutoFillOnPageLoadOptions = - this.cipher.type === CipherType.Login && - (await firstValueFrom(this.autofillSettingsService.autofillOnPageLoad$)); - } - - async submit(): Promise { - const fido2SessionData = await firstValueFrom(this.fido2PopoutSessionData$); - const { isFido2Session, sessionId, userVerification } = fido2SessionData; - const inFido2PopoutWindow = BrowserPopupUtils.inPopout(window) && isFido2Session; - - // normalize card expiry year on save - if (this.cipher.type === this.cipherType.Card) { - this.cipher.card.expYear = normalizeExpiryYearFormat(this.cipher.card.expYear); - } - - // TODO: Revert to use fido2 user verification service once user verification for passkeys is approved for production. - // PM-4577 - https://github.com/bitwarden/clients/pull/8746 - if ( - inFido2PopoutWindow && - !(await this.handleFido2UserVerification(sessionId, userVerification)) - ) { - return false; - } - - const success = await super.submit(); - if (!success) { - return false; - } - - if (BrowserPopupUtils.inPopout(window)) { - this.popupCloseWarningService.disable(); - } - - if (inFido2PopoutWindow) { - BrowserFido2UserInterfaceSession.confirmNewCredentialResponse( - sessionId, - this.cipher.id, - userVerification, - ); - return true; - } - - if (this.inAddEditPopoutWindow()) { - this.messagingService.send("addEditCipherSubmitted"); - await closeAddEditVaultItemPopout(1000); - return true; - } - - if (this.cloneMode) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/tabs/vault"]); - } else { - this.location.back(); - } - return true; - } - - attachments() { - super.attachments(); - - if (this.openAttachmentsInPopup) { - const destinationUrl = this.router - .createUrlTree(["/attachments"], { queryParams: { cipherId: this.cipher.id } }) - .toString(); - const currentBaseUrl = window.location.href.replace(this.router.url, ""); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserPopupUtils.openCurrentPagePopout(window, currentBaseUrl + destinationUrl); - } else { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/attachments"], { queryParams: { cipherId: this.cipher.id } }); - } - } - - editCollections() { - super.editCollections(); - if (this.cipher.organizationId != null) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/collections"], { queryParams: { cipherId: this.cipher.id } }); - } - } - - async cancel() { - super.cancel(); - - const sessionData = await firstValueFrom(this.fido2PopoutSessionData$); - if (BrowserPopupUtils.inPopout(window) && sessionData.isFido2Session) { - this.popupCloseWarningService.disable(); - BrowserFido2UserInterfaceSession.abortPopout(sessionData.sessionId); - return; - } - - if (this.inAddEditPopoutWindow()) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - closeAddEditVaultItemPopout(); - return; - } - - this.location.back(); - } - - async generateUsername(): Promise { - const confirmed = await super.generateUsername(); - if (confirmed) { - await this.saveCipherState(); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["generator"], { queryParams: { type: "username" } }); - } - return confirmed; - } - - async generatePassword(): Promise { - const confirmed = await super.generatePassword(); - if (confirmed) { - await this.saveCipherState(); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["generator"], { queryParams: { type: "password" } }); - } - return confirmed; - } - - async delete(): Promise { - const confirmed = await super.delete(); - if (confirmed) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/tabs/vault"]); - } - return confirmed; - } - - toggleUriInput(uri: LoginUriView) { - const u = uri as any; - u.showCurrentUris = !u.showCurrentUris; - } - - allowOwnershipOptions(): boolean { - return ( - (!this.editMode || this.cloneMode) && - this.ownershipOptions && - (this.ownershipOptions.length > 1 || !this.allowPersonal) - ); - } - - private saveCipherState() { - return this.cipherService.setAddEditCipherInfo({ - cipher: this.cipher, - collectionIds: - this.collections == null - ? [] - : this.collections.filter((c) => (c as any).checked).map((c) => c.id), - }); - } - - private setFocus() { - window.setTimeout(() => { - if (this.editMode) { - return; - } - - if (this.cipher.name != null && this.cipher.name !== "") { - document.getElementById("loginUsername").focus(); - } else { - document.getElementById("name").focus(); - } - }, 200); - } - - repromptChanged() { - super.repromptChanged(); - - if (!this.showAutoFillOnPageLoadOptions) { - return; - } - - if (this.reprompt) { - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("passwordRepromptDisabledAutofillOnPageLoad"), - ); - return; - } - - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("autofillOnPageLoadSetToDefault"), - ); - } - - private inAddEditPopoutWindow() { - return BrowserPopupUtils.inSingleActionPopout(window, VaultPopoutType.addEditVaultItem); - } - - async captureTOTPFromTab() { - try { - const screenshot = await BrowserApi.captureVisibleTab(); - const data = await qrcodeParser(screenshot); - const url = new URL(data.toString()); - if (url.protocol == "otpauth:" && url.searchParams.has("secret")) { - this.cipher.login.totp = data.toString(); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("totpCaptureSuccess"), - ); - } - } catch (e) { - this.platformUtilsService.showToast( - "error", - this.i18nService.t("errorOccurred"), - this.i18nService.t("totpCaptureError"), - ); - } - } - - private handleExtensionMessage(message: { [key: string]: any; command: string }) { - if (message.command === "inlineAutofillMenuRefreshAddEditCipher") { - this.load().catch((error) => this.logService.error(error)); - } - } - - // TODO: Remove and use fido2 user verification service once user verification for passkeys is approved for production. - // Be sure to make the same changes to add-edit-v2.component.ts if applicable - private async handleFido2UserVerification( - sessionId: string, - userVerification: boolean, - ): Promise { - // We are bypassing user verification pending approval for production. - return true; - } -} diff --git a/apps/browser/src/vault/popup/components/vault/attachments.component.html b/apps/browser/src/vault/popup/components/vault/attachments.component.html deleted file mode 100644 index b95dc69af8f..00000000000 --- a/apps/browser/src/vault/popup/components/vault/attachments.component.html +++ /dev/null @@ -1,72 +0,0 @@ -
-
-
- - -
-

- {{ "attachments" | i18n }} -

-
- -
-
-
-
-
-
-
- {{ a.fileName }} -
- {{ a.sizeName }} -
- -
-
-
-
-
-

- {{ "newAttachment" | i18n }} -

-
-
- - -
-
- -
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/attachments.component.ts b/apps/browser/src/vault/popup/components/vault/attachments.component.ts deleted file mode 100644 index b63b743b9fa..00000000000 --- a/apps/browser/src/vault/popup/components/vault/attachments.component.ts +++ /dev/null @@ -1,82 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Location } from "@angular/common"; -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; -import { first } from "rxjs/operators"; - -import { AttachmentsComponent as BaseAttachmentsComponent } from "@bitwarden/angular/vault/components/attachments.component"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { DialogService, ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; - -@Component({ - selector: "app-vault-attachments", - templateUrl: "attachments.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class AttachmentsComponent extends BaseAttachmentsComponent implements OnInit { - openedAttachmentsInPopup: boolean; - - constructor( - cipherService: CipherService, - i18nService: I18nService, - keyService: KeyService, - encryptService: EncryptService, - platformUtilsService: PlatformUtilsService, - apiService: ApiService, - private location: Location, - private route: ActivatedRoute, - stateService: StateService, - logService: LogService, - fileDownloadService: FileDownloadService, - dialogService: DialogService, - billingAccountProfileStateService: BillingAccountProfileStateService, - accountService: AccountService, - toastService: ToastService, - ) { - super( - cipherService, - i18nService, - keyService, - encryptService, - platformUtilsService, - apiService, - window, - logService, - stateService, - fileDownloadService, - dialogService, - billingAccountProfileStateService, - accountService, - toastService, - ); - } - - async ngOnInit() { - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - this.cipherId = params.cipherId; - await this.init(); - }); - - this.openedAttachmentsInPopup = history.length === 1; - } - - back() { - this.location.back(); - } - - close() { - window.close(); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/collections.component.html b/apps/browser/src/vault/popup/components/vault/collections.component.html deleted file mode 100644 index 36c1336c5b4..00000000000 --- a/apps/browser/src/vault/popup/components/vault/collections.component.html +++ /dev/null @@ -1,43 +0,0 @@ -
-
-
- -
-

- {{ "collections" | i18n }} -

-
- -
-
-
-
-
-
- {{ "noCollectionsInList" | i18n }} -
-
-
-
- - -
-
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/collections.component.ts b/apps/browser/src/vault/popup/components/vault/collections.component.ts deleted file mode 100644 index 407f87e996c..00000000000 --- a/apps/browser/src/vault/popup/components/vault/collections.component.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Location } from "@angular/common"; -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; -import { first } from "rxjs/operators"; - -import { CollectionService } from "@bitwarden/admin-console/common"; -import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { ToastService } from "@bitwarden/components"; - -@Component({ - selector: "app-vault-collections", - templateUrl: "collections.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class CollectionsComponent extends BaseCollectionsComponent implements OnInit { - constructor( - collectionService: CollectionService, - platformUtilsService: PlatformUtilsService, - i18nService: I18nService, - cipherService: CipherService, - organizationService: OrganizationService, - private route: ActivatedRoute, - private location: Location, - logService: LogService, - accountService: AccountService, - toastService: ToastService, - ) { - super( - collectionService, - platformUtilsService, - i18nService, - cipherService, - organizationService, - logService, - accountService, - toastService, - ); - } - - async ngOnInit() { - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - this.onSavedCollections.subscribe(() => { - this.back(); - }); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - this.cipherId = params.cipherId; - await this.load(); - }); - } - - back() { - this.location.back(); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/current-tab.component.html b/apps/browser/src/vault/popup/components/vault/current-tab.component.html deleted file mode 100644 index bb8a401da62..00000000000 --- a/apps/browser/src/vault/popup/components/vault/current-tab.component.html +++ /dev/null @@ -1,95 +0,0 @@ - -

{{ "currentTab" | i18n }}

-
- - -
- -
- -
-
-
-
- -
- - -
-

- {{ "typeLogins" | i18n }} - {{ loginCiphers.length }} -

-
- - -
-

{{ "autoFillInfo" | i18n }}

- -
-
-
-
-

- {{ "cards" | i18n }} - {{ cardCiphers.length }} -

-
- -
-
-
-

- {{ "identities" | i18n }} - {{ identityCiphers.length }} -

-
- -
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/current-tab.component.ts b/apps/browser/src/vault/popup/components/vault/current-tab.component.ts deleted file mode 100644 index 156a708015f..00000000000 --- a/apps/browser/src/vault/popup/components/vault/current-tab.component.ts +++ /dev/null @@ -1,354 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angular/core"; -import { Router } from "@angular/router"; -import { Subject, firstValueFrom, from, Subscription } from "rxjs"; -import { debounceTime, switchMap, takeUntil } from "rxjs/operators"; - -import { SearchService } from "@bitwarden/common/abstractions/search.service"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants"; -import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { SyncService } from "@bitwarden/common/platform/sync"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type"; -import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { PasswordRepromptService } from "@bitwarden/vault"; - -import { AutofillService } from "../../../../autofill/services/abstractions/autofill.service"; -import { BrowserApi } from "../../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; -import { VaultFilterService } from "../../../services/vault-filter.service"; - -const BroadcasterSubscriptionId = "CurrentTabComponent"; - -@Component({ - selector: "app-current-tab", - templateUrl: "current-tab.component.html", -}) -export class CurrentTabComponent implements OnInit, OnDestroy { - pageDetails: any[] = []; - tab: chrome.tabs.Tab; - cardCiphers: CipherView[]; - identityCiphers: CipherView[]; - loginCiphers: CipherView[]; - url: string; - hostname: string; - searchText: string; - inSidebar = false; - searchTypeSearch = false; - loaded = false; - isLoading = false; - showOrganizations = false; - showHowToAutofill = false; - autofillCalloutText: string; - protected search$ = new Subject(); - private destroy$ = new Subject(); - private collectPageDetailsSubscription: Subscription; - - private totpCode: string; - private totpTimeout: number; - private loadedTimeout: number; - private searchTimeout: number; - - constructor( - private platformUtilsService: PlatformUtilsService, - private cipherService: CipherService, - private autofillService: AutofillService, - private i18nService: I18nService, - private router: Router, - private ngZone: NgZone, - private broadcasterService: BroadcasterService, - private changeDetectorRef: ChangeDetectorRef, - private syncService: SyncService, - private searchService: SearchService, - private autofillSettingsService: AutofillSettingsServiceAbstraction, - private passwordRepromptService: PasswordRepromptService, - private organizationService: OrganizationService, - private vaultFilterService: VaultFilterService, - private vaultSettingsService: VaultSettingsService, - ) {} - - async ngOnInit() { - this.searchTypeSearch = !this.platformUtilsService.isSafari(); - this.inSidebar = BrowserPopupUtils.inSidebar(window); - - this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.ngZone.run(async () => { - switch (message.command) { - case "syncCompleted": - if (this.isLoading) { - window.setTimeout(() => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.load(); - }, 500); - } - break; - default: - break; - } - - this.changeDetectorRef.detectChanges(); - }); - }); - - if (!this.syncService.syncInProgress) { - await this.load(); - await this.setCallout(); - } else { - this.loadedTimeout = window.setTimeout(async () => { - if (!this.isLoading) { - await this.load(); - await this.setCallout(); - } - }, 5000); - } - - this.search$ - .pipe( - debounceTime(500), - switchMap(() => { - return from(this.searchVault()); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - - const autofillOnPageLoadOrgPolicy = await firstValueFrom( - this.autofillSettingsService.activateAutofillOnPageLoadFromPolicy$, - ); - const autofillOnPageLoadPolicyToastHasDisplayed = await firstValueFrom( - this.autofillSettingsService.autofillOnPageLoadPolicyToastHasDisplayed$, - ); - - // If the org "autofill on page load" policy is set, set the user setting to match it - // @TODO override user setting instead of overwriting - if (autofillOnPageLoadOrgPolicy === true) { - await this.autofillSettingsService.setAutofillOnPageLoad(true); - - if (!autofillOnPageLoadPolicyToastHasDisplayed) { - this.platformUtilsService.showToast( - "info", - null, - this.i18nService.t("autofillPageLoadPolicyActivated"), - ); - - await this.autofillSettingsService.setAutofillOnPageLoadPolicyToastHasDisplayed(true); - } - } - - // If the org policy is ever disabled after being enabled, reset the toast notification - if (!autofillOnPageLoadOrgPolicy && autofillOnPageLoadPolicyToastHasDisplayed) { - await this.autofillSettingsService.setAutofillOnPageLoadPolicyToastHasDisplayed(false); - } - } - - ngOnDestroy() { - window.clearTimeout(this.loadedTimeout); - this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); - - this.destroy$.next(); - this.destroy$.complete(); - } - - async refresh() { - await this.load(); - } - - addCipher() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/add-cipher"], { - queryParams: { - name: this.hostname, - uri: this.url, - selectedVault: this.vaultFilterService.getVaultFilter().selectedOrganizationId, - }, - }); - } - - viewCipher(cipher: CipherView) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/view-cipher"], { queryParams: { cipherId: cipher.id } }); - } - - async fillCipher(cipher: CipherView, closePopupDelay?: number) { - if ( - cipher.reprompt !== CipherRepromptType.None && - !(await this.passwordRepromptService.showPasswordPrompt()) - ) { - return; - } - - this.totpCode = null; - if (this.totpTimeout != null) { - window.clearTimeout(this.totpTimeout); - } - - if (this.pageDetails == null || this.pageDetails.length === 0) { - this.platformUtilsService.showToast("error", null, this.i18nService.t("autofillError")); - return; - } - - try { - this.totpCode = await this.autofillService.doAutoFill({ - tab: this.tab, - cipher: cipher, - pageDetails: this.pageDetails, - doc: window.document, - fillNewPassword: true, - allowTotpAutofill: true, - }); - if (this.totpCode != null) { - this.platformUtilsService.copyToClipboard(this.totpCode, { window: window }); - } - if (BrowserPopupUtils.inPopup(window)) { - if (!closePopupDelay) { - if (this.platformUtilsService.isFirefox() || this.platformUtilsService.isSafari()) { - BrowserApi.closePopup(window); - } else { - // Slight delay to fix bug in Chromium browsers where popup closes without copying totp to clipboard - setTimeout(() => BrowserApi.closePopup(window), 50); - } - } else { - setTimeout(() => BrowserApi.closePopup(window), closePopupDelay); - } - } - } catch { - this.ngZone.run(() => { - this.platformUtilsService.showToast("error", null, this.i18nService.t("autofillError")); - this.changeDetectorRef.detectChanges(); - }); - } - } - - async searchVault() { - if (!(await this.searchService.isSearchable(this.searchText))) { - return; - } - - await this.router.navigate(["/tabs/vault"], { queryParams: { searchText: this.searchText } }); - } - - closeOnEsc(e: KeyboardEvent) { - // If input not empty, use browser default behavior of clearing input instead - if (e.key === "Escape" && (this.searchText == null || this.searchText === "")) { - BrowserApi.closePopup(window); - } - } - - protected async load() { - this.isLoading = false; - this.tab = await BrowserApi.getTabFromCurrentWindow(); - - if (this.tab != null) { - this.url = this.tab.url; - } else { - this.loginCiphers = []; - this.isLoading = this.loaded = true; - return; - } - - this.pageDetails = []; - this.collectPageDetailsSubscription?.unsubscribe(); - this.collectPageDetailsSubscription = this.autofillService - .collectPageDetailsFromTab$(this.tab) - .pipe(takeUntil(this.destroy$)) - .subscribe((pageDetails) => (this.pageDetails = pageDetails)); - - this.hostname = Utils.getHostname(this.url); - const otherTypes: CipherType[] = []; - const dontShowCards = !(await firstValueFrom(this.vaultSettingsService.showCardsCurrentTab$)); - const dontShowIdentities = !(await firstValueFrom( - this.vaultSettingsService.showIdentitiesCurrentTab$, - )); - this.showOrganizations = await this.organizationService.hasOrganizations(); - if (!dontShowCards) { - otherTypes.push(CipherType.Card); - } - if (!dontShowIdentities) { - otherTypes.push(CipherType.Identity); - } - - const ciphers = await this.cipherService.getAllDecryptedForUrl( - this.url, - otherTypes.length > 0 ? otherTypes : null, - ); - - this.loginCiphers = []; - this.cardCiphers = []; - this.identityCiphers = []; - - ciphers.forEach((c) => { - if (!this.vaultFilterService.filterCipherForSelectedVault(c)) { - switch (c.type) { - case CipherType.Login: - this.loginCiphers.push(c); - break; - case CipherType.Card: - this.cardCiphers.push(c); - break; - case CipherType.Identity: - this.identityCiphers.push(c); - break; - default: - break; - } - } - }); - - if (this.loginCiphers.length) { - this.loginCiphers = this.loginCiphers.sort((a, b) => - this.cipherService.sortCiphersByLastUsedThenName(a, b), - ); - } - - this.isLoading = this.loaded = true; - } - - async goToSettings() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["autofill"]); - } - - async dismissCallout() { - await this.autofillSettingsService.setAutofillOnPageLoadCalloutIsDismissed(true); - this.showHowToAutofill = false; - } - - private async setCallout() { - const inlineMenuVisibilityIsOff = - (await firstValueFrom(this.autofillSettingsService.inlineMenuVisibility$)) === - AutofillOverlayVisibility.Off; - - this.showHowToAutofill = - this.loginCiphers.length > 0 && - inlineMenuVisibilityIsOff && - !(await firstValueFrom(this.autofillSettingsService.autofillOnPageLoad$)) && - !(await firstValueFrom(this.autofillSettingsService.autofillOnPageLoadCalloutIsDismissed$)); - - if (this.showHowToAutofill) { - const autofillCommand = await this.platformUtilsService.getAutofillKeyboardShortcut(); - await this.setAutofillCalloutText(autofillCommand); - } - } - - private setAutofillCalloutText(command: string) { - if (command) { - this.autofillCalloutText = this.i18nService.t("autofillSelectInfoWithCommand", command); - } else { - this.autofillCalloutText = this.i18nService.t("autofillSelectInfoWithoutCommand"); - } - } -} diff --git a/apps/browser/src/vault/popup/components/vault/password-history.component.html b/apps/browser/src/vault/popup/components/vault/password-history.component.html deleted file mode 100644 index 6286aa1022d..00000000000 --- a/apps/browser/src/vault/popup/components/vault/password-history.component.html +++ /dev/null @@ -1,40 +0,0 @@ -
-
- -
-

- {{ "passwordHistory" | i18n }} -

-
-
-
-
-
-
-
-
- - {{ h.lastUsedDate | date: "medium" }} -
-
-
- -
-
-
-
-
-

{{ "noPasswordsInList" | i18n }}

-
-
diff --git a/apps/browser/src/vault/popup/components/vault/password-history.component.ts b/apps/browser/src/vault/popup/components/vault/password-history.component.ts deleted file mode 100644 index bf1b4ea7717..00000000000 --- a/apps/browser/src/vault/popup/components/vault/password-history.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Location } from "@angular/common"; -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; -import { first } from "rxjs/operators"; - -import { PasswordHistoryComponent as BasePasswordHistoryComponent } from "@bitwarden/angular/vault/components/password-history.component"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; - -@Component({ - selector: "app-password-history", - templateUrl: "password-history.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class PasswordHistoryComponent extends BasePasswordHistoryComponent implements OnInit { - constructor( - cipherService: CipherService, - platformUtilsService: PlatformUtilsService, - i18nService: I18nService, - accountService: AccountService, - private location: Location, - private route: ActivatedRoute, - ) { - super(cipherService, platformUtilsService, i18nService, accountService, window); - } - - async ngOnInit() { - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - if (params.cipherId) { - this.cipherId = params.cipherId; - } else { - this.close(); - } - await this.init(); - }); - } - - close() { - this.location.back(); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/share.component.html b/apps/browser/src/vault/popup/components/vault/share.component.html deleted file mode 100644 index 46aaecd06b8..00000000000 --- a/apps/browser/src/vault/popup/components/vault/share.component.html +++ /dev/null @@ -1,77 +0,0 @@ -
- -
-
- -
-

- {{ "moveToOrganization" | i18n }} -

-
- -
-
-
-
-
-
- {{ "noOrganizationsList" | i18n }} -
-
-
-
- - -
-
- -
-
-

- {{ "collections" | i18n }} -

-
-
- {{ "noCollectionsInList" | i18n }} -
-
-
-
- - -
-
-
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/share.component.ts b/apps/browser/src/vault/popup/components/vault/share.component.ts deleted file mode 100644 index 8e061665b73..00000000000 --- a/apps/browser/src/vault/popup/components/vault/share.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Component, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { first } from "rxjs/operators"; - -import { CollectionService } from "@bitwarden/admin-console/common"; -import { ShareComponent as BaseShareComponent } from "@bitwarden/angular/components/share.component"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; - -@Component({ - selector: "app-vault-share", - templateUrl: "share.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class ShareComponent extends BaseShareComponent implements OnInit { - constructor( - collectionService: CollectionService, - platformUtilsService: PlatformUtilsService, - i18nService: I18nService, - logService: LogService, - cipherService: CipherService, - private route: ActivatedRoute, - private router: Router, - organizationService: OrganizationService, - accountService: AccountService, - ) { - super( - collectionService, - platformUtilsService, - i18nService, - cipherService, - logService, - organizationService, - accountService, - ); - } - - async ngOnInit() { - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - this.onSharedCipher.subscribe(() => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["view-cipher", { cipherId: this.cipherId }]); - }); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - this.cipherId = params.cipherId; - await this.load(); - }); - } - - async submit(): Promise { - const success = await super.submit(); - if (success) { - this.cancel(); - } - return success; - } - - cancel() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/view-cipher"], { - replaceUrl: true, - queryParams: { cipherId: this.cipher.id }, - }); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/vault-filter.component.html b/apps/browser/src/vault/popup/components/vault/vault-filter.component.html deleted file mode 100644 index bf557f74608..00000000000 --- a/apps/browser/src/vault/popup/components/vault/vault-filter.component.html +++ /dev/null @@ -1,238 +0,0 @@ - -
- -
-

{{ "myVault" | i18n }}

- -
- -
-
-
- -
- - - -

{{ "noItemsInList" | i18n }}

- -
-
- -
-

- {{ "favorites" | i18n }} - {{ favoriteCiphers.length }} -

-
- - -
-
-
-

- {{ "types" | i18n }} - 4 -

-
- - - - - -
-
-
-

- {{ "folders" | i18n }} - {{ folderCount }} -

-
- -
-
-
-

- {{ "collections" | i18n }} - {{ nestedCollections.length }} -

-
- -
-
-
-

- {{ "noneFolder" | i18n }} -
{{ noFolderCiphers.length }}
-

-
- - -
-
-
-

- {{ "trash" | i18n }} - {{ deletedCount }} -

-
- -
-
-
- -
-

{{ "noItemsInList" | i18n }}

-
- -
-
- - -
-
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/vault-filter.component.ts b/apps/browser/src/vault/popup/components/vault/vault-filter.component.ts deleted file mode 100644 index d430568869c..00000000000 --- a/apps/browser/src/vault/popup/components/vault/vault-filter.component.ts +++ /dev/null @@ -1,482 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Location } from "@angular/common"; -import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { BehaviorSubject, Subject, firstValueFrom, from } from "rxjs"; -import { first, switchMap, takeUntil } from "rxjs/operators"; - -import { CollectionView } from "@bitwarden/admin-console/common"; -import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model"; -import { SearchService } from "@bitwarden/common/abstractions/search.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -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/platform/sync"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node"; -import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; - -import { BrowserGroupingsComponentState } from "../../../../models/browserGroupingsComponentState"; -import { BrowserApi } from "../../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; -import { VaultBrowserStateService } from "../../../services/vault-browser-state.service"; -import { VaultFilterService } from "../../../services/vault-filter.service"; - -const ComponentId = "VaultComponent"; - -@Component({ - selector: "app-vault-filter", - templateUrl: "vault-filter.component.html", -}) -export class VaultFilterComponent implements OnInit, OnDestroy { - get showNoFolderCiphers(): boolean { - return ( - this.noFolderCiphers != null && - this.noFolderCiphers.length < this.noFolderListSize && - this.collections.length === 0 - ); - } - - get folderCount(): number { - return this.nestedFolders.length - (this.showNoFolderCiphers ? 0 : 1); - } - folders: FolderView[]; - nestedFolders: TreeNode[]; - collections: CollectionView[]; - nestedCollections: TreeNode[]; - loaded = false; - cipherType = CipherType; - ciphers: CipherView[]; - favoriteCiphers: CipherView[]; - noFolderCiphers: CipherView[]; - folderCounts = new Map(); - collectionCounts = new Map(); - typeCounts = new Map(); - state: BrowserGroupingsComponentState; - showLeftHeader = true; - searchPending = false; - searchTypeSearch = false; - deletedCount = 0; - vaultFilter: VaultFilter; - selectedOrganization: string = null; - showCollections = true; - - isSshKeysEnabled = false; - - private loadedTimeout: number; - private selectedTimeout: number; - private preventSelected = false; - private noFolderListSize = 100; - private searchTimeout: any = null; - private hasSearched = false; - private hasLoadedAllCiphers = false; - private allCiphers: CipherView[] = null; - private destroy$ = new Subject(); - private _searchText$ = new BehaviorSubject(""); - private isSearchable: boolean = false; - - get searchText() { - return this._searchText$.value; - } - set searchText(value: string) { - this._searchText$.next(value); - } - - constructor( - private i18nService: I18nService, - private cipherService: CipherService, - private router: Router, - private ngZone: NgZone, - private broadcasterService: BroadcasterService, - private changeDetectorRef: ChangeDetectorRef, - private route: ActivatedRoute, - private syncService: SyncService, - private platformUtilsService: PlatformUtilsService, - private searchService: SearchService, - private location: Location, - private vaultFilterService: VaultFilterService, - private vaultBrowserStateService: VaultBrowserStateService, - private configService: ConfigService, - ) { - this.noFolderListSize = 100; - } - - async ngOnInit() { - this.searchTypeSearch = !this.platformUtilsService.isSafari(); - this.showLeftHeader = !( - BrowserPopupUtils.inSidebar(window) && this.platformUtilsService.isFirefox() - ); - await this.vaultBrowserStateService.setBrowserVaultItemsComponentState(null); - - this.broadcasterService.subscribe(ComponentId, (message: any) => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.ngZone.run(async () => { - switch (message.command) { - case "syncCompleted": - window.setTimeout(() => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.load(); - }, 500); - break; - default: - break; - } - - this.changeDetectorRef.detectChanges(); - }); - }); - - const restoredScopeState = await this.restoreState(); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - this.state = await this.vaultBrowserStateService.getBrowserGroupingsComponentState(); - if (this.state?.searchText) { - this.searchText = this.state.searchText; - } else if (params.searchText) { - this.searchText = params.searchText; - this.location.replaceState("vault"); - } - - if (!this.syncService.syncInProgress) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.load(); - } else { - this.loadedTimeout = window.setTimeout(() => { - if (!this.loaded) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.load(); - } - }, 5000); - } - - if (!this.syncService.syncInProgress || restoredScopeState) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserPopupUtils.setContentScrollY(window, this.state?.scrollY); - } - }); - - this._searchText$ - .pipe( - switchMap((searchText) => from(this.searchService.isSearchable(searchText))), - takeUntil(this.destroy$), - ) - .subscribe((isSearchable) => { - this.isSearchable = isSearchable; - }); - - this.isSshKeysEnabled = await this.configService.getFeatureFlag(FeatureFlag.SSHKeyVaultItem); - } - - ngOnDestroy() { - if (this.loadedTimeout != null) { - window.clearTimeout(this.loadedTimeout); - } - if (this.selectedTimeout != null) { - window.clearTimeout(this.selectedTimeout); - } - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.saveState(); - this.broadcasterService.unsubscribe(ComponentId); - this.destroy$.next(); - this.destroy$.complete(); - } - - async load() { - this.vaultFilter = this.vaultFilterService.getVaultFilter(); - - this.updateSelectedOrg(); - await this.loadCollectionsAndFolders(); - await this.loadCiphers(); - - if (this.showNoFolderCiphers && this.nestedFolders.length > 0) { - // Remove "No Folder" from folder listing - this.nestedFolders = this.nestedFolders.slice(0, this.nestedFolders.length - 1); - } - - this.loaded = true; - } - - async loadCiphers() { - this.allCiphers = await this.cipherService.getAllDecrypted(); - if (!this.hasLoadedAllCiphers) { - this.hasLoadedAllCiphers = !(await this.searchService.isSearchable(this.searchText)); - } - await this.search(null); - this.getCounts(); - } - - async loadCollections() { - const allCollections = await this.vaultFilterService.buildCollections( - this.selectedOrganization, - ); - this.collections = allCollections.fullList; - this.nestedCollections = allCollections.nestedList; - } - - async loadFolders() { - const allFolders = await firstValueFrom( - this.vaultFilterService.buildNestedFolders(this.selectedOrganization), - ); - this.folders = allFolders.fullList; - this.nestedFolders = allFolders.nestedList; - } - - async search(timeout: number = null) { - this.searchPending = false; - if (this.searchTimeout != null) { - clearTimeout(this.searchTimeout); - } - const filterDeleted = (c: CipherView) => !c.isDeleted; - if (timeout == null) { - this.hasSearched = this.isSearchable; - this.ciphers = await this.searchService.searchCiphers( - this.searchText, - filterDeleted, - this.allCiphers, - ); - this.ciphers = this.ciphers.filter( - (c) => !this.vaultFilterService.filterCipherForSelectedVault(c), - ); - return; - } - this.searchPending = true; - this.searchTimeout = setTimeout(async () => { - this.hasSearched = this.isSearchable; - if (!this.hasLoadedAllCiphers && !this.hasSearched) { - await this.loadCiphers(); - } else { - this.ciphers = await this.searchService.searchCiphers( - this.searchText, - filterDeleted, - this.allCiphers, - ); - } - this.ciphers = this.ciphers.filter( - (c) => !this.vaultFilterService.filterCipherForSelectedVault(c), - ); - this.searchPending = false; - }, timeout); - } - - async selectType(type: CipherType) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/ciphers"], { queryParams: { type: type } }); - } - - async selectFolder(folder: FolderView) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/ciphers"], { queryParams: { folderId: folder.id || "none" } }); - } - - async selectCollection(collection: CollectionView) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/ciphers"], { queryParams: { collectionId: collection.id } }); - } - - async selectTrash() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/ciphers"], { queryParams: { deleted: true } }); - } - - async selectCipher(cipher: CipherView) { - this.selectedTimeout = window.setTimeout(() => { - if (!this.preventSelected) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/view-cipher"], { queryParams: { cipherId: cipher.id } }); - } - this.preventSelected = false; - }, 200); - } - - async launchCipher(cipher: CipherView) { - if (cipher.type !== CipherType.Login || !cipher.login.canLaunch) { - return; - } - - if (this.selectedTimeout != null) { - window.clearTimeout(this.selectedTimeout); - } - this.preventSelected = true; - await this.cipherService.updateLastLaunchedDate(cipher.id); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserApi.createNewTab(cipher.login.launchUri); - if (BrowserPopupUtils.inPopup(window)) { - BrowserApi.closePopup(window); - } - } - - async addCipher() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/add-cipher"], { - queryParams: { selectedVault: this.vaultFilter.selectedOrganizationId }, - }); - } - - async vaultFilterChanged() { - if (this.showSearching) { - await this.search(); - } - this.updateSelectedOrg(); - await this.loadCollectionsAndFolders(); - this.getCounts(); - } - - updateSelectedOrg() { - this.vaultFilter = this.vaultFilterService.getVaultFilter(); - if (this.vaultFilter.selectedOrganizationId != null) { - this.selectedOrganization = this.vaultFilter.selectedOrganizationId; - } else { - this.selectedOrganization = null; - } - } - - getCounts() { - let favoriteCiphers: CipherView[] = null; - let noFolderCiphers: CipherView[] = null; - const folderCounts = new Map(); - const collectionCounts = new Map(); - const typeCounts = new Map(); - - this.deletedCount = this.allCiphers.filter( - (c) => c.isDeleted && !this.vaultFilterService.filterCipherForSelectedVault(c), - ).length; - - this.ciphers?.forEach((c) => { - if (!this.vaultFilterService.filterCipherForSelectedVault(c)) { - if (c.isDeleted) { - return; - } - if (c.favorite) { - if (favoriteCiphers == null) { - favoriteCiphers = []; - } - favoriteCiphers.push(c); - } - - if (c.folderId == null) { - if (noFolderCiphers == null) { - noFolderCiphers = []; - } - noFolderCiphers.push(c); - } - - if (typeCounts.has(c.type)) { - typeCounts.set(c.type, typeCounts.get(c.type) + 1); - } else { - typeCounts.set(c.type, 1); - } - - if (folderCounts.has(c.folderId)) { - folderCounts.set(c.folderId, folderCounts.get(c.folderId) + 1); - } else { - folderCounts.set(c.folderId, 1); - } - - if (c.collectionIds != null) { - c.collectionIds.forEach((colId) => { - if (collectionCounts.has(colId)) { - collectionCounts.set(colId, collectionCounts.get(colId) + 1); - } else { - collectionCounts.set(colId, 1); - } - }); - } - } - }); - - this.favoriteCiphers = favoriteCiphers; - this.noFolderCiphers = noFolderCiphers; - this.typeCounts = typeCounts; - this.folderCounts = folderCounts; - this.collectionCounts = collectionCounts; - } - - showSearching() { - return this.hasSearched || (!this.searchPending && this.isSearchable); - } - - closeOnEsc(e: KeyboardEvent) { - // If input not empty, use browser default behavior of clearing input instead - if (e.key === "Escape" && (this.searchText == null || this.searchText === "")) { - BrowserApi.closePopup(window); - } - } - - private async loadCollectionsAndFolders() { - this.showCollections = !this.vaultFilter.myVaultOnly; - await this.loadFolders(); - await this.loadCollections(); - } - - private async saveState() { - this.state = Object.assign(new BrowserGroupingsComponentState(), { - scrollY: BrowserPopupUtils.getContentScrollY(window), - searchText: this.searchText, - favoriteCiphers: this.favoriteCiphers, - noFolderCiphers: this.noFolderCiphers, - ciphers: this.ciphers, - collectionCounts: this.collectionCounts, - folderCounts: this.folderCounts, - typeCounts: this.typeCounts, - folders: this.folders, - collections: this.collections, - deletedCount: this.deletedCount, - }); - await this.vaultBrowserStateService.setBrowserGroupingsComponentState(this.state); - } - - private async restoreState(): Promise { - this.state = await this.vaultBrowserStateService.getBrowserGroupingsComponentState(); - if (this.state == null) { - return false; - } - - if (this.state.favoriteCiphers != null) { - this.favoriteCiphers = this.state.favoriteCiphers; - } - if (this.state.noFolderCiphers != null) { - this.noFolderCiphers = this.state.noFolderCiphers; - } - if (this.state.ciphers != null) { - this.ciphers = this.state.ciphers; - } - if (this.state.collectionCounts != null) { - this.collectionCounts = this.state.collectionCounts; - } - if (this.state.folderCounts != null) { - this.folderCounts = this.state.folderCounts; - } - if (this.state.typeCounts != null) { - this.typeCounts = this.state.typeCounts; - } - if (this.state.folders != null) { - this.folders = this.state.folders; - } - if (this.state.collections != null) { - this.collections = this.state.collections; - } - if (this.state.deletedCount != null) { - this.deletedCount = this.state.deletedCount; - } - - return true; - } -} diff --git a/apps/browser/src/vault/popup/components/vault/vault-items.component.html b/apps/browser/src/vault/popup/components/vault/vault-items.component.html deleted file mode 100644 index f10688554d9..00000000000 --- a/apps/browser/src/vault/popup/components/vault/vault-items.component.html +++ /dev/null @@ -1,123 +0,0 @@ -
-
- -
-

{{ "myVault" | i18n }}

- -
- -
-
-
- - -
-

- {{ "folders" | i18n }} -

-
- -
-
-
-

- {{ "collections" | i18n }} -

-
- -
-
-
- -
- -
- - - -

{{ "noItemsInList" | i18n }}

- -
-
-
- -
-

- {{ groupingTitle }} - {{ isSearching() ? ciphers.length : ciphers.length }} -

-
- -
-
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/vault-items.component.ts b/apps/browser/src/vault/popup/components/vault/vault-items.component.ts deleted file mode 100644 index 387afcfe217..00000000000 --- a/apps/browser/src/vault/popup/components/vault/vault-items.component.ts +++ /dev/null @@ -1,316 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Location } from "@angular/common"; -import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { first } from "rxjs/operators"; - -import { CollectionService, CollectionView } from "@bitwarden/admin-console/common"; -import { VaultItemsComponent as BaseVaultItemsComponent } from "@bitwarden/angular/vault/components/vault-items.component"; -import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model"; -import { SearchService } from "@bitwarden/common/abstractions/search.service"; -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node"; -import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; - -import { BrowserComponentState } from "../../../../models/browserComponentState"; -import { BrowserApi } from "../../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; -import { VaultBrowserStateService } from "../../../services/vault-browser-state.service"; -import { VaultFilterService } from "../../../services/vault-filter.service"; - -const ComponentId = "VaultItemsComponent"; - -@Component({ - selector: "app-vault-items", - templateUrl: "vault-items.component.html", -}) -export class VaultItemsComponent extends BaseVaultItemsComponent implements OnInit, OnDestroy { - groupingTitle: string; - state: BrowserComponentState; - folderId: string = null; - collectionId: string = null; - type: CipherType = null; - nestedFolders: TreeNode[]; - nestedCollections: TreeNode[]; - searchTypeSearch = false; - showOrganizations = false; - vaultFilter: VaultFilter; - deleted = true; - noneFolder = false; - showVaultFilter = false; - - private selectedTimeout: number; - private preventSelected = false; - private applySavedState = true; - private scrollingContainer = "cdk-virtual-scroll-viewport"; - - constructor( - searchService: SearchService, - private organizationService: OrganizationService, - private route: ActivatedRoute, - private router: Router, - private location: Location, - private ngZone: NgZone, - private broadcasterService: BroadcasterService, - private changeDetectorRef: ChangeDetectorRef, - private stateService: VaultBrowserStateService, - private i18nService: I18nService, - private collectionService: CollectionService, - private platformUtilsService: PlatformUtilsService, - cipherService: CipherService, - private vaultFilterService: VaultFilterService, - ) { - super(searchService, cipherService); - this.applySavedState = - (window as any).previousPopupUrl != null && - !(window as any).previousPopupUrl.startsWith("/ciphers"); - } - - async ngOnInit() { - this.searchTypeSearch = !this.platformUtilsService.isSafari(); - this.showOrganizations = await this.organizationService.hasOrganizations(); - this.vaultFilter = this.vaultFilterService.getVaultFilter(); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - if (this.applySavedState) { - this.state = await this.stateService.getBrowserVaultItemsComponentState(); - if (this.state?.searchText) { - this.searchText = this.state.searchText; - } - } - - if (params.deleted) { - this.showVaultFilter = true; - this.groupingTitle = this.i18nService.t("trash"); - this.searchPlaceholder = this.i18nService.t("searchTrash"); - await this.load(this.buildFilter(), true); - } else if (params.type) { - this.showVaultFilter = true; - this.searchPlaceholder = this.i18nService.t("searchType"); - this.type = parseInt(params.type, null); - switch (this.type) { - case CipherType.Login: - this.groupingTitle = this.i18nService.t("logins"); - break; - case CipherType.Card: - this.groupingTitle = this.i18nService.t("cards"); - break; - case CipherType.Identity: - this.groupingTitle = this.i18nService.t("identities"); - break; - case CipherType.SecureNote: - this.groupingTitle = this.i18nService.t("secureNotes"); - break; - case CipherType.SshKey: - this.groupingTitle = this.i18nService.t("sshKeys"); - break; - default: - break; - } - await this.load(this.buildFilter()); - } else if (params.folderId) { - this.showVaultFilter = true; - this.folderId = params.folderId === "none" ? null : params.folderId; - this.searchPlaceholder = this.i18nService.t("searchFolder"); - if (this.folderId != null) { - this.showOrganizations = false; - const folderNode = await this.vaultFilterService.getFolderNested(this.folderId); - if (folderNode != null && folderNode.node != null) { - this.groupingTitle = folderNode.node.name; - this.nestedFolders = - folderNode.children != null && folderNode.children.length > 0 - ? folderNode.children - : null; - } - } else { - this.noneFolder = true; - this.groupingTitle = this.i18nService.t("noneFolder"); - } - await this.load(this.buildFilter()); - } else if (params.collectionId) { - this.showVaultFilter = false; - this.collectionId = params.collectionId; - this.searchPlaceholder = this.i18nService.t("searchCollection"); - const collectionNode = await this.collectionService.getNested(this.collectionId); - if (collectionNode != null && collectionNode.node != null) { - this.groupingTitle = collectionNode.node.name; - this.nestedCollections = - collectionNode.children != null && collectionNode.children.length > 0 - ? collectionNode.children - : null; - } - await this.load( - (c) => c.collectionIds != null && c.collectionIds.indexOf(this.collectionId) > -1, - ); - } else { - this.showVaultFilter = true; - this.groupingTitle = this.i18nService.t("allItems"); - await this.load(this.buildFilter()); - } - - if (this.applySavedState && this.state != null) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserPopupUtils.setContentScrollY(window, this.state.scrollY, { - delay: 0, - containerSelector: this.scrollingContainer, - }); - } - await this.stateService.setBrowserVaultItemsComponentState(null); - }); - - this.broadcasterService.subscribe(ComponentId, (message: any) => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.ngZone.run(async () => { - switch (message.command) { - case "syncCompleted": - if (message.successfully) { - window.setTimeout(() => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.refresh(); - }, 500); - } - break; - default: - break; - } - - this.changeDetectorRef.detectChanges(); - }); - }); - } - - ngOnDestroy() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.saveState(); - this.broadcasterService.unsubscribe(ComponentId); - } - - selectCipher(cipher: CipherView) { - this.selectedTimeout = window.setTimeout(() => { - if (!this.preventSelected) { - super.selectCipher(cipher); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/view-cipher"], { - queryParams: { cipherId: cipher.id, collectionId: this.collectionId }, - }); - } - this.preventSelected = false; - }, 200); - } - - selectFolder(folder: FolderView) { - if (folder.id != null) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/ciphers"], { queryParams: { folderId: folder.id } }); - } - } - - selectCollection(collection: CollectionView) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/ciphers"], { queryParams: { collectionId: collection.id } }); - } - - async launchCipher(cipher: CipherView) { - if (cipher.type !== CipherType.Login || !cipher.login.canLaunch) { - return; - } - - if (this.selectedTimeout != null) { - window.clearTimeout(this.selectedTimeout); - } - this.preventSelected = true; - await this.cipherService.updateLastLaunchedDate(cipher.id); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserApi.createNewTab(cipher.login.launchUri); - if (BrowserPopupUtils.inPopup(window)) { - BrowserApi.closePopup(window); - } - } - - addCipher() { - if (this.deleted) { - return false; - } - super.addCipher(); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/add-cipher"], { - queryParams: { - folderId: this.folderId, - type: this.type, - collectionId: this.collectionId, - selectedVault: this.vaultFilter.selectedOrganizationId, - }, - }); - } - - back() { - (window as any).routeDirection = "b"; - this.location.back(); - } - - showGroupings() { - return ( - !this.isSearching() && - ((this.nestedFolders && this.nestedFolders.length) || - (this.nestedCollections && this.nestedCollections.length)) - ); - } - - async changeVaultSelection() { - this.vaultFilter = this.vaultFilterService.getVaultFilter(); - await this.load(this.buildFilter(), this.deleted); - } - - private buildFilter(): (cipher: CipherView) => boolean { - return (cipher) => { - let cipherPassesFilter = true; - if (this.deleted && cipherPassesFilter) { - cipherPassesFilter = cipher.isDeleted; - } - if (this.type != null && cipherPassesFilter) { - cipherPassesFilter = cipher.type === this.type; - } - if (this.folderId != null && this.folderId != "none" && cipherPassesFilter) { - cipherPassesFilter = cipher.folderId === this.folderId; - } - if (this.noneFolder) { - cipherPassesFilter = cipher.folderId == null; - } - if (this.collectionId != null && cipherPassesFilter) { - cipherPassesFilter = - cipher.collectionIds != null && cipher.collectionIds.indexOf(this.collectionId) > -1; - } - if (this.vaultFilter.selectedOrganizationId != null && cipherPassesFilter) { - cipherPassesFilter = cipher.organizationId === this.vaultFilter.selectedOrganizationId; - } - if (this.vaultFilter.myVaultOnly && cipherPassesFilter) { - cipherPassesFilter = cipher.organizationId === null; - } - return cipherPassesFilter; - }; - } - - private async saveState() { - this.state = { - scrollY: BrowserPopupUtils.getContentScrollY(window, this.scrollingContainer), - searchText: this.searchText, - }; - await this.stateService.setBrowserVaultItemsComponentState(this.state); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/vault-select.component.html b/apps/browser/src/vault/popup/components/vault/vault-select.component.html deleted file mode 100644 index 4f6ce3a11e6..00000000000 --- a/apps/browser/src/vault/popup/components/vault/vault-select.component.html +++ /dev/null @@ -1,82 +0,0 @@ - -
- - - - - - -
-
diff --git a/apps/browser/src/vault/popup/components/vault/vault-select.component.ts b/apps/browser/src/vault/popup/components/vault/vault-select.component.ts deleted file mode 100644 index 3c5061a516f..00000000000 --- a/apps/browser/src/vault/popup/components/vault/vault-select.component.ts +++ /dev/null @@ -1,227 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { animate, state, style, transition, trigger } from "@angular/animations"; -import { ConnectedPosition, Overlay, OverlayRef } from "@angular/cdk/overlay"; -import { TemplatePortal } from "@angular/cdk/portal"; -import { - Component, - ElementRef, - EventEmitter, - HostListener, - OnDestroy, - OnInit, - Output, - TemplateRef, - ViewChild, - ViewContainerRef, -} from "@angular/core"; -import { - BehaviorSubject, - combineLatest, - concatMap, - map, - merge, - Observable, - Subject, - takeUntil, -} 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; - -import { VaultFilterService } from "../../../services/vault-filter.service"; - -@Component({ - selector: "app-vault-select", - templateUrl: "vault-select.component.html", - animations: [ - trigger("transformPanel", [ - state( - "void", - style({ - opacity: 0, - }), - ), - transition( - "void => open", - animate( - "100ms linear", - style({ - opacity: 1, - }), - ), - ), - transition("* => void", animate("100ms linear", style({ opacity: 0 }))), - ]), - ], -}) -export class VaultSelectComponent implements OnInit, OnDestroy { - @Output() onVaultSelectionChanged = new EventEmitter(); - - @ViewChild("toggleVaults", { read: ElementRef }) - buttonRef: ElementRef; - @ViewChild("vaultSelectorTemplate", { read: TemplateRef }) templateRef: TemplateRef; - - private _selectedVault = new BehaviorSubject(null); - - isOpen = false; - loaded = false; - organizations$: Observable; - selectedVault$: Observable = this._selectedVault.asObservable(); - - enforcePersonalOwnership = false; - overlayPosition: ConnectedPosition[] = [ - { - originX: "start", - originY: "bottom", - overlayX: "start", - overlayY: "top", - }, - ]; - - private overlayRef: OverlayRef; - private _destroy = new Subject(); - - shouldShow(organizations: Organization[]): boolean { - return ( - (organizations.length > 0 && !this.enforcePersonalOwnership) || - (organizations.length > 1 && this.enforcePersonalOwnership) - ); - } - - constructor( - private vaultFilterService: VaultFilterService, - private i18nService: I18nService, - private overlay: Overlay, - private viewContainerRef: ViewContainerRef, - private platformUtilsService: PlatformUtilsService, - private organizationService: OrganizationService, - private policyService: PolicyService, - ) {} - - @HostListener("document:keydown.escape", ["$event"]) - handleKeyboardEvent(event: KeyboardEvent) { - if (this.isOpen) { - event.preventDefault(); - this.close(); - } - } - - async ngOnInit() { - this.organizations$ = this.organizationService.memberOrganizations$ - .pipe(takeUntil(this._destroy)) - .pipe(map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name")))); - - combineLatest([ - this.organizations$, - this.policyService.policyAppliesToActiveUser$(PolicyType.PersonalOwnership), - ]) - .pipe( - concatMap(async ([organizations, enforcePersonalOwnership]) => { - this.enforcePersonalOwnership = enforcePersonalOwnership; - - if (this.shouldShow(organizations)) { - if (this.enforcePersonalOwnership && !this.vaultFilterService.vaultFilter.myVaultOnly) { - const firstOrganization = organizations[0]; - this._selectedVault.next(firstOrganization.name); - this.vaultFilterService.setVaultFilter(firstOrganization.id); - } else if (this.vaultFilterService.vaultFilter.myVaultOnly) { - this._selectedVault.next(this.i18nService.t(this.vaultFilterService.myVault)); - } else if (this.vaultFilterService.vaultFilter.selectedOrganizationId != null) { - const selectedOrganization = organizations.find( - (o) => o.id === this.vaultFilterService.vaultFilter.selectedOrganizationId, - ); - this._selectedVault.next(selectedOrganization.name); - } else { - this._selectedVault.next(this.i18nService.t(this.vaultFilterService.allVaults)); - } - } - }), - ) - .pipe(takeUntil(this._destroy)) - .subscribe(); - - this.loaded = true; - } - - ngOnDestroy(): void { - this._destroy.next(); - this._destroy.complete(); - this._selectedVault.complete(); - } - - openOverlay() { - const viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); - const positionStrategyBuilder = this.overlay.position(); - - const positionStrategy = positionStrategyBuilder - .flexibleConnectedTo(this.buttonRef.nativeElement) - .withFlexibleDimensions(true) - .withPush(true) - .withViewportMargin(10) - .withGrowAfterOpen(true) - .withPositions(this.overlayPosition); - - this.overlayRef = this.overlay.create({ - hasBackdrop: true, - positionStrategy, - maxHeight: viewPortHeight - 160, - backdropClass: "cdk-overlay-transparent-backdrop", - scrollStrategy: this.overlay.scrollStrategies.close(), - }); - - const templatePortal = new TemplatePortal(this.templateRef, this.viewContainerRef); - this.overlayRef.attach(templatePortal); - this.isOpen = true; - - // Handle closing - merge( - this.overlayRef.outsidePointerEvents(), - this.overlayRef.backdropClick(), - this.overlayRef.detachments(), - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - ).subscribe(() => { - this.close(); - }); - } - - close() { - if (this.overlayRef) { - this.overlayRef.dispose(); - this.overlayRef = undefined; - } - this.isOpen = false; - } - - selectOrganization(organization: Organization) { - if (!organization.enabled) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("disabledOrganizationFilterError"), - ); - } else { - this._selectedVault.next(organization.name); - this.vaultFilterService.setVaultFilter(organization.id); - this.onVaultSelectionChanged.emit(); - this.close(); - } - } - selectAllVaults() { - this._selectedVault.next(this.i18nService.t(this.vaultFilterService.allVaults)); - this.vaultFilterService.setVaultFilter(this.vaultFilterService.allVaults); - this.onVaultSelectionChanged.emit(); - this.close(); - } - selectMyVault() { - this._selectedVault.next(this.i18nService.t(this.vaultFilterService.myVault)); - this.vaultFilterService.setVaultFilter(this.vaultFilterService.myVault); - this.onVaultSelectionChanged.emit(); - this.close(); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/view-custom-fields.component.html b/apps/browser/src/vault/popup/components/vault/view-custom-fields.component.html deleted file mode 100644 index 4fbca28734b..00000000000 --- a/apps/browser/src/vault/popup/components/vault/view-custom-fields.component.html +++ /dev/null @@ -1,98 +0,0 @@ - -

- {{ "customFields" | i18n }} -

-
-
-
- {{ field.name }} - {{ field.name }} -
- {{ field.value || " " }} -
-
- {{ field.maskedValue }} - - -
-
- - - {{ field.value }} -
-
-
- - {{ "linkedValue" | i18n }} -
- {{ cipher.linkedFieldI18nKey(field.linkedId) | i18n }} -
-
-
- - - -
-
-
-
diff --git a/apps/browser/src/vault/popup/components/vault/view-custom-fields.component.ts b/apps/browser/src/vault/popup/components/vault/view-custom-fields.component.ts deleted file mode 100644 index 249f83c4444..00000000000 --- a/apps/browser/src/vault/popup/components/vault/view-custom-fields.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component } from "@angular/core"; - -import { ViewCustomFieldsComponent as BaseViewCustomFieldsComponent } from "@bitwarden/angular/vault/components/view-custom-fields.component"; -import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; - -@Component({ - selector: "app-vault-view-custom-fields", - templateUrl: "view-custom-fields.component.html", -}) -export class ViewCustomFieldsComponent extends BaseViewCustomFieldsComponent { - constructor(eventCollectionService: EventCollectionService) { - super(eventCollectionService); - } -} diff --git a/apps/browser/src/vault/popup/components/vault/view.component.html b/apps/browser/src/vault/popup/components/vault/view.component.html deleted file mode 100644 index 57a5d007d8a..00000000000 --- a/apps/browser/src/vault/popup/components/vault/view.component.html +++ /dev/null @@ -1,719 +0,0 @@ -
-
- -
-

- {{ "viewItem" | i18n }} -

-
- -
-
-
-
-

- {{ "itemInformation" | i18n }} -

-
-
- - -
- -
-
-
- - -
-
- -
-
-
-
- {{ "password" | i18n }} -
- {{ cipher.login.maskedPassword }} -
-
-
-
-
- - - - -
-
- - -
-
-
- {{ "typePasskey" | i18n }} - {{ fido2CredentialCreationDateValue }} -
-
-
- -
-
- {{ "verificationCodeTotp" | i18n }} - {{ totpCodeFormatted }} -
- -
- -
-
-
-
- {{ "verificationCodeTotp" | i18n }} - - - {{ "premiumSubcriptionRequired" | i18n }} - - -
-
-
- -
-
- {{ "cardholderName" | i18n }} - {{ cipher.card.cardholderName }} -
-
-
- {{ "number" | i18n }} - {{ - cipher.card.maskedNumber | creditCardNumber: cipher.card.brand - }} - {{ - cipher.card.number | creditCardNumber: cipher.card.brand - }} -
-
- - -
-
-
- {{ "brand" | i18n }} - {{ cipher.card.brand }} -
-
- {{ "expiration" | i18n }} - {{ cipher.card.expiration }} -
-
-
- {{ "securityCode" | i18n }} - {{ cipher.card.maskedCode }} - {{ cipher.card.code }} -
-
- - -
-
-
- -
-
- {{ "identityName" | i18n }} - {{ cipher.identity.fullName }} -
-
- {{ "username" | i18n }} - {{ cipher.identity.username }} -
-
- {{ "company" | i18n }} - {{ cipher.identity.company }} -
-
- {{ "ssn" | i18n }} - {{ cipher.identity.ssn }} -
-
- {{ "passportNumber" | i18n }} - {{ cipher.identity.passportNumber }} -
-
- {{ "licenseNumber" | i18n }} - {{ cipher.identity.licenseNumber }} -
-
- {{ "email" | i18n }} - {{ cipher.identity.email }} -
-
- {{ "phone" | i18n }} - {{ cipher.identity.phone }} -
-
- {{ "address" | i18n }} -
{{ cipher.identity.address1 }}
-
{{ cipher.identity.address2 }}
-
{{ cipher.identity.address3 }}
-
{{ cipher.identity.fullAddressPart2 }}
-
{{ cipher.identity.country }}
-
-
- -
-
- - {{ "sshPrivateKey" | i18n }} - -
-
-
- - {{ "sshPublicKey" | i18n }} - {{ cipher.sshKey.publicKey }} -
-
- - {{ "sshFingerprint" | i18n }} - {{ cipher.sshKey.keyFingerprint }} -
-
-
-
-
-
-
-
- - - - - -
-
- - -
-
-
-
-
-
-
- - -
-
-
-
-

- -

-
-
- -
-
-
-
- -
-
-

- {{ "attachments" | i18n }} -

-
- -
-
-
-
- - - - - - -
-
-
- -
-
diff --git a/apps/browser/src/vault/popup/components/vault/view.component.ts b/apps/browser/src/vault/popup/components/vault/view.component.ts deleted file mode 100644 index 242cff03c75..00000000000 --- a/apps/browser/src/vault/popup/components/vault/view.component.ts +++ /dev/null @@ -1,443 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { DatePipe, Location } from "@angular/common"; -import { ChangeDetectorRef, Component, NgZone, OnInit, OnDestroy } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { Subject, firstValueFrom, takeUntil, Subscription } from "rxjs"; -import { first, map } from "rxjs/operators"; - -import { ViewComponent as BaseViewComponent } from "@bitwarden/angular/vault/components/view.component"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; -import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/abstractions/totp.service"; -import { CipherType } from "@bitwarden/common/vault/enums"; -import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; -import { LoginUriView } from "@bitwarden/common/vault/models/view/login-uri.view"; -import { CipherAuthorizationService } from "@bitwarden/common/vault/services/cipher-authorization.service"; -import { DialogService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; -import { PasswordRepromptService } from "@bitwarden/vault"; - -import { BrowserFido2UserInterfaceSession } from "../../../../autofill/fido2/services/browser-fido2-user-interface.service"; -import { AutofillService } from "../../../../autofill/services/abstractions/autofill.service"; -import { BrowserApi } from "../../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../../platform/popup/browser-popup-utils"; -import { fido2PopoutSessionData$ } from "../../utils/fido2-popout-session-data"; -import { closeViewVaultItemPopout, VaultPopoutType } from "../../utils/vault-popout-window"; - -const BroadcasterSubscriptionId = "ChildViewComponent"; - -export const AUTOFILL_ID = "autofill"; -export const SHOW_AUTOFILL_BUTTON = "show-autofill-button"; -export const COPY_USERNAME_ID = "copy-username"; -export const COPY_PASSWORD_ID = "copy-password"; -export const COPY_VERIFICATION_CODE_ID = "copy-totp"; - -type CopyAction = - | typeof COPY_USERNAME_ID - | typeof COPY_PASSWORD_ID - | typeof COPY_VERIFICATION_CODE_ID; -type LoadAction = typeof AUTOFILL_ID | typeof SHOW_AUTOFILL_BUTTON | CopyAction; - -@Component({ - selector: "app-vault-view", - templateUrl: "view.component.html", -}) -export class ViewComponent extends BaseViewComponent implements OnInit, OnDestroy { - showAttachments = true; - pageDetails: any[] = []; - tab: any; - senderTabId?: number; - loadAction?: LoadAction; - private static readonly copyActions = new Set([ - COPY_USERNAME_ID, - COPY_PASSWORD_ID, - COPY_VERIFICATION_CODE_ID, - ]); - uilocation?: "popout" | "popup" | "sidebar" | "tab"; - loadPageDetailsTimeout: number; - inPopout = false; - cipherType = CipherType; - private fido2PopoutSessionData$ = fido2PopoutSessionData$(); - private collectPageDetailsSubscription: Subscription; - - private destroy$ = new Subject(); - - constructor( - cipherService: CipherService, - folderService: FolderService, - totpService: TotpServiceAbstraction, - tokenService: TokenService, - i18nService: I18nService, - keyService: KeyService, - encryptService: EncryptService, - platformUtilsService: PlatformUtilsService, - auditService: AuditService, - private route: ActivatedRoute, - private router: Router, - private location: Location, - broadcasterService: BroadcasterService, - ngZone: NgZone, - changeDetectorRef: ChangeDetectorRef, - stateService: StateService, - eventCollectionService: EventCollectionService, - private autofillService: AutofillService, - private messagingService: MessagingService, - apiService: ApiService, - passwordRepromptService: PasswordRepromptService, - logService: LogService, - fileDownloadService: FileDownloadService, - dialogService: DialogService, - datePipe: DatePipe, - accountService: AccountService, - billingAccountProfileStateService: BillingAccountProfileStateService, - cipherAuthorizationService: CipherAuthorizationService, - ) { - super( - cipherService, - folderService, - totpService, - tokenService, - i18nService, - keyService, - encryptService, - platformUtilsService, - auditService, - window, - broadcasterService, - ngZone, - changeDetectorRef, - eventCollectionService, - apiService, - passwordRepromptService, - logService, - stateService, - fileDownloadService, - dialogService, - datePipe, - accountService, - billingAccountProfileStateService, - cipherAuthorizationService, - ); - } - - ngOnInit() { - this.route.queryParams.pipe(takeUntil(this.destroy$)).subscribe((value) => { - this.loadAction = value?.action; - this.senderTabId = parseInt(value?.senderTabId, 10) || undefined; - this.uilocation = value?.uilocation; - }); - - this.inPopout = this.uilocation === "popout" || BrowserPopupUtils.inPopout(window); - - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - if (params.cipherId) { - this.cipherId = params.cipherId; - } - - if (params.collectionId) { - this.collectionId = params.collectionId; - } - - if (!params.cipherId) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.close(); - } - - await this.load(); - }); - - super.ngOnInit(); - - this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.ngZone.run(async () => { - switch (message.command) { - case "tabChanged": - case "windowChanged": - if (this.loadPageDetailsTimeout != null) { - window.clearTimeout(this.loadPageDetailsTimeout); - } - this.loadPageDetailsTimeout = window.setTimeout(() => this.loadPageDetails(), 500); - break; - default: - break; - } - }); - }); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - super.ngOnDestroy(); - this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); - } - - async load() { - await super.load(); - await this.loadPageDetails(); - await this.handleLoadAction(); - } - - async edit() { - if (this.cipher.isDeleted) { - return false; - } - if (!(await super.edit())) { - return false; - } - - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/edit-cipher"], { - queryParams: { - cipherId: this.cipher.id, - type: this.cipher.type, - isNew: false, - collectionId: this.collectionId, - }, - }); - return true; - } - - async clone() { - if (this.cipher.isDeleted) { - return false; - } - - if (!(await super.clone())) { - return false; - } - - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/clone-cipher"], { - queryParams: { - cloneMode: true, - cipherId: this.cipher.id, - }, - }); - return true; - } - - async share() { - if (!(await super.share())) { - return false; - } - - if (this.cipher.organizationId == null) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/share-cipher"], { - replaceUrl: true, - queryParams: { cipherId: this.cipher.id }, - }); - } - return true; - } - - async fillCipher() { - const didAutofill = await this.doAutofill(); - if (didAutofill) { - this.platformUtilsService.showToast("success", null, this.i18nService.t("autoFillSuccess")); - } - - return didAutofill; - } - - async fillCipherAndSave() { - const didAutofill = await this.doAutofill(); - - if (didAutofill) { - if (this.tab == null) { - throw new Error("No tab found."); - } - - if (this.cipher.login.uris == null) { - this.cipher.login.uris = []; - } else { - if (this.cipher.login.uris.some((uri) => uri.uri === this.tab.url)) { - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("autoFillSuccessAndSavedUri"), - ); - return; - } - } - - const loginUri = new LoginUriView(); - loginUri.uri = this.tab.url; - this.cipher.login.uris.push(loginUri); - - try { - const activeUserId = await firstValueFrom( - this.accountService.activeAccount$.pipe(map((a) => a?.id)), - ); - const cipher: Cipher = await this.cipherService.encrypt(this.cipher, activeUserId); - await this.cipherService.updateWithServer(cipher); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("autoFillSuccessAndSavedUri"), - ); - this.messagingService.send("editedCipher"); - } catch { - this.platformUtilsService.showToast("error", null, this.i18nService.t("unexpectedError")); - } - } - } - - async restore() { - if (!this.cipher.isDeleted) { - return false; - } - if (await super.restore()) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.close(); - return true; - } - return false; - } - - async delete() { - if (await super.delete()) { - this.messagingService.send("deletedCipher"); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.close(); - return true; - } - return false; - } - - async close() { - const sessionData = await firstValueFrom(this.fido2PopoutSessionData$); - if (this.inPopout && sessionData.isFido2Session) { - BrowserFido2UserInterfaceSession.abortPopout(sessionData.sessionId); - return; - } - - if ( - BrowserPopupUtils.inSingleActionPopout(window, VaultPopoutType.viewVaultItem) && - this.senderTabId - ) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - BrowserApi.focusTab(this.senderTabId); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - closeViewVaultItemPopout(`${VaultPopoutType.viewVaultItem}_${this.cipher.id}`); - return; - } - - this.location.back(); - } - - private async loadPageDetails() { - this.collectPageDetailsSubscription?.unsubscribe(); - this.pageDetails = []; - this.tab = this.senderTabId - ? await BrowserApi.getTab(this.senderTabId) - : await BrowserApi.getTabFromCurrentWindow(); - - if (!this.tab) { - return; - } - - this.collectPageDetailsSubscription = this.autofillService - .collectPageDetailsFromTab$(this.tab) - .pipe(takeUntil(this.destroy$)) - .subscribe((pageDetails) => (this.pageDetails = pageDetails)); - } - - private async doAutofill() { - const originalTabURL = this.tab.url?.length && new URL(this.tab.url); - - if (!(await this.promptPassword())) { - return false; - } - - const currentTabURL = this.tab.url?.length && new URL(this.tab.url); - - const originalTabHostPath = - originalTabURL && `${originalTabURL.origin}${originalTabURL.pathname}`; - const currentTabHostPath = currentTabURL && `${currentTabURL.origin}${currentTabURL.pathname}`; - - const tabUrlChanged = originalTabHostPath !== currentTabHostPath; - - if (this.pageDetails == null || this.pageDetails.length === 0 || tabUrlChanged) { - this.platformUtilsService.showToast("error", null, this.i18nService.t("autofillError")); - return false; - } - - try { - this.totpCode = await this.autofillService.doAutoFill({ - tab: this.tab, - cipher: this.cipher, - pageDetails: this.pageDetails, - doc: window.document, - fillNewPassword: true, - allowTotpAutofill: true, - }); - if (this.totpCode != null) { - this.platformUtilsService.copyToClipboard(this.totpCode, { window: window }); - } - } catch { - this.platformUtilsService.showToast("error", null, this.i18nService.t("autofillError")); - this.changeDetectorRef.detectChanges(); - return false; - } - - return true; - } - - private async handleLoadAction() { - if (!this.loadAction || this.loadAction === SHOW_AUTOFILL_BUTTON) { - return; - } - - let loadActionSuccess = false; - if (this.loadAction === AUTOFILL_ID) { - loadActionSuccess = await this.fillCipher(); - } - - if (ViewComponent.copyActions.has(this.loadAction)) { - const { username, password } = this.cipher.login; - const copyParams: Record> = { - [COPY_USERNAME_ID]: { value: username, type: "username", name: "Username" }, - [COPY_PASSWORD_ID]: { value: password, type: "password", name: "Password" }, - [COPY_VERIFICATION_CODE_ID]: { - value: this.totpCode, - type: "verificationCodeTotp", - name: "TOTP", - }, - }; - const { value, type, name } = copyParams[this.loadAction as CopyAction]; - loadActionSuccess = await this.copy(value, type, name); - } - - if (this.inPopout) { - setTimeout(() => this.close(), loadActionSuccess ? 1000 : 0); - } - } -} diff --git a/apps/browser/src/vault/popup/settings/appearance.component.html b/apps/browser/src/vault/popup/settings/appearance.component.html deleted file mode 100644 index a431fc72a1f..00000000000 --- a/apps/browser/src/vault/popup/settings/appearance.component.html +++ /dev/null @@ -1,80 +0,0 @@ -
-
- -
-

- {{ "appearance" | i18n }} -

-
- -
-
-
-
-
-
- - -
-
- -
-
-
-
- - -
-
- -
-
-
-
- - -
-
- -
-
-
-
- - -
-
-
-
diff --git a/apps/browser/src/vault/popup/settings/appearance.component.ts b/apps/browser/src/vault/popup/settings/appearance.component.ts deleted file mode 100644 index e6d03c5b01f..00000000000 --- a/apps/browser/src/vault/popup/settings/appearance.component.ts +++ /dev/null @@ -1,75 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, OnInit } from "@angular/core"; -import { firstValueFrom } from "rxjs"; - -import { BadgeSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/badge-settings.service"; -import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; -import { AnimationControlService } from "@bitwarden/common/platform/abstractions/animation-control.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -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 { enableAccountSwitching } from "../../../platform/flags"; - -@Component({ - selector: "vault-appearance", - templateUrl: "appearance.component.html", -}) -export class AppearanceComponent implements OnInit { - enableFavicon = false; - enableBadgeCounter = true; - theme: ThemeType; - themeOptions: any[]; - accountSwitcherEnabled = false; - enableRoutingAnimation: boolean; - - constructor( - private messagingService: MessagingService, - private domainSettingsService: DomainSettingsService, - private badgeSettingsService: BadgeSettingsServiceAbstraction, - i18nService: I18nService, - private themeStateService: ThemeStateService, - private animationControlService: AnimationControlService, - ) { - this.themeOptions = [ - { name: i18nService.t("default"), value: ThemeType.System }, - { name: i18nService.t("light"), value: ThemeType.Light }, - { name: i18nService.t("dark"), value: ThemeType.Dark }, - { name: "Nord", value: ThemeType.Nord }, - { name: i18nService.t("solarizedDark"), value: ThemeType.SolarizedDark }, - ]; - - this.accountSwitcherEnabled = enableAccountSwitching(); - } - - async ngOnInit() { - this.enableRoutingAnimation = await firstValueFrom( - this.animationControlService.enableRoutingAnimation$, - ); - - this.enableFavicon = await firstValueFrom(this.domainSettingsService.showFavicons$); - - this.enableBadgeCounter = await firstValueFrom(this.badgeSettingsService.enableBadgeCounter$); - - this.theme = await firstValueFrom(this.themeStateService.selectedTheme$); - } - - async updateRoutingAnimation() { - await this.animationControlService.setEnableRoutingAnimation(this.enableRoutingAnimation); - } - - async updateFavicon() { - await this.domainSettingsService.setShowFavicons(this.enableFavicon); - } - - async updateBadgeCounter() { - await this.badgeSettingsService.setEnableBadgeCounter(this.enableBadgeCounter); - this.messagingService.send("bgUpdateContextMenu"); - } - - async saveTheme() { - await this.themeStateService.setSelectedTheme(this.theme); - } -} diff --git a/apps/browser/src/vault/popup/settings/folder-add-edit.component.html b/apps/browser/src/vault/popup/settings/folder-add-edit.component.html deleted file mode 100644 index 14393b83ddc..00000000000 --- a/apps/browser/src/vault/popup/settings/folder-add-edit.component.html +++ /dev/null @@ -1,49 +0,0 @@ -
-
-
- -
-

- {{ title }} -

-
- -
-
-
-
-
-
- - -
-
-
-
-
- -
-
-
-
diff --git a/apps/browser/src/vault/popup/settings/folder-add-edit.component.ts b/apps/browser/src/vault/popup/settings/folder-add-edit.component.ts deleted file mode 100644 index 122922a4d2d..00000000000 --- a/apps/browser/src/vault/popup/settings/folder-add-edit.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Component, OnInit } from "@angular/core"; -import { FormBuilder } from "@angular/forms"; -import { ActivatedRoute, Router } from "@angular/router"; -import { first } from "rxjs/operators"; - -import { FolderAddEditComponent as BaseFolderAddEditComponent } from "@bitwarden/angular/vault/components/folder-add-edit.component"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction"; -import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; -import { DialogService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; - -@Component({ - selector: "app-folder-add-edit", - templateUrl: "folder-add-edit.component.html", -}) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class FolderAddEditComponent extends BaseFolderAddEditComponent implements OnInit { - constructor( - folderService: FolderService, - folderApiService: FolderApiServiceAbstraction, - accountService: AccountService, - keyService: KeyService, - i18nService: I18nService, - platformUtilsService: PlatformUtilsService, - private router: Router, - private route: ActivatedRoute, - logService: LogService, - dialogService: DialogService, - formBuilder: FormBuilder, - ) { - super( - folderService, - folderApiService, - accountService, - keyService, - i18nService, - platformUtilsService, - logService, - dialogService, - formBuilder, - ); - } - - async ngOnInit() { - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (params) => { - if (params.folderId) { - this.folderId = params.folderId; - } - await this.init(); - }); - } - - async submit(): Promise { - if (await super.submit()) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/folders"]); - return true; - } - - return false; - } - - async delete(): Promise { - const confirmed = await super.delete(); - if (confirmed) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/folders"]); - } - return confirmed; - } -} diff --git a/apps/browser/src/vault/popup/settings/folders.component.html b/apps/browser/src/vault/popup/settings/folders.component.html deleted file mode 100644 index 47cdb0188d2..00000000000 --- a/apps/browser/src/vault/popup/settings/folders.component.html +++ /dev/null @@ -1,38 +0,0 @@ -
-
- -
-

- {{ "folders" | i18n }} -

-
- -
-
-
- -
-
- -
-
-
- -
-

{{ "noFolders" | i18n }}

-
-
-
diff --git a/apps/browser/src/vault/popup/settings/folders.component.ts b/apps/browser/src/vault/popup/settings/folders.component.ts deleted file mode 100644 index 1e3f182b43d..00000000000 --- a/apps/browser/src/vault/popup/settings/folders.component.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Component } from "@angular/core"; -import { Router } from "@angular/router"; -import { filter, map, Observable, switchMap } from "rxjs"; - -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { UserId } from "@bitwarden/common/types/guid"; -import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; -import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; - -@Component({ - selector: "app-folders", - templateUrl: "folders.component.html", -}) -export class FoldersComponent { - folders$: Observable; - - private activeUserId$ = this.accountService.activeAccount$.pipe(map((a) => a?.id)); - - constructor( - private folderService: FolderService, - private router: Router, - private accountService: AccountService, - ) { - this.folders$ = this.activeUserId$.pipe( - filter((userId): userId is UserId => userId != null), - switchMap((userId) => this.folderService.folderViews$(userId)), - map((folders) => { - // Remove the last folder, which is the "no folder" option folder - if (folders.length > 0) { - return folders.slice(0, folders.length - 1); - } - return folders; - }), - ); - } - - folderSelected(folder: FolderView) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/edit-folder"], { queryParams: { folderId: folder.id } }); - } - - addFolder() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/add-folder"]); - } -} diff --git a/apps/browser/src/vault/popup/settings/sync.component.html b/apps/browser/src/vault/popup/settings/sync.component.html deleted file mode 100644 index 6d0a1c31a8b..00000000000 --- a/apps/browser/src/vault/popup/settings/sync.component.html +++ /dev/null @@ -1,35 +0,0 @@ -
-
- -
-

- {{ "sync" | i18n }} -

-
-
-
-
- -

- {{ "lastSync" | i18n }} {{ lastSync }} -

-
-
diff --git a/apps/browser/src/vault/popup/settings/sync.component.ts b/apps/browser/src/vault/popup/settings/sync.component.ts deleted file mode 100644 index 6585a71d94b..00000000000 --- a/apps/browser/src/vault/popup/settings/sync.component.ts +++ /dev/null @@ -1,46 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, OnInit } from "@angular/core"; - -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { SyncService } from "@bitwarden/common/platform/sync"; - -@Component({ - selector: "app-sync", - templateUrl: "sync.component.html", -}) -export class SyncComponent implements OnInit { - lastSync = "--"; - syncPromise: Promise; - - constructor( - private syncService: SyncService, - private platformUtilsService: PlatformUtilsService, - private i18nService: I18nService, - ) {} - - async ngOnInit() { - await this.setLastSync(); - } - - async sync() { - this.syncPromise = this.syncService.fullSync(true); - const success = await this.syncPromise; - if (success) { - await this.setLastSync(); - this.platformUtilsService.showToast("success", null, this.i18nService.t("syncingComplete")); - } else { - this.platformUtilsService.showToast("error", null, this.i18nService.t("syncingFailed")); - } - } - - async setLastSync() { - const last = await this.syncService.getLastSync(); - if (last != null) { - this.lastSync = last.toLocaleDateString() + " " + last.toLocaleTimeString(); - } else { - this.lastSync = this.i18nService.t("never"); - } - } -} diff --git a/apps/browser/src/vault/popup/settings/vault-settings.component.html b/apps/browser/src/vault/popup/settings/vault-settings.component.html deleted file mode 100644 index 4928720e46e..00000000000 --- a/apps/browser/src/vault/popup/settings/vault-settings.component.html +++ /dev/null @@ -1,56 +0,0 @@ - -
- -
-

- {{ "vault" | i18n }} -

-
- -
-
-
-
-
- - - - -
-
-
diff --git a/apps/browser/src/vault/popup/settings/vault-settings.component.ts b/apps/browser/src/vault/popup/settings/vault-settings.component.ts deleted file mode 100644 index a12f6d1d5be..00000000000 --- a/apps/browser/src/vault/popup/settings/vault-settings.component.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Component } from "@angular/core"; -import { Router } from "@angular/router"; - -import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; - -import { BrowserApi } from "../../../platform/browser/browser-api"; -import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; - -@Component({ - selector: "vault-settings", - templateUrl: "vault-settings.component.html", -}) -export class VaultSettingsComponent { - constructor( - public messagingService: MessagingService, - private router: Router, - ) {} - - async import() { - await this.router.navigate(["/import"]); - if (await BrowserApi.isPopupOpen()) { - await BrowserPopupUtils.openCurrentPagePopout(window); - } - } -} From 066773e9834e679afe308ef1b215b9c280f3dd1b Mon Sep 17 00:00:00 2001 From: Brandon Treston Date: Mon, 6 Jan 2025 16:05:29 -0500 Subject: [PATCH 57/65] [PM-16524] move integration page shared components into admin console ownership (#12664) * move integrations shared components to AC ownership * fix stories --- .../integrations/integrations.component.ts | 4 +++- .../shared/components/integrations/index.ts | 4 ++++ .../integration-card.component.html | 0 .../integration-card.component.spec.ts | 0 .../integration-card.component.ts | 2 +- .../integration-card.stories.ts | 17 ++++++--------- .../integration-grid.component.html | 0 .../integration-grid.component.spec.ts | 0 .../integration-grid.component.ts | 2 +- .../integration-grid.stories.ts | 21 +++++++------------ .../integrations/integrations.pipe.ts | 0 .../shared/components/integrations/models.ts | 0 apps/web/src/app/shared/components/index.ts | 4 ---- apps/web/src/app/shared/index.ts | 1 - .../integrations.component.spec.ts | 7 +++---- .../integrations/integrations.component.ts | 2 +- .../integrations/integrations.module.ts | 6 ++---- 17 files changed, 28 insertions(+), 42 deletions(-) create mode 100644 apps/web/src/app/admin-console/organizations/shared/components/integrations/index.ts rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-card/integration-card.component.html (100%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-card/integration-card.component.spec.ts (100%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-card/integration-card.component.ts (97%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-card/integration-card.stories.ts (74%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-grid/integration-grid.component.html (100%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-grid/integration-grid.component.spec.ts (100%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-grid/integration-grid.component.ts (91%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integration-grid/integration-grid.stories.ts (75%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/integrations.pipe.ts (100%) rename apps/web/src/app/{ => admin-console/organizations}/shared/components/integrations/models.ts (100%) delete mode 100644 apps/web/src/app/shared/components/index.ts diff --git a/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts b/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts index d7ab6a6f617..e3edb41de76 100644 --- a/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts +++ b/apps/web/src/app/admin-console/organizations/integrations/integrations.component.ts @@ -9,9 +9,11 @@ import { Organization } from "@bitwarden/common/admin-console/models/domain/orga import { IntegrationType } from "@bitwarden/common/enums"; import { HeaderModule } from "../../../layouts/header/header.module"; -import { FilterIntegrationsPipe, IntegrationGridComponent, Integration } from "../../../shared/"; import { SharedModule } from "../../../shared/shared.module"; import { SharedOrganizationModule } from "../shared"; +import { IntegrationGridComponent } from "../shared/components/integrations/integration-grid/integration-grid.component"; +import { FilterIntegrationsPipe } from "../shared/components/integrations/integrations.pipe"; +import { Integration } from "../shared/components/integrations/models"; @Component({ selector: "ac-integrations", diff --git a/apps/web/src/app/admin-console/organizations/shared/components/integrations/index.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/index.ts new file mode 100644 index 00000000000..c8fe9d32652 --- /dev/null +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/index.ts @@ -0,0 +1,4 @@ +export * from "./integrations.pipe"; +export * from "./integration-card/integration-card.component"; +export * from "./integration-grid/integration-grid.component"; +export * from "./models"; diff --git a/apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.html b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.html similarity index 100% rename from apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.html rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.html diff --git a/apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.spec.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.spec.ts similarity index 100% rename from apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.spec.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.spec.ts diff --git a/apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts similarity index 97% rename from apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts index 5e47c1e0b31..681b93413e8 100644 --- a/apps/web/src/app/shared/components/integrations/integration-card/integration-card.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component.ts @@ -15,7 +15,7 @@ import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-t import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; -import { SharedModule } from "../../../shared.module"; +import { SharedModule } from "../../../../../../shared/shared.module"; @Component({ selector: "app-integration-card", diff --git a/apps/web/src/app/shared/components/integrations/integration-card/integration-card.stories.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.stories.ts similarity index 74% rename from apps/web/src/app/shared/components/integrations/integration-card/integration-card.stories.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.stories.ts index 1d1e229740f..256bfd3d827 100644 --- a/apps/web/src/app/shared/components/integrations/integration-card/integration-card.stories.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.stories.ts @@ -1,13 +1,12 @@ -import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; +import { importProvidersFrom } from "@angular/core"; +import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; import { of } from "rxjs"; import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-tokens"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ThemeTypes } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; -import { I18nMockService } from "@bitwarden/components"; -import { SharedModule } from "../../../shared.module"; +import { PreloadedEnglishI18nModule } from "../../../../../../core/tests"; import { IntegrationCardComponent } from "./integration-card.component"; @@ -17,15 +16,11 @@ export default { title: "Web/Integration Layout/Integration Card", component: IntegrationCardComponent, decorators: [ + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), moduleMetadata({ - imports: [SharedModule], providers: [ - { - provide: I18nService, - useFactory: () => { - return new I18nMockService({}); - }, - }, { provide: ThemeStateService, useClass: MockThemeService, diff --git a/apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.html b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.html similarity index 100% rename from apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.html rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.html diff --git a/apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.spec.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.spec.ts similarity index 100% rename from apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.spec.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.spec.ts diff --git a/apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts similarity index 91% rename from apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts index 1ec3f0d8d48..2e3158f9894 100644 --- a/apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.component.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component.ts @@ -4,7 +4,7 @@ import { Component, Input } from "@angular/core"; import { IntegrationType } from "@bitwarden/common/enums"; -import { SharedModule } from "../../../shared.module"; +import { SharedModule } from "../../../../../../shared/shared.module"; import { IntegrationCardComponent } from "../integration-card/integration-card.component"; import { Integration } from "../models"; diff --git a/apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.stories.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.stories.ts similarity index 75% rename from apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.stories.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.stories.ts index 2ec0bccec3d..b6580af2881 100644 --- a/apps/web/src/app/shared/components/integrations/integration-grid/integration-grid.stories.ts +++ b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.stories.ts @@ -1,14 +1,13 @@ -import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; +import { importProvidersFrom } from "@angular/core"; +import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; import { of } from "rxjs"; import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-tokens"; import { IntegrationType } from "@bitwarden/common/enums"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ThemeTypes } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; -import { I18nMockService } from "@bitwarden/components"; -import { SharedModule } from "../../../shared.module"; +import { PreloadedEnglishI18nModule } from "../../../../../../core/tests"; import { IntegrationCardComponent } from "../integration-card/integration-card.component"; import { IntegrationGridComponent } from "../integration-grid/integration-grid.component"; @@ -18,18 +17,12 @@ export default { title: "Web/Integration Layout/Integration Grid", component: IntegrationGridComponent, decorators: [ + applicationConfig({ + providers: [importProvidersFrom(PreloadedEnglishI18nModule)], + }), moduleMetadata({ - imports: [IntegrationCardComponent, SharedModule], + imports: [IntegrationCardComponent], providers: [ - { - provide: I18nService, - useFactory: () => { - return new I18nMockService({ - integrationCardAriaLabel: "Go to integration", - integrationCardTooltip: "Go to integration", - }); - }, - }, { provide: ThemeStateService, useClass: MockThemeService, diff --git a/apps/web/src/app/shared/components/integrations/integrations.pipe.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/integrations.pipe.ts similarity index 100% rename from apps/web/src/app/shared/components/integrations/integrations.pipe.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/integrations.pipe.ts diff --git a/apps/web/src/app/shared/components/integrations/models.ts b/apps/web/src/app/admin-console/organizations/shared/components/integrations/models.ts similarity index 100% rename from apps/web/src/app/shared/components/integrations/models.ts rename to apps/web/src/app/admin-console/organizations/shared/components/integrations/models.ts diff --git a/apps/web/src/app/shared/components/index.ts b/apps/web/src/app/shared/components/index.ts deleted file mode 100644 index 5745a7827ff..00000000000 --- a/apps/web/src/app/shared/components/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./integrations/integration-card/integration-card.component"; -export * from "./integrations/integration-grid/integration-grid.component"; -export * from "./integrations/integrations.pipe"; -export * from "./integrations/models"; diff --git a/apps/web/src/app/shared/index.ts b/apps/web/src/app/shared/index.ts index f57648c0e40..7defcdedfda 100644 --- a/apps/web/src/app/shared/index.ts +++ b/apps/web/src/app/shared/index.ts @@ -1,3 +1,2 @@ export * from "./shared.module"; export * from "./loose-components.module"; -export * from "./components/index"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts index e4a65f7ddd8..5d626da9364 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.spec.ts @@ -5,10 +5,9 @@ import { mock } from "jest-mock-extended"; import { of } from "rxjs"; import { SharedModule } from "@bitwarden/components/src/shared"; -import { - IntegrationCardComponent, - IntegrationGridComponent, -} from "@bitwarden/web-vault/app/shared"; +import { IntegrationCardComponent } from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component"; +import { IntegrationGridComponent } from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component"; +import {} from "@bitwarden/web-vault/app/shared"; import { SYSTEM_THEME_OBSERVABLE } from "../../../../../../libs/angular/src/services/injection-tokens"; import { I18nService } from "../../../../../../libs/common/src/platform/abstractions/i18n.service"; diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts index af15c2c8b6d..cdae129de4f 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.component.ts @@ -1,7 +1,7 @@ import { Component } from "@angular/core"; import { IntegrationType } from "@bitwarden/common/enums"; -import { Integration } from "@bitwarden/web-vault/app/shared"; +import { Integration } from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/integrations/models"; @Component({ selector: "sm-integrations", diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.module.ts b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.module.ts index b79892f5ed6..eee426e3b07 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.module.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/integrations/integrations.module.ts @@ -1,9 +1,7 @@ import { NgModule } from "@angular/core"; -import { - IntegrationCardComponent, - IntegrationGridComponent, -} from "@bitwarden/web-vault/app/shared"; +import { IntegrationCardComponent } from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/integrations/integration-card/integration-card.component"; +import { IntegrationGridComponent } from "@bitwarden/web-vault/app/admin-console/organizations/shared/components/integrations/integration-grid/integration-grid.component"; import { SecretsManagerSharedModule } from "../shared/sm-shared.module"; From 5a46991e4e5e21b84ad0519391204ecddb0b3266 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Mon, 6 Jan 2025 16:08:29 -0500 Subject: [PATCH 58/65] [PM-16696] New Device Verification Notice Learn More (#12715) * add learn more link to new device verification notification page one --- ...new-device-verification-notice-page-one.component.html | 8 ++++++++ .../new-device-verification-notice-page-one.component.ts | 2 ++ 2 files changed, 10 insertions(+) diff --git a/libs/vault/src/components/new-device-verification-notice/new-device-verification-notice-page-one.component.html b/libs/vault/src/components/new-device-verification-notice/new-device-verification-notice-page-one.component.html index 316df3aed17..ddff560fd00 100644 --- a/libs/vault/src/components/new-device-verification-notice/new-device-verification-notice-page-one.component.html +++ b/libs/vault/src/components/new-device-verification-notice/new-device-verification-notice-page-one.component.html @@ -1,6 +1,14 @@

{{ "newDeviceVerificationNoticeContentPage1" | i18n }} + + {{ "learnMore" | i18n }}. +

Date: Mon, 6 Jan 2025 13:52:42 -0800 Subject: [PATCH 59/65] [PM-13365] - don't display totp capture when in popout (#12645) * don't display totp capture when in popout * add canCaptureTotp method * dry up logic * add unit tests * fix failing tests * add missing mock to cipher-form story --- .../services/browser-totp-capture.service.spec.ts | 15 +++++++++++++++ .../services/browser-totp-capture.service.ts | 5 +++++ .../abstractions/totp-capture.service.ts | 5 +++++ libs/vault/src/cipher-form/cipher-form.stories.ts | 1 + .../login-details-section.component.spec.ts | 4 +++- .../login-details-section.component.ts | 8 ++++++-- 6 files changed, 35 insertions(+), 3 deletions(-) diff --git a/apps/browser/src/vault/popup/services/browser-totp-capture.service.spec.ts b/apps/browser/src/vault/popup/services/browser-totp-capture.service.spec.ts index 2c9afacffd7..2b309e8f817 100644 --- a/apps/browser/src/vault/popup/services/browser-totp-capture.service.spec.ts +++ b/apps/browser/src/vault/popup/services/browser-totp-capture.service.spec.ts @@ -2,6 +2,7 @@ import { TestBed } from "@angular/core/testing"; import qrcodeParser from "qrcode-parser"; import { BrowserApi } from "../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; import { BrowserTotpCaptureService } from "./browser-totp-capture.service"; @@ -13,12 +14,14 @@ describe("BrowserTotpCaptureService", () => { let testBed: TestBed; let service: BrowserTotpCaptureService; let mockCaptureVisibleTab: jest.SpyInstance; + let mockBrowserPopupUtilsInPopout: jest.SpyInstance; const validTotpUrl = "otpauth://totp/label?secret=123"; beforeEach(() => { mockCaptureVisibleTab = jest.spyOn(BrowserApi, "captureVisibleTab"); mockCaptureVisibleTab.mockResolvedValue("screenshot"); + mockBrowserPopupUtilsInPopout = jest.spyOn(BrowserPopupUtils, "inPopout"); testBed = TestBed.configureTestingModule({ providers: [BrowserTotpCaptureService], @@ -66,4 +69,16 @@ describe("BrowserTotpCaptureService", () => { expect(result).toBeNull(); }); + + describe("canCaptureTotp", () => { + it("should return true when not in a popout window", () => { + mockBrowserPopupUtilsInPopout.mockReturnValue(false); + expect(service.canCaptureTotp({} as Window)).toBe(true); + }); + + it("should return false when in a popout window", () => { + mockBrowserPopupUtilsInPopout.mockReturnValue(true); + expect(service.canCaptureTotp({} as Window)).toBe(false); + }); + }); }); diff --git a/apps/browser/src/vault/popup/services/browser-totp-capture.service.ts b/apps/browser/src/vault/popup/services/browser-totp-capture.service.ts index 3f8ba61ed36..ac73b271c84 100644 --- a/apps/browser/src/vault/popup/services/browser-totp-capture.service.ts +++ b/apps/browser/src/vault/popup/services/browser-totp-capture.service.ts @@ -4,6 +4,7 @@ import qrcodeParser from "qrcode-parser"; import { TotpCaptureService } from "@bitwarden/vault"; import { BrowserApi } from "../../../platform/browser/browser-api"; +import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils"; /** * Implementation of TotpCaptureService for the browser which captures the @@ -20,4 +21,8 @@ export class BrowserTotpCaptureService implements TotpCaptureService { } return null; } + + canCaptureTotp(window: Window) { + return !BrowserPopupUtils.inPopout(window); + } } diff --git a/libs/vault/src/cipher-form/abstractions/totp-capture.service.ts b/libs/vault/src/cipher-form/abstractions/totp-capture.service.ts index d6d95565869..72bbb0da12c 100644 --- a/libs/vault/src/cipher-form/abstractions/totp-capture.service.ts +++ b/libs/vault/src/cipher-form/abstractions/totp-capture.service.ts @@ -6,4 +6,9 @@ export abstract class TotpCaptureService { * Captures a TOTP secret and returns it as a string. Returns null if no TOTP secret was found. */ abstract captureTotpSecret(): Promise; + /** + * Returns whether the TOTP secret can be captured from the current tab. + * Only available in the browser extension and when not in a popout window. + */ + abstract canCaptureTotp(window: Window): boolean; } diff --git a/libs/vault/src/cipher-form/cipher-form.stories.ts b/libs/vault/src/cipher-form/cipher-form.stories.ts index 1d44e4542bc..72c4acb23cd 100644 --- a/libs/vault/src/cipher-form/cipher-form.stories.ts +++ b/libs/vault/src/cipher-form/cipher-form.stories.ts @@ -152,6 +152,7 @@ export default { provide: TotpCaptureService, useValue: { captureTotpSecret: () => Promise.resolve("some-value"), + canCaptureTotp: () => true, }, }, { diff --git a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts index 232a4b2d27b..182427f7f42 100644 --- a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts +++ b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.spec.ts @@ -434,6 +434,7 @@ describe("LoginDetailsSectionComponent", () => { }); it("should call captureTotp when the capture totp button is clicked", fakeAsync(() => { + jest.spyOn(component, "canCaptureTotp", "get").mockReturnValue(true); component.captureTotp = jest.fn(); fixture.detectChanges(); @@ -445,7 +446,8 @@ describe("LoginDetailsSectionComponent", () => { })); describe("canCaptureTotp", () => { - it("should return true when totpCaptureService is present and totp is editable", () => { + it("should return true when totpCaptureService is present and totpCaptureService.canCaptureTotp is true and totp is editable", () => { + jest.spyOn(component, "canCaptureTotp", "get").mockReturnValue(true); component.loginDetailsForm.controls.totp.enable(); expect(component.canCaptureTotp).toBe(true); }); diff --git a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts index 0a6772e5ef1..2296932aca3 100644 --- a/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts +++ b/libs/vault/src/cipher-form/components/login-details-section/login-details-section.component.ts @@ -65,10 +65,14 @@ export class LoginDetailsSectionComponent implements OnInit { newPasswordGenerated: boolean; /** - * Whether the TOTP field can be captured from the current tab. Only available in the browser extension. + * Whether the TOTP field can be captured from the current tab. Only available in the browser extension and + * when not in a popout window. */ get canCaptureTotp() { - return this.totpCaptureService != null && this.loginDetailsForm.controls.totp.enabled; + return ( + !!this.totpCaptureService?.canCaptureTotp(window) && + this.loginDetailsForm.controls.totp.enabled + ); } private datePipe = inject(DatePipe); From 15faf52f57a0e0f8e0cb2b48e91216f6b1045907 Mon Sep 17 00:00:00 2001 From: Jonathan Prusik Date: Mon, 6 Jan 2025 17:10:34 -0500 Subject: [PATCH 60/65] [PM-13115] Allow users to disable extension content script injections by domain (#11826) * add disabledInteractionsUris state to the domain settings service * add routes and ui for user disabledInteractionsUris state management * use disabled URIs service state as a preemptive conditon to injecting content scripts * move disabled domains navigation button from account security settings to autofill settings * update disabled domain terminology to blocked domain terminology * update copy * handle blocked domains initializing with null value * add dismissable banner to the vault view when the active autofill tab is on the blocked domains list * add autofill blocked domain indicators to autofill suggestions section header * add BlockBrowserInjectionsByDomain feature flag and put feature behind it * update router config to new style * update tests and cleanup * use full-width-notice slot for domain script injection blocked banner * convert thrown error on content script injection block to a warning and early return * simplify and enspeeden state resolution for blockedInteractionsUris * refactor feature flag state fetching and update tests * document domain settings service * remove vault component presentational updates --- apps/browser/src/_locales/en/messages.json | 15 ++ .../background/overlay.background.spec.ts | 8 +- .../overlay.background.deprecated.spec.ts | 6 +- .../popup/settings/autofill-v1.component.html | 12 + .../popup/settings/autofill-v1.component.ts | 5 + .../popup/settings/autofill.component.html | 6 + .../popup/settings/autofill.component.ts | 7 +- .../settings/blocked-domains.component.html | 66 ++++++ .../settings/blocked-domains.component.ts | 208 ++++++++++++++++++ .../settings/excluded-domains.component.ts | 37 ++-- .../services/autofill.service.spec.ts | 13 +- .../browser/src/background/main.background.ts | 7 +- .../browser-script-injector.service.spec.ts | 102 ++++++++- .../browser-script-injector.service.ts | 28 +++ apps/browser/src/popup/app-routing.module.ts | 7 + .../src/popup/services/services.module.ts | 4 +- .../fileless-importer.background.spec.ts | 34 +-- .../service-container/service-container.ts | 43 ++-- .../src/services/jslib-services.module.ts | 10 +- .../services/domain-settings.service.spec.ts | 9 +- .../services/domain-settings.service.ts | 69 +++++- libs/common/src/enums/feature-flag.enum.ts | 2 + .../src/models/domain/domain-service.ts | 2 +- 23 files changed, 623 insertions(+), 77 deletions(-) create mode 100644 apps/browser/src/autofill/popup/settings/blocked-domains.component.html create mode 100644 apps/browser/src/autofill/popup/settings/blocked-domains.component.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 06f11406b68..85937b63304 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -2324,6 +2324,9 @@ "message": "Domains", "description": "A category title describing the concept of web domains" }, + "blockedDomains": { + "message": "Blocked domains" + }, "excludedDomains": { "message": "Excluded domains" }, @@ -2333,6 +2336,15 @@ "excludedDomainsDescAlt": { "message": "Bitwarden will not ask to save login details for these domains for all logged in accounts. You must refresh the page for changes to take effect." }, + "blockedDomainsDesc": { + "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." + }, + "autofillBlockedNotice": { + "message": "Autofill is blocked for this website. Review or change this in settings." + }, + "autofillBlockedTooltip": { + "message": "Autofill is blocked on this website. Review in settings." + }, "websiteItemLabel": { "message": "Website $number$ (URI)", "placeholders": { @@ -2351,6 +2363,9 @@ } } }, + "blockedDomainsSavedSuccess": { + "message": "Blocked domain changes saved" + }, "excludedDomainsSavedSuccess": { "message": "Excluded domain changes saved" }, diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index e7b72b72c9b..512a9ff4c2a 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -1,5 +1,5 @@ import { mock, MockProxy, mockReset } from "jest-mock-extended"; -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject, of } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; @@ -14,6 +14,7 @@ import { } from "@bitwarden/common/autofill/services/domain-settings.service"; import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types"; import { NeverDomains } from "@bitwarden/common/models/domain/domain-service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService, Region, @@ -93,6 +94,7 @@ describe("OverlayBackground", () => { let logService: MockProxy; let cipherService: MockProxy; let autofillService: MockProxy; + let configService: MockProxy; let activeAccountStatusMock$: BehaviorSubject; let authService: MockProxy; let environmentMock$: BehaviorSubject; @@ -149,11 +151,13 @@ describe("OverlayBackground", () => { } beforeEach(() => { + configService = mock(); + configService.getFeatureFlag$.mockImplementation(() => of(true)); accountService = mockAccountServiceWith(mockUserId); fakeStateProvider = new FakeStateProvider(accountService); showFaviconsMock$ = new BehaviorSubject(true); neverDomainsMock$ = new BehaviorSubject({}); - domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider); + domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider, configService); domainSettingsService.showFavicons$ = showFaviconsMock$; domainSettingsService.neverDomains$ = neverDomainsMock$; logService = mock(); diff --git a/apps/browser/src/autofill/deprecated/background/overlay.background.deprecated.spec.ts b/apps/browser/src/autofill/deprecated/background/overlay.background.deprecated.spec.ts index 3adaf9e276c..2c22097f3d0 100644 --- a/apps/browser/src/autofill/deprecated/background/overlay.background.deprecated.spec.ts +++ b/apps/browser/src/autofill/deprecated/background/overlay.background.deprecated.spec.ts @@ -12,6 +12,7 @@ import { DefaultDomainSettingsService, DomainSettingsService, } from "@bitwarden/common/autofill/services/domain-settings.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService, Region, @@ -61,6 +62,7 @@ describe("OverlayBackground", () => { let overlayBackground: LegacyOverlayBackground; const cipherService = mock(); const autofillService = mock(); + let configService: MockProxy; let activeAccountStatusMock$: BehaviorSubject; let authService: MockProxy; @@ -92,7 +94,9 @@ describe("OverlayBackground", () => { }; beforeEach(() => { - domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider); + configService = mock(); + configService.getFeatureFlag$.mockImplementation(() => of(true)); + domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider, configService); activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Unlocked); authService = mock(); authService.activeAccountStatus$ = activeAccountStatusMock$; diff --git a/apps/browser/src/autofill/popup/settings/autofill-v1.component.html b/apps/browser/src/autofill/popup/settings/autofill-v1.component.html index 530519e88f1..1c16ee1fe12 100644 --- a/apps/browser/src/autofill/popup/settings/autofill-v1.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill-v1.component.html @@ -255,4 +255,16 @@

{{ "additionalOptions" | i18n }}

{{ "showIdentitiesCurrentTabDesc" | i18n }}

+
+
+ +
+
diff --git a/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts b/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts index 085ccba7e1e..9f015d990e9 100644 --- a/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts +++ b/apps/browser/src/autofill/popup/settings/autofill-v1.component.ts @@ -36,6 +36,7 @@ export class AutofillV1Component implements OnInit { protected autoFillOverlayVisibilityOptions: any[]; protected disablePasswordManagerLink: string; protected inlineMenuPositioningImprovementsEnabled: boolean = false; + protected blockBrowserInjectionsByDomainEnabled: boolean = false; protected showInlineMenuIdentities: boolean = true; protected showInlineMenuCards: boolean = true; inlineMenuIsEnabled: boolean = false; @@ -120,6 +121,10 @@ export class AutofillV1Component implements OnInit { FeatureFlag.InlineMenuPositioningImprovements, ); + this.blockBrowserInjectionsByDomainEnabled = await this.configService.getFeatureFlag( + FeatureFlag.BlockBrowserInjectionsByDomain, + ); + this.inlineMenuIsEnabled = this.isInlineMenuEnabled(); this.showInlineMenuIdentities = diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html index e8882cf7bbb..eeae0a85e3f 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.html +++ b/apps/browser/src/autofill/popup/settings/autofill.component.html @@ -282,5 +282,11 @@

{{ "additionalOptions" | i18n }}

+ + + {{ "blockedDomains" | i18n }} + + +
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.ts b/apps/browser/src/autofill/popup/settings/autofill.component.ts index da997f550b3..884503fa360 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.ts +++ b/apps/browser/src/autofill/popup/settings/autofill.component.ts @@ -49,7 +49,6 @@ import { import { BrowserApi } from "../../../platform/browser/browser-api"; import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; -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"; @@ -67,7 +66,6 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co JslibModule, LinkModule, PopOutComponent, - PopupFooterComponent, PopupHeaderComponent, PopupPageComponent, RouterModule, @@ -87,6 +85,7 @@ export class AutofillComponent implements OnInit { protected inlineMenuVisibility: InlineMenuVisibilitySetting = AutofillOverlayVisibility.OnFieldFocus; protected inlineMenuPositioningImprovementsEnabled: boolean = false; + protected blockBrowserInjectionsByDomainEnabled: boolean = false; protected browserClientVendor: BrowserClientVendor = BrowserClientVendors.Unknown; protected disablePasswordManagerURI: DisablePasswordManagerUri = DisablePasswordManagerUris.Unknown; @@ -164,6 +163,10 @@ export class AutofillComponent implements OnInit { FeatureFlag.InlineMenuPositioningImprovements, ); + this.blockBrowserInjectionsByDomainEnabled = await this.configService.getFeatureFlag( + FeatureFlag.BlockBrowserInjectionsByDomain, + ); + this.showInlineMenuIdentities = this.inlineMenuPositioningImprovementsEnabled && (await firstValueFrom(this.autofillSettingsService.showInlineMenuIdentities$)); diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html new file mode 100644 index 00000000000..bf5f40f2b90 --- /dev/null +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html @@ -0,0 +1,66 @@ + + + + + + + +
+

{{ "blockedDomainsDesc" | i18n }}

+ + +

{{ "domainsTitle" | i18n }}

+ {{ blockedDomainsState?.length || 0 }} +
+ + + + + {{ + "websiteItemLabel" | i18n: i + 1 + }} + +
{{ domain }}
+
+ +
+
+ +
+
+ + + +
diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts b/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts new file mode 100644 index 00000000000..461f62da6dc --- /dev/null +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts @@ -0,0 +1,208 @@ +import { CommonModule } from "@angular/common"; +import { + QueryList, + Component, + ElementRef, + OnDestroy, + AfterViewInit, + ViewChildren, +} from "@angular/core"; +import { FormsModule } from "@angular/forms"; +import { RouterModule } from "@angular/router"; +import { Subject, takeUntil } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; +import { NeverDomains } from "@bitwarden/common/models/domain/domain-service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { + ButtonModule, + CardComponent, + FormFieldModule, + IconButtonModule, + ItemModule, + LinkModule, + SectionComponent, + SectionHeaderComponent, + ToastService, + TypographyModule, +} from "@bitwarden/components"; + +import { PopOutComponent } from "../../../platform/popup/components/pop-out.component"; +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"; + +@Component({ + selector: "app-blocked-domains", + templateUrl: "blocked-domains.component.html", + standalone: true, + imports: [ + ButtonModule, + CardComponent, + CommonModule, + FormFieldModule, + FormsModule, + IconButtonModule, + ItemModule, + JslibModule, + LinkModule, + PopOutComponent, + PopupFooterComponent, + PopupHeaderComponent, + PopupPageComponent, + RouterModule, + SectionComponent, + SectionHeaderComponent, + TypographyModule, + ], +}) +export class BlockedDomainsComponent implements AfterViewInit, OnDestroy { + @ViewChildren("uriInput") uriInputElements: QueryList> = + new QueryList(); + + dataIsPristine = true; + isLoading = false; + blockedDomainsState: string[] = []; + storedBlockedDomains: string[] = []; + // How many fields should be non-editable before editable fields + fieldsEditThreshold: number = 0; + + private destroy$ = new Subject(); + + constructor( + private domainSettingsService: DomainSettingsService, + private i18nService: I18nService, + private toastService: ToastService, + ) {} + + async ngAfterViewInit() { + this.domainSettingsService.blockedInteractionsUris$ + .pipe(takeUntil(this.destroy$)) + .subscribe((neverDomains: NeverDomains) => this.handleStateUpdate(neverDomains)); + + this.uriInputElements.changes.pipe(takeUntil(this.destroy$)).subscribe(({ last }) => { + this.focusNewUriInput(last); + }); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + handleStateUpdate(neverDomains: NeverDomains) { + if (neverDomains) { + this.storedBlockedDomains = Object.keys(neverDomains); + } + + this.blockedDomainsState = [...this.storedBlockedDomains]; + + // Do not allow the first x (pre-existing) fields to be edited + this.fieldsEditThreshold = this.storedBlockedDomains.length; + + this.dataIsPristine = true; + this.isLoading = false; + } + + focusNewUriInput(elementRef: ElementRef) { + if (elementRef?.nativeElement) { + elementRef.nativeElement.focus(); + } + } + + async addNewDomain() { + // add empty field to the Domains list interface + this.blockedDomainsState.push(""); + + await this.fieldChange(); + } + + async removeDomain(i: number) { + this.blockedDomainsState.splice(i, 1); + + // If a pre-existing field was dropped, lower the edit threshold + if (i < this.fieldsEditThreshold) { + this.fieldsEditThreshold--; + } + + await this.fieldChange(); + } + + async fieldChange() { + if (this.dataIsPristine) { + this.dataIsPristine = false; + } + } + + async saveChanges() { + if (this.dataIsPristine) { + return; + } + + this.isLoading = true; + + const newBlockedDomainsSaveState: NeverDomains = {}; + const uniqueBlockedDomains = new Set(this.blockedDomainsState); + + for (const uri of uniqueBlockedDomains) { + if (uri && uri !== "") { + const validatedHost = Utils.getHostname(uri); + + if (!validatedHost) { + this.toastService.showToast({ + message: this.i18nService.t("excludedDomainsInvalidDomain", uri), + title: "", + variant: "error", + }); + + // Don't reset via `handleStateUpdate` to allow existing input value correction + this.isLoading = false; + return; + } + + newBlockedDomainsSaveState[validatedHost] = null; + } + } + + try { + const existingState = new Set(this.storedBlockedDomains); + const newState = new Set(Object.keys(newBlockedDomainsSaveState)); + const stateIsUnchanged = + existingState.size === newState.size && + new Set([...existingState, ...newState]).size === existingState.size; + + // The subscriber updates don't trigger if `setNeverDomains` sets an equivalent state + if (stateIsUnchanged) { + // Reset UI state directly + const constructedNeverDomainsState = this.storedBlockedDomains.reduce( + (neverDomains: NeverDomains, uri: string) => ({ ...neverDomains, [uri]: null }), + {}, + ); + this.handleStateUpdate(constructedNeverDomainsState); + } else { + await this.domainSettingsService.setBlockedInteractionsUris(newBlockedDomainsSaveState); + } + + this.toastService.showToast({ + message: this.i18nService.t("blockedDomainsSavedSuccess"), + title: "", + variant: "success", + }); + } catch { + this.toastService.showToast({ + message: this.i18nService.t("unexpectedError"), + title: "", + variant: "error", + }); + + // Don't reset via `handleStateUpdate` to preserve input values + this.isLoading = false; + } + } + + trackByFunction(index: number, _: string) { + return index; + } +} diff --git a/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts b/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts index 1391ad516fb..7d429bfe4f0 100644 --- a/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts +++ b/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { CommonModule } from "@angular/common"; import { QueryList, @@ -17,7 +15,6 @@ import { JslibModule } from "@bitwarden/angular/jslib.module"; import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; import { NeverDomains } from "@bitwarden/common/models/domain/domain-service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { ButtonModule, @@ -28,6 +25,7 @@ import { LinkModule, SectionComponent, SectionHeaderComponent, + ToastService, TypographyModule, } from "@bitwarden/components"; @@ -62,7 +60,8 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co ], }) export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { - @ViewChildren("uriInput") uriInputElements: QueryList>; + @ViewChildren("uriInput") uriInputElements: QueryList> = + new QueryList(); accountSwitcherEnabled = false; dataIsPristine = true; @@ -77,7 +76,7 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { constructor( private domainSettingsService: DomainSettingsService, private i18nService: I18nService, - private platformUtilsService: PlatformUtilsService, + private toastService: ToastService, ) { this.accountSwitcherEnabled = enableAccountSwitching(); } @@ -156,11 +155,11 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { const validatedHost = Utils.getHostname(uri); if (!validatedHost) { - this.platformUtilsService.showToast( - "error", - null, - this.i18nService.t("excludedDomainsInvalidDomain", uri), - ); + this.toastService.showToast({ + message: this.i18nService.t("excludedDomainsInvalidDomain", uri), + title: "", + variant: "error", + }); // Don't reset via `handleStateUpdate` to allow existing input value correction this.isLoading = false; @@ -182,7 +181,7 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { if (stateIsUnchanged) { // Reset UI state directly const constructedNeverDomainsState = this.storedExcludedDomains.reduce( - (neverDomains, uri) => ({ ...neverDomains, [uri]: null }), + (neverDomains: NeverDomains, uri: string) => ({ ...neverDomains, [uri]: null }), {}, ); this.handleStateUpdate(constructedNeverDomainsState); @@ -190,13 +189,17 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { await this.domainSettingsService.setNeverDomains(newExcludedDomainsSaveState); } - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("excludedDomainsSavedSuccess"), - ); + this.toastService.showToast({ + message: this.i18nService.t("excludedDomainsSavedSuccess"), + title: "", + variant: "success", + }); } catch { - this.platformUtilsService.showToast("error", null, this.i18nService.t("unexpectedError")); + this.toastService.showToast({ + message: this.i18nService.t("unexpectedError"), + title: "", + variant: "error", + }); // Don't reset via `handleStateUpdate` to preserve input values this.isLoading = false; diff --git a/apps/browser/src/autofill/services/autofill.service.spec.ts b/apps/browser/src/autofill/services/autofill.service.spec.ts index 91f926440a0..77d73d7ae65 100644 --- a/apps/browser/src/autofill/services/autofill.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill.service.spec.ts @@ -98,7 +98,13 @@ describe("AutofillService", () => { let messageListener: MockProxy; beforeEach(() => { - scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService); + configService = mock(); + configService.getFeatureFlag$.mockImplementation(() => of(false)); + scriptInjectorService = new BrowserScriptInjectorService( + domainSettingsService, + platformUtilsService, + logService, + ); inlineMenuVisibilityMock$ = new BehaviorSubject(AutofillOverlayVisibility.OnFieldFocus); showInlineMenuCardsMock$ = new BehaviorSubject(false); showInlineMenuIdentitiesMock$ = new BehaviorSubject(false); @@ -106,10 +112,10 @@ describe("AutofillService", () => { autofillSettingsService.inlineMenuVisibility$ = inlineMenuVisibilityMock$; autofillSettingsService.showInlineMenuCards$ = showInlineMenuCardsMock$; autofillSettingsService.showInlineMenuIdentities$ = showInlineMenuIdentitiesMock$; + autofillSettingsService.autofillOnPageLoad$ = of(true); activeAccountStatusMock$ = new BehaviorSubject(AuthenticationStatus.Unlocked); authService = mock(); authService.activeAccountStatus$ = activeAccountStatusMock$; - configService = mock(); messageListener = mock(); enableChangedPasswordPromptMock$ = new BehaviorSubject(true); enableAddedLoginPromptMock$ = new BehaviorSubject(true); @@ -132,7 +138,7 @@ describe("AutofillService", () => { userNotificationsSettings, messageListener, ); - domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider); + domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider, configService); domainSettingsService.equivalentDomains$ = of(mockEquivalentDomains); jest.spyOn(BrowserApi, "tabSendMessage"); }); @@ -385,6 +391,7 @@ describe("AutofillService", () => { ); tabMock = createChromeTabMock(); sender = { tab: tabMock, frameId: 1 }; + jest.spyOn(BrowserApi, "getTab").mockImplementation(async () => tabMock); jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation(); jest .spyOn(autofillService, "getInlineMenuVisibility") diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 555e3a13fa0..34c10508485 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -695,7 +695,6 @@ export default class MainBackground { this.vaultTimeoutSettingsService, ); - this.domainSettingsService = new DefaultDomainSettingsService(this.stateProvider); this.fileUploadService = new FileUploadService(this.logService, this.apiService); this.cipherFileUploadService = new CipherFileUploadService( this.apiService, @@ -809,6 +808,11 @@ export default class MainBackground { this.authService, ); + this.domainSettingsService = new DefaultDomainSettingsService( + this.stateProvider, + this.configService, + ); + this.themeStateService = new DefaultThemeStateService( this.globalStateProvider, this.configService, @@ -957,6 +961,7 @@ export default class MainBackground { this.totpService = new TotpService(this.cryptoFunctionService, this.logService); this.scriptInjectorService = new BrowserScriptInjectorService( + this.domainSettingsService, this.platformUtilsService, this.logService, ); diff --git a/apps/browser/src/platform/services/browser-script-injector.service.spec.ts b/apps/browser/src/platform/services/browser-script-injector.service.spec.ts index d6ec3dfde96..0919de46776 100644 --- a/apps/browser/src/platform/services/browser-script-injector.service.spec.ts +++ b/apps/browser/src/platform/services/browser-script-injector.service.spec.ts @@ -1,8 +1,22 @@ -import { mock } from "jest-mock-extended"; +import { mock, MockProxy } from "jest-mock-extended"; +import { of } from "rxjs"; +import { + DomainSettingsService, + DefaultDomainSettingsService, +} from "@bitwarden/common/autofill/services/domain-settings.service"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { Utils } from "@bitwarden/common/platform/misc/utils"; +import { + FakeStateProvider, + FakeAccountService, + mockAccountServiceWith, +} from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/types/guid"; +import { createChromeTabMock } from "../../autofill/spec/autofill-mocks"; import { BrowserApi } from "../browser/browser-api"; import { @@ -11,8 +25,19 @@ import { } from "./abstractions/script-injector.service"; import { BrowserScriptInjectorService } from "./browser-script-injector.service"; +const mockEquivalentDomains = [ + ["example.com", "exampleapp.com", "example.co.uk", "ejemplo.es"], + ["bitwarden.com", "bitwarden.co.uk", "sm-bitwarden.com"], + ["example.co.uk", "exampleapp.co.uk"], +]; + describe("ScriptInjectorService", () => { const tabId = 1; + const tabMock = createChromeTabMock({ id: tabId }); + const mockBlockedURI = new URL(tabMock.url); + jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation(); + jest.spyOn(BrowserApi, "isManifestVersion"); + const combinedManifestVersionFile = "content/autofill-init.js"; const mv2SpecificFile = "content/autofill-init-mv2.js"; const mv2Details = { file: mv2SpecificFile }; @@ -22,14 +47,29 @@ describe("ScriptInjectorService", () => { runAt: "document_start", }; const manifestVersionSpy = jest.spyOn(BrowserApi, "manifestVersion", "get"); + let scriptInjectorService: BrowserScriptInjectorService; - jest.spyOn(BrowserApi, "executeScriptInTab").mockImplementation(); - jest.spyOn(BrowserApi, "isManifestVersion"); - const platformUtilsService = mock(); const logService = mock(); + const platformUtilsService = mock(); + const mockUserId = Utils.newGuid() as UserId; + const accountService: FakeAccountService = mockAccountServiceWith(mockUserId); + const fakeStateProvider: FakeStateProvider = new FakeStateProvider(accountService); + let configService: MockProxy; + let domainSettingsService: DomainSettingsService; beforeEach(() => { - scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService); + jest.spyOn(BrowserApi, "getTab").mockImplementation(async () => tabMock); + configService = mock(); + configService.getFeatureFlag$.mockImplementation(() => of(false)); + domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider, configService); + domainSettingsService.equivalentDomains$ = of(mockEquivalentDomains); + domainSettingsService.blockedInteractionsUris$ = of(null); + scriptInjectorService = new BrowserScriptInjectorService( + domainSettingsService, + platformUtilsService, + logService, + ); + jest.spyOn(scriptInjectorService as any, "buildInjectionDetails"); }); describe("inject", () => { @@ -71,6 +111,58 @@ describe("ScriptInjectorService", () => { { world: "ISOLATED" }, ); }); + + it("skips injecting the script in manifest v3 when the tab domain is a blocked domain", async () => { + domainSettingsService.blockedInteractionsUris$ = of({ [mockBlockedURI.host]: null }); + manifestVersionSpy.mockReturnValue(3); + + await expect(scriptInjectorService["buildInjectionDetails"]).not.toHaveBeenCalled(); + }); + + it("skips injecting the script in manifest v2 when the tab domain is a blocked domain", async () => { + domainSettingsService.blockedInteractionsUris$ = of({ [mockBlockedURI.host]: null }); + manifestVersionSpy.mockReturnValue(2); + + await expect(scriptInjectorService["buildInjectionDetails"]).not.toHaveBeenCalled(); + }); + + it("injects the script in manifest v2 when given combined injection details", async () => { + manifestVersionSpy.mockReturnValue(2); + + await scriptInjectorService.inject({ + tabId, + injectDetails: { + file: combinedManifestVersionFile, + frame: "all_frames", + ...sharedInjectDetails, + }, + }); + + expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith(tabId, { + ...sharedInjectDetails, + allFrames: true, + file: combinedManifestVersionFile, + }); + }); + + it("injects the script in manifest v3 when given combined injection details", async () => { + manifestVersionSpy.mockReturnValue(3); + + await scriptInjectorService.inject({ + tabId, + injectDetails: { + file: combinedManifestVersionFile, + frame: 10, + ...sharedInjectDetails, + }, + }); + + expect(BrowserApi.executeScriptInTab).toHaveBeenCalledWith( + tabId, + { ...sharedInjectDetails, frameId: 10, file: combinedManifestVersionFile }, + { world: "ISOLATED" }, + ); + }); }); describe("injection of mv2 specific details", () => { diff --git a/apps/browser/src/platform/services/browser-script-injector.service.ts b/apps/browser/src/platform/services/browser-script-injector.service.ts index 2a6b7397a6c..c2bace669dc 100644 --- a/apps/browser/src/platform/services/browser-script-injector.service.ts +++ b/apps/browser/src/platform/services/browser-script-injector.service.ts @@ -1,3 +1,6 @@ +import { firstValueFrom } from "rxjs"; + +import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -12,7 +15,10 @@ import { } from "./abstractions/script-injector.service"; export class BrowserScriptInjectorService extends ScriptInjectorService { + blockedDomains: Set = null; + constructor( + private readonly domainSettingsService: DomainSettingsService, private readonly platformUtilsService: PlatformUtilsService, private readonly logService: LogService, ) { @@ -32,6 +38,28 @@ export class BrowserScriptInjectorService extends ScriptInjectorService { throw new Error("No file specified for script injection"); } + const tab = tabId && (await BrowserApi.getTab(tabId)); + const tabURL = tab?.url ? new URL(tab.url) : null; + + // Check if the tab URI is on the disabled URIs list + let injectionAllowedInTab = true; + const blockedDomains = await firstValueFrom( + this.domainSettingsService.blockedInteractionsUris$, + ); + + if (blockedDomains && tabURL?.hostname) { + const blockedDomainsSet = new Set(Object.keys(blockedDomains)); + + injectionAllowedInTab = !(tabURL && blockedDomainsSet.has(tabURL.hostname)); + } + + if (!injectionAllowedInTab) { + this.logService.warning( + `${injectDetails.file} was not injected because ${tabURL?.hostname || "the tab URI"} is on the user's blocked domains list.`, + ); + return; + } + const injectionDetails = this.buildInjectionDetails(injectDetails, file); if (BrowserApi.isManifestVersion(3)) { diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 161c4ca0524..2d53ae7e239 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -75,6 +75,7 @@ import { Fido2V1Component } from "../autofill/popup/fido2/fido2-v1.component"; import { Fido2Component } from "../autofill/popup/fido2/fido2.component"; import { AutofillV1Component } from "../autofill/popup/settings/autofill-v1.component"; import { AutofillComponent } from "../autofill/popup/settings/autofill.component"; +import { BlockedDomainsComponent } from "../autofill/popup/settings/blocked-domains.component"; import { ExcludedDomainsV1Component } from "../autofill/popup/settings/excluded-domains-v1.component"; import { ExcludedDomainsComponent } from "../autofill/popup/settings/excluded-domains.component"; import { NotificationsSettingsV1Component } from "../autofill/popup/settings/notifications-v1.component"; @@ -348,6 +349,12 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 2 } satisfies RouteDataProperties, }, + { + path: "blocked-domains", + component: BlockedDomainsComponent, + canActivate: [authGuard], + data: { elevation: 2 } satisfies RouteDataProperties, + }, ...extensionRefreshSwap(ExcludedDomainsV1Component, ExcludedDomainsComponent, { path: "excluded-domains", canActivate: [authGuard], diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 5b27833636f..92eb8973235 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -327,7 +327,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: DomainSettingsService, useClass: DefaultDomainSettingsService, - deps: [StateProvider], + deps: [StateProvider, ConfigService], }), safeProvider({ provide: AbstractStorageService, @@ -365,7 +365,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: ScriptInjectorService, useClass: BrowserScriptInjectorService, - deps: [PlatformUtilsService, LogService], + deps: [DomainSettingsService, PlatformUtilsService, LogService], }), safeProvider({ provide: VaultTimeoutService, diff --git a/apps/browser/src/tools/background/fileless-importer.background.spec.ts b/apps/browser/src/tools/background/fileless-importer.background.spec.ts index 7b356b18fd5..429a0e12184 100644 --- a/apps/browser/src/tools/background/fileless-importer.background.spec.ts +++ b/apps/browser/src/tools/background/fileless-importer.background.spec.ts @@ -1,9 +1,10 @@ import { mock } from "jest-mock-extended"; -import { firstValueFrom } from "rxjs"; +import { of } from "rxjs"; import { PolicyService } from "@bitwarden/common/admin-console/services/policy/policy.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; +import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -23,18 +24,10 @@ import { FilelessImportPort, FilelessImportType } from "../enums/fileless-import import FilelessImporterBackground from "./fileless-importer.background"; -jest.mock("rxjs", () => { - const rxjs = jest.requireActual("rxjs"); - const { firstValueFrom } = rxjs; - return { - ...rxjs, - firstValueFrom: jest.fn(firstValueFrom), - }; -}); - describe("FilelessImporterBackground ", () => { let filelessImporterBackground: FilelessImporterBackground; const configService = mock(); + const domainSettingsService = mock(); const authService = mock(); const policyService = mock(); const notificationBackground = mock(); @@ -43,9 +36,16 @@ describe("FilelessImporterBackground ", () => { const platformUtilsService = mock(); const logService = mock(); let scriptInjectorService: BrowserScriptInjectorService; + let tabMock: chrome.tabs.Tab; beforeEach(() => { - scriptInjectorService = new BrowserScriptInjectorService(platformUtilsService, logService); + domainSettingsService.blockedInteractionsUris$ = of(null); + policyService.policyAppliesToActiveUser$.mockImplementation(() => of(true)); + scriptInjectorService = new BrowserScriptInjectorService( + domainSettingsService, + platformUtilsService, + logService, + ); filelessImporterBackground = new FilelessImporterBackground( configService, authService, @@ -75,12 +75,13 @@ describe("FilelessImporterBackground ", () => { beforeEach(() => { lpImporterPort = createPortSpyMock(FilelessImportPort.LpImporter); + tabMock = lpImporterPort.sender.tab; + jest.spyOn(BrowserApi, "getTab").mockImplementation(async () => tabMock); manifestVersionSpy = jest.spyOn(BrowserApi, "manifestVersion", "get"); executeScriptInTabSpy = jest.spyOn(BrowserApi, "executeScriptInTab").mockResolvedValue(null); jest.spyOn(authService, "getAuthStatus").mockResolvedValue(AuthenticationStatus.Unlocked); jest.spyOn(configService, "getFeatureFlag").mockResolvedValue(true); jest.spyOn(filelessImporterBackground as any, "removeIndividualVault"); - (firstValueFrom as jest.Mock).mockResolvedValue(false); }); it("ignores the port connection if the port name is not present in the set of filelessImportNames", async () => { @@ -105,8 +106,6 @@ describe("FilelessImporterBackground ", () => { }); it("posts a message to the port indicating that the fileless import feature is disabled if the user's policy removes individual vaults", async () => { - (firstValueFrom as jest.Mock).mockResolvedValue(true); - triggerRuntimeOnConnectEvent(lpImporterPort); await flushPromises(); @@ -129,6 +128,8 @@ describe("FilelessImporterBackground ", () => { }); it("posts a message to the port indicating that the fileless import feature is enabled", async () => { + policyService.policyAppliesToActiveUser$.mockImplementationOnce(() => of(false)); + triggerRuntimeOnConnectEvent(lpImporterPort); await flushPromises(); @@ -139,6 +140,7 @@ describe("FilelessImporterBackground ", () => { }); it("triggers an injection of the `lp-suppress-import-download.js` script in manifest v3", async () => { + policyService.policyAppliesToActiveUser$.mockImplementationOnce(() => of(false)); manifestVersionSpy.mockReturnValue(3); triggerRuntimeOnConnectEvent(lpImporterPort); @@ -152,6 +154,7 @@ describe("FilelessImporterBackground ", () => { }); it("triggers an injection of the `lp-suppress-import-download-script-append-mv2.js` script in manifest v2", async () => { + policyService.policyAppliesToActiveUser$.mockImplementationOnce(() => of(false)); manifestVersionSpy.mockReturnValue(2); triggerRuntimeOnConnectEvent(lpImporterPort); @@ -170,9 +173,10 @@ describe("FilelessImporterBackground ", () => { let lpImporterPort: chrome.runtime.Port; beforeEach(async () => { + policyService.policyAppliesToActiveUser$.mockImplementation(() => of(false)); jest.spyOn(authService, "getAuthStatus").mockResolvedValue(AuthenticationStatus.Unlocked); jest.spyOn(configService, "getFeatureFlag").mockResolvedValue(true); - (firstValueFrom as jest.Mock).mockResolvedValue(false); + triggerRuntimeOnConnectEvent(createPortSpyMock(FilelessImportPort.NotificationBar)); triggerRuntimeOnConnectEvent(createPortSpyMock(FilelessImportPort.LpImporter)); await flushPromises(); diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index 2afbae0782f..9f9e45e86d4 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -483,7 +483,29 @@ export class ServiceContainer { this.containerService = new ContainerService(this.keyService, this.encryptService); - this.domainSettingsService = new DefaultDomainSettingsService(this.stateProvider); + this.configApiService = new ConfigApiService(this.apiService, this.tokenService); + + this.authService = new AuthService( + this.accountService, + this.messagingService, + this.keyService, + this.apiService, + this.stateService, + this.tokenService, + ); + + this.configService = new DefaultConfigService( + this.configApiService, + this.environmentService, + this.logService, + this.stateProvider, + this.authService, + ); + + this.domainSettingsService = new DefaultDomainSettingsService( + this.stateProvider, + this.configService, + ); this.fileUploadService = new FileUploadService(this.logService, this.apiService); @@ -579,25 +601,6 @@ export class ServiceContainer { this.taskSchedulerService = new DefaultTaskSchedulerService(this.logService); - this.authService = new AuthService( - this.accountService, - this.messagingService, - this.keyService, - this.apiService, - this.stateService, - this.tokenService, - ); - - this.configApiService = new ConfigApiService(this.apiService, this.tokenService); - - this.configService = new DefaultConfigService( - this.configApiService, - this.environmentService, - this.logService, - this.stateProvider, - this.authService, - ); - this.devicesApiService = new DevicesApiServiceImplementation(this.apiService); this.deviceTrustService = new DeviceTrustService( this.keyGenerationService, diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 149d553696e..583ba82fc98 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -463,6 +463,11 @@ const safeProviders: SafeProvider[] = [ useClass: CipherFileUploadService, deps: [ApiServiceAbstraction, FileUploadServiceAbstraction], }), + safeProvider({ + provide: DomainSettingsService, + useClass: DefaultDomainSettingsService, + deps: [StateProvider, ConfigService], + }), safeProvider({ provide: CipherServiceAbstraction, useFactory: ( @@ -1243,11 +1248,6 @@ const safeProviders: SafeProvider[] = [ useClass: BadgeSettingsService, deps: [StateProvider], }), - safeProvider({ - provide: DomainSettingsService, - useClass: DefaultDomainSettingsService, - deps: [StateProvider], - }), safeProvider({ provide: BiometricStateService, useClass: DefaultBiometricStateService, diff --git a/libs/common/src/autofill/services/domain-settings.service.spec.ts b/libs/common/src/autofill/services/domain-settings.service.spec.ts index 24e3763eb45..a25653f168c 100644 --- a/libs/common/src/autofill/services/domain-settings.service.spec.ts +++ b/libs/common/src/autofill/services/domain-settings.service.spec.ts @@ -1,5 +1,8 @@ +import { MockProxy, mock } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; + import { FakeStateProvider, FakeAccountService, mockAccountServiceWith } from "../../../spec"; import { Utils } from "../../platform/misc/utils"; import { UserId } from "../../types/guid"; @@ -8,6 +11,7 @@ import { DefaultDomainSettingsService, DomainSettingsService } from "./domain-se describe("DefaultDomainSettingsService", () => { let domainSettingsService: DomainSettingsService; + let configService: MockProxy; const mockUserId = Utils.newGuid() as UserId; const accountService: FakeAccountService = mockAccountServiceWith(mockUserId); const fakeStateProvider: FakeStateProvider = new FakeStateProvider(accountService); @@ -19,10 +23,13 @@ describe("DefaultDomainSettingsService", () => { ]; beforeEach(() => { - domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider); + configService = mock(); + configService.getFeatureFlag$.mockImplementation(() => of(false)); + domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider, configService); jest.spyOn(domainSettingsService, "getUrlEquivalentDomains"); domainSettingsService.equivalentDomains$ = of(mockEquivalentDomains); + domainSettingsService.blockedInteractionsUris$ = of(null); }); describe("getUrlEquivalentDomains", () => { diff --git a/libs/common/src/autofill/services/domain-settings.service.ts b/libs/common/src/autofill/services/domain-settings.service.ts index 708341563e0..aeb3af69dae 100644 --- a/libs/common/src/autofill/services/domain-settings.service.ts +++ b/libs/common/src/autofill/services/domain-settings.service.ts @@ -1,6 +1,8 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { map, Observable } from "rxjs"; +import { map, Observable, switchMap, of } from "rxjs"; + +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { NeverDomains, @@ -8,6 +10,7 @@ import { UriMatchStrategySetting, UriMatchStrategy, } from "../../models/domain/domain-service"; +import { ConfigService } from "../../platform/abstractions/config/config.service"; import { Utils } from "../../platform/misc/utils"; import { DOMAIN_SETTINGS_DISK, @@ -23,10 +26,20 @@ const SHOW_FAVICONS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "showFavicons", { deserializer: (value: boolean) => value ?? true, }); +// Domain exclusion list for notifications const NEVER_DOMAINS = new KeyDefinition(DOMAIN_SETTINGS_DISK, "neverDomains", { deserializer: (value: NeverDomains) => value ?? null, }); +// Domain exclusion list for content script injections +const BLOCKED_INTERACTIONS_URIS = new KeyDefinition( + DOMAIN_SETTINGS_DISK, + "blockedInteractionsUris", + { + deserializer: (value: NeverDomains) => value ?? null, + }, +); + const EQUIVALENT_DOMAINS = new UserKeyDefinition(DOMAIN_SETTINGS_DISK, "equivalentDomains", { deserializer: (value: EquivalentDomains) => value ?? null, clearOn: ["logout"], @@ -41,15 +54,45 @@ const DEFAULT_URI_MATCH_STRATEGY = new UserKeyDefinition( }, ); +/** + * The Domain Settings service; provides client settings state for "active client view" URI concerns + */ export abstract class DomainSettingsService { + /** + * Indicates if the favicons for ciphers' URIs should be shown instead of a placeholder + */ showFavicons$: Observable; setShowFavicons: (newValue: boolean) => Promise; + + /** + * User-specified URIs for which the client notifications should not appear + */ neverDomains$: Observable; setNeverDomains: (newValue: NeverDomains) => Promise; + + /** + * User-specified URIs for which client content script injections should not occur, and the state + * of banner/notice visibility for those domains within the client + */ + blockedInteractionsUris$: Observable; + setBlockedInteractionsUris: (newValue: NeverDomains) => Promise; + + /** + * URIs which should be treated as equivalent to each other for various concerns (autofill, etc) + */ equivalentDomains$: Observable; setEquivalentDomains: (newValue: EquivalentDomains, userId: UserId) => Promise; + + /** + * User-specified default for URI-matching strategies (for example, when determining relevant + * ciphers for an active browser tab). Can be overridden by cipher-specific settings. + */ defaultUriMatchStrategy$: Observable; setDefaultUriMatchStrategy: (newValue: UriMatchStrategySetting) => Promise; + + /** + * Helper function for the common resolution of a given URL against equivalent domains + */ getUrlEquivalentDomains: (url: string) => Observable>; } @@ -60,19 +103,37 @@ export class DefaultDomainSettingsService implements DomainSettingsService { private neverDomainsState: GlobalState; readonly neverDomains$: Observable; + private blockedInteractionsUrisState: GlobalState; + readonly blockedInteractionsUris$: Observable; + private equivalentDomainsState: ActiveUserState; readonly equivalentDomains$: Observable; private defaultUriMatchStrategyState: ActiveUserState; readonly defaultUriMatchStrategy$: Observable; - constructor(private stateProvider: StateProvider) { + constructor( + private stateProvider: StateProvider, + private configService: ConfigService, + ) { this.showFaviconsState = this.stateProvider.getGlobal(SHOW_FAVICONS); this.showFavicons$ = this.showFaviconsState.state$.pipe(map((x) => x ?? true)); this.neverDomainsState = this.stateProvider.getGlobal(NEVER_DOMAINS); this.neverDomains$ = this.neverDomainsState.state$.pipe(map((x) => x ?? null)); + // Needs to be global to prevent pre-login injections + this.blockedInteractionsUrisState = this.stateProvider.getGlobal(BLOCKED_INTERACTIONS_URIS); + + this.blockedInteractionsUris$ = this.configService + .getFeatureFlag$(FeatureFlag.BlockBrowserInjectionsByDomain) + .pipe( + switchMap((featureIsEnabled) => + featureIsEnabled ? this.blockedInteractionsUrisState.state$ : of({} as NeverDomains), + ), + map((disabledUris) => (Object.keys(disabledUris).length ? disabledUris : null)), + ); + this.equivalentDomainsState = this.stateProvider.getActive(EQUIVALENT_DOMAINS); this.equivalentDomains$ = this.equivalentDomainsState.state$.pipe(map((x) => x ?? null)); @@ -90,6 +151,10 @@ export class DefaultDomainSettingsService implements DomainSettingsService { await this.neverDomainsState.update(() => newValue); } + async setBlockedInteractionsUris(newValue: NeverDomains): Promise { + await this.blockedInteractionsUrisState.update(() => newValue); + } + async setEquivalentDomains(newValue: EquivalentDomains, userId: UserId): Promise { await this.stateProvider.getUser(userId, EQUIVALENT_DOMAINS).update(() => newValue); } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 135119bf133..0ab7d47acfc 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -27,6 +27,7 @@ export enum FeatureFlag { SSHKeyVaultItem = "ssh-key-vault-item", SSHAgent = "ssh-agent", NotificationBarAddLoginImprovements = "notification-bar-add-login-improvements", + BlockBrowserInjectionsByDomain = "block-browser-injections-by-domain", AC2476_DeprecateStripeSourcesAPI = "AC-2476-deprecate-stripe-sources-api", CipherKeyEncryption = "cipher-key-encryption", VerifiedSsoDomainEndpoint = "pm-12337-refactor-sso-details-endpoint", @@ -81,6 +82,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.SSHKeyVaultItem]: FALSE, [FeatureFlag.SSHAgent]: FALSE, [FeatureFlag.NotificationBarAddLoginImprovements]: FALSE, + [FeatureFlag.BlockBrowserInjectionsByDomain]: FALSE, [FeatureFlag.AC2476_DeprecateStripeSourcesAPI]: FALSE, [FeatureFlag.CipherKeyEncryption]: FALSE, [FeatureFlag.VerifiedSsoDomainEndpoint]: FALSE, diff --git a/libs/common/src/models/domain/domain-service.ts b/libs/common/src/models/domain/domain-service.ts index 9ff53cc8787..a6b5ecfdaac 100644 --- a/libs/common/src/models/domain/domain-service.ts +++ b/libs/common/src/models/domain/domain-service.ts @@ -21,5 +21,5 @@ export const UriMatchStrategy = { export type UriMatchStrategySetting = (typeof UriMatchStrategy)[keyof typeof UriMatchStrategy]; // using uniqueness properties of object shape over Set for ease of state storability -export type NeverDomains = { [id: string]: null }; +export type NeverDomains = { [id: string]: null | { bannerIsDismissed?: boolean } }; export type EquivalentDomains = string[][]; From 1075d7a79859f7b63d2364de497bddd07c4efd5d Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:56:21 -0500 Subject: [PATCH 61/65] PM-16685 - Web - Fix locking (#12722) --- libs/common/src/services/vault-timeout/vault-timeout.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/common/src/services/vault-timeout/vault-timeout.service.ts b/libs/common/src/services/vault-timeout/vault-timeout.service.ts index f465174bf40..55d5bffa99a 100644 --- a/libs/common/src/services/vault-timeout/vault-timeout.service.ts +++ b/libs/common/src/services/vault-timeout/vault-timeout.service.ts @@ -138,7 +138,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction { await this.collectionService.clearActiveUserCache(); } - await this.folderService.clearDecryptedFolderState(userId); + await this.folderService.clearDecryptedFolderState(lockingUserId); await this.masterPasswordService.clearMasterKey(lockingUserId); await this.stateService.setUserKeyAutoUnlock(null, { userId: lockingUserId }); From 003f5fdae9ce3fb84281f42219153971af4df26b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:38:19 +0100 Subject: [PATCH 62/65] [deps]: Lock file maintenance (#12709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Daniel García --- apps/desktop/desktop_native/Cargo.lock | 93 +++++++++++++------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock index b40246fca2d..96c7d8955db 100644 --- a/apps/desktop/desktop_native/Cargo.lock +++ b/apps/desktop/desktop_native/Cargo.lock @@ -189,9 +189,9 @@ dependencies = [ [[package]] name = "async-broadcast" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ "event-listener", "event-listener-strategy", @@ -354,9 +354,9 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.83" +version = "0.1.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +checksum = "1b1244b10dcd56c92219da4e14caa97e312079e185f04ba3eea25061561dc0a0" dependencies = [ "proc-macro2", "quote", @@ -567,9 +567,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.6" +version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ "shlex", ] @@ -811,9 +811,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d44ff199ff93242c3afe480ab588d544dd08d72e92885e152ffebc670f076ad" +checksum = "ad7c7515609502d316ab9a24f67dc045132d93bfd3f00713389e90d9898bf30d" dependencies = [ "cc", "cxxbridge-cmd", @@ -825,9 +825,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fd8f17ad454fc1e4f4ab83abffcc88a532e90350d3ffddcb73030220fcbd52" +checksum = "8bfd16fca6fd420aebbd80d643c201ee4692114a0de208b790b9cd02ceae65fb" dependencies = [ "cc", "codespan-reporting", @@ -839,9 +839,9 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4717c9c806a9e07fdcb34c84965a414ea40fafe57667187052cf1eb7f5e8a8a9" +checksum = "6c33fd49f5d956a1b7ee5f7a9768d58580c6752838d92e39d0d56439efdedc35" dependencies = [ "clap", "codespan-reporting", @@ -852,15 +852,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f6515329bf3d98f4073101c7866ff2bec4e635a13acb82e3f3753fff0bf43cb" +checksum = "be0f1077278fac36299cce8446effd19fe93a95eedb10d39265f3bf67b3036c9" [[package]] name = "cxxbridge-macro" -version = "1.0.135" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb93e6a7ce8ec985c02bbb758237a31598b340acbbc3c19c5a4fa6adaaac92ab" +checksum = "3da7e4d6e74af6b79031d264b2f13c3ea70af1978083741c41ffce9308f1f24f" dependencies = [ "proc-macro2", "quote", @@ -1134,7 +1134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1190,9 +1190,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "fs-err" @@ -1354,9 +1354,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "goblin" @@ -1519,7 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -1961,9 +1961,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.5" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] @@ -2300,9 +2300,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -2482,9 +2482,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "ryu" @@ -2584,18 +2584,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -2604,9 +2604,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ "itoa", "memchr", @@ -2803,9 +2803,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a" dependencies = [ "proc-macro2", "quote", @@ -2814,9 +2814,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ae3f4f7d64646c46c4cae4e3f01d1c5d255c7406fdd7c7f999a94e488791" +checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" dependencies = [ "core-foundation-sys", "libc", @@ -2828,15 +2828,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", + "getrandom", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3050,9 +3051,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" @@ -3340,7 +3341,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3636,9 +3637,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "39281189af81c07ec09db316b302a3e67bf9bd7cbf6c820b50e35fee9c2fa980" dependencies = [ "memchr", ] From 91d696307445c81b6c2441de7a75fba9a426cd31 Mon Sep 17 00:00:00 2001 From: Conner Turnbull <133619638+cturnbull-bitwarden@users.noreply.github.com> Date: Tue, 7 Jan 2025 10:25:26 -0500 Subject: [PATCH 63/65] [PM-14366] Deprecated active user state from billing state service (#12273) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updated billing state provider to not rely on ActiveUserStateProvider * Updated usages * Resolved browser build * Resolved web build * Resolved CLI build * resolved desktop build * Update apps/cli/src/tools/send/commands/create.command.ts Co-authored-by: ✨ Audrey ✨ * Move subscription visibility logic from component to service * Resolved unit test failures. Using existing userIds where present * Simplified activeUserId access * Resolved typescript strict errors * Resolved broken unit test * Resolved ts strict error --------- Co-authored-by: ✨ Audrey ✨ --- .../browser/main-context-menu-handler.spec.ts | 20 ++- .../browser/main-context-menu-handler.ts | 15 +- .../services/autofill.service.spec.ts | 22 ++- .../src/autofill/services/autofill.service.ts | 3 +- .../browser/src/background/main.background.ts | 3 + .../src/background/runtime.background.ts | 5 +- .../popup/settings/premium-v2.component.ts | 3 + .../popup/send-v2/send-v2.component.spec.ts | 12 +- .../more-from-bitwarden-page-v2.component.ts | 14 +- .../open-attachments.component.spec.ts | 19 ++- .../open-attachments.component.ts | 11 +- apps/cli/src/commands/get.command.ts | 6 +- apps/cli/src/oss-serve-configurator.ts | 2 + .../service-container/service-container.ts | 2 + .../src/tools/send/commands/create.command.ts | 10 +- .../src/tools/send/commands/edit.command.ts | 5 +- apps/cli/src/tools/send/send.program.ts | 2 + apps/cli/src/vault/create.command.ts | 12 +- apps/cli/src/vault/delete.command.ts | 3 +- .../vault/app/accounts/premium.component.ts | 5 +- .../src/vault/app/vault/vault.component.ts | 13 +- .../settings/two-factor-setup.component.ts | 3 + .../emergency-access.component.ts | 10 +- .../two-factor/two-factor-setup.component.ts | 9 +- .../premium/premium-v2.component.ts | 17 ++- .../individual/premium/premium.component.ts | 15 +- .../individual/subscription.component.ts | 8 +- .../individual/user-subscription.component.ts | 7 +- .../src/app/core/guards/has-premium.guard.ts | 13 +- .../src/app/layouts/user-layout.component.ts | 37 ++--- .../reports/pages/reports-home.component.ts | 9 +- .../vault-item-dialog.component.ts | 8 +- .../add-edit-v2.component.spec.ts | 10 +- .../individual-vault/add-edit-v2.component.ts | 16 ++- .../individual-vault/add-edit.component.ts | 9 +- .../services/vault-banners.service.spec.ts | 10 +- .../services/vault-banners.service.ts | 32 ++++- .../vault/individual-vault/vault.component.ts | 2 +- .../src/directives/not-premium.directive.ts | 11 +- .../src/directives/premium.directive.ts | 19 ++- .../src/services/jslib-services.module.ts | 2 +- .../src/tools/send/add-edit.component.ts | 19 ++- .../vault/components/attachments.component.ts | 2 +- .../src/vault/components/premium.component.ts | 10 +- .../src/vault/components/view.component.ts | 2 +- .../billing-account-profile-state.service.ts | 21 +-- ...ling-account-profile-state.service.spec.ts | 128 ++++++++++++++---- .../billing-account-profile-state.service.ts | 89 ++++++------ .../new-send-dropdown.component.ts | 10 +- .../send-list-filters.component.spec.ts | 20 ++- .../send-list-filters.component.ts | 14 +- .../attachments-v2-view.component.ts | 15 +- .../login-credentials-view.component.spec.ts | 18 ++- .../login-credentials-view.component.ts | 13 +- .../copy-cipher-field.service.spec.ts | 17 ++- .../src/services/copy-cipher-field.service.ts | 10 +- 56 files changed, 595 insertions(+), 227 deletions(-) diff --git a/apps/browser/src/autofill/browser/main-context-menu-handler.spec.ts b/apps/browser/src/autofill/browser/main-context-menu-handler.spec.ts index 21eadfaf668..79998b65205 100644 --- a/apps/browser/src/autofill/browser/main-context-menu-handler.spec.ts +++ b/apps/browser/src/autofill/browser/main-context-menu-handler.spec.ts @@ -1,12 +1,14 @@ import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { NOOP_COMMAND_SUFFIX } from "@bitwarden/common/autofill/constants"; import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { CipherType } from "@bitwarden/common/vault/enums"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -19,6 +21,7 @@ describe("context-menu", () => { let i18nService: MockProxy; let logService: MockProxy; let billingAccountProfileStateService: MockProxy; + let accountService: MockProxy; let removeAllSpy: jest.SpyInstance void]>; let createSpy: jest.SpyInstance< @@ -34,6 +37,7 @@ describe("context-menu", () => { i18nService = mock(); logService = mock(); billingAccountProfileStateService = mock(); + accountService = mock(); removeAllSpy = jest .spyOn(chrome.contextMenus, "removeAll") @@ -53,8 +57,15 @@ describe("context-menu", () => { i18nService, logService, billingAccountProfileStateService, + accountService, ); autofillSettingsService.enableContextMenu$ = of(true); + accountService.activeAccount$ = of({ + id: "userId" as UserId, + email: "", + emailVerified: false, + name: undefined, + }); }); afterEach(() => jest.resetAllMocks()); @@ -69,7 +80,7 @@ describe("context-menu", () => { }); it("has menu enabled, but does not have premium", async () => { - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(false); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(false)); const createdMenu = await sut.init(); expect(createdMenu).toBeTruthy(); @@ -77,7 +88,7 @@ describe("context-menu", () => { }); it("has menu enabled and has premium", async () => { - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true)); const createdMenu = await sut.init(); expect(createdMenu).toBeTruthy(); @@ -131,16 +142,15 @@ describe("context-menu", () => { }); it("create entry for each cipher piece", async () => { - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true)); await sut.loadOptions("TEST_TITLE", "1", createCipher()); - // One for autofill, copy username, copy password, and copy totp code expect(createSpy).toHaveBeenCalledTimes(4); }); it("creates a login/unlock item for each context menu action option when user is not authenticated", async () => { - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true)); await sut.loadOptions("TEST_TITLE", "NOOP"); diff --git a/apps/browser/src/autofill/browser/main-context-menu-handler.ts b/apps/browser/src/autofill/browser/main-context-menu-handler.ts index e755524da47..41d88439e8f 100644 --- a/apps/browser/src/autofill/browser/main-context-menu-handler.ts +++ b/apps/browser/src/autofill/browser/main-context-menu-handler.ts @@ -2,6 +2,7 @@ // @ts-strict-ignore import { firstValueFrom } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AUTOFILL_CARD_ID, AUTOFILL_ID, @@ -149,6 +150,7 @@ export class MainContextMenuHandler { private i18nService: I18nService, private logService: LogService, private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} /** @@ -168,11 +170,13 @@ export class MainContextMenuHandler { this.initRunning = true; try { + const account = await firstValueFrom(this.accountService.activeAccount$); + const hasPremium = await firstValueFrom( + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ); + for (const options of this.initContextMenuItems) { - if ( - options.checkPremiumAccess && - !(await firstValueFrom(this.billingAccountProfileStateService.hasPremiumFromAnySource$)) - ) { + if (options.checkPremiumAccess && !hasPremium) { continue; } @@ -267,8 +271,9 @@ export class MainContextMenuHandler { await createChildItem(COPY_USERNAME_ID); } + const account = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), ); if (canAccessPremium && (!cipher || !Utils.isNullOrEmpty(cipher.login?.totp))) { await createChildItem(COPY_VERIFICATION_CODE_ID); diff --git a/apps/browser/src/autofill/services/autofill.service.spec.ts b/apps/browser/src/autofill/services/autofill.service.spec.ts index 77d73d7ae65..16b11b98866 100644 --- a/apps/browser/src/autofill/services/autofill.service.spec.ts +++ b/apps/browser/src/autofill/services/autofill.service.spec.ts @@ -1,4 +1,4 @@ -import { mock, mockReset, MockProxy } from "jest-mock-extended"; +import { mock, MockProxy, mockReset } from "jest-mock-extended"; import { BehaviorSubject, of, Subject } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; @@ -730,7 +730,9 @@ describe("AutofillService", () => { it("throws an error if an autofill did not occur for any of the passed pages", async () => { autofillOptions.tab.url = "https://a-different-url.com"; - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + jest + .spyOn(billingAccountProfileStateService, "hasPremiumFromAnySource$") + .mockImplementation(() => of(true)); try { await autofillService.doAutoFill(autofillOptions); @@ -912,7 +914,9 @@ describe("AutofillService", () => { it("returns a TOTP value", async () => { const totpCode = "123456"; autofillOptions.cipher.login.totp = "totp"; - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + jest + .spyOn(billingAccountProfileStateService, "hasPremiumFromAnySource$") + .mockImplementation(() => of(true)); jest.spyOn(autofillService, "getShouldAutoCopyTotp").mockResolvedValue(true); jest.spyOn(totpService, "getCode").mockResolvedValue(totpCode); @@ -925,7 +929,9 @@ describe("AutofillService", () => { it("does not return a TOTP value if the user does not have premium features", async () => { autofillOptions.cipher.login.totp = "totp"; - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(false); + jest + .spyOn(billingAccountProfileStateService, "hasPremiumFromAnySource$") + .mockImplementation(() => of(false)); jest.spyOn(autofillService, "getShouldAutoCopyTotp").mockResolvedValue(true); const autofillResult = await autofillService.doAutoFill(autofillOptions); @@ -959,7 +965,9 @@ describe("AutofillService", () => { it("returns a null value if the user cannot access premium and the organization does not use TOTP", async () => { autofillOptions.cipher.login.totp = "totp"; autofillOptions.cipher.organizationUseTotp = false; - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(false); + jest + .spyOn(billingAccountProfileStateService, "hasPremiumFromAnySource$") + .mockImplementation(() => of(false)); const autofillResult = await autofillService.doAutoFill(autofillOptions); @@ -969,7 +977,9 @@ describe("AutofillService", () => { it("returns a null value if the user has disabled `auto TOTP copy`", async () => { autofillOptions.cipher.login.totp = "totp"; autofillOptions.cipher.organizationUseTotp = true; - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + jest + .spyOn(billingAccountProfileStateService, "hasPremiumFromAnySource$") + .mockImplementation(() => of(true)); jest.spyOn(autofillService, "getShouldAutoCopyTotp").mockResolvedValue(false); jest.spyOn(totpService, "getCode"); diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index 093f4bfb638..6d0e9954ade 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -416,8 +416,9 @@ export default class AutofillService implements AutofillServiceInterface { let totp: string | null = null; + const activeAccount = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeAccount.id), ); const defaultUriMatch = await this.getDefaultUriMatchStrategy(); diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 34c10508485..ff240ec8cac 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -792,6 +792,8 @@ export default class MainBackground { this.billingAccountProfileStateService = new DefaultBillingAccountProfileStateService( this.stateProvider, + this.platformUtilsService, + this.apiService, ); this.ssoLoginService = new SsoLoginService(this.stateProvider); @@ -1229,6 +1231,7 @@ export default class MainBackground { this.i18nService, this.logService, this.billingAccountProfileStateService, + this.accountService, ); this.cipherContextMenuHandler = new CipherContextMenuHandler( diff --git a/apps/browser/src/background/runtime.background.ts b/apps/browser/src/background/runtime.background.ts index 56ad7909e61..c31ec94be90 100644 --- a/apps/browser/src/background/runtime.background.ts +++ b/apps/browser/src/background/runtime.background.ts @@ -202,8 +202,11 @@ export default class RuntimeBackground { return await this.configService.getFeatureFlag(FeatureFlag.InlineMenuFieldQualification); } case "getUserPremiumStatus": { + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.id)), + ); const result = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeUserId), ); return result; } diff --git a/apps/browser/src/billing/popup/settings/premium-v2.component.ts b/apps/browser/src/billing/popup/settings/premium-v2.component.ts index c17adcd52fe..f658f71a209 100644 --- a/apps/browser/src/billing/popup/settings/premium-v2.component.ts +++ b/apps/browser/src/billing/popup/settings/premium-v2.component.ts @@ -7,6 +7,7 @@ import { RouterModule } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/vault/components/premium.component"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -56,6 +57,7 @@ export class PremiumV2Component extends BasePremiumComponent { dialogService: DialogService, environmentService: EnvironmentService, billingAccountProfileStateService: BillingAccountProfileStateService, + accountService: AccountService, ) { super( i18nService, @@ -66,6 +68,7 @@ export class PremiumV2Component extends BasePremiumComponent { dialogService, environmentService, billingAccountProfileStateService, + accountService, ); // Support old price string. Can be removed in future once all translations are properly updated. diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts index 506d7146dd6..c3f4634a6c2 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts @@ -91,7 +91,17 @@ describe("SendV2Component", () => { CurrentAccountComponent, ], providers: [ - { provide: AccountService, useValue: mock() }, + { + provide: AccountService, + useValue: { + activeAccount$: of({ + id: "123", + email: "test@email.com", + emailVerified: true, + name: "Test User", + }), + }, + }, { provide: AuthService, useValue: mock() }, { provide: AvatarService, useValue: mock() }, { diff --git a/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts b/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts index 2d451dddaa7..8b880e88671 100644 --- a/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/about-page/more-from-bitwarden-page-v2.component.ts @@ -1,10 +1,11 @@ import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Observable, firstValueFrom } from "rxjs"; +import { Observable, firstValueFrom, of, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { DialogService, ItemModule } from "@bitwarden/components"; @@ -36,12 +37,19 @@ export class MoreFromBitwardenPageV2Component { constructor( private dialogService: DialogService, - billingAccountProfileStateService: BillingAccountProfileStateService, + private billingAccountProfileStateService: BillingAccountProfileStateService, private environmentService: EnvironmentService, private organizationService: OrganizationService, private familiesPolicyService: FamiliesPolicyService, + private accountService: AccountService, ) { - this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + this.canAccessPremium$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + account + ? this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id) + : of(false), + ), + ); this.familySponsorshipAvailable$ = this.organizationService.familySponsorshipAvailable$; this.hasSingleEnterpriseOrg$ = this.familiesPolicyService.hasSingleEnterpriseOrg$(); this.isFreeFamilyPolicyEnabled$ = this.familiesPolicyService.isFreeFamilyPolicyEnabled$(); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts index 8c1e0641b03..4f6c4aa07cf 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.spec.ts @@ -1,7 +1,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing"; import { Router } from "@angular/router"; import { RouterTestingModule } from "@angular/router/testing"; -import { BehaviorSubject } from "rxjs"; +import { BehaviorSubject, of } from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; @@ -10,7 +10,6 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs import { ProductTierType } from "@bitwarden/common/billing/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; -import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; import { CipherId, UserId } from "@bitwarden/common/types/guid"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { CipherType } from "@bitwarden/common/vault/enums"; @@ -55,7 +54,14 @@ describe("OpenAttachmentsComponent", () => { const showFilePopoutMessage = jest.fn().mockReturnValue(false); const mockUserId = Utils.newGuid() as UserId; - const accountService: FakeAccountService = mockAccountServiceWith(mockUserId); + const accountService = { + activeAccount$: of({ + id: mockUserId, + email: "test@email.com", + emailVerified: true, + name: "Test User", + }), + }; beforeEach(async () => { openCurrentPagePopout.mockClear(); @@ -63,6 +69,7 @@ describe("OpenAttachmentsComponent", () => { showToast.mockClear(); getOrganization.mockClear(); showFilePopoutMessage.mockClear(); + hasPremiumFromAnySource$.next(true); await TestBed.configureTestingModule({ imports: [OpenAttachmentsComponent, RouterTestingModule], @@ -96,7 +103,7 @@ describe("OpenAttachmentsComponent", () => { }).compileComponents(); }); - beforeEach(() => { + beforeEach(async () => { fixture = TestBed.createComponent(OpenAttachmentsComponent); component = fixture.componentInstance; component.cipherId = "5555-444-3333" as CipherId; @@ -107,7 +114,7 @@ describe("OpenAttachmentsComponent", () => { it("opens attachments in new popout", async () => { showFilePopoutMessage.mockReturnValue(true); - + component.canAccessAttachments = true; await component.ngOnInit(); await component.openAttachments(); @@ -120,7 +127,7 @@ describe("OpenAttachmentsComponent", () => { it("opens attachments in same window", async () => { showFilePopoutMessage.mockReturnValue(false); - + component.canAccessAttachments = true; await component.ngOnInit(); await component.openAttachments(); diff --git a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts index ca620531ca8..5e27ccd5c41 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts +++ b/apps/browser/src/vault/popup/components/vault-v2/attachments/open-attachments/open-attachments.component.ts @@ -4,7 +4,7 @@ import { CommonModule } from "@angular/common"; import { Component, Input, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { Router } from "@angular/router"; -import { firstValueFrom, map } from "rxjs"; +import { firstValueFrom, map, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -54,8 +54,13 @@ export class OpenAttachmentsComponent implements OnInit { private filePopoutUtilsService: FilePopoutUtilsService, private accountService: AccountService, ) { - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntilDestroyed()) + this.accountService.activeAccount$ + .pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + takeUntilDestroyed(), + ) .subscribe((canAccessPremium) => { this.canAccessAttachments = canAccessPremium; }); diff --git a/apps/cli/src/commands/get.command.ts b/apps/cli/src/commands/get.command.ts index 7c3cc7caa9f..454db2858ab 100644 --- a/apps/cli/src/commands/get.command.ts +++ b/apps/cli/src/commands/get.command.ts @@ -262,8 +262,9 @@ export class GetCommand extends DownloadCommand { return Response.error("Couldn't generate TOTP code."); } + const account = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.accountProfileService.hasPremiumFromAnySource$, + this.accountProfileService.hasPremiumFromAnySource$(account.id), ); if (!canAccessPremium) { const originalCipher = await this.cipherService.get(cipher.id); @@ -347,8 +348,9 @@ export class GetCommand extends DownloadCommand { return Response.multipleResults(attachments.map((a) => a.id)); } + const account = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.accountProfileService.hasPremiumFromAnySource$, + this.accountProfileService.hasPremiumFromAnySource$(account.id), ); if (!canAccessPremium) { const originalCipher = await this.cipherService.get(cipher.id); diff --git a/apps/cli/src/oss-serve-configurator.ts b/apps/cli/src/oss-serve-configurator.ts index 9bd3a2bee5f..be476d19814 100644 --- a/apps/cli/src/oss-serve-configurator.ts +++ b/apps/cli/src/oss-serve-configurator.ts @@ -149,6 +149,7 @@ export class OssServeConfigurator { this.serviceContainer.environmentService, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, + this.serviceContainer.accountService, ); this.sendDeleteCommand = new SendDeleteCommand( this.serviceContainer.sendService, @@ -166,6 +167,7 @@ export class OssServeConfigurator { this.sendGetCommand, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, + this.serviceContainer.accountService, ); this.sendListCommand = new SendListCommand( this.serviceContainer.sendService, diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index 9f9e45e86d4..bef4d52fad5 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -597,6 +597,8 @@ export class ServiceContainer { this.billingAccountProfileStateService = new DefaultBillingAccountProfileStateService( this.stateProvider, + this.platformUtilsService, + this.apiService, ); this.taskSchedulerService = new DefaultTaskSchedulerService(this.logService); diff --git a/apps/cli/src/tools/send/commands/create.command.ts b/apps/cli/src/tools/send/commands/create.command.ts index 09c7937be3a..eff351be22a 100644 --- a/apps/cli/src/tools/send/commands/create.command.ts +++ b/apps/cli/src/tools/send/commands/create.command.ts @@ -3,8 +3,9 @@ import * as fs from "fs"; import * as path from "path"; -import { firstValueFrom } from "rxjs"; +import { firstValueFrom, switchMap } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; @@ -23,6 +24,7 @@ export class SendCreateCommand { private environmentService: EnvironmentService, private sendApiService: SendApiService, private accountProfileService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} async run(requestJson: any, cmdOptions: Record) { @@ -78,6 +80,10 @@ export class SendCreateCommand { req.key = null; req.maxAccessCount = maxAccessCount; + const hasPremium$ = this.accountService.activeAccount$.pipe( + switchMap(({ id }) => this.accountProfileService.hasPremiumFromAnySource$(id)), + ); + switch (req.type) { case SendType.File: if (process.env.BW_SERVE === "true") { @@ -86,7 +92,7 @@ export class SendCreateCommand { ); } - if (!(await firstValueFrom(this.accountProfileService.hasPremiumFromAnySource$))) { + if (!(await firstValueFrom(hasPremium$))) { return Response.error("Premium status is required to use this feature."); } diff --git a/apps/cli/src/tools/send/commands/edit.command.ts b/apps/cli/src/tools/send/commands/edit.command.ts index 2793c450fb6..11508d5c417 100644 --- a/apps/cli/src/tools/send/commands/edit.command.ts +++ b/apps/cli/src/tools/send/commands/edit.command.ts @@ -2,6 +2,7 @@ // @ts-strict-ignore import { firstValueFrom } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction"; @@ -19,6 +20,7 @@ export class SendEditCommand { private getCommand: SendGetCommand, private sendApiService: SendApiService, private accountProfileService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} async run(requestJson: string, cmdOptions: Record): Promise { @@ -61,8 +63,9 @@ export class SendEditCommand { return Response.badRequest("Cannot change a Send's type"); } + const account = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.accountProfileService.hasPremiumFromAnySource$, + this.accountProfileService.hasPremiumFromAnySource$(account.id), ); if (send.type === SendType.File && !canAccessPremium) { return Response.error("Premium status is required to use this feature."); diff --git a/apps/cli/src/tools/send/send.program.ts b/apps/cli/src/tools/send/send.program.ts index b59ae770380..052faa33867 100644 --- a/apps/cli/src/tools/send/send.program.ts +++ b/apps/cli/src/tools/send/send.program.ts @@ -258,6 +258,7 @@ export class SendProgram extends BaseProgram { getCmd, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, + this.serviceContainer.accountService, ); const response = await cmd.run(encodedJson, options); this.processResponse(response); @@ -331,6 +332,7 @@ export class SendProgram extends BaseProgram { this.serviceContainer.environmentService, this.serviceContainer.sendApiService, this.serviceContainer.billingAccountProfileStateService, + this.serviceContainer.accountService, ); return await cmd.run(encodedJson, options); } diff --git a/apps/cli/src/vault/create.command.ts b/apps/cli/src/vault/create.command.ts index 47e91cb55ff..13cd666754f 100644 --- a/apps/cli/src/vault/create.command.ts +++ b/apps/cli/src/vault/create.command.ts @@ -136,10 +136,13 @@ export class CreateCommand { return Response.notFound(); } - if ( - cipher.organizationId == null && - !(await firstValueFrom(this.accountProfileService.hasPremiumFromAnySource$)) - ) { + const activeUserId = await firstValueFrom(this.activeUserId$); + + const canAccessPremium = await firstValueFrom( + this.accountProfileService.hasPremiumFromAnySource$(activeUserId), + ); + + if (cipher.organizationId == null && !canAccessPremium) { return Response.error("Premium status is required to use this feature."); } @@ -152,7 +155,6 @@ export class CreateCommand { } try { - const activeUserId = await firstValueFrom(this.activeUserId$); const updatedCipher = await this.cipherService.saveAttachmentRawWithServer( cipher, fileName, diff --git a/apps/cli/src/vault/delete.command.ts b/apps/cli/src/vault/delete.command.ts index 6b66b8bc7bb..a285f8f5b34 100644 --- a/apps/cli/src/vault/delete.command.ts +++ b/apps/cli/src/vault/delete.command.ts @@ -89,8 +89,9 @@ export class DeleteCommand { return Response.error("Attachment `" + id + "` was not found."); } + const account = await firstValueFrom(this.accountService.activeAccount$); const canAccessPremium = await firstValueFrom( - this.accountProfileService.hasPremiumFromAnySource$, + this.accountProfileService.hasPremiumFromAnySource$(account.id), ); if (cipher.organizationId == null && !canAccessPremium) { return Response.error("Premium status is required to use this feature."); diff --git a/apps/desktop/src/vault/app/accounts/premium.component.ts b/apps/desktop/src/vault/app/accounts/premium.component.ts index 373e5d88177..4b547384545 100644 --- a/apps/desktop/src/vault/app/accounts/premium.component.ts +++ b/apps/desktop/src/vault/app/accounts/premium.component.ts @@ -2,13 +2,13 @@ import { Component } from "@angular/core"; import { PremiumComponent as BasePremiumComponent } from "@bitwarden/angular/vault/components/premium.component"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { DialogService } from "@bitwarden/components"; @Component({ @@ -22,10 +22,10 @@ export class PremiumComponent extends BasePremiumComponent { apiService: ApiService, configService: ConfigService, logService: LogService, - stateService: StateService, dialogService: DialogService, environmentService: EnvironmentService, billingAccountProfileStateService: BillingAccountProfileStateService, + accountService: AccountService, ) { super( i18nService, @@ -36,6 +36,7 @@ export class PremiumComponent extends BasePremiumComponent { dialogService, environmentService, billingAccountProfileStateService, + accountService, ); } } diff --git a/apps/desktop/src/vault/app/vault/vault.component.ts b/apps/desktop/src/vault/app/vault/vault.component.ts index f375b303024..ec2dbec5b8f 100644 --- a/apps/desktop/src/vault/app/vault/vault.component.ts +++ b/apps/desktop/src/vault/app/vault/vault.component.ts @@ -10,7 +10,7 @@ import { ViewContainerRef, } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; -import { Subject, takeUntil } from "rxjs"; +import { Subject, takeUntil, switchMap } from "rxjs"; import { first } from "rxjs/operators"; import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; @@ -18,6 +18,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service"; import { VaultFilter } from "@bitwarden/angular/vault/vault-filter/models/vault-filter.model"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EventType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -111,11 +112,17 @@ export class VaultComponent implements OnInit, OnDestroy { private dialogService: DialogService, private billingAccountProfileStateService: BillingAccountProfileStateService, private configService: ConfigService, + private accountService: AccountService, ) {} async ngOnInit() { - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntil(this.componentIsDestroyed$)) + this.accountService.activeAccount$ + .pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + takeUntil(this.componentIsDestroyed$), + ) .subscribe((canAccessPremium: boolean) => { this.userHasPremiumAccess = canAccessPremium; }); diff --git a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts index 48a844caa22..9cc6341c082 100644 --- a/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts +++ b/apps/web/src/app/admin-console/organizations/settings/two-factor-setup.component.ts @@ -10,6 +10,7 @@ import { ModalService } from "@bitwarden/angular/services/modal.service"; 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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response"; import { AuthResponse } from "@bitwarden/common/auth/types/auth-response"; @@ -37,6 +38,7 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent impleme private route: ActivatedRoute, private organizationService: OrganizationService, billingAccountProfileStateService: BillingAccountProfileStateService, + accountService: AccountService, ) { super( dialogService, @@ -45,6 +47,7 @@ export class TwoFactorSetupComponent extends BaseTwoFactorSetupComponent impleme messagingService, policyService, billingAccountProfileStateService, + accountService, ); } diff --git a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts index 316be3ed65c..5271e50c9a3 100644 --- a/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/emergency-access.component.ts @@ -1,11 +1,12 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Component, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; -import { lastValueFrom, Observable, firstValueFrom } from "rxjs"; +import { lastValueFrom, Observable, firstValueFrom, switchMap } from "rxjs"; import { UserNamePipe } from "@bitwarden/angular/pipes/user-name.pipe"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationManagementPreferencesService } from "@bitwarden/common/admin-console/abstractions/organization-management-preferences/organization-management-preferences.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -69,8 +70,13 @@ export class EmergencyAccessComponent implements OnInit { billingAccountProfileStateService: BillingAccountProfileStateService, protected organizationManagementPreferencesService: OrganizationManagementPreferencesService, private toastService: ToastService, + private accountService: AccountService, ) { - this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + this.canAccessPremium$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + ); } async ngOnInit() { diff --git a/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts b/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts index 14cf63d3f4e..3b20718873d 100644 --- a/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts +++ b/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts @@ -10,6 +10,7 @@ import { Subject, Subscription, takeUntil, + switchMap, } from "rxjs"; import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref"; @@ -18,6 +19,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; 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 { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { TwoFactorAuthenticatorResponse } from "@bitwarden/common/auth/models/response/two-factor-authenticator.response"; import { TwoFactorDuoResponse } from "@bitwarden/common/auth/models/response/two-factor-duo.response"; @@ -69,8 +71,13 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy { protected messagingService: MessagingService, protected policyService: PolicyService, billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) { - this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + this.canAccessPremium$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + ); } async ngOnInit() { diff --git a/apps/web/src/app/billing/individual/premium/premium-v2.component.ts b/apps/web/src/app/billing/individual/premium/premium-v2.component.ts index 2abab57b7e0..11b55f92b40 100644 --- a/apps/web/src/app/billing/individual/premium/premium-v2.component.ts +++ b/apps/web/src/app/billing/individual/premium/premium-v2.component.ts @@ -4,10 +4,11 @@ import { Component, ViewChild } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; -import { combineLatest, concatMap, from, Observable, of } from "rxjs"; +import { combineLatest, concatMap, from, Observable, of, switchMap } from "rxjs"; import { debounceTime } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; @@ -65,14 +66,22 @@ export class PremiumV2Component { private toastService: ToastService, private tokenService: TokenService, private taxService: TaxServiceAbstraction, + private accountService: AccountService, ) { this.isSelfHost = this.platformUtilsService.isSelfHost(); - this.hasPremiumFromAnyOrganization$ = - this.billingAccountProfileStateService.hasPremiumFromAnyOrganization$; + this.hasPremiumFromAnyOrganization$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnyOrganization$(account.id), + ), + ); combineLatest([ - this.billingAccountProfileStateService.hasPremiumPersonally$, + this.accountService.activeAccount$.pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumPersonally$(account.id), + ), + ), this.environmentService.cloudWebVaultUrl$, ]) .pipe( diff --git a/apps/web/src/app/billing/individual/premium/premium.component.ts b/apps/web/src/app/billing/individual/premium/premium.component.ts index 76ca25c8cc6..f96f573cd4d 100644 --- a/apps/web/src/app/billing/individual/premium/premium.component.ts +++ b/apps/web/src/app/billing/individual/premium/premium.component.ts @@ -4,10 +4,11 @@ import { Component, OnInit, ViewChild } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { FormControl, FormGroup, Validators } from "@angular/forms"; import { Router } from "@angular/router"; -import { firstValueFrom, Observable } from "rxjs"; +import { firstValueFrom, Observable, switchMap } from "rxjs"; import { debounceTime } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { TaxServiceAbstraction } from "@bitwarden/common/billing/abstractions/tax.service.abstraction"; @@ -58,9 +59,14 @@ export class PremiumComponent implements OnInit { private billingAccountProfileStateService: BillingAccountProfileStateService, private toastService: ToastService, private taxService: TaxServiceAbstraction, + private accountService: AccountService, ) { this.selfHosted = platformUtilsService.isSelfHost(); - this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + this.canAccessPremium$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + ); this.addonForm.controls.additionalStorage.valueChanges .pipe(debounceTime(1000), takeUntilDestroyed()) @@ -75,7 +81,10 @@ export class PremiumComponent implements OnInit { } async ngOnInit() { this.cloudWebVaultUrl = await firstValueFrom(this.environmentService.cloudWebVaultUrl$); - if (await firstValueFrom(this.billingAccountProfileStateService.hasPremiumPersonally$)) { + const account = await firstValueFrom(this.accountService.activeAccount$); + if ( + await firstValueFrom(this.billingAccountProfileStateService.hasPremiumPersonally$(account.id)) + ) { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.router.navigate(["/settings/subscription/user-subscription"]); diff --git a/apps/web/src/app/billing/individual/subscription.component.ts b/apps/web/src/app/billing/individual/subscription.component.ts index d8d435d8fe5..edd16ca81fe 100644 --- a/apps/web/src/app/billing/individual/subscription.component.ts +++ b/apps/web/src/app/billing/individual/subscription.component.ts @@ -1,8 +1,9 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { Component, OnInit } from "@angular/core"; -import { Observable } from "rxjs"; +import { Observable, switchMap } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -16,8 +17,11 @@ export class SubscriptionComponent implements OnInit { constructor( private platformUtilsService: PlatformUtilsService, billingAccountProfileStateService: BillingAccountProfileStateService, + accountService: AccountService, ) { - this.hasPremium$ = billingAccountProfileStateService.hasPremiumPersonally$; + this.hasPremium$ = accountService.activeAccount$.pipe( + switchMap((account) => billingAccountProfileStateService.hasPremiumPersonally$(account.id)), + ); } ngOnInit() { diff --git a/apps/web/src/app/billing/individual/user-subscription.component.ts b/apps/web/src/app/billing/individual/user-subscription.component.ts index 57d5ef314ec..97b4725e6d7 100644 --- a/apps/web/src/app/billing/individual/user-subscription.component.ts +++ b/apps/web/src/app/billing/individual/user-subscription.component.ts @@ -5,6 +5,7 @@ import { Router } from "@angular/router"; import { firstValueFrom, lastValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { SubscriptionResponse } from "@bitwarden/common/billing/models/response/subscription.response"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -60,6 +61,7 @@ export class UserSubscriptionComponent implements OnInit { private billingAccountProfileStateService: BillingAccountProfileStateService, private toastService: ToastService, private configService: ConfigService, + private accountService: AccountService, ) { this.selfHosted = this.platformUtilsService.isSelfHost(); } @@ -75,7 +77,10 @@ export class UserSubscriptionComponent implements OnInit { return; } - if (await firstValueFrom(this.billingAccountProfileStateService.hasPremiumPersonally$)) { + const userId = await firstValueFrom(this.accountService.activeAccount$); + if ( + await firstValueFrom(this.billingAccountProfileStateService.hasPremiumPersonally$(userId.id)) + ) { this.loading = true; this.sub = await this.apiService.getUserSubscription(); } else { diff --git a/apps/web/src/app/core/guards/has-premium.guard.ts b/apps/web/src/app/core/guards/has-premium.guard.ts index ab544dafb61..61853b25cb8 100644 --- a/apps/web/src/app/core/guards/has-premium.guard.ts +++ b/apps/web/src/app/core/guards/has-premium.guard.ts @@ -6,9 +6,10 @@ import { CanActivateFn, UrlTree, } from "@angular/router"; -import { Observable } from "rxjs"; -import { tap } from "rxjs/operators"; +import { Observable, of } from "rxjs"; +import { switchMap, tap } from "rxjs/operators"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -24,8 +25,14 @@ export function hasPremiumGuard(): CanActivateFn { const router = inject(Router); const messagingService = inject(MessagingService); const billingAccountProfileStateService = inject(BillingAccountProfileStateService); + const accountService = inject(AccountService); - return billingAccountProfileStateService.hasPremiumFromAnySource$.pipe( + return accountService.activeAccount$.pipe( + switchMap((account) => + account + ? billingAccountProfileStateService.hasPremiumFromAnySource$(account.id) + : of(false), + ), tap((userHasPremium: boolean) => { if (!userHasPremium) { messagingService.send("premiumRequired"); diff --git a/apps/web/src/app/layouts/user-layout.component.ts b/apps/web/src/app/layouts/user-layout.component.ts index 18277abebef..f0ac3ef9b48 100644 --- a/apps/web/src/app/layouts/user-layout.component.ts +++ b/apps/web/src/app/layouts/user-layout.component.ts @@ -3,12 +3,11 @@ import { CommonModule } from "@angular/common"; import { Component, OnInit } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { Observable, concatMap, combineLatest } from "rxjs"; +import { Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { IconModule } from "@bitwarden/components"; @@ -38,35 +37,19 @@ export class UserLayoutComponent implements OnInit { protected showSubscription$: Observable; constructor( - private platformUtilsService: PlatformUtilsService, - private apiService: ApiService, private syncService: SyncService, private billingAccountProfileStateService: BillingAccountProfileStateService, - ) {} + private accountService: AccountService, + ) { + this.showSubscription$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + this.billingAccountProfileStateService.canViewSubscription$(account.id), + ), + ); + } async ngOnInit() { document.body.classList.remove("layout_frontend"); - await this.syncService.fullSync(false); - - // We want to hide the subscription menu for organizations that provide premium. - // Except if the user has premium personally or has a billing history. - this.showSubscription$ = combineLatest([ - this.billingAccountProfileStateService.hasPremiumPersonally$, - this.billingAccountProfileStateService.hasPremiumFromAnyOrganization$, - ]).pipe( - concatMap(async ([hasPremiumPersonally, hasPremiumFromOrg]) => { - const isCloud = !this.platformUtilsService.isSelfHost(); - - let billing = null; - if (isCloud) { - // TODO: We should remove the need to call this! - billing = await this.apiService.getUserBillingHistory(); - } - - const cloudAndBillingHistory = isCloud && !billing?.hasNoHistory; - return hasPremiumPersonally || !hasPremiumFromOrg || cloudAndBillingHistory; - }), - ); } } diff --git a/apps/web/src/app/tools/reports/pages/reports-home.component.ts b/apps/web/src/app/tools/reports/pages/reports-home.component.ts index 961c24bb017..604d66f6858 100644 --- a/apps/web/src/app/tools/reports/pages/reports-home.component.ts +++ b/apps/web/src/app/tools/reports/pages/reports-home.component.ts @@ -3,6 +3,7 @@ import { Component, OnInit } from "@angular/core"; import { firstValueFrom } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { reports, ReportType } from "../reports"; @@ -15,11 +16,15 @@ import { ReportEntry, ReportVariant } from "../shared"; export class ReportsHomeComponent implements OnInit { reports: ReportEntry[]; - constructor(private billingAccountProfileStateService: BillingAccountProfileStateService) {} + constructor( + private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, + ) {} async ngOnInit(): Promise { + const account = await firstValueFrom(this.accountService.activeAccount$); const userHasPremium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), ); const reportRequiresPremium = userHasPremium ? ReportVariant.Enabled diff --git a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts index a9ff49c5791..c91314f68d7 100644 --- a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts +++ b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts @@ -4,7 +4,7 @@ import { DIALOG_DATA, DialogRef } from "@angular/cdk/dialog"; import { CommonModule } from "@angular/common"; import { Component, ElementRef, Inject, OnDestroy, OnInit, ViewChild } from "@angular/core"; import { Router } from "@angular/router"; -import { firstValueFrom, Observable, Subject } from "rxjs"; +import { firstValueFrom, Observable, Subject, switchMap } from "rxjs"; import { map } from "rxjs/operators"; import { CollectionView } from "@bitwarden/admin-console/common"; @@ -183,7 +183,11 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { * Flag to indicate if the user has access to attachments via a premium subscription. * @protected */ - protected canAccessAttachments$ = this.billingAccountProfileStateService.hasPremiumFromAnySource$; + protected canAccessAttachments$ = this.accountService.activeAccount$.pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + ); protected get loadingForm() { return this.loadForm && !this.formReady; diff --git a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.spec.ts b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.spec.ts index 6c126235234..1ca9b0de47c 100644 --- a/apps/web/src/app/vault/individual-vault/add-edit-v2.component.spec.ts +++ b/apps/web/src/app/vault/individual-vault/add-edit-v2.component.spec.ts @@ -9,6 +9,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/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 { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -34,6 +35,7 @@ describe("AddEditComponentV2", () => { let messagingService: MockProxy; let folderService: MockProxy; let collectionService: MockProxy; + let accountService: MockProxy; const mockParams = { cloneMode: false, @@ -55,7 +57,9 @@ describe("AddEditComponentV2", () => { ); billingAccountProfileStateService = mock(); - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockImplementation((userId) => + of(true), + ); activatedRoute = mock(); activatedRoute.queryParams = of({}); @@ -68,6 +72,9 @@ describe("AddEditComponentV2", () => { collectionService = mock(); collectionService.decryptedCollections$ = of([]); + accountService = mock(); + accountService.activeAccount$ = of({ id: "test-id" } as any); + const mockDefaultCipherFormConfigService = { buildConfig: jest.fn().mockResolvedValue({ allowPersonal: true, @@ -97,6 +104,7 @@ describe("AddEditComponentV2", () => { provide: PasswordGenerationServiceAbstraction, useValue: mock(), }, + { provide: AccountService, useValue: accountService }, ], }).compileComponents(); 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 5237db15b3c..c0a17a4aeb8 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 @@ -4,8 +4,10 @@ import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog"; import { CommonModule } from "@angular/common"; import { Component, Inject, OnInit } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { switchMap } from "rxjs"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { CipherId } from "@bitwarden/common/types/guid"; import { CipherType } from "@bitwarden/common/vault/enums/cipher-type"; @@ -85,10 +87,16 @@ export class AddEditComponentV2 implements OnInit { private i18nService: I18nService, private dialogService: DialogService, private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) { - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntilDestroyed()) - .subscribe((canAccessPremium) => { + this.accountService.activeAccount$ + .pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + takeUntilDestroyed(), + ) + .subscribe((canAccessPremium: boolean) => { this.canAccessAttachments = canAccessPremium; }); } 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 7038ffb898a..53a9e839064 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 @@ -2,7 +2,7 @@ // @ts-strict-ignore import { DatePipe } from "@angular/common"; import { Component, OnDestroy, OnInit } from "@angular/core"; -import { firstValueFrom } from "rxjs"; +import { firstValueFrom, map } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; import { AddEditComponent as BaseAddEditComponent } from "@bitwarden/angular/vault/components/add-edit.component"; @@ -116,9 +116,14 @@ export class AddEditComponent extends BaseAddEditComponent implements OnInit, On this.hasPasswordHistory = this.cipher.hasPasswordHistory; this.cleanUp(); + const activeUserId = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a.id)), + ); + this.canAccessPremium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeUserId), ); + if (this.showTotp()) { await this.totpUpdateCode(); const interval = this.totpService.getTimeInterval(this.cipher.login.totp); diff --git a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts index 9a5537985b8..7f7e0f075b7 100644 --- a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts +++ b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts @@ -1,6 +1,7 @@ import { TestBed } from "@angular/core/testing"; import { BehaviorSubject, firstValueFrom } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; @@ -21,7 +22,8 @@ describe("VaultBannersService", () => { let service: VaultBannersService; const isSelfHost = jest.fn().mockReturnValue(false); const hasPremiumFromAnySource$ = new BehaviorSubject(false); - const fakeStateProvider = new FakeStateProvider(mockAccountServiceWith("user-id" as UserId)); + const userId = "user-id" as UserId; + const fakeStateProvider = new FakeStateProvider(mockAccountServiceWith(userId)); const getEmailVerified = jest.fn().mockResolvedValue(true); const hasMasterPassword = jest.fn().mockResolvedValue(true); const getKdfConfig = jest @@ -44,15 +46,15 @@ describe("VaultBannersService", () => { }, { provide: BillingAccountProfileStateService, - useValue: { hasPremiumFromAnySource$: hasPremiumFromAnySource$ }, + useValue: { hasPremiumFromAnySource$: () => hasPremiumFromAnySource$ }, }, { provide: StateProvider, useValue: fakeStateProvider, }, { - provide: PlatformUtilsService, - useValue: { isSelfHost }, + provide: AccountService, + useValue: mockAccountServiceWith(userId), }, { provide: TokenService, diff --git a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts index 6ab37ea0cdd..c18b046e35e 100644 --- a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts +++ b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts @@ -1,7 +1,17 @@ import { Injectable } from "@angular/core"; -import { Subject, Observable, combineLatest, firstValueFrom, map } from "rxjs"; -import { mergeMap, take } from "rxjs/operators"; - +import { + Subject, + Observable, + combineLatest, + firstValueFrom, + map, + mergeMap, + take, + switchMap, + of, +} from "rxjs"; + +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; @@ -74,15 +84,23 @@ export class VaultBannersService { private platformUtilsService: PlatformUtilsService, private kdfConfigService: KdfConfigService, private syncService: SyncService, + private accountService: AccountService, ) { this.pollUntilSynced(); this.premiumBannerState = this.stateProvider.getActive(PREMIUM_BANNER_REPROMPT_KEY); this.sessionBannerState = this.stateProvider.getActive(BANNERS_DISMISSED_DISK_KEY); - const premiumSources$ = combineLatest([ - this.billingAccountProfileStateService.hasPremiumFromAnySource$, - this.premiumBannerState.state$, - ]); + const premiumSources$ = this.accountService.activeAccount$.pipe( + take(1), + switchMap((account) => { + return combineLatest([ + account + ? this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id) + : of(false), + this.premiumBannerState.state$, + ]); + }), + ); this.shouldShowPremiumBanner$ = this.syncCompleted$.pipe( take(1), // Wait until the first sync is complete before considering the premium status diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts index 18a1d8b338a..fe030162d19 100644 --- a/apps/web/src/app/vault/individual-vault/vault.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault.component.ts @@ -467,7 +467,7 @@ export class VaultComponent implements OnInit, OnDestroy { switchMap(() => combineLatest([ filter$, - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(this.activeUserId), allCollections$, this.organizationService.organizations$, ciphers$, diff --git a/libs/angular/src/directives/not-premium.directive.ts b/libs/angular/src/directives/not-premium.directive.ts index 3aee9b192d2..5a1c636c009 100644 --- a/libs/angular/src/directives/not-premium.directive.ts +++ b/libs/angular/src/directives/not-premium.directive.ts @@ -1,6 +1,7 @@ import { Directive, OnInit, TemplateRef, ViewContainerRef } from "@angular/core"; import { firstValueFrom } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; /** @@ -14,11 +15,19 @@ export class NotPremiumDirective implements OnInit { private templateRef: TemplateRef, private viewContainer: ViewContainerRef, private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} async ngOnInit(): Promise { + const account = await firstValueFrom(this.accountService.activeAccount$); + + if (!account) { + this.viewContainer.createEmbeddedView(this.templateRef); + return; + } + const premium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), ); if (premium) { diff --git a/libs/angular/src/directives/premium.directive.ts b/libs/angular/src/directives/premium.directive.ts index d475669a1ab..2188205ba65 100644 --- a/libs/angular/src/directives/premium.directive.ts +++ b/libs/angular/src/directives/premium.directive.ts @@ -1,6 +1,7 @@ import { Directive, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from "@angular/core"; -import { Subject, takeUntil } from "rxjs"; +import { of, Subject, switchMap, takeUntil } from "rxjs"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; /** @@ -16,16 +17,24 @@ export class PremiumDirective implements OnInit, OnDestroy { private templateRef: TemplateRef, private viewContainer: ViewContainerRef, private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} async ngOnInit(): Promise { - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntil(this.directiveIsDestroyed$)) + this.accountService.activeAccount$ + .pipe( + switchMap((account) => + account + ? this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id) + : of(false), + ), + takeUntil(this.directiveIsDestroyed$), + ) .subscribe((premium: boolean) => { if (premium) { - this.viewContainer.clear(); - } else { this.viewContainer.createEmbeddedView(this.templateRef); + } else { + this.viewContainer.clear(); } }); } diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 583ba82fc98..f9a72f24476 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -1281,7 +1281,7 @@ const safeProviders: SafeProvider[] = [ safeProvider({ provide: BillingAccountProfileStateService, useClass: DefaultBillingAccountProfileStateService, - deps: [StateProvider], + deps: [StateProvider, PlatformUtilsServiceAbstraction, ApiServiceAbstraction], }), safeProvider({ provide: OrganizationManagementPreferencesService, diff --git a/libs/angular/src/tools/send/add-edit.component.ts b/libs/angular/src/tools/send/add-edit.component.ts index 228abec98a9..aeee1fa104c 100644 --- a/libs/angular/src/tools/send/add-edit.component.ts +++ b/libs/angular/src/tools/send/add-edit.component.ts @@ -3,7 +3,15 @@ import { DatePipe } from "@angular/common"; import { Directive, EventEmitter, Input, OnDestroy, OnInit, Output } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; -import { Subject, firstValueFrom, takeUntil, map, BehaviorSubject, concatMap } from "rxjs"; +import { + Subject, + firstValueFrom, + takeUntil, + map, + BehaviorSubject, + concatMap, + switchMap, +} from "rxjs"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; @@ -197,8 +205,13 @@ export class AddEditComponent implements OnInit, OnDestroy { const env = await firstValueFrom(this.environmentService.environment$); this.sendLinkBaseUrl = env.getSendUrl(); - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntil(this.destroy$)) + this.accountService.activeAccount$ + .pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + takeUntil(this.destroy$), + ) .subscribe((hasPremiumFromAnySource) => { this.canAccessPremium = hasPremiumFromAnySource; }); diff --git a/libs/angular/src/vault/components/attachments.component.ts b/libs/angular/src/vault/components/attachments.component.ts index 521d38a1f47..425b4be2840 100644 --- a/libs/angular/src/vault/components/attachments.component.ts +++ b/libs/angular/src/vault/components/attachments.component.ts @@ -209,7 +209,7 @@ export class AttachmentsComponent implements OnInit { ); const canAccessPremium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeUserId), ); this.canAccessAttachments = canAccessPremium || this.cipher.organizationId != null; diff --git a/libs/angular/src/vault/components/premium.component.ts b/libs/angular/src/vault/components/premium.component.ts index 2ad25f2e45a..8b1f215ef42 100644 --- a/libs/angular/src/vault/components/premium.component.ts +++ b/libs/angular/src/vault/components/premium.component.ts @@ -1,9 +1,10 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore import { OnInit, Directive } from "@angular/core"; -import { firstValueFrom, Observable } from "rxjs"; +import { firstValueFrom, Observable, switchMap } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -30,8 +31,13 @@ export class PremiumComponent implements OnInit { protected dialogService: DialogService, private environmentService: EnvironmentService, billingAccountProfileStateService: BillingAccountProfileStateService, + accountService: AccountService, ) { - this.isPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + this.isPremium$ = accountService.activeAccount$.pipe( + switchMap((account) => + billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + ); } async ngOnInit() { diff --git a/libs/angular/src/vault/components/view.component.ts b/libs/angular/src/vault/components/view.component.ts index 6bea4cd6150..fc12aeff2f2 100644 --- a/libs/angular/src/vault/components/view.component.ts +++ b/libs/angular/src/vault/components/view.component.ts @@ -148,7 +148,7 @@ export class ViewComponent implements OnDestroy, OnInit { await this.cipherService.getKeyForCipherKeyDecryption(cipher, activeUserId), ); this.canAccessPremium = await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeUserId), ); this.showPremiumRequiredTotp = this.cipher.login.totp && !this.canAccessPremium && !this.cipher.organizationUseTotp; diff --git a/libs/common/src/billing/abstractions/account/billing-account-profile-state.service.ts b/libs/common/src/billing/abstractions/account/billing-account-profile-state.service.ts index 8fbbc7c1c91..a4253226880 100644 --- a/libs/common/src/billing/abstractions/account/billing-account-profile-state.service.ts +++ b/libs/common/src/billing/abstractions/account/billing-account-profile-state.service.ts @@ -11,27 +11,32 @@ export type BillingAccountProfile = { export abstract class BillingAccountProfileStateService { /** - * Emits `true` when the active user's account has been granted premium from any of the + * Emits `true` when the user's account has been granted premium from any of the * organizations it is a member of. Otherwise, emits `false` */ - hasPremiumFromAnyOrganization$: Observable; + abstract hasPremiumFromAnyOrganization$(userId: UserId): Observable; /** - * Emits `true` when the active user's account has an active premium subscription at the + * Emits `true` when the user's account has an active premium subscription at the * individual user level */ - hasPremiumPersonally$: Observable; + abstract hasPremiumPersonally$(userId: UserId): Observable; /** * Emits `true` when either `hasPremiumPersonally` or `hasPremiumFromAnyOrganization` is `true` */ - hasPremiumFromAnySource$: Observable; + abstract hasPremiumFromAnySource$(userId: UserId): Observable; /** - * Sets the active user's premium status fields upon every full sync, either from their personal + * Emits `true` when the subscription menu item should be shown in navigation. + * This is hidden for organizations that provide premium, except if the user has premium personally + * or has a billing history. + */ + abstract canViewSubscription$(userId: UserId): Observable; + + /** + * Sets the user's premium status fields upon every full sync, either from their personal * subscription to premium, or an organization they're a part of that grants them premium. - * @param hasPremiumPersonally - * @param hasPremiumFromAnyOrganization */ abstract setHasPremium( hasPremiumPersonally: boolean, diff --git a/libs/common/src/billing/services/account/billing-account-profile-state.service.spec.ts b/libs/common/src/billing/services/account/billing-account-profile-state.service.spec.ts index 7e0dee0eedf..372d8099865 100644 --- a/libs/common/src/billing/services/account/billing-account-profile-state.service.spec.ts +++ b/libs/common/src/billing/services/account/billing-account-profile-state.service.spec.ts @@ -1,5 +1,9 @@ import { firstValueFrom } from "rxjs"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { BillingHistoryResponse } from "@bitwarden/common/billing/models/response/billing-history.response"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + import { FakeAccountService, mockAccountServiceWith, @@ -19,14 +23,26 @@ describe("BillingAccountProfileStateService", () => { let sut: DefaultBillingAccountProfileStateService; let userBillingAccountProfileState: FakeSingleUserState; let accountService: FakeAccountService; + let platformUtilsService: jest.Mocked; + let apiService: jest.Mocked; const userId = "fakeUserId" as UserId; beforeEach(() => { accountService = mockAccountServiceWith(userId); stateProvider = new FakeStateProvider(accountService); - - sut = new DefaultBillingAccountProfileStateService(stateProvider); + platformUtilsService = { + isSelfHost: jest.fn(), + } as any; + apiService = { + getUserBillingHistory: jest.fn(), + } as any; + + sut = new DefaultBillingAccountProfileStateService( + stateProvider, + platformUtilsService, + apiService, + ); userBillingAccountProfileState = stateProvider.singleUser.getFake( userId, @@ -45,7 +61,7 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: true, }); - expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$)).toBe(true); + expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$(userId))).toBe(true); }); it("return false when they do not have premium from an organization", async () => { @@ -54,13 +70,7 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: false, }); - expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$)).toBe(false); - }); - - it("returns false when there is no active user", async () => { - await accountService.switchAccount(null); - - expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$)).toBe(false); + expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$(userId))).toBe(false); }); }); @@ -71,7 +81,7 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: false, }); - expect(await firstValueFrom(sut.hasPremiumPersonally$)).toBe(true); + expect(await firstValueFrom(sut.hasPremiumPersonally$(userId))).toBe(true); }); it("returns false when the user does not have premium personally", async () => { @@ -80,13 +90,7 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: false, }); - expect(await firstValueFrom(sut.hasPremiumPersonally$)).toBe(false); - }); - - it("returns false when there is no active user", async () => { - await accountService.switchAccount(null); - - expect(await firstValueFrom(sut.hasPremiumPersonally$)).toBe(false); + expect(await firstValueFrom(sut.hasPremiumPersonally$(userId))).toBe(false); }); }); @@ -97,7 +101,7 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: false, }); - expect(await firstValueFrom(sut.hasPremiumFromAnySource$)).toBe(true); + expect(await firstValueFrom(sut.hasPremiumFromAnySource$(userId))).toBe(true); }); it("returns true when the user has premium from an organization", async () => { @@ -106,7 +110,7 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: true, }); - expect(await firstValueFrom(sut.hasPremiumFromAnySource$)).toBe(true); + expect(await firstValueFrom(sut.hasPremiumFromAnySource$(userId))).toBe(true); }); it("returns true when they have premium personally AND from an organization", async () => { @@ -115,23 +119,87 @@ describe("BillingAccountProfileStateService", () => { hasPremiumFromAnyOrganization: true, }); - expect(await firstValueFrom(sut.hasPremiumFromAnySource$)).toBe(true); + expect(await firstValueFrom(sut.hasPremiumFromAnySource$(userId))).toBe(true); }); + }); - it("returns false when there is no active user", async () => { - await accountService.switchAccount(null); + describe("setHasPremium", () => { + it("should update the user's state when called", async () => { + await sut.setHasPremium(true, false, userId); - expect(await firstValueFrom(sut.hasPremiumFromAnySource$)).toBe(false); + expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$(userId))).toBe(false); + expect(await firstValueFrom(sut.hasPremiumPersonally$(userId))).toBe(true); + expect(await firstValueFrom(sut.hasPremiumFromAnySource$(userId))).toBe(true); }); }); - describe("setHasPremium", () => { - it("should update the active users state when called", async () => { - await sut.setHasPremium(true, false, userId); + describe("canViewSubscription$", () => { + beforeEach(() => { + platformUtilsService.isSelfHost.mockReturnValue(false); + apiService.getUserBillingHistory.mockResolvedValue( + new BillingHistoryResponse({ invoices: [], transactions: [] }), + ); + }); + + it("returns true when user has premium personally", async () => { + userBillingAccountProfileState.nextState({ + hasPremiumPersonally: true, + hasPremiumFromAnyOrganization: true, + }); + + expect(await firstValueFrom(sut.canViewSubscription$(userId))).toBe(true); + }); + + it("returns true when user has no premium from any source", async () => { + userBillingAccountProfileState.nextState({ + hasPremiumPersonally: false, + hasPremiumFromAnyOrganization: false, + }); + + expect(await firstValueFrom(sut.canViewSubscription$(userId))).toBe(true); + }); + + it("returns true when user has billing history in cloud environment", async () => { + userBillingAccountProfileState.nextState({ + hasPremiumPersonally: false, + hasPremiumFromAnyOrganization: true, + }); + platformUtilsService.isSelfHost.mockReturnValue(false); + apiService.getUserBillingHistory.mockResolvedValue( + new BillingHistoryResponse({ + invoices: [{ id: "1" }], + transactions: [{ id: "2" }], + }), + ); + + expect(await firstValueFrom(sut.canViewSubscription$(userId))).toBe(true); + }); + + it("returns false when user has no premium personally, has org premium, and no billing history", async () => { + userBillingAccountProfileState.nextState({ + hasPremiumPersonally: false, + hasPremiumFromAnyOrganization: true, + }); + platformUtilsService.isSelfHost.mockReturnValue(false); + apiService.getUserBillingHistory.mockResolvedValue( + new BillingHistoryResponse({ + invoices: [], + transactions: [], + }), + ); + + expect(await firstValueFrom(sut.canViewSubscription$(userId))).toBe(false); + }); + + it("returns false when user has no premium personally, has org premium, in self-hosted environment", async () => { + userBillingAccountProfileState.nextState({ + hasPremiumPersonally: false, + hasPremiumFromAnyOrganization: true, + }); + platformUtilsService.isSelfHost.mockReturnValue(true); - expect(await firstValueFrom(sut.hasPremiumFromAnyOrganization$)).toBe(false); - expect(await firstValueFrom(sut.hasPremiumPersonally$)).toBe(true); - expect(await firstValueFrom(sut.hasPremiumFromAnySource$)).toBe(true); + expect(await firstValueFrom(sut.canViewSubscription$(userId))).toBe(false); + expect(apiService.getUserBillingHistory).not.toHaveBeenCalled(); }); }); }); diff --git a/libs/common/src/billing/services/account/billing-account-profile-state.service.ts b/libs/common/src/billing/services/account/billing-account-profile-state.service.ts index 7d256da9714..579a81eeb5c 100644 --- a/libs/common/src/billing/services/account/billing-account-profile-state.service.ts +++ b/libs/common/src/billing/services/account/billing-account-profile-state.service.ts @@ -1,11 +1,9 @@ -import { map, Observable, of, switchMap } from "rxjs"; +import { map, Observable, combineLatest, concatMap } from "rxjs"; -import { - ActiveUserState, - BILLING_DISK, - StateProvider, - UserKeyDefinition, -} from "../../../platform/state"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; + +import { BILLING_DISK, StateProvider, UserKeyDefinition } from "../../../platform/state"; import { UserId } from "../../../types/guid"; import { BillingAccountProfile, @@ -22,42 +20,34 @@ export const BILLING_ACCOUNT_PROFILE_KEY_DEFINITION = new UserKeyDefinition; + constructor( + private readonly stateProvider: StateProvider, + private readonly platformUtilsService: PlatformUtilsService, + private readonly apiService: ApiService, + ) {} - hasPremiumFromAnyOrganization$: Observable; - hasPremiumPersonally$: Observable; - hasPremiumFromAnySource$: Observable; - - constructor(private readonly stateProvider: StateProvider) { - this.billingAccountProfileState = stateProvider.getActive( - BILLING_ACCOUNT_PROFILE_KEY_DEFINITION, - ); - - // Setup an observable that will always track the currently active user - // but will fallback to emitting null when there is no active user. - const billingAccountProfileOrNull = stateProvider.activeUserId$.pipe( - switchMap((userId) => - userId != null - ? stateProvider.getUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION).state$ - : of(null), - ), - ); - - this.hasPremiumFromAnyOrganization$ = billingAccountProfileOrNull.pipe( - map((billingAccountProfile) => !!billingAccountProfile?.hasPremiumFromAnyOrganization), - ); + hasPremiumFromAnyOrganization$(userId: UserId): Observable { + return this.stateProvider + .getUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION) + .state$.pipe(map((profile) => !!profile?.hasPremiumFromAnyOrganization)); + } - this.hasPremiumPersonally$ = billingAccountProfileOrNull.pipe( - map((billingAccountProfile) => !!billingAccountProfile?.hasPremiumPersonally), - ); + hasPremiumPersonally$(userId: UserId): Observable { + return this.stateProvider + .getUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION) + .state$.pipe(map((profile) => !!profile?.hasPremiumPersonally)); + } - this.hasPremiumFromAnySource$ = billingAccountProfileOrNull.pipe( - map( - (billingAccountProfile) => - billingAccountProfile?.hasPremiumFromAnyOrganization === true || - billingAccountProfile?.hasPremiumPersonally === true, - ), - ); + hasPremiumFromAnySource$(userId: UserId): Observable { + return this.stateProvider + .getUser(userId, BILLING_ACCOUNT_PROFILE_KEY_DEFINITION) + .state$.pipe( + map( + (profile) => + profile?.hasPremiumFromAnyOrganization === true || + profile?.hasPremiumPersonally === true, + ), + ); } async setHasPremium( @@ -72,4 +62,23 @@ export class DefaultBillingAccountProfileStateService implements BillingAccountP }; }); } + + canViewSubscription$(userId: UserId): Observable { + return combineLatest([ + this.hasPremiumPersonally$(userId), + this.hasPremiumFromAnyOrganization$(userId), + ]).pipe( + concatMap(async ([hasPremiumPersonally, hasPremiumFromOrg]) => { + const isCloud = !this.platformUtilsService.isSelfHost(); + + let billing = null; + if (isCloud) { + billing = await this.apiService.getUserBillingHistory(); + } + + const cloudAndBillingHistory = isCloud && !billing?.hasNoHistory; + return hasPremiumPersonally || !hasPremiumFromOrg || cloudAndBillingHistory; + }), + ); + } } diff --git a/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts index d446bcb92ab..19f9d3a174a 100644 --- a/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts +++ b/libs/tools/send/send-ui/src/new-send-dropdown/new-send-dropdown.component.ts @@ -4,6 +4,7 @@ import { Router, RouterLink } from "@angular/router"; import { firstValueFrom } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; import { BadgeModule, ButtonModule, MenuModule } from "@bitwarden/components"; @@ -24,11 +25,18 @@ export class NewSendDropdownComponent implements OnInit { constructor( private router: Router, private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} async ngOnInit() { + const account = await firstValueFrom(this.accountService.activeAccount$); + if (!account) { + this.hasNoPremium = true; + return; + } + this.hasNoPremium = !(await firstValueFrom( - this.billingAccountProfileStateService.hasPremiumFromAnySource$, + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), )); } diff --git a/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.spec.ts b/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.spec.ts index bb687c6d5e9..2f6bf691c1d 100644 --- a/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.spec.ts +++ b/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.spec.ts @@ -5,8 +5,10 @@ import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { UserId } from "@bitwarden/common/types/guid"; import { ChipSelectComponent } from "@bitwarden/components"; import { SendListFiltersService } from "../services/send-list-filters.service"; @@ -18,13 +20,22 @@ describe("SendListFiltersComponent", () => { let fixture: ComponentFixture; let sendListFiltersService: SendListFiltersService; let billingAccountProfileStateService: MockProxy; + let accountService: MockProxy; + const userId = "userId" as UserId; beforeEach(async () => { sendListFiltersService = new SendListFiltersService(mock(), new FormBuilder()); sendListFiltersService.resetFilterForm = jest.fn(); billingAccountProfileStateService = mock(); + accountService = mock(); - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + accountService.activeAccount$ = of({ + id: userId, + email: "test@email.com", + emailVerified: true, + name: "Test User", + }); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true)); await TestBed.configureTestingModule({ imports: [ @@ -37,10 +48,8 @@ describe("SendListFiltersComponent", () => { providers: [ { provide: I18nService, useValue: { t: (key: string) => key } }, { provide: SendListFiltersService, useValue: sendListFiltersService }, - { - provide: BillingAccountProfileStateService, - useValue: billingAccountProfileStateService, - }, + { provide: BillingAccountProfileStateService, useValue: billingAccountProfileStateService }, + { provide: AccountService, useValue: accountService }, ], }).compileComponents(); @@ -57,6 +66,7 @@ describe("SendListFiltersComponent", () => { let canAccessPremium: boolean | undefined; component["canAccessPremium$"].subscribe((value) => (canAccessPremium = value)); expect(canAccessPremium).toBe(true); + expect(billingAccountProfileStateService.hasPremiumFromAnySource$).toHaveBeenCalledWith(userId); }); it("should call resetFilterForm on ngOnDestroy", () => { diff --git a/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.ts b/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.ts index b313ced742a..d42eab382e9 100644 --- a/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.ts +++ b/libs/tools/send/send-ui/src/send-list-filters/send-list-filters.component.ts @@ -1,10 +1,11 @@ import { CommonModule } from "@angular/common"; import { Component, OnDestroy } from "@angular/core"; import { ReactiveFormsModule } from "@angular/forms"; -import { Observable } from "rxjs"; +import { Observable, of, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ChipSelectComponent } from "@bitwarden/components"; import { SendListFiltersService } from "../services/send-list-filters.service"; @@ -23,8 +24,15 @@ export class SendListFiltersComponent implements OnDestroy { constructor( private sendListFiltersService: SendListFiltersService, billingAccountProfileStateService: BillingAccountProfileStateService, + accountService: AccountService, ) { - this.canAccessPremium$ = billingAccountProfileStateService.hasPremiumFromAnySource$; + this.canAccessPremium$ = accountService.activeAccount$.pipe( + switchMap((account) => + account + ? billingAccountProfileStateService.hasPremiumFromAnySource$(account.id) + : of(false), + ), + ); } ngOnDestroy(): void { diff --git a/libs/vault/src/cipher-view/attachments/attachments-v2-view.component.ts b/libs/vault/src/cipher-view/attachments/attachments-v2-view.component.ts index acfdfa3337d..0c2ca35cbbc 100644 --- a/libs/vault/src/cipher-view/attachments/attachments-v2-view.component.ts +++ b/libs/vault/src/cipher-view/attachments/attachments-v2-view.component.ts @@ -6,6 +6,7 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { NEVER, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { StateProvider } from "@bitwarden/common/platform/state"; import { OrganizationId } from "@bitwarden/common/types/guid"; @@ -47,16 +48,22 @@ export class AttachmentsV2ViewComponent { private keyService: KeyService, private billingAccountProfileStateService: BillingAccountProfileStateService, private stateProvider: StateProvider, + private accountService: AccountService, ) { this.subscribeToHasPremiumCheck(); this.subscribeToOrgKey(); } subscribeToHasPremiumCheck() { - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntilDestroyed()) - .subscribe((data) => { - this.canAccessPremium = data; + this.accountService.activeAccount$ + .pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + takeUntilDestroyed(), + ) + .subscribe((hasPremium) => { + this.canAccessPremium = hasPremium; }); } diff --git a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts index c8ac0598c97..9c09028650e 100644 --- a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts +++ b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.spec.ts @@ -6,10 +6,12 @@ import { BehaviorSubject } from "rxjs"; import { CopyClickDirective } from "@bitwarden/angular/directives/copy-click.directive"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { EventType } from "@bitwarden/common/enums"; 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 { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; @@ -26,6 +28,17 @@ describe("LoginCredentialsViewComponent", () => { let fixture: ComponentFixture; const hasPremiumFromAnySource$ = new BehaviorSubject(true); + const mockAccount = { + id: "test-user-id" as UserId, + email: "test@example.com", + emailVerified: true, + name: "Test User", + type: 0, + status: 0, + kdf: 0, + kdfIterations: 0, + }; + const activeAccount$ = new BehaviorSubject(mockAccount); const cipher = { id: "cipher-id", @@ -48,8 +61,11 @@ describe("LoginCredentialsViewComponent", () => { providers: [ { provide: BillingAccountProfileStateService, - useValue: mock({ hasPremiumFromAnySource$ }), + useValue: mock({ + hasPremiumFromAnySource$: () => hasPremiumFromAnySource$, + }), }, + { provide: AccountService, useValue: mock({ activeAccount$ }) }, { provide: PremiumUpgradePromptService, useValue: mock() }, { provide: EventCollectionService, useValue: mock({ collect }) }, { provide: PlatformUtilsService, useValue: mock() }, diff --git a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts index 0c42c2ddda7..b24fcdfa1fd 100644 --- a/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts +++ b/libs/vault/src/cipher-view/login-credentials/login-credentials-view.component.ts @@ -2,10 +2,11 @@ // @ts-strict-ignore import { CommonModule, DatePipe } from "@angular/common"; import { Component, inject, Input } from "@angular/core"; -import { Observable, shareReplay } from "rxjs"; +import { Observable, switchMap } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -50,10 +51,11 @@ type TotpCodeValues = { export class LoginCredentialsViewComponent { @Input() cipher: CipherView; - isPremium$: Observable = - this.billingAccountProfileStateService.hasPremiumFromAnySource$.pipe( - shareReplay({ refCount: true, bufferSize: 1 }), - ); + isPremium$: Observable = this.accountService.activeAccount$.pipe( + switchMap((account) => + this.billingAccountProfileStateService.hasPremiumFromAnySource$(account.id), + ), + ); showPasswordCount: boolean = false; passwordRevealed: boolean = false; totpCodeCopyObj: TotpCodeValues; @@ -64,6 +66,7 @@ export class LoginCredentialsViewComponent { private i18nService: I18nService, private premiumUpgradeService: PremiumUpgradePromptService, private eventCollectionService: EventCollectionService, + private accountService: AccountService, ) {} get fido2CredentialCreationDateValue(): string { diff --git a/libs/vault/src/services/copy-cipher-field.service.spec.ts b/libs/vault/src/services/copy-cipher-field.service.spec.ts index 48510b2efd9..5a273c0828f 100644 --- a/libs/vault/src/services/copy-cipher-field.service.spec.ts +++ b/libs/vault/src/services/copy-cipher-field.service.spec.ts @@ -2,6 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { of } from "rxjs"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService, Account } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -22,6 +23,8 @@ describe("CopyCipherFieldService", () => { let totpService: MockProxy; let i18nService: MockProxy; let billingAccountProfileStateService: MockProxy; + let accountService: MockProxy; + const userId = "userId"; beforeEach(() => { platformUtilsService = mock(); @@ -31,6 +34,9 @@ describe("CopyCipherFieldService", () => { totpService = mock(); i18nService = mock(); billingAccountProfileStateService = mock(); + accountService = mock(); + + accountService.activeAccount$ = of({ id: userId } as Account); service = new CopyCipherFieldService( platformUtilsService, @@ -40,6 +46,7 @@ describe("CopyCipherFieldService", () => { totpService, i18nService, billingAccountProfileStateService, + accountService, ); }); @@ -128,12 +135,15 @@ describe("CopyCipherFieldService", () => { }); it("should get TOTP code when allowed from premium", async () => { - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(true); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(true)); totpService.getCode.mockResolvedValue("123456"); const result = await service.copy(valueToCopy, actionType, cipher, skipReprompt); expect(result).toBeTruthy(); expect(totpService.getCode).toHaveBeenCalledWith(valueToCopy); expect(platformUtilsService.copyToClipboard).toHaveBeenCalledWith("123456"); + expect(billingAccountProfileStateService.hasPremiumFromAnySource$).toHaveBeenCalledWith( + userId, + ); }); it("should get TOTP code when allowed from organization", async () => { @@ -146,11 +156,14 @@ describe("CopyCipherFieldService", () => { }); it("should return early when the user is not allowed to use TOTP", async () => { - billingAccountProfileStateService.hasPremiumFromAnySource$ = of(false); + billingAccountProfileStateService.hasPremiumFromAnySource$.mockReturnValue(of(false)); const result = await service.copy(valueToCopy, actionType, cipher, skipReprompt); expect(result).toBeFalsy(); expect(totpService.getCode).not.toHaveBeenCalled(); expect(platformUtilsService.copyToClipboard).not.toHaveBeenCalled(); + expect(billingAccountProfileStateService.hasPremiumFromAnySource$).toHaveBeenCalledWith( + userId, + ); }); it("should return early when TOTP is not set", async () => { diff --git a/libs/vault/src/services/copy-cipher-field.service.ts b/libs/vault/src/services/copy-cipher-field.service.ts index bfcf3495865..2805f3e7541 100644 --- a/libs/vault/src/services/copy-cipher-field.service.ts +++ b/libs/vault/src/services/copy-cipher-field.service.ts @@ -2,6 +2,7 @@ import { Injectable } from "@angular/core"; import { firstValueFrom } from "rxjs"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; +import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EventType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -87,6 +88,7 @@ export class CopyCipherFieldService { private totpService: TotpService, private i18nService: I18nService, private billingAccountProfileStateService: BillingAccountProfileStateService, + private accountService: AccountService, ) {} /** @@ -148,10 +150,16 @@ export class CopyCipherFieldService { * Determines if TOTP generation is allowed for a cipher and user. */ async totpAllowed(cipher: CipherView): Promise { + const activeAccount = await firstValueFrom(this.accountService.activeAccount$); + if (!activeAccount?.id) { + return false; + } return ( (cipher?.login?.hasTotp ?? false) && (cipher.organizationUseTotp || - (await firstValueFrom(this.billingAccountProfileStateService.hasPremiumFromAnySource$))) + (await firstValueFrom( + this.billingAccountProfileStateService.hasPremiumFromAnySource$(activeAccount.id), + ))) ); } } From c0d3fe15d10300353e435a1d524c287dc05b60d4 Mon Sep 17 00:00:00 2001 From: Thomas Avery <43214426+Thomas-Avery@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:47:51 -0600 Subject: [PATCH 64/65] [PM-11528] Move Lock to KM ownership (#12407) * update code owners * Move lock component v2 to KM * Add @bitwarden/key-management/angular to tsconfigs * Move lock component service to KM * Move lock component v1 to KM * Update imports * Move into @bitwarden/key-management * Revert "Move into @bitwarden/key-management" This reverts commit b7514fb8c2ba3ee57331829b297949aa9052bf4d. * Add to tsconfig.libs --- .github/CODEOWNERS | 1 + .../extension-lock-component.service.spec.ts | 4 ++-- .../services/extension-lock-component.service.ts | 14 +++++++------- apps/browser/src/popup/app-routing.module.ts | 2 +- apps/browser/src/popup/services/services.module.ts | 4 ++-- apps/browser/tsconfig.json | 1 + apps/cli/tsconfig.json | 1 + apps/desktop/src/app/app-routing.module.ts | 2 +- apps/desktop/src/app/services/services.module.ts | 4 ++-- .../desktop-lock-component.service.spec.ts | 2 +- .../services/desktop-lock-component.service.ts | 10 +++++----- apps/desktop/tsconfig.json | 1 + apps/web/src/app/auth/core/services/index.ts | 1 - apps/web/src/app/core/core.module.ts | 4 ++-- .../services/web-lock-component.service.spec.ts | 0 .../lock}/services/web-lock-component.service.ts | 2 +- apps/web/src/app/oss-routing.module.ts | 2 +- apps/web/tsconfig.json | 1 + bitwarden_license/bit-cli/tsconfig.json | 1 + bitwarden_license/bit-common/tsconfig.json | 1 + bitwarden_license/bit-web/tsconfig.json | 1 + libs/auth/src/angular/index.ts | 4 ---- libs/key-management/src/angular/index.ts | 10 ++++++++++ .../angular/lock/components}/lock.component.html | 0 .../src/angular/lock/components}/lock.component.ts | 7 +++---- .../lock/services}/lock-component.service.ts | 0 libs/shared/tsconfig.libs.json | 1 + tsconfig.json | 1 + 28 files changed, 48 insertions(+), 34 deletions(-) rename apps/browser/src/{ => key-management/lock}/services/extension-lock-component.service.spec.ts (98%) rename apps/browser/src/{ => key-management/lock}/services/extension-lock-component.service.ts (94%) rename apps/desktop/src/{ => key-management/lock}/services/desktop-lock-component.service.spec.ts (99%) rename apps/desktop/src/{ => key-management/lock}/services/desktop-lock-component.service.ts (99%) rename apps/web/src/app/{auth/core => key-management/lock}/services/web-lock-component.service.spec.ts (100%) rename apps/web/src/app/{auth/core => key-management/lock}/services/web-lock-component.service.ts (98%) create mode 100644 libs/key-management/src/angular/index.ts rename libs/{auth/src/angular/lock => key-management/src/angular/lock/components}/lock.component.html (100%) rename libs/{auth/src/angular/lock => key-management/src/angular/lock/components}/lock.component.ts (99%) rename libs/{auth/src/angular/lock => key-management/src/angular/lock/services}/lock-component.service.ts (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index e38277877bb..cb36d87b9e1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -126,6 +126,7 @@ apps/web/src/app/key-management @bitwarden/team-key-management-dev apps/browser/src/key-management @bitwarden/team-key-management-dev apps/cli/src/key-management @bitwarden/team-key-management-dev libs/key-management @bitwarden/team-key-management-dev +libs/common/src/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 diff --git a/apps/browser/src/services/extension-lock-component.service.spec.ts b/apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts similarity index 98% rename from apps/browser/src/services/extension-lock-component.service.spec.ts rename to apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts index a8a019662ef..272201c6ede 100644 --- a/apps/browser/src/services/extension-lock-component.service.spec.ts +++ b/apps/browser/src/key-management/lock/services/extension-lock-component.service.spec.ts @@ -2,7 +2,6 @@ import { TestBed } from "@angular/core/testing"; import { mock, MockProxy } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; -import { BiometricsDisableReason, UnlockOptions } from "@bitwarden/auth/angular"; import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, @@ -11,8 +10,9 @@ import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaul import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { UserId } from "@bitwarden/common/types/guid"; import { KeyService, BiometricsService } from "@bitwarden/key-management"; +import { BiometricsDisableReason, UnlockOptions } from "@bitwarden/key-management/angular"; -import { BrowserRouterService } from "../platform/popup/services/browser-router.service"; +import { BrowserRouterService } from "../../../platform/popup/services/browser-router.service"; import { ExtensionLockComponentService } from "./extension-lock-component.service"; diff --git a/apps/browser/src/services/extension-lock-component.service.ts b/apps/browser/src/key-management/lock/services/extension-lock-component.service.ts similarity index 94% rename from apps/browser/src/services/extension-lock-component.service.ts rename to apps/browser/src/key-management/lock/services/extension-lock-component.service.ts index 4fc2ef69b21..07fb2ec6b87 100644 --- a/apps/browser/src/services/extension-lock-component.service.ts +++ b/apps/browser/src/key-management/lock/services/extension-lock-component.service.ts @@ -3,11 +3,6 @@ import { inject } from "@angular/core"; import { combineLatest, defer, map, Observable } from "rxjs"; -import { - BiometricsDisableReason, - LockComponentService, - UnlockOptions, -} from "@bitwarden/auth/angular"; import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, @@ -17,9 +12,14 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { UserId } from "@bitwarden/common/types/guid"; import { KeyService, BiometricsService } from "@bitwarden/key-management"; +import { + LockComponentService, + BiometricsDisableReason, + UnlockOptions, +} from "@bitwarden/key-management/angular"; -import { BiometricErrors, BiometricErrorTypes } from "../models/biometricErrors"; -import { BrowserRouterService } from "../platform/popup/services/browser-router.service"; +import { BiometricErrors, BiometricErrorTypes } from "../../../models/biometricErrors"; +import { BrowserRouterService } from "../../../platform/popup/services/browser-router.service"; export class ExtensionLockComponentService implements LockComponentService { private readonly userDecryptionOptionsService = inject(UserDecryptionOptionsServiceAbstraction); diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index 2d53ae7e239..7cc5bbe2f82 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -25,7 +25,6 @@ import { LoginComponent, LoginSecondaryContentComponent, LockIcon, - LockComponent, LoginViaAuthRequestComponent, PasswordHintComponent, RegistrationFinishComponent, @@ -43,6 +42,7 @@ import { TwoFactorTimeoutIcon, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { LockComponent } from "@bitwarden/key-management/angular"; import { NewDeviceVerificationNoticePageOneComponent, NewDeviceVerificationNoticePageTwoComponent, diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 92eb8973235..6542eb9c814 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -24,7 +24,6 @@ import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services. import { AnonLayoutWrapperDataService, LoginComponentService, - LockComponentService, SsoComponentService, LoginDecryptionOptionsService, } from "@bitwarden/auth/angular"; @@ -115,6 +114,7 @@ import { BiometricStateService, BiometricsService, } from "@bitwarden/key-management"; +import { LockComponentService } from "@bitwarden/key-management/angular"; import { PasswordRepromptService } from "@bitwarden/vault"; import { ForegroundLockService } from "../../auth/popup/accounts/foreground-lock.service"; @@ -127,6 +127,7 @@ import AutofillService from "../../autofill/services/autofill.service"; import { InlineMenuFieldQualificationService } from "../../autofill/services/inline-menu-field-qualification.service"; import { ForegroundBrowserBiometricsService } from "../../key-management/biometrics/foreground-browser-biometrics"; import { BrowserKeyService } from "../../key-management/browser-key.service"; +import { ExtensionLockComponentService } from "../../key-management/lock/services/extension-lock-component.service"; import { BrowserApi } from "../../platform/browser/browser-api"; import { runInsideAngular } from "../../platform/browser/run-inside-angular.operator"; /* eslint-disable no-restricted-imports */ @@ -150,7 +151,6 @@ import { BrowserStorageServiceProvider } from "../../platform/storage/browser-st import { ForegroundMemoryStorageService } from "../../platform/storage/foreground-memory-storage.service"; import { ForegroundSyncService } from "../../platform/sync/foreground-sync.service"; import { fromChromeRuntimeMessaging } from "../../platform/utils/from-chrome-runtime-messaging"; -import { ExtensionLockComponentService } from "../../services/extension-lock-component.service"; import { ForegroundVaultTimeoutService } from "../../services/vault-timeout/foreground-vault-timeout.service"; import { FilePopoutUtilsService } from "../../tools/popup/services/file-popout-utils.service"; import { Fido2UserVerificationService } from "../../vault/services/fido2-user-verification.service"; diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json index 6b53186e076..c1ef1443acc 100644 --- a/apps/browser/tsconfig.json +++ b/apps/browser/tsconfig.json @@ -34,6 +34,7 @@ "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/vault": ["../../libs/vault/src"] }, "plugins": [ diff --git a/apps/cli/tsconfig.json b/apps/cli/tsconfig.json index 3853cd93126..0668ecacdb4 100644 --- a/apps/cli/tsconfig.json +++ b/apps/cli/tsconfig.json @@ -26,6 +26,7 @@ "../../libs/tools/export/vault-export/vault-export-core/src" ], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/node/*": ["../../libs/node/src/*"] }, "plugins": [ diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index 7e82bb004fa..cd4932c616a 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -22,7 +22,6 @@ import { LoginComponent, LoginSecondaryContentComponent, LockIcon, - LockComponent, LoginViaAuthRequestComponent, PasswordHintComponent, RegistrationFinishComponent, @@ -40,6 +39,7 @@ import { TwoFactorTimeoutIcon, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { LockComponent } from "@bitwarden/key-management/angular"; import { NewDeviceVerificationNoticePageOneComponent, NewDeviceVerificationNoticePageTwoComponent, diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index 0f541907995..87c2a833073 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -24,7 +24,6 @@ import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services. import { LoginComponentService, SetPasswordJitService, - LockComponentService, SsoComponentService, DefaultSsoComponentService, } from "@bitwarden/auth/angular"; @@ -96,6 +95,7 @@ import { BiometricStateService, BiometricsService, } from "@bitwarden/key-management"; +import { LockComponentService } from "@bitwarden/key-management/angular"; import { DesktopLoginApprovalComponentService } from "../../auth/login/desktop-login-approval-component.service"; import { DesktopLoginComponentService } from "../../auth/login/desktop-login-component.service"; @@ -103,6 +103,7 @@ import { DesktopAutofillSettingsService } from "../../autofill/services/desktop- import { DesktopAutofillService } from "../../autofill/services/desktop-autofill.service"; import { DesktopFido2UserInterfaceService } from "../../autofill/services/desktop-fido2-user-interface.service"; import { ElectronBiometricsService } from "../../key-management/biometrics/electron-biometrics.service"; +import { DesktopLockComponentService } from "../../key-management/lock/services/desktop-lock-component.service"; import { flagEnabled } from "../../platform/flags"; import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; import { ElectronKeyService } from "../../platform/services/electron-key.service"; @@ -118,7 +119,6 @@ import { I18nRendererService } from "../../platform/services/i18n.renderer.servi 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 { NativeMessagingService } from "../../services/native-messaging.service"; diff --git a/apps/desktop/src/services/desktop-lock-component.service.spec.ts b/apps/desktop/src/key-management/lock/services/desktop-lock-component.service.spec.ts similarity index 99% rename from apps/desktop/src/services/desktop-lock-component.service.spec.ts rename to apps/desktop/src/key-management/lock/services/desktop-lock-component.service.spec.ts index 0d673a5b51c..2d60cdeb663 100644 --- a/apps/desktop/src/services/desktop-lock-component.service.spec.ts +++ b/apps/desktop/src/key-management/lock/services/desktop-lock-component.service.spec.ts @@ -2,7 +2,6 @@ import { TestBed } from "@angular/core/testing"; import { mock, MockProxy } from "jest-mock-extended"; import { firstValueFrom, of } from "rxjs"; -import { BiometricsDisableReason, UnlockOptions } from "@bitwarden/auth/angular"; import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, @@ -12,6 +11,7 @@ import { DeviceType } from "@bitwarden/common/enums"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { UserId } from "@bitwarden/common/types/guid"; import { KeyService, BiometricsService } from "@bitwarden/key-management"; +import { BiometricsDisableReason, UnlockOptions } from "@bitwarden/key-management/angular"; import { DesktopLockComponentService } from "./desktop-lock-component.service"; diff --git a/apps/desktop/src/services/desktop-lock-component.service.ts b/apps/desktop/src/key-management/lock/services/desktop-lock-component.service.ts similarity index 99% rename from apps/desktop/src/services/desktop-lock-component.service.ts rename to apps/desktop/src/key-management/lock/services/desktop-lock-component.service.ts index 7402779121f..76232fd3196 100644 --- a/apps/desktop/src/services/desktop-lock-component.service.ts +++ b/apps/desktop/src/key-management/lock/services/desktop-lock-component.service.ts @@ -1,11 +1,6 @@ import { inject } from "@angular/core"; import { combineLatest, defer, map, Observable } from "rxjs"; -import { - BiometricsDisableReason, - LockComponentService, - UnlockOptions, -} from "@bitwarden/auth/angular"; import { PinServiceAbstraction, UserDecryptionOptionsServiceAbstraction, @@ -16,6 +11,11 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { KeySuffixOptions } from "@bitwarden/common/platform/enums"; import { UserId } from "@bitwarden/common/types/guid"; import { KeyService, BiometricsService } from "@bitwarden/key-management"; +import { + BiometricsDisableReason, + LockComponentService, + UnlockOptions, +} from "@bitwarden/key-management/angular"; export class DesktopLockComponentService implements LockComponentService { private readonly userDecryptionOptionsService = inject(UserDecryptionOptionsServiceAbstraction); diff --git a/apps/desktop/tsconfig.json b/apps/desktop/tsconfig.json index 2d9de5fee49..da61ef22dd4 100644 --- a/apps/desktop/tsconfig.json +++ b/apps/desktop/tsconfig.json @@ -29,6 +29,7 @@ "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/node/*": ["../../libs/node/src/*"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], diff --git a/apps/web/src/app/auth/core/services/index.ts b/apps/web/src/app/auth/core/services/index.ts index c14292d7c6d..6275ad4f4f3 100644 --- a/apps/web/src/app/auth/core/services/index.ts +++ b/apps/web/src/app/auth/core/services/index.ts @@ -3,4 +3,3 @@ export * from "./login-decryption-options"; export * from "./webauthn-login"; export * from "./set-password-jit"; export * from "./registration"; -export * from "./web-lock-component.service"; diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 2dd1db9fdb6..8f21dfa2c8b 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -30,7 +30,6 @@ import { ModalService as ModalServiceAbstraction } from "@bitwarden/angular/serv import { RegistrationFinishService as RegistrationFinishServiceAbstraction, LoginComponentService, - LockComponentService, SetPasswordJitService, SsoComponentService, LoginDecryptionOptionsService, @@ -92,6 +91,7 @@ import { KeyService as KeyServiceAbstraction, BiometricsService, } from "@bitwarden/key-management"; +import { LockComponentService } from "@bitwarden/key-management/angular"; import { flagEnabled } from "../../utils/flags"; import { PolicyListService } from "../admin-console/core/policy-list.service"; @@ -99,13 +99,13 @@ import { WebSetPasswordJitService, WebRegistrationFinishService, WebLoginComponentService, - WebLockComponentService, WebLoginDecryptionOptionsService, } from "../auth"; import { WebSsoComponentService } from "../auth/core/services/login/web-sso-component.service"; import { AcceptOrganizationInviteService } from "../auth/organization-invite/accept-organization.service"; import { HtmlStorageService } from "../core/html-storage.service"; import { I18nService } from "../core/i18n.service"; +import { WebLockComponentService } from "../key-management/lock/services/web-lock-component.service"; import { WebProcessReloadService } from "../key-management/services/web-process-reload.service"; import { WebBiometricsService } from "../key-management/web-biometric.service"; import { WebEnvironmentService } from "../platform/web-environment.service"; diff --git a/apps/web/src/app/auth/core/services/web-lock-component.service.spec.ts b/apps/web/src/app/key-management/lock/services/web-lock-component.service.spec.ts similarity index 100% rename from apps/web/src/app/auth/core/services/web-lock-component.service.spec.ts rename to apps/web/src/app/key-management/lock/services/web-lock-component.service.spec.ts diff --git a/apps/web/src/app/auth/core/services/web-lock-component.service.ts b/apps/web/src/app/key-management/lock/services/web-lock-component.service.ts similarity index 98% rename from apps/web/src/app/auth/core/services/web-lock-component.service.ts rename to apps/web/src/app/key-management/lock/services/web-lock-component.service.ts index e24f299e23b..dc124983c9a 100644 --- a/apps/web/src/app/auth/core/services/web-lock-component.service.ts +++ b/apps/web/src/app/key-management/lock/services/web-lock-component.service.ts @@ -1,12 +1,12 @@ import { inject } from "@angular/core"; import { map, Observable } from "rxjs"; -import { LockComponentService, UnlockOptions } from "@bitwarden/auth/angular"; import { UserDecryptionOptions, UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; import { UserId } from "@bitwarden/common/types/guid"; +import { LockComponentService, UnlockOptions } from "@bitwarden/key-management/angular"; export class WebLockComponentService implements LockComponentService { private readonly userDecryptionOptionsService = inject(UserDecryptionOptionsServiceAbstraction); diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index ad536110b74..fadcc28f832 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -25,7 +25,6 @@ import { RegistrationLinkExpiredComponent, LoginComponent, LoginSecondaryContentComponent, - LockComponent, LockIcon, TwoFactorTimeoutIcon, UserLockIcon, @@ -40,6 +39,7 @@ import { LoginDecryptionOptionsComponent, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { LockComponent } from "@bitwarden/key-management/angular"; import { NewDeviceVerificationNoticePageOneComponent, NewDeviceVerificationNoticePageTwoComponent, diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 3799945ea98..678db7c4af5 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -25,6 +25,7 @@ "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["../../libs/tools/card/src"], diff --git a/bitwarden_license/bit-cli/tsconfig.json b/bitwarden_license/bit-cli/tsconfig.json index e3d6cc5c7b7..92a206f44db 100644 --- a/bitwarden_license/bit-cli/tsconfig.json +++ b/bitwarden_license/bit-cli/tsconfig.json @@ -24,6 +24,7 @@ "@bitwarden/generator-history": ["../../libs/tools/generator/extensions/history/src"], "@bitwarden/generator-navigation": ["../../libs/tools/generator/extensions/navigation/src"], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/vault-export-core": [ "../../libs/tools/export/vault-export/vault-export-core/src" ], diff --git a/bitwarden_license/bit-common/tsconfig.json b/bitwarden_license/bit-common/tsconfig.json index 03f3bd2d2f1..a0a44f2ab30 100644 --- a/bitwarden_license/bit-common/tsconfig.json +++ b/bitwarden_license/bit-common/tsconfig.json @@ -23,6 +23,7 @@ "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/vault": ["../../libs/vault/src"], "@bitwarden/web-vault/*": ["../../apps/web/src/*"], diff --git a/bitwarden_license/bit-web/tsconfig.json b/bitwarden_license/bit-web/tsconfig.json index 09de92d355d..c4304ec2bd9 100644 --- a/bitwarden_license/bit-web/tsconfig.json +++ b/bitwarden_license/bit-web/tsconfig.json @@ -24,6 +24,7 @@ "@bitwarden/importer/core": ["../../libs/importer/src"], "@bitwarden/importer/ui": ["../../libs/importer/src/components"], "@bitwarden/key-management": ["../../libs/key-management/src"], + "@bitwarden/key-management/angular": ["../../libs/key-management/src/angular"], "@bitwarden/platform": ["../../libs/platform/src"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["../../libs/tools/card/src"], diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index 817687ef2bc..66111f3e5af 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -57,10 +57,6 @@ export * from "./user-verification/user-verification-dialog.component"; export * from "./user-verification/user-verification-dialog.types"; export * from "./user-verification/user-verification-form-input.component"; -// lock -export * from "./lock/lock.component"; -export * from "./lock/lock-component.service"; - // vault timeout export * from "./vault-timeout-input/vault-timeout-input.component"; diff --git a/libs/key-management/src/angular/index.ts b/libs/key-management/src/angular/index.ts new file mode 100644 index 00000000000..d7fadc52ce6 --- /dev/null +++ b/libs/key-management/src/angular/index.ts @@ -0,0 +1,10 @@ +/** + * This barrel file should only contain Angular exports + */ + +export { LockComponent } from "./lock/components/lock.component"; +export { + LockComponentService, + BiometricsDisableReason, + UnlockOptions, +} from "./lock/services/lock-component.service"; diff --git a/libs/auth/src/angular/lock/lock.component.html b/libs/key-management/src/angular/lock/components/lock.component.html similarity index 100% rename from libs/auth/src/angular/lock/lock.component.html rename to libs/key-management/src/angular/lock/components/lock.component.html diff --git a/libs/auth/src/angular/lock/lock.component.ts b/libs/key-management/src/angular/lock/components/lock.component.ts similarity index 99% rename from libs/auth/src/angular/lock/lock.component.ts rename to libs/key-management/src/angular/lock/components/lock.component.ts index aa7b43c2e53..fda870bb2ed 100644 --- a/libs/auth/src/angular/lock/lock.component.ts +++ b/libs/key-management/src/angular/lock/components/lock.component.ts @@ -7,6 +7,8 @@ import { Router } from "@angular/router"; import { BehaviorSubject, firstValueFrom, Subject, switchMap, take, takeUntil } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { AnonLayoutWrapperDataService } from "@bitwarden/auth/angular"; +import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -43,15 +45,12 @@ import { UserAsymmetricKeysRegenerationService, } from "@bitwarden/key-management"; -import { PinServiceAbstraction } from "../../common/abstractions"; -import { AnonLayoutWrapperDataService } from "../anon-layout/anon-layout-wrapper-data.service"; - import { UnlockOption, LockComponentService, UnlockOptions, UnlockOptionValue, -} from "./lock-component.service"; +} from "../services/lock-component.service"; const BroadcasterSubscriptionId = "LockComponent"; diff --git a/libs/auth/src/angular/lock/lock-component.service.ts b/libs/key-management/src/angular/lock/services/lock-component.service.ts similarity index 100% rename from libs/auth/src/angular/lock/lock-component.service.ts rename to libs/key-management/src/angular/lock/services/lock-component.service.ts diff --git a/libs/shared/tsconfig.libs.json b/libs/shared/tsconfig.libs.json index 6057152419c..2366507918e 100644 --- a/libs/shared/tsconfig.libs.json +++ b/libs/shared/tsconfig.libs.json @@ -20,6 +20,7 @@ "@bitwarden/importer/core": ["../importer/src"], "@bitwarden/importer/ui": ["../importer/src/components"], "@bitwarden/key-management": ["../key-management/src"], + "@bitwarden/key-management/angular": ["../key-management/src/angular"], "@bitwarden/platform": ["../platform/src"], "@bitwarden/send-ui": ["../tools/send/send-ui/src"], "@bitwarden/tools-card": ["../tools/card/src"], diff --git a/tsconfig.json b/tsconfig.json index 47b561e0829..91b4ee7dd6b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -33,6 +33,7 @@ "@bitwarden/importer/core": ["./libs/importer/src"], "@bitwarden/importer/ui": ["./libs/importer/src/components"], "@bitwarden/key-management": ["./libs/key-management/src"], + "@bitwarden/key-management/angular": ["./libs/key-management/src/angular"], "@bitwarden/platform": ["./libs/platform/src"], "@bitwarden/send-ui": ["./libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["./libs/tools/card/src"], From 9ca3d0653d74ef21b6694c750ba88bddebc61b52 Mon Sep 17 00:00:00 2001 From: Oscar Hinton Date: Tue, 7 Jan 2025 17:28:35 +0100 Subject: [PATCH 65/65] Fix strict typescript for Component Library stories (#12423) Fixing some low hanging fruits for moving CL to strict typescript. This primarily removes the types from args since TS infers them differently. We previously needed them since storybook would use any for args but now provides proper typings --- libs/components/src/button/button.stories.ts | 6 ++---- .../components/src/dialog/dialog/dialog.stories.ts | 8 +++----- .../simple-configurable-dialog.service.stories.ts | 6 ++---- .../src/form-field/bit-validators.stories.ts | 6 ++---- .../src/form-field/form-field.stories.ts | 14 ++++++-------- libs/components/src/search/search.stories.ts | 4 +--- libs/components/src/toast/toast.stories.ts | 6 ++---- 7 files changed, 18 insertions(+), 32 deletions(-) diff --git a/libs/components/src/button/button.stories.ts b/libs/components/src/button/button.stories.ts index ed3dfc4e134..3654442801c 100644 --- a/libs/components/src/button/button.stories.ts +++ b/libs/components/src/button/button.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Meta, StoryObj } from "@storybook/angular"; import { ButtonComponent } from "./button.component"; @@ -107,13 +105,13 @@ export const DisabledWithAttribute: Story = { }; export const Block: Story = { - render: (args: ButtonComponent) => ({ + render: (args) => ({ props: args, template: ` [block]="true" Link - + block Link diff --git a/libs/components/src/dialog/dialog/dialog.stories.ts b/libs/components/src/dialog/dialog/dialog.stories.ts index 1525d2e0171..7cb6f40aa5b 100644 --- a/libs/components/src/dialog/dialog/dialog.stories.ts +++ b/libs/components/src/dialog/dialog/dialog.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from "@angular/forms"; import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; @@ -78,7 +76,7 @@ export default { type Story = StoryObj; export const Default: Story = { - render: (args: DialogComponent) => ({ + render: (args) => ({ props: args, template: ` @@ -142,7 +140,7 @@ export const Loading: Story = { }; export const ScrollingContent: Story = { - render: (args: DialogComponent) => ({ + render: (args) => ({ props: args, template: ` @@ -197,7 +195,7 @@ export const TabContent: Story = { }; export const WithCards: Story = { - render: (args: DialogComponent) => ({ + render: (args) => ({ props: { formObj: new FormGroup({ name: new FormControl(""), diff --git a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts index 409d691beb0..4f21b8611b3 100644 --- a/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts +++ b/libs/components/src/dialog/simple-dialog/simple-configurable-dialog/simple-configurable-dialog.service.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { Component } from "@angular/core"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; @@ -72,7 +70,7 @@ class StoryDialogComponent { content: this.i18nService.t("dialogContent"), type: "primary", acceptButtonText: "Ok", - cancelButtonText: null, + cancelButtonText: undefined, }, { title: this.i18nService.t("primaryTypeSimpleDialog"), @@ -123,7 +121,7 @@ class StoryDialogComponent { showCallout = false; calloutType = "info"; - dialogCloseResult: boolean; + dialogCloseResult?: boolean; constructor( public dialogService: DialogService, diff --git a/libs/components/src/form-field/bit-validators.stories.ts b/libs/components/src/form-field/bit-validators.stories.ts index df021256400..642ff30bb5a 100644 --- a/libs/components/src/form-field/bit-validators.stories.ts +++ b/libs/components/src/form-field/bit-validators.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { FormsModule, ReactiveFormsModule, FormBuilder } from "@angular/forms"; import { StoryObj, Meta, moduleMetadata } from "@storybook/angular"; @@ -51,7 +49,7 @@ const template = ` `; export const ForbiddenCharacters: StoryObj = { - render: (args: BitFormFieldComponent) => ({ + render: (args) => ({ props: { formObj: new FormBuilder().group({ name: ["", forbiddenCharacters(["\\", "/", "@", "#", "$", "%", "^", "&", "*", "(", ")"])], @@ -62,7 +60,7 @@ export const ForbiddenCharacters: StoryObj = { }; export const TrimValidator: StoryObj = { - render: (args: BitFormFieldComponent) => ({ + render: (args) => ({ props: { formObj: new FormBuilder().group({ name: [ diff --git a/libs/components/src/form-field/form-field.stories.ts b/libs/components/src/form-field/form-field.stories.ts index a02158655ee..ccd80d6fa75 100644 --- a/libs/components/src/form-field/form-field.stories.ts +++ b/libs/components/src/form-field/form-field.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { TextFieldModule } from "@angular/cdk/text-field"; import { AbstractControl, @@ -190,7 +188,7 @@ export const Required: Story = { Label - + FormControl @@ -200,7 +198,7 @@ export const Required: Story = { }; export const Hint: Story = { - render: (args: BitFormFieldComponent) => ({ + render: (args) => ({ props: { formObj: formObj, ...args, @@ -268,7 +266,7 @@ export const Readonly: Story = { Textarea Premium @@ -361,7 +359,7 @@ export const PartiallyDisabledButtonInputGroup: Story = { }; export const Select: Story = { - render: (args: BitFormFieldComponent) => ({ + render: (args) => ({ props: args, template: /*html*/ ` @@ -377,7 +375,7 @@ export const Select: Story = { }; export const AdvancedSelect: Story = { - render: (args: BitFormFieldComponent) => ({ + render: (args) => ({ props: args, template: /*html*/ ` @@ -422,7 +420,7 @@ export const FileInput: Story = { }; export const Textarea: Story = { - render: (args: BitFormFieldComponent) => ({ + render: (args) => ({ props: args, template: /*html*/ ` diff --git a/libs/components/src/search/search.stories.ts b/libs/components/src/search/search.stories.ts index 71c180c6d51..a6cd714d43a 100644 --- a/libs/components/src/search/search.stories.ts +++ b/libs/components/src/search/search.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { Meta, StoryObj, moduleMetadata } from "@storybook/angular"; @@ -34,7 +32,7 @@ export default { type Story = StoryObj; export const Default: Story = { - render: (args: SearchComponent) => ({ + render: (args) => ({ props: args, template: ` diff --git a/libs/components/src/toast/toast.stories.ts b/libs/components/src/toast/toast.stories.ts index 2ca1c0fa952..382e19097b0 100644 --- a/libs/components/src/toast/toast.stories.ts +++ b/libs/components/src/toast/toast.stories.ts @@ -1,5 +1,3 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore import { CommonModule } from "@angular/common"; import { Component, Input } from "@angular/core"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; @@ -24,7 +22,7 @@ const toastServiceExampleTemplate = ` }) export class ToastServiceExampleComponent { @Input() - toastOptions: ToastOptions; + toastOptions?: ToastOptions; constructor(protected toastService: ToastService) {} } @@ -40,7 +38,7 @@ export default { }), applicationConfig({ providers: [ - ToastModule.forRoot().providers, + ToastModule.forRoot().providers!, { provide: I18nService, useFactory: () => {