From 96558074e2b3e01031ab32bba4fab20a08579568 Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Thu, 27 Mar 2025 12:14:16 -0400 Subject: [PATCH 01/16] Updated short name to no longer be localized (#14022) --- apps/browser/src/manifest.json | 2 +- apps/browser/src/manifest.v3.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index af2bf72b7b5..07aa3d2e4a9 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "__MSG_extName__", - "short_name": "__MSG_appName__", + "short_name": "Bitwarden", "version": "2025.3.2", "description": "__MSG_extDesc__", "default_locale": "en", diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index 131724e38f9..be1a3f17827 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -2,7 +2,7 @@ "manifest_version": 3, "minimum_chrome_version": "102.0", "name": "__MSG_extName__", - "short_name": "__MSG_appName__", + "short_name": "Bitwarden", "version": "2025.3.2", "description": "__MSG_extDesc__", "default_locale": "en", From 7d3e43abd8f98ec1169f2d2b1ac148a6b7820da9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 12:21:27 -0400 Subject: [PATCH 02/16] [deps] Autofill: Update prettier-plugin-tailwindcss to v0.6.11 (#13225) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19b1772e4bc..395cf52f05a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -158,7 +158,7 @@ "postcss": "8.5.1", "postcss-loader": "8.1.1", "prettier": "3.4.2", - "prettier-plugin-tailwindcss": "0.6.10", + "prettier-plugin-tailwindcss": "0.6.11", "process": "0.11.10", "remark-gfm": "4.0.0", "rimraf": "6.0.1", @@ -30145,9 +30145,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.10.tgz", - "integrity": "sha512-ndj2WLDaMzACnr1gAYZiZZLs5ZdOeBYgOsbBmHj3nvW/6q8h8PymsXiEnKvj/9qgCCAoHyvLOisoQdIcsDvIgw==", + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.11.tgz", + "integrity": "sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index 943fde5fcf3..83a0aa96fa3 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "postcss": "8.5.1", "postcss-loader": "8.1.1", "prettier": "3.4.2", - "prettier-plugin-tailwindcss": "0.6.10", + "prettier-plugin-tailwindcss": "0.6.11", "process": "0.11.10", "remark-gfm": "4.0.0", "rimraf": "6.0.1", From 93a289bfa81d1ef8cc955696f03e7272e31f39ce Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Thu, 27 Mar 2025 10:46:39 -0700 Subject: [PATCH 03/16] add tests (#13923) --- .../src/vault/services/cipher.service.spec.ts | 69 ++++++++++++++----- .../src/vault/services/cipher.service.ts | 6 +- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/libs/common/src/vault/services/cipher.service.spec.ts b/libs/common/src/vault/services/cipher.service.spec.ts index def0c04dd16..dd7faea8e8a 100644 --- a/libs/common/src/vault/services/cipher.service.spec.ts +++ b/libs/common/src/vault/services/cipher.service.spec.ts @@ -305,51 +305,86 @@ describe("Cipher Service", () => { }); describe("cipher.key", () => { - it("is null when feature flag is false", async () => { - configService.getFeatureFlag.mockResolvedValue(false); - + beforeEach(() => { keyService.getOrgKey.mockReturnValue( Promise.resolve(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey), ); + }); + + it("is null when feature flag is false", async () => { + configService.getFeatureFlag.mockResolvedValue(false); const cipher = await cipherService.encrypt(cipherView, userId); expect(cipher.key).toBeNull(); }); - it("is defined when feature flag flag is true", async () => { - configService.getFeatureFlag.mockResolvedValue(true); + describe("when feature flag is true", () => { + beforeEach(() => { + configService.getFeatureFlag.mockResolvedValue(true); + }); - const cipher = await cipherService.encrypt(cipherView, userId); + it("is null when the cipher is not viewPassword", async () => { + cipherView.viewPassword = false; - expect(cipher.key).toBeDefined(); + const cipher = await cipherService.encrypt(cipherView, userId); + + expect(cipher.key).toBeNull(); + }); + + it("is defined when the cipher is viewPassword", async () => { + cipherView.viewPassword = true; + + const cipher = await cipherService.encrypt(cipherView, userId); + + expect(cipher.key).toBeDefined(); + }); }); }); describe("encryptWithCipherKey", () => { beforeEach(() => { jest.spyOn(cipherService, "encryptCipherWithCipherKey"); + keyService.getOrgKey.mockReturnValue( + Promise.resolve(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey), + ); }); it("is not called when feature flag is false", async () => { configService.getFeatureFlag.mockResolvedValue(false); - keyService.getOrgKey.mockReturnValue( - Promise.resolve(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey), - ); await cipherService.encrypt(cipherView, userId); expect(cipherService["encryptCipherWithCipherKey"]).not.toHaveBeenCalled(); }); - it("is called when feature flag is true", async () => { - configService.getFeatureFlag.mockResolvedValue(true); - keyService.getOrgKey.mockReturnValue( - Promise.resolve(new SymmetricCryptoKey(new Uint8Array(32)) as OrgKey), - ); + describe("when feature flag is true", () => { + beforeEach(() => { + configService.getFeatureFlag.mockResolvedValue(true); + }); - await cipherService.encrypt(cipherView, userId); + it("is called when cipher viewPassword is true", async () => { + cipherView.viewPassword = true; - expect(cipherService["encryptCipherWithCipherKey"]).toHaveBeenCalled(); + await cipherService.encrypt(cipherView, userId); + + expect(cipherService["encryptCipherWithCipherKey"]).toHaveBeenCalled(); + }); + + it("is not called when cipher viewPassword is false and original cipher has no key", async () => { + cipherView.viewPassword = false; + + await cipherService.encrypt(cipherView, userId, undefined, undefined, new Cipher()); + + expect(cipherService["encryptCipherWithCipherKey"]).not.toHaveBeenCalled(); + }); + + it("is called when cipher viewPassword is false and original cipher has a key", async () => { + cipherView.viewPassword = false; + + await cipherService.encrypt(cipherView, userId, undefined, undefined, cipherObj); + + expect(cipherService["encryptCipherWithCipherKey"]).toHaveBeenCalled(); + }); }); }); }); diff --git a/libs/common/src/vault/services/cipher.service.ts b/libs/common/src/vault/services/cipher.service.ts index 4876a755ed8..bb5ae710cfb 100644 --- a/libs/common/src/vault/services/cipher.service.ts +++ b/libs/common/src/vault/services/cipher.service.ts @@ -222,7 +222,11 @@ export class CipherService implements CipherServiceAbstraction { cipher.reprompt = model.reprompt; cipher.edit = model.edit; - if (await this.getCipherKeyEncryptionEnabled()) { + if ( + // prevent unprivileged users from migrating to cipher key encryption + (model.viewPassword || originalCipher?.key) && + (await this.getCipherKeyEncryptionEnabled()) + ) { cipher.key = originalCipher?.key ?? null; const userOrOrgKey = await this.getKeyForCipherKeyDecryption(cipher, userId); // The keyForEncryption is only used for encrypting the cipher key, not the cipher itself, since cipher key encryption is enabled. From 10695fd9719b0bdeac5d73f3a11b1b3a7f5bd464 Mon Sep 17 00:00:00 2001 From: bnagawiecki <107435978+bnagawiecki@users.noreply.github.com> Date: Thu, 27 Mar 2025 14:20:34 -0400 Subject: [PATCH 04/16] add data-testids to 3 ssh key fields (#14024) --- .../sshkey-view.component.html | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/libs/vault/src/cipher-view/sshkey-sections/sshkey-view.component.html b/libs/vault/src/cipher-view/sshkey-sections/sshkey-view.component.html index ee5a94249c4..20390c0a285 100644 --- a/libs/vault/src/cipher-view/sshkey-sections/sshkey-view.component.html +++ b/libs/vault/src/cipher-view/sshkey-sections/sshkey-view.component.html @@ -5,7 +5,14 @@ {{ "sshPrivateKey" | i18n }} - + From 6d4179052a318655f26de0408c82fe0563ef5295 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:22:38 +0100 Subject: [PATCH 09/16] Autosync the updated translations (#14038) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/desktop/src/locales/af/messages.json | 9 +++++++++ apps/desktop/src/locales/ar/messages.json | 9 +++++++++ apps/desktop/src/locales/az/messages.json | 9 +++++++++ apps/desktop/src/locales/be/messages.json | 9 +++++++++ apps/desktop/src/locales/bg/messages.json | 9 +++++++++ apps/desktop/src/locales/bn/messages.json | 9 +++++++++ apps/desktop/src/locales/bs/messages.json | 9 +++++++++ apps/desktop/src/locales/ca/messages.json | 9 +++++++++ apps/desktop/src/locales/cs/messages.json | 9 +++++++++ apps/desktop/src/locales/cy/messages.json | 9 +++++++++ apps/desktop/src/locales/da/messages.json | 9 +++++++++ apps/desktop/src/locales/de/messages.json | 9 +++++++++ apps/desktop/src/locales/el/messages.json | 9 +++++++++ apps/desktop/src/locales/en_GB/messages.json | 9 +++++++++ apps/desktop/src/locales/en_IN/messages.json | 9 +++++++++ apps/desktop/src/locales/eo/messages.json | 9 +++++++++ apps/desktop/src/locales/es/messages.json | 9 +++++++++ apps/desktop/src/locales/et/messages.json | 9 +++++++++ apps/desktop/src/locales/eu/messages.json | 9 +++++++++ apps/desktop/src/locales/fa/messages.json | 9 +++++++++ apps/desktop/src/locales/fi/messages.json | 9 +++++++++ apps/desktop/src/locales/fil/messages.json | 9 +++++++++ apps/desktop/src/locales/fr/messages.json | 9 +++++++++ apps/desktop/src/locales/gl/messages.json | 9 +++++++++ apps/desktop/src/locales/he/messages.json | 9 +++++++++ apps/desktop/src/locales/hi/messages.json | 9 +++++++++ apps/desktop/src/locales/hr/messages.json | 9 +++++++++ apps/desktop/src/locales/hu/messages.json | 9 +++++++++ apps/desktop/src/locales/id/messages.json | 9 +++++++++ apps/desktop/src/locales/it/messages.json | 9 +++++++++ apps/desktop/src/locales/ja/messages.json | 11 ++++++++++- apps/desktop/src/locales/ka/messages.json | 9 +++++++++ apps/desktop/src/locales/km/messages.json | 9 +++++++++ apps/desktop/src/locales/kn/messages.json | 9 +++++++++ apps/desktop/src/locales/ko/messages.json | 9 +++++++++ apps/desktop/src/locales/lt/messages.json | 9 +++++++++ apps/desktop/src/locales/lv/messages.json | 11 ++++++++++- apps/desktop/src/locales/me/messages.json | 9 +++++++++ apps/desktop/src/locales/ml/messages.json | 9 +++++++++ apps/desktop/src/locales/mr/messages.json | 9 +++++++++ apps/desktop/src/locales/my/messages.json | 9 +++++++++ apps/desktop/src/locales/nb/messages.json | 9 +++++++++ apps/desktop/src/locales/ne/messages.json | 9 +++++++++ apps/desktop/src/locales/nl/messages.json | 9 +++++++++ apps/desktop/src/locales/nn/messages.json | 9 +++++++++ apps/desktop/src/locales/or/messages.json | 9 +++++++++ apps/desktop/src/locales/pl/messages.json | 9 +++++++++ apps/desktop/src/locales/pt_BR/messages.json | 9 +++++++++ apps/desktop/src/locales/pt_PT/messages.json | 9 +++++++++ apps/desktop/src/locales/ro/messages.json | 9 +++++++++ apps/desktop/src/locales/ru/messages.json | 9 +++++++++ apps/desktop/src/locales/si/messages.json | 9 +++++++++ apps/desktop/src/locales/sk/messages.json | 9 +++++++++ apps/desktop/src/locales/sl/messages.json | 9 +++++++++ apps/desktop/src/locales/sr/messages.json | 9 +++++++++ apps/desktop/src/locales/sv/messages.json | 9 +++++++++ apps/desktop/src/locales/te/messages.json | 9 +++++++++ apps/desktop/src/locales/th/messages.json | 9 +++++++++ apps/desktop/src/locales/tr/messages.json | 9 +++++++++ apps/desktop/src/locales/uk/messages.json | 9 +++++++++ apps/desktop/src/locales/vi/messages.json | 9 +++++++++ apps/desktop/src/locales/zh_CN/messages.json | 9 +++++++++ apps/desktop/src/locales/zh_TW/messages.json | 9 +++++++++ 63 files changed, 569 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index ae324eda6bc..e288e9e70cc 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index 9f5b1f3501c..7de8ecb50f5 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "تصدير خزانة المؤسسة" }, diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index b7c7cb3cd67..738944f1791 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Yalnız $EMAIL$ ilə əlaqələndirilmiş qoşmalar daxil olmaqla fərdi anbar elementləri xaricə köçürüləcək. Təşkilat anbar elementləri daxil edilməyəcək", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Təşkilat seyfini xaricə köçürmə" }, diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index 4c90222be42..ef73dcb3ed3 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index 6a1c0983278..c9bae830eff 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Ще бъдат изнесени само записите и прикачените файлове от личния трезор свързан с $EMAIL$. Записите в трезора на организацията няма да бъдат включени.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Изнасяне на трезора на организацията" }, diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index 68848c9ef2a..440462cf5d3 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 885af404f95..4fb9697a2c9 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index 5707fd0c0ff..dbba24a9050 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "S'està exportant la caixa forta de l’organització" }, diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 336ea2a795c..c4d61da936b 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Budou exportovány jen osobní položky trezoru včetně příloh spojené s účtem $EMAIL$. Nebudou zahrnuty položky trezoru v organizaci.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportování trezoru organizace" }, diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index 1c6d824c22e..5f06fd762f4 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index ef5b22e33f4..e11aef18e14 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Eksport af organisationsboks" }, diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index 79f61475ab0..b28c2fced1d 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Tresor der Organisation wird exportiert" }, diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index ecee8bd9894..9c59be2e0a7 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Εξαγωγή θησαυ/κίου οργανισμού" }, diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index f70a70e975a..74e43b24076 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organisation vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organisation vault" }, diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index f91a7b21876..3ec9e17769b 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organisation vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organisation vault" }, diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 200c3f4a1de..2dfdcdd9484 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index 665721beb3a..6936753ebb2 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportando caja fuerte de la organización" }, diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index c4ca9bef886..20650145478 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Ekspordin organisatsiooni hoidlat" }, diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index 1abc24612ca..57763cc62c1 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index 2d13b86c4a8..eecbd6dcb85 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index 2da2b7dcf7a..8964e7cf982 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Organisaation holvin vienti" }, diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index d54c5a21a87..ec1a2d0e281 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 431a70ef373..750b91adf57 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Export du coffre-fort de l'organisation" }, diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index f93db44aa69..07404b37fcd 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 7f98ab977ae..34db4dd53ba 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "מייצא כספת ארגון" }, diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 90fed49de76..7cfbb08a7d4 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index cb66437bedd..989faae1759 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Izvest će se samo stavke i privici osobnog trezora povezanog s $EMAIL$. Stavke organizacijskog trezora neće biti uključene", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Izvoz organizacijskog trezora" }, diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index b9573428136..775ce2dd80c 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Csak $EMAIL$ email címmel társított személyes széf elemek kerülnek exportálásra. Ebbe nem kerülnek be a szervezeti széf elemek.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Szervezeti széf exportálása" }, diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index df9b6484778..0c46ff5e5ea 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index ef5fa5ce381..f97b3135c9f 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Esportando cassaforte dell'organizzazione" }, diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index e8ba0e8509b..58c4d866e42 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "$EMAIL$ に関連付けられた個人用保管庫のアイテムのみが、添付ファイルを含めてエクスポートされます。組織用保管庫のアイテムは含まれません。", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "組織保管庫のエクスポート" }, @@ -3539,7 +3548,7 @@ "message": "後で再通知" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "新しいメールアドレス $EMAIL$ はあなたが管理しているものですか?", + "message": "メールアドレス $EMAIL$ は、確実にアクセスできるものですか?", "placeholders": { "email": { "content": "$1", diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 96962e14ff5..3eb666c7d44 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index f93db44aa69..07404b37fcd 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index f9bb154b66e..c530ab799f7 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 44bc681f205..e5df2555531 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index 40436c7ccda..7cf1bc463b3 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index c519987fc72..b3fa396d811 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -1706,7 +1706,7 @@ "message": "Apstiprināt glabātavas satura izgūšanu" }, "exportWarningDesc": { - "message": "Šī izguve satur glabātavas datus nešifrētā veidā. Izdoto datni nevajadzētu glabāt vai sūtīt nedrošos veidos (piemēram, e-pastā). Tā ir jāizdzēš uzreiz pēc izmantošanas." + "message": "Šī izguve satur glabātavas datus nešifrētā veidā. Izgūto datni nevajadzētu glabāt vai sūtīt nedrošos veidos (piemēram, e-pastā). Tā ir jāizdzēš uzreiz pēc izmantošanas." }, "encExportKeyWarningDesc": { "message": "Šī izguve šifrē datus ar konta šifrēšanas atslēgu. Ja tā jebkad tiks mainīta, izvadi vajadzētu veikt vēlreiz, jo vairs nebūs iespējams atšifrēt šo datni." @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Tiks izdoti tikai atsevišķi glabātavas vienumi, tajā skaitā pielikumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Izgūst apvienības glabātavu" }, diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index ea8defdc07c..99944c6e10c 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index a4af9251191..79d36b99526 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index f93db44aa69..07404b37fcd 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index 493d6fdb5b9..8aa0327203b 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index caf4d3da64b..d96eb92efb2 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index 297708953df..79aa89aed90 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 1cfd5ff5523..29dddbf0f08 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Exporteert alleen de persoonlijke kluis-items, inclusief attachments, gerelateerd aan $EMAIL$. Geen kluis-items van de organisatie", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Organisatiekluis exporteren" }, diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 9195311cc67..753b3ba5524 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index 6f15ed21991..b5c3d4eab46 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index ef8cdc6eb9b..a8b5205a9d9 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Eksportowanie sejfu organizacji" }, diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index e09ee6e16d2..539d254344d 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportando cofre da organização" }, diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index 2261357ba08..28ac0c82486 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Apenas os itens individuais do cofre, incluindo os anexos associados a $EMAIL$, serão exportados. Os itens do cofre da organização não serão incluídos", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "A exportar o cofre da organização" }, diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index d148d90a4fd..b160bfc14e3 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index ea5b8c6d526..73f52200e04 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Будут экспортированы только отдельные элементы хранилища, включая вложения, связанные с $EMAIL$. Элементы хранилища организации включены не будут", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Экспорт хранилища организации" }, diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index cb837ea4f76..e2f23c7bc56 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 7eaa1026c00..0f32c9945ce 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Exportované budú iba položky osobného trezora spojené s $EMAIL$. Položky trezora organizácie nebudú zahrnuté v exporte", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportovanie trezora organizácie" }, diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 3987587828a..4d50b4d9def 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index 69b45469dc8..561e3d35ec2 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Извоз сефа организације" }, diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index 1303243a8cc..f33339ea80d 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index f93db44aa69..07404b37fcd 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index cb9df027ad7..2bec157ec15 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 55b3b6059b7..974d27f4735 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Yalnızca $EMAIL$ ile ilişkili kişisel kasadaki kayıtlar ve dosyalar dışa aktarılacaktır. Kuruluş kasasındaki kayıtlar dahil edilmeyecektir", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Kuruluş kasasını dışa aktarma" }, diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index d5f908e011c..6fb5c564f3a 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Експортування сховища організації" }, diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index f6495e4f915..8b5f3250b85 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Đang xuất dữ liệu kho tổ chức" }, diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 6a12138b48f..e85b2606535 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "仅会导出与 $EMAIL$ 关联的个人密码库项目(包括附件)。不包括组织密码库项目。", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "正在导出组织密码库" }, diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 5da6c4a0b6e..ab09790dcd0 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -2490,6 +2490,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "正匯出組織密碼庫" }, From 251a08fd93c4c5526f1c2d6e398633d70fcca221 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:31:57 +0100 Subject: [PATCH 10/16] Autosync the updated translations (#14037) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/browser/src/_locales/ar/messages.json | 37 ++++ apps/browser/src/_locales/az/messages.json | 37 ++++ apps/browser/src/_locales/be/messages.json | 53 ++++- apps/browser/src/_locales/bg/messages.json | 37 ++++ apps/browser/src/_locales/bn/messages.json | 37 ++++ apps/browser/src/_locales/bs/messages.json | 37 ++++ apps/browser/src/_locales/ca/messages.json | 37 ++++ apps/browser/src/_locales/cs/messages.json | 37 ++++ apps/browser/src/_locales/cy/messages.json | 37 ++++ apps/browser/src/_locales/da/messages.json | 37 ++++ apps/browser/src/_locales/de/messages.json | 37 ++++ apps/browser/src/_locales/el/messages.json | 37 ++++ apps/browser/src/_locales/en_GB/messages.json | 37 ++++ apps/browser/src/_locales/en_IN/messages.json | 37 ++++ apps/browser/src/_locales/es/messages.json | 37 ++++ apps/browser/src/_locales/et/messages.json | 37 ++++ apps/browser/src/_locales/eu/messages.json | 37 ++++ apps/browser/src/_locales/fa/messages.json | 37 ++++ apps/browser/src/_locales/fi/messages.json | 37 ++++ apps/browser/src/_locales/fil/messages.json | 37 ++++ apps/browser/src/_locales/fr/messages.json | 37 ++++ apps/browser/src/_locales/gl/messages.json | 37 ++++ apps/browser/src/_locales/he/messages.json | 37 ++++ apps/browser/src/_locales/hi/messages.json | 37 ++++ apps/browser/src/_locales/hr/messages.json | 37 ++++ apps/browser/src/_locales/hu/messages.json | 37 ++++ apps/browser/src/_locales/id/messages.json | 193 +++++++++++------- apps/browser/src/_locales/it/messages.json | 37 ++++ apps/browser/src/_locales/ja/messages.json | 39 +++- apps/browser/src/_locales/ka/messages.json | 37 ++++ apps/browser/src/_locales/km/messages.json | 37 ++++ apps/browser/src/_locales/kn/messages.json | 37 ++++ apps/browser/src/_locales/ko/messages.json | 37 ++++ apps/browser/src/_locales/lt/messages.json | 37 ++++ apps/browser/src/_locales/lv/messages.json | 37 ++++ apps/browser/src/_locales/ml/messages.json | 37 ++++ apps/browser/src/_locales/mr/messages.json | 37 ++++ apps/browser/src/_locales/my/messages.json | 37 ++++ apps/browser/src/_locales/nb/messages.json | 37 ++++ apps/browser/src/_locales/ne/messages.json | 37 ++++ apps/browser/src/_locales/nl/messages.json | 37 ++++ apps/browser/src/_locales/nn/messages.json | 37 ++++ apps/browser/src/_locales/or/messages.json | 37 ++++ apps/browser/src/_locales/pl/messages.json | 37 ++++ apps/browser/src/_locales/pt_BR/messages.json | 37 ++++ apps/browser/src/_locales/pt_PT/messages.json | 37 ++++ apps/browser/src/_locales/ro/messages.json | 37 ++++ apps/browser/src/_locales/ru/messages.json | 37 ++++ apps/browser/src/_locales/si/messages.json | 37 ++++ apps/browser/src/_locales/sk/messages.json | 37 ++++ apps/browser/src/_locales/sl/messages.json | 37 ++++ apps/browser/src/_locales/sr/messages.json | 37 ++++ apps/browser/src/_locales/sv/messages.json | 37 ++++ apps/browser/src/_locales/te/messages.json | 37 ++++ apps/browser/src/_locales/th/messages.json | 37 ++++ apps/browser/src/_locales/tr/messages.json | 37 ++++ apps/browser/src/_locales/uk/messages.json | 37 ++++ apps/browser/src/_locales/vi/messages.json | 37 ++++ apps/browser/src/_locales/zh_CN/messages.json | 37 ++++ apps/browser/src/_locales/zh_TW/messages.json | 37 ++++ 60 files changed, 2307 insertions(+), 87 deletions(-) diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index 4c051d455ac..bf22a38be08 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 6f3ace453ae..1ca7642eb19 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Yalnız $EMAIL$ ilə əlaqələndirilmiş qoşmalar daxil olmaqla fərdi anbar elementləri xaricə köçürüləcək. Təşkilat anbar elementləri daxil edilməyəcək", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Təşkilat seyfini xaricə köçürmə" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Avto-doldur - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopyala: $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 905f6b6ac1d..a9a237aeb99 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -23,7 +23,7 @@ "message": "Упершыню ў Bitwarden?" }, "logInWithPasskey": { - "message": "Log in with passkey" + "message": "Увайсці з ключом доступу" }, "useSingleSignOn": { "message": "Выкарыстаць аднаразовы ўваход" @@ -35,7 +35,7 @@ "message": "Прызначыць надзейны пароль" }, "finishCreatingYourAccountBySettingAPassword": { - "message": "Finish creating your account by setting a password" + "message": "Завяршыць стварэнне вашага ўліковага запісу нарадзіўшы пароль" }, "enterpriseSingleSignOn": { "message": "Адзіны ўваход прадпрыемства (SSO)" @@ -62,7 +62,7 @@ "message": "Падказка да асноўнага пароля можа дапамагчы вам успомніць яго, калі вы яго забылі." }, "masterPassHintText": { - "message": "If you forget your password, the password hint can be sent to your email. $CURRENT$/$MAXIMUM$ character maximum.", + "message": "Падказка пароля можа быць адпраўлена на ваш адрас электроннай пошты, калі вы яго забудзеце. Максімум сімвалаў: $CURRENT$/$MAXIMUM$.", "placeholders": { "current": { "content": "$1", @@ -81,7 +81,7 @@ "message": "Падказка да асноўнага пароля (неабавязкова)" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Ацэнка надзейнасці пароля $SCORE$", "placeholders": { "score": { "content": "$1", @@ -206,10 +206,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": { @@ -261,7 +261,7 @@ "message": "Запытаць падказку да асноўнага пароля" }, "enterYourAccountEmailAddressAndYourPasswordHintWillBeSentToYou": { - "message": "Enter your account email address and your password hint will be sent to you" + "message": "Увядзіце адрас электроннай пошты ўліковага запісу і падказка пароля будзе адпраўлена вам" }, "getMasterPasswordHint": { "message": "Атрымаць падказку да асноўнага пароля" @@ -291,7 +291,7 @@ "message": "Працягнуць у вэб-праграме?" }, "continueToWebAppDesc": { - "message": "Explore more features of your Bitwarden account on the web app." + "message": "Даследуйце больш функцый вашага уліковага запісу Bitwarden у вэб-праграме." }, "continueToHelpCenter": { "message": "Працягнуць працу ў Даведачным цэнтры?" @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Экспартаванне сховішча арганізацыі" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 226e63e32cb..c5dd0237a2c 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Ще бъдат изнесени само записите и прикачените файлове от личния трезор свързан с $EMAIL$. Записите в трезора на организацията няма да бъдат включени.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Изнасяне на трезора на организацията" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Авт. попълване – $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Копиране на $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index 983b9fadde4..21a455265e4 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index 08fedb6f10a..a2457c94080 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 14e4a577440..d16a679824d 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Només s'exportaran els elements personals incloent adjunts de la caixa forta associats a $EMAIL$. Els elements de la caixa forta de l'organització no s'inclouran", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "S'està exportant la caixa forta de l’organització" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index e106d371d57..e6bf4a728e4 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Budou exportovány jen osobní položky trezoru včetně příloh spojené s účtem $EMAIL$. Nebudou zahrnuty položky trezoru v organizaci.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportování trezoru organizace" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Zobrazit položku - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Automatické vyplnění - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Automatické vyplnění - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopírovat $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index 83d09d13273..5ccff5a8332 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 69c8b28d29a..f66f8f34495 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Eksport af organisationsboks" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autoudfyld - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index a7439db6432..25e8b53cdb5 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Tresor der Organisation wird exportiert" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Auto-Ausfüllen - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "$FIELD$, $VALUE$ kopieren", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index fc07f12a48f..47dca3701ec 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Εξαγωγή θησαυ/κίου οργανισμού" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Αυτόματη συμπλήρωση - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index 1381afbdc6e..9c6d212f8c9 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organisation vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organisation vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Auto-fill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 6b14a358148..aa7a234246f 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organisation vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organisation vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Auto-fill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 4d430d23337..d282011e628 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportando caja fuerte de la organización" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autocompletar - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 2daf5f9d7f0..e2ad9a1e53a 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index b1e1ca3526b..95d843a3aa8 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index 2b3d66ad104..0f5616cd001 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index a37bd0235c1..ff71b93a62d 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Organisaation holvin vienti" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Automaattitäytä - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopioi $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 9f991843f4f..292c5fd0576 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 32b6dd0296b..5ec06f52a76 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Export du coffre de l'organisation" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Saisie automatique - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copier $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index 6c0b9cce87b..c76c60114c9 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportar Caixa forte da organización" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autoenchido - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 035bf9da48e..0d15c90c3d1 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "מייצא כספת ארגון" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "מילוי אוטומטי - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "העתק $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index 748d9eb966b..6dc3dced829 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "केवल $EMAIL$ से जुड़े अनुलग्नकों सहित व्यक्तिगत वॉल्ट आइटम ही निर्यात किए जाएंगे. संगठन वॉल्ट आइटम शामिल नहीं किए जाएंगे", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index b88fc45493f..eda6d7267a3 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Izvest će se samo stavke i privici osobnog trezora povezanog s $EMAIL$. Stavke organizacijskog trezora neće biti uključene", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Izvoz organizacijskog trezora" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Auto-ispuna - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopiraj $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index 80b1dbf095d..ec313c2cd10 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Csak $EMAIL$ email címmel társított személyes széf elemek kerülnek exportálásra. Ebbe nem kerülnek be a szervezeti széf elemek.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Szervezeti széf exportálása" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Automatikus kitöltés - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "$FIELD$, $VALUE$ másolása", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index 0146fb2a000..daccc3d8272 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -81,7 +81,7 @@ "message": "Petunjuk Kata Sandi Utama (opsional)" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "Skor kekuatan kata sandi $SCORE$", "placeholders": { "score": { "content": "$1", @@ -656,10 +656,10 @@ "message": "Verifikasikan identitas Anda" }, "weDontRecognizeThisDevice": { - "message": "We don't recognize this device. Enter the code sent to your email to verify your identity." + "message": "Kami tidak mengenali perangkat ini. Masukkan kode yang dikirim ke surel Anda untuk memverifikasi identitas Anda." }, "continueLoggingIn": { - "message": "Continue logging in" + "message": "Lanjutkan log masuk" }, "yourVaultIsLocked": { "message": "Brankas Anda terkunci. Verifikasi kata sandi utama Anda untuk melanjutkan." @@ -869,19 +869,19 @@ "message": "Masuk ke Bitwarden" }, "enterTheCodeSentToYourEmail": { - "message": "Enter the code sent to your email" + "message": "Masukkan kode yang dikirim ke surel Anda" }, "enterTheCodeFromYourAuthenticatorApp": { - "message": "Enter the code from your authenticator app" + "message": "Masukkan kode dari aplikasi autentikator Anda" }, "pressYourYubiKeyToAuthenticate": { - "message": "Press your YubiKey to authenticate" + "message": "Sentuh YubiKey Anda untuk mengautentikasi" }, "duoTwoFactorRequiredPageSubtitle": { - "message": "Duo two-step login is required for your account. Follow the steps below to finish logging in." + "message": "Log masuk dua langkah berganda diperlukan bagi akun Anda. Ikuti langkah di bawah untuk menyelesaikan log masuk." }, "followTheStepsBelowToFinishLoggingIn": { - "message": "Follow the steps below to finish logging in." + "message": "Ikuti langkah-langkah di bawah untuk menyelesaikan log masuk." }, "restartRegistration": { "message": "Mulai ulang pendaftaran" @@ -1019,7 +1019,7 @@ "message": "Tanyakan untuk menambah sebuah benda jika benda itu tidak ditemukan di brankas Anda. Diterapkan ke seluruh akun yang telah masuk." }, "showCardsInVaultViewV2": { - "message": "Always show cards as Autofill suggestions on Vault view" + "message": "Selalu tampilan kartu sebagai saran isi otomatis pada tampilan Brankas" }, "showCardsCurrentTab": { "message": "Tamplikan kartu pada halaman Tab" @@ -1028,7 +1028,7 @@ "message": "Buat tampilan daftar benda dari kartu pada halaman Tab untuk isi otomatis yang mudah." }, "showIdentitiesInVaultViewV2": { - "message": "Always show identities as Autofill suggestions on Vault view" + "message": "Selalu tampilan identitas sebagai saran isi otomatis pada tampilan Brankas" }, "showIdentitiesCurrentTab": { "message": "Tampilkan identitas pada halaman Tab" @@ -1037,10 +1037,10 @@ "message": "Buat tampilan daftar benda dari identitas pada halaman Tab untuk isi otomatis yang mudah." }, "clickToAutofillOnVault": { - "message": "Click items to autofill on Vault view" + "message": "Klik butir untuk mengisi otomatis pada tampilan Brankas" }, "clickToAutofill": { - "message": "Click items in autofill suggestion to fill" + "message": "Klik butir dalam saran isi otomatis untuk mengisi" }, "clearClipboard": { "message": "Hapus Papan Klip", @@ -1057,7 +1057,7 @@ "message": "Iya, Simpan Sekarang" }, "loginSaveSuccessDetails": { - "message": "$USERNAME$ saved to Bitwarden.", + "message": "$USERNAME$ disimpan ke Bitwarden.", "placeholders": { "username": { "content": "$1" @@ -1066,7 +1066,7 @@ "description": "Shown to user after login is saved." }, "loginUpdatedSuccessDetails": { - "message": "$USERNAME$ updated in Bitwarden.", + "message": "$USERNAME$ diperbarui di Bitwarden.", "placeholders": { "username": { "content": "$1" @@ -1075,35 +1075,35 @@ "description": "Shown to user after login is updated." }, "saveAsNewLoginAction": { - "message": "Save as new login", + "message": "Simpan sebagai log masuk baru", "description": "Button text for saving login details as a new entry." }, "updateLoginAction": { - "message": "Update login", + "message": "Perbarui log masuk", "description": "Button text for updating an existing login entry." }, "saveLoginPrompt": { - "message": "Save login?", + "message": "Simpan log masuk?", "description": "Prompt asking the user if they want to save their login details." }, "updateLoginPrompt": { - "message": "Update existing login?", + "message": "Perbarui log masuk yang ada?", "description": "Prompt asking the user if they want to update an existing login entry." }, "loginSaveSuccess": { - "message": "Login saved", + "message": "Log masuk disimpan", "description": "Message displayed when login details are successfully saved." }, "loginUpdateSuccess": { - "message": "Login updated", + "message": "Log masuk diperbarui", "description": "Message displayed when login details are successfully updated." }, "saveFailure": { - "message": "Error saving", + "message": "Kesalahan saat menyimpan", "description": "Error message shown when the system fails to save login details." }, "saveFailureDetails": { - "message": "Oh no! We couldn't save this. Try entering the details manually.", + "message": "Oh tidak! Kami tidak bisa menyimpan ini. Cobalah memasukkan rincian secara manual.", "description": "Detailed error message shown when saving login details fails." }, "enableChangedPasswordNotification": { @@ -1422,7 +1422,7 @@ "message": "Ingat saya" }, "dontAskAgainOnThisDeviceFor30Days": { - "message": "Don't ask again on this device for 30 days" + "message": "Jangan tanyakan lagi pada perangkat ini untuk 30 hari" }, "sendVerificationCodeEmailAgain": { "message": "Kirim ulang email kode verifikasi" @@ -1431,11 +1431,11 @@ "message": "Gunakan metode masuk dua langkah lainnya" }, "selectAnotherMethod": { - "message": "Select another method", + "message": "Pilih metode lain", "description": "Select another two-step login method" }, "useYourRecoveryCode": { - "message": "Use your recovery code" + "message": "Gunakan kode pemulihan Anda" }, "insertYubiKey": { "message": "Masukkan YubiKey Anda ke port USB komputer Anda, lalu sentuh tombolnya." @@ -1450,16 +1450,16 @@ "message": "Buka tab baru" }, "openInNewTab": { - "message": "Open in new tab" + "message": "Buka dalam tab baru" }, "webAuthnAuthenticate": { "message": "Autentikasi dengan WebAuthn." }, "readSecurityKey": { - "message": "Read security key" + "message": "Baca kunci keamanan" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "Menunggu interaksi kunci keamanan..." }, "loginUnavailable": { "message": "Info Masuk Tidak Tersedia" @@ -1474,7 +1474,7 @@ "message": "Opsi Info Masuk Dua Langkah" }, "selectTwoStepLoginMethod": { - "message": "Select two-step login method" + "message": "Pilih metode log masuk dua langkah" }, "recoveryCodeDesc": { "message": "Kehilangan akses ke semua penyedia dua faktor Anda? Gunakan kode pemulihan untuk menonaktifkan semua penyedia dua faktor dari akun Anda." @@ -1668,7 +1668,7 @@ "message": "Seret untuk mengurutkan" }, "dragToReorder": { - "message": "Drag to reorder" + "message": "Seret untuk mengubah urutan" }, "cfTypeText": { "message": "Teks" @@ -2144,7 +2144,7 @@ "message": "Pembuat nama pengguna" }, "useThisEmail": { - "message": "Use this email" + "message": "Pakai surel ini" }, "useThisPassword": { "message": "Gunakan kata sandi ini" @@ -2164,7 +2164,7 @@ "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, "vaultCustomization": { - "message": "Vault customization" + "message": "Penyesuaian brankas" }, "vaultTimeoutAction": { "message": "Tindakan Batas Waktu Brankas" @@ -2173,13 +2173,13 @@ "message": "Batas waktu tindakan" }, "newCustomizationOptionsCalloutTitle": { - "message": "New customization options" + "message": "Opsi penyesuaian baru" }, "newCustomizationOptionsCalloutContent": { - "message": "Customize your vault experience with quick copy actions, compact mode, and more!" + "message": "Sesuaikan pengalaman brankas Anda dengan aksi salin cepat, mode kompak, dan lainnya!" }, "newCustomizationOptionsCalloutLink": { - "message": "View all Appearance settings" + "message": "Lihat semua pengaturan Penampilan" }, "lock": { "message": "Kunci", @@ -2437,10 +2437,10 @@ "description": "A category title describing the concept of web domains" }, "blockedDomains": { - "message": "Blocked domains" + "message": "Domain terblokir" }, "learnMoreAboutBlockedDomains": { - "message": "Learn more about blocked domains" + "message": "Pelajari lebih lanjut tentang domain yang diblokir" }, "excludedDomains": { "message": "Domain yang Dikecualikan" @@ -2452,19 +2452,19 @@ "message": "Bitwarden tidak akan meminta untuk menyimpan rincian login untuk domain tersebut. Anda harus menyegarkan halaman agar perubahan diterapkan." }, "blockedDomainsDesc": { - "message": "Autofill and other related features will not be offered for these websites. You must refresh the page for changes to take effect." + "message": "Isi otomatis dan fitur terkait lain tidak akan ditawarkan bagi situs-situs web ini. Anda mesti menyegarkan halaman agar perubahan berdampak." }, "autofillBlockedNoticeV2": { - "message": "Autofill is blocked for this website." + "message": "Isi otomatis diblokir bagi situs web ini." }, "autofillBlockedNoticeGuidance": { - "message": "Change this in settings" + "message": "Ubah ini di pengaturan" }, "change": { "message": "Ubah" }, "changeButtonTitle": { - "message": "Change password - $ITEMNAME$", + "message": "Ubah kata sandi - $ITEMNAME$", "placeholders": { "itemname": { "content": "$1", @@ -2473,10 +2473,10 @@ } }, "atRiskPasswords": { - "message": "At-risk passwords" + "message": "Kata sandi yang berrisiko" }, "atRiskPasswordDescSingleOrg": { - "message": "$ORGANIZATION$ is requesting you change one password because it is at-risk.", + "message": "$ORGANIZATION$ meminta Ada mengubah satu kata sandi karena itu berrisiko.", "placeholders": { "organization": { "content": "$1", @@ -2485,7 +2485,7 @@ } }, "atRiskPasswordsDescSingleOrgPlural": { - "message": "$ORGANIZATION$ is requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "$ORGANIZATION$ meminta Anda mengubah $COUNT$ kata sandi karena mereka berrisiko.", "placeholders": { "organization": { "content": "$1", @@ -2498,7 +2498,7 @@ } }, "atRiskPasswordsDescMultiOrgPlural": { - "message": "Your organizations are requesting you change the $COUNT$ passwords because they are at-risk.", + "message": "Organisasi Anda meminta Anda mengubah $COUNT$ kata sandi karena mereka berrisiko.", "placeholders": { "count": { "content": "$1", @@ -2507,10 +2507,10 @@ } }, "reviewAndChangeAtRiskPassword": { - "message": "Review and change one at-risk password" + "message": "Tinjau dan ubah satu kata sandi berrisiko" }, "reviewAndChangeAtRiskPasswordsPlural": { - "message": "Review and change $COUNT$ at-risk passwords", + "message": "Tinjau dan ubah $COUNT$ kata sandi berrisiko", "placeholders": { "count": { "content": "$1", @@ -2519,7 +2519,7 @@ } }, "changeAtRiskPasswordsFaster": { - "message": "Change at-risk passwords faster" + "message": "Ubah lebih cepat kata sandi yang berrisiko" }, "changeAtRiskPasswordsFasterDesc": { "message": "Update your settings so you can quickly autofill your passwords and generate new ones" @@ -2528,14 +2528,14 @@ "message": "Review at-risk logins" }, "reviewAtRiskPasswords": { - "message": "Review at-risk passwords" + "message": "Tinjau kata sandi yang berrisiko" }, "reviewAtRiskLoginsSlideDesc": { - "message": "Your organization passwords are at-risk because they are weak, reused, and/or exposed.", + "message": "Kata sandi organisasi Anda berrisiko karena mereka lemah, dipakai ulang, dan/atau terpapar.", "description": "Description of the review at-risk login slide on the at-risk password page carousel" }, "reviewAtRiskLoginSlideImgAlt": { - "message": "Illustration of a list of logins that are at-risk" + "message": "Ilustrasi dari daftar log masuk yang berrisiko" }, "generatePasswordSlideDesc": { "message": "Quickly generate a strong, unique password with the Bitwarden autofill menu on the at-risk site.", @@ -2561,7 +2561,7 @@ "message": "Turned on autofill" }, "dismiss": { - "message": "Dismiss" + "message": "Tutup" }, "websiteItemLabel": { "message": "Situs web $number$ (URI)", @@ -2582,7 +2582,7 @@ } }, "blockedDomainsSavedSuccess": { - "message": "Blocked domain changes saved" + "message": "Perubahan domain yang diblokir disimpan" }, "excludedDomainsSavedSuccess": { "message": "Perubahan domain yang diabaikan telah disimpan" @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Mengekspor brankas organisasi" }, @@ -3023,17 +3032,17 @@ "message": "Galat" }, "decryptionError": { - "message": "Decryption error" + "message": "Kesalahan dekripsi" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden tidak bisa mendekripsi butir brankas yang tercantum di bawah." }, "contactCSToAvoidDataLossPart1": { "message": "Contact customer success", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "untuk menghindari lanjutan hilang data.", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "generateUsername": { @@ -3168,7 +3177,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ menolak permintaan Anda. Harap hubungi penyedia layanan Anda untuk bantuan.", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -3178,7 +3187,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ menolak permintaan Anda: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -3327,13 +3336,13 @@ "message": "Sebuah pemberitahuan dikirim ke perangkat Anda." }, "notificationSentDevicePart1": { - "message": "Unlock Bitwarden on your device or on the" + "message": "Buka kunci Bitwarden pada perangkat Anda atau pada" }, "notificationSentDeviceAnchor": { - "message": "web app" + "message": "aplikasi web" }, "notificationSentDevicePart2": { - "message": "Make sure the Fingerprint phrase matches the one below before approving." + "message": "Pastikan frasa Sidik Jari cocok dengan yang di bawah sebelum menyetujui." }, "aNotificationWasSentToYourDevice": { "message": "Sebuah pemberitahuan telah dikirim ke perangkat Anda" @@ -3348,7 +3357,7 @@ "message": "Memulai login" }, "logInRequestSent": { - "message": "Request sent" + "message": "Permintaan terkirim" }, "exposedMasterPassword": { "message": "Kata Sandi Utama yang Terpapar" @@ -4080,7 +4089,7 @@ "message": "Akun aktif" }, "bitwardenAccount": { - "message": "Bitwarden account" + "message": "Akun Bitwarden" }, "availableAccounts": { "message": "Akun yang tersedia" @@ -4203,10 +4212,10 @@ "message": "Kunci sandi dihapus" }, "autofillSuggestions": { - "message": "Autofill suggestions" + "message": "Saran isi otomatis" }, "itemSuggestions": { - "message": "Suggested items" + "message": "Butir yang disarankan" }, "autofillSuggestionsTip": { "message": "Simpan benda login untuk situs ini ke isi otomatis" @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Isi otomatis - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,8 +4303,22 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { - "message": "Copy $FIELD$, $VALUE$", + "message": "Salin $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", "placeholders": { "field": { @@ -4769,7 +4806,7 @@ } }, "itemLocation": { - "message": "Item Location" + "message": "Lokasi Item" }, "fileSend": { "message": "File Send" @@ -4835,7 +4872,7 @@ "message": "File saved to device. Manage from your device downloads." }, "showCharacterCount": { - "message": "Show character count" + "message": "Tunjukkan cacah karakter" }, "hideCharacterCount": { "message": "Hide character count" @@ -4896,15 +4933,15 @@ "description": "Heading for the password generator within the inline menu" }, "passwordRegenerated": { - "message": "Password regenerated", + "message": "Kata sandi dibuat ulang", "description": "Notification message for when a password has been regenerated" }, "saveLoginToBitwarden": { - "message": "Save login to Bitwarden?", + "message": "Simpan log masuk ke Bitwarden?", "description": "Confirmation message for saving a login to Bitwarden" }, "spaceCharacterDescriptor": { - "message": "Space", + "message": "Spasi", "description": "Represents the space key in screen reader content as a readable word" }, "tildeCharacterDescriptor": { @@ -5051,22 +5088,22 @@ "message": "Beta" }, "importantNotice": { - "message": "Important notice" + "message": "Pemberitahuan penting" }, "setupTwoStepLogin": { - "message": "Set up two-step login" + "message": "Siapkan log masuk dua langkah" }, "newDeviceVerificationNoticeContentPage1": { - "message": "Bitwarden will send a code to your account email to verify logins from new devices starting in February 2025." + "message": "Bitwarden akan mengirim suatu kode ke akun surel Anda untuk memverifikasi log masuk dari perangkat baru sejak Februari 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": "Anda dapat menyiapkan log masuk dua langkah sebagai cara alternatif untuk melindungi akun Anda atau mengubah surel Anda ke yang bisa Anda akses." }, "remindMeLater": { - "message": "Remind me later" + "message": "Ingatkan saya nanti" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "Do you have reliable access to your email, $EMAIL$?", + "message": "Apakah Anda punya akses yang handal ke surel Anda, $EMAIL$?", "placeholders": { "email": { "content": "$1", @@ -5081,7 +5118,7 @@ "message": "Ya, saya dapat mengakses surel saya secara handla" }, "turnOnTwoStepLogin": { - "message": "Turn on two-step login" + "message": "Nyalakan log masuk dua langkah" }, "changeAcctEmail": { "message": "Ubah surel akun" diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index cb8e414ca37..b18acbc79b8 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Esportando cassaforte dell'organizzazione" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Riempi automaticamente - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copia $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index b67d0b62a6e..a6dd0f709a2 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "$EMAIL$ に関連付けられた個人用保管庫のアイテムのみが、添付ファイルを含めてエクスポートされます。組織用保管庫のアイテムは含まれません。", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "組織保管庫のエクスポート" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "自動入力 - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "$FIELD$ 「$VALUE$」 をコピー", "description": "Title for a button that copies a field value to the clipboard.", @@ -5066,7 +5103,7 @@ "message": "後で再通知" }, "newDeviceVerificationNoticePageOneFormContent": { - "message": "新しいメールアドレス $EMAIL$ はあなたが管理しているものですか?", + "message": "メールアドレス $EMAIL$ は、確実にアクセスできるものですか?", "placeholders": { "email": { "content": "$1", diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 818d7cdcd19..0e11594faac 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index c9c29611deb..0c087ef7de9 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index c8aff3a6488..31ea7daa668 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index cd54ac47506..92654f84e31 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "조직 보관함을 내보내는 중" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "자동 완성 - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index 8bf8a8f7518..e1536abdf83 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 7b5f077f69d..789666ef2c1 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Tiks izdoti tikai atsevišķi glabātavas vienumi, tajā skaitā pielikumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Izgūst apvienības glabātavu" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Apskatīt vienumu - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Automātiski aizpildīt - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Automātiskā aizpilde - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Ievietot starpliktuvē $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index 24a096db0ef..11af6b54202 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index 9a49998d3d9..472a8378bb7 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index c9c29611deb..0c087ef7de9 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 0ff4ed9486a..9a52eeea4cb 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autoutfyll - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index c9c29611deb..0c087ef7de9 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 1c2b09ca3e3..80877839adb 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Exporteert alleen de persoonlijke kluis-items, inclusief attachments, gerelateerd aan $EMAIL$. Geen kluis-items van de organisatie", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Organisatiekluis exporteren" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Item weergeven - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Automatisch invullen - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Automatisch aanvullen - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "$FIELD$, $VALUE$ kopiëren", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index c9c29611deb..0c087ef7de9 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index c9c29611deb..0c087ef7de9 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index f4c1303bd18..c345972bd4a 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Tylko poszczególne elementy sejfu łącznie z załącznikami powiązanymi z $EMAIL$ zostaną wyeksportowane. Elementy sejfu organizacji nie będą dołączone", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Eksportowanie sejfu organizacji" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Zobacz element - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autouzupełnij - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autouzupełnij - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopiuj $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index 0b5d569f443..5aacad23a93 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportando cofre da organização" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Auto-preenchimento - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copiar $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index c1f1f51609c..0e467b65183 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Apenas os itens individuais do cofre, incluindo os anexos associados a $EMAIL$, serão exportados. Os itens do cofre da organização não serão incluídos", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "A exportar o cofre da organização" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Ver item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Preencher automaticamente - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Preencher automaticamente - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copiar $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index 5ce73eb2e49..fa4d754e99d 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index 11d8de4acbe..c775bee3289 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Будут экспортированы только отдельные элементы хранилища, включая вложения, связанные с $EMAIL$. Элементы хранилища организации включены не будут", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Экспорт хранилища организации" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Автозаполнение - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Скопировать $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 721d16a2eee..12bac21e11f 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index 897db9f3176..cd4095f8ff5 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Exportované budú iba položky osobného trezora spojené s $EMAIL$. Položky trezora organizácie nebudú zahrnuté v exporte", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exportovanie trezora organizácie" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Zobraziť položku - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Automatické vyplnenie - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Automatické vyplnenie - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopírovať $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index f6a543ea5ea..c77d4cb55f4 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 3c7bef94c13..5e325c6a97c 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Извоз сефа организације" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Ауто-пуњење - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Копирај $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index 6db7a22490e..e3ff6986cae 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index c9c29611deb..0c087ef7de9 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index c545f802d64..e2225327664 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Exporting organization vault" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Autofill - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index e69b33d63af..e8788a00d70 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Yalnızca $EMAIL$ ile ilişkili kişisel kasadaki kayıtlar ve dosyalar dışa aktarılacaktır. Kuruluş kasasındaki kayıtlar dahil edilmeyecektir", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Kuruluş kasasını dışa aktarma" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "Kaydı görüntüle - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Otomatik doldur - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Otomatik doldur - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Kopyala: $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index d18d90babff..6bd9ca7fc36 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Експортування сховища організації" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Автозаповнення – $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Копіювати $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index db0da3b5874..35c553f72f1 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "Đang xuất dữ liệu kho tổ chức" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "Tự động điền - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index bdfaeb92531..fc6f70cb6a4 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "仅会导出与 $EMAIL$ 关联的个人密码库项目(包括附件)。不包括组织密码库项目。", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "正在导出组织密码库" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "查看项目 - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "自动填充 - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "自动填充 - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "复制 $FIELD$,$VALUE$", "description": "Title for a button that copies a field value to the clipboard.", diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 37e450c8fd2..365aae61ebf 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -3007,6 +3007,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultTitle": { "message": "正在匯出組織密碼庫" }, @@ -4270,6 +4279,20 @@ } } }, + "viewItemTitleWithField": { + "message": "View item - $ITEMNAME$ - $FIELD$", + "description": "Title for a link that opens a view for an item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "autofillTitle": { "message": "自動填入 - $ITEMNAME$", "description": "Title for a button that autofills a login item.", @@ -4280,6 +4303,20 @@ } } }, + "autofillTitleWithField": { + "message": "Autofill - $ITEMNAME$ - $FIELD$", + "description": "Title for a button that autofills a login item.", + "placeholders": { + "itemname": { + "content": "$1", + "example": "Secret Item" + }, + "field": { + "content": "$2", + "example": "Username" + } + } + }, "copyFieldValue": { "message": "Copy $FIELD$, $VALUE$", "description": "Title for a button that copies a field value to the clipboard.", From 8b14b0c09f0df761ba2ea28dd2c35a4f8d2e0f96 Mon Sep 17 00:00:00 2001 From: "bw-ghapp[bot]" <178206702+bw-ghapp[bot]@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:34:52 +0100 Subject: [PATCH 11/16] Autosync the updated translations (#14039) Co-authored-by: bitwarden-devops-bot <106330231+bitwarden-devops-bot@users.noreply.github.com> --- apps/web/src/locales/af/messages.json | 9 ++ apps/web/src/locales/ar/messages.json | 9 ++ apps/web/src/locales/az/messages.json | 9 ++ apps/web/src/locales/be/messages.json | 9 ++ apps/web/src/locales/bg/messages.json | 9 ++ apps/web/src/locales/bn/messages.json | 9 ++ apps/web/src/locales/bs/messages.json | 9 ++ apps/web/src/locales/ca/messages.json | 9 ++ apps/web/src/locales/cs/messages.json | 9 ++ apps/web/src/locales/cy/messages.json | 9 ++ apps/web/src/locales/da/messages.json | 9 ++ apps/web/src/locales/de/messages.json | 9 ++ apps/web/src/locales/el/messages.json | 9 ++ apps/web/src/locales/en_GB/messages.json | 9 ++ apps/web/src/locales/en_IN/messages.json | 9 ++ apps/web/src/locales/eo/messages.json | 9 ++ apps/web/src/locales/es/messages.json | 9 ++ apps/web/src/locales/et/messages.json | 9 ++ apps/web/src/locales/eu/messages.json | 9 ++ apps/web/src/locales/fa/messages.json | 9 ++ apps/web/src/locales/fi/messages.json | 9 ++ apps/web/src/locales/fil/messages.json | 9 ++ apps/web/src/locales/fr/messages.json | 9 ++ apps/web/src/locales/gl/messages.json | 9 ++ apps/web/src/locales/he/messages.json | 9 ++ apps/web/src/locales/hi/messages.json | 9 ++ apps/web/src/locales/hr/messages.json | 9 ++ apps/web/src/locales/hu/messages.json | 9 ++ apps/web/src/locales/id/messages.json | 9 ++ apps/web/src/locales/it/messages.json | 9 ++ apps/web/src/locales/ja/messages.json | 123 ++++++++++++----------- apps/web/src/locales/ka/messages.json | 9 ++ apps/web/src/locales/km/messages.json | 9 ++ apps/web/src/locales/kn/messages.json | 9 ++ apps/web/src/locales/ko/messages.json | 9 ++ apps/web/src/locales/lv/messages.json | 9 ++ apps/web/src/locales/ml/messages.json | 9 ++ apps/web/src/locales/mr/messages.json | 9 ++ apps/web/src/locales/my/messages.json | 9 ++ apps/web/src/locales/nb/messages.json | 9 ++ apps/web/src/locales/ne/messages.json | 9 ++ apps/web/src/locales/nl/messages.json | 9 ++ apps/web/src/locales/nn/messages.json | 9 ++ apps/web/src/locales/or/messages.json | 9 ++ apps/web/src/locales/pl/messages.json | 9 ++ apps/web/src/locales/pt_BR/messages.json | 9 ++ apps/web/src/locales/pt_PT/messages.json | 9 ++ apps/web/src/locales/ro/messages.json | 9 ++ apps/web/src/locales/ru/messages.json | 9 ++ apps/web/src/locales/si/messages.json | 9 ++ apps/web/src/locales/sk/messages.json | 9 ++ apps/web/src/locales/sl/messages.json | 9 ++ apps/web/src/locales/sr/messages.json | 9 ++ apps/web/src/locales/sr_CS/messages.json | 9 ++ apps/web/src/locales/sv/messages.json | 9 ++ apps/web/src/locales/te/messages.json | 9 ++ apps/web/src/locales/th/messages.json | 9 ++ apps/web/src/locales/tr/messages.json | 9 ++ apps/web/src/locales/uk/messages.json | 9 ++ apps/web/src/locales/vi/messages.json | 9 ++ apps/web/src/locales/zh_CN/messages.json | 13 ++- apps/web/src/locales/zh_TW/messages.json | 9 ++ 62 files changed, 617 insertions(+), 59 deletions(-) diff --git a/apps/web/src/locales/af/messages.json b/apps/web/src/locales/af/messages.json index 3b9168b29b2..fa25494f4bf 100644 --- a/apps/web/src/locales/af/messages.json +++ b/apps/web/src/locales/af/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/ar/messages.json b/apps/web/src/locales/ar/messages.json index 13777f942de..4a289082039 100644 --- a/apps/web/src/locales/ar/messages.json +++ b/apps/web/src/locales/ar/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index f092620b00a..dfafeab1877 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Yalnız $EMAIL$ ilə əlaqələndirilmiş qoşmalar daxil olmaqla fərdi anbar elementləri xaricə köçürüləcək. Təşkilat anbar elementləri daxil edilməyəcək", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Yalnız $ORGANIZATION$ ilə əlaqələndirilmiş təşkilat seyfi xaricə köçürüləcək. Fərdi seyfdə və digər təşkilatlardakı elementlər daxil edilməyəcək.", "placeholders": { diff --git a/apps/web/src/locales/be/messages.json b/apps/web/src/locales/be/messages.json index 2e5aeabff32..a22b463f4f2 100644 --- a/apps/web/src/locales/be/messages.json +++ b/apps/web/src/locales/be/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Толькі сховішча арганізацыі, якія звязаны з $ORGANIZATION$ будуць экспартаваны. Элементы асабістага сховішча і элементы з іншых арганізацый не будуць уключаны.", "placeholders": { diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index 04d4e25bb7c..0599d3a73f2 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Ще бъдат изнесени само записите и прикачените файлове от личния трезор свързан с $EMAIL$. Записите в трезора на организацията няма да бъдат включени.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Ще бъдат изнесени само записите от трезора свързан с $ORGANIZATION$. Записите в отделните лични трезори и тези в други организации няма да бъдат включени.", "placeholders": { diff --git a/apps/web/src/locales/bn/messages.json b/apps/web/src/locales/bn/messages.json index 8c082c57e30..15ca72e1642 100644 --- a/apps/web/src/locales/bn/messages.json +++ b/apps/web/src/locales/bn/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/bs/messages.json b/apps/web/src/locales/bs/messages.json index 7efb47bd86c..2c0f177ad67 100644 --- a/apps/web/src/locales/bs/messages.json +++ b/apps/web/src/locales/bs/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/ca/messages.json b/apps/web/src/locales/ca/messages.json index a4f2aeb7f55..d394a75b70f 100644 --- a/apps/web/src/locales/ca/messages.json +++ b/apps/web/src/locales/ca/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Només s'exportarà la caixa forta de l'organització associada a $ORGANIZATION$. No s'inclouran els elements de les caixes fortes individuals ni d'altres organitzacions.", "placeholders": { diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index 46b510a6459..552a717ab82 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Budou exportovány jen osobní položky trezoru včetně příloh spojené s účtem $EMAIL$. Nebudou zahrnuty položky trezoru v organizaci.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Exportován bude jen trezor organizace přidružený k položce $ORGANIZATION$. Osobní položky trezoru a položky z jiných organizací nebudou zahrnuty.", "placeholders": { diff --git a/apps/web/src/locales/cy/messages.json b/apps/web/src/locales/cy/messages.json index 2fd61e01526..ba8bd6bd8a4 100644 --- a/apps/web/src/locales/cy/messages.json +++ b/apps/web/src/locales/cy/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index f8a335011e5..dddef79ddd0 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Kun organisationsboksen tilknyttet $ORGANIZATION$ eksporteres. Emner i individuelle bokse eller andre organisationer medtages ikke.", "placeholders": { diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index 135ab8af923..b5eeb9db7ce 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Nur der mit $ORGANIZATION$ verbundene Organisationstresor wird exportiert. Einträge in persönlichen Tresoren oder anderen Organisationen werden nicht berücksichtigt.", "placeholders": { diff --git a/apps/web/src/locales/el/messages.json b/apps/web/src/locales/el/messages.json index e20b5cc52a0..27e39f9798e 100644 --- a/apps/web/src/locales/el/messages.json +++ b/apps/web/src/locales/el/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/en_GB/messages.json b/apps/web/src/locales/en_GB/messages.json index b211ec070ab..b4f0ace607a 100644 --- a/apps/web/src/locales/en_GB/messages.json +++ b/apps/web/src/locales/en_GB/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organisation vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organisation vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organisations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/en_IN/messages.json b/apps/web/src/locales/en_IN/messages.json index 6b4b6e11ab3..a8c4bfca62e 100644 --- a/apps/web/src/locales/en_IN/messages.json +++ b/apps/web/src/locales/en_IN/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organisation vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organisation vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organisations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/eo/messages.json b/apps/web/src/locales/eo/messages.json index ce40767f4c1..c31274e6198 100644 --- a/apps/web/src/locales/eo/messages.json +++ b/apps/web/src/locales/eo/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/es/messages.json b/apps/web/src/locales/es/messages.json index 1c71a29f48b..80b982bd928 100644 --- a/apps/web/src/locales/es/messages.json +++ b/apps/web/src/locales/es/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/et/messages.json b/apps/web/src/locales/et/messages.json index f9a5b810ded..a55fce63349 100644 --- a/apps/web/src/locales/et/messages.json +++ b/apps/web/src/locales/et/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/eu/messages.json b/apps/web/src/locales/eu/messages.json index d0e99c73e66..a8b64594065 100644 --- a/apps/web/src/locales/eu/messages.json +++ b/apps/web/src/locales/eu/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/fa/messages.json b/apps/web/src/locales/fa/messages.json index 04cddc65f2f..4657d4a9732 100644 --- a/apps/web/src/locales/fa/messages.json +++ b/apps/web/src/locales/fa/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "فقط گاوصدوق سازمان مرتبط با $ORGANIZATION$ برون ریزی خواهد شد. موارد موجود در گاوصندوق‌های فردی یا سایر سازمان‌ها شامل نمی‌شوند.", "placeholders": { diff --git a/apps/web/src/locales/fi/messages.json b/apps/web/src/locales/fi/messages.json index 9427a4e8e22..38671c12f79 100644 --- a/apps/web/src/locales/fi/messages.json +++ b/apps/web/src/locales/fi/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Vain organisaatioon $ORGANIZATION$ liitetyn holvin kohteet viedään. Yksityisen holvin ja muiden organisaatioiden kohteita ei sisällytetä.", "placeholders": { diff --git a/apps/web/src/locales/fil/messages.json b/apps/web/src/locales/fil/messages.json index 414bbda91d8..0a07cf17526 100644 --- a/apps/web/src/locales/fil/messages.json +++ b/apps/web/src/locales/fil/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index 95aa573f14b..e26b5ef1250 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Seuls les éléments individuels du coffre et les pièces jointes associées à $EMAIL$ seront exportés. Les éléments du coffre de l'organisation ne seront pas inclus", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Seul le coffre d'organisation associé à $ORGANIZATION$ sera exporté. Les éléments dans les coffres individuels ou d'autres organisations ne seront pas inclus.", "placeholders": { diff --git a/apps/web/src/locales/gl/messages.json b/apps/web/src/locales/gl/messages.json index 38a94f9307f..6964a867768 100644 --- a/apps/web/src/locales/gl/messages.json +++ b/apps/web/src/locales/gl/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/he/messages.json b/apps/web/src/locales/he/messages.json index 4df39c8496f..115482c021b 100644 --- a/apps/web/src/locales/he/messages.json +++ b/apps/web/src/locales/he/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "רק כספת הארגון המשויכת עם $ORGANIZATION$ תיוצא. פריטים בכספת אישית או ארגונים אחרים לא יכללו.", "placeholders": { diff --git a/apps/web/src/locales/hi/messages.json b/apps/web/src/locales/hi/messages.json index 1cab0dc843b..bdd11c6561f 100644 --- a/apps/web/src/locales/hi/messages.json +++ b/apps/web/src/locales/hi/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/hr/messages.json b/apps/web/src/locales/hr/messages.json index 65c42a0cbf0..5ae2ddcfc0b 100644 --- a/apps/web/src/locales/hr/messages.json +++ b/apps/web/src/locales/hr/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Izvest će se samo stavke i privici osobnog trezora povezanog s $EMAIL$. Stavke organizacijskog trezora neće biti uključene", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Izvest će se samo organizacijski trezor povezan s $ORGANIZATION$. Stavke iz osobnih trezora i stavke iz drugih organizacija neće biti uključene.", "placeholders": { diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index 3d6a2e258a4..b7a51e5048b 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Csak $EMAIL$ email címmel társított személyes széf elemek kerülnek exportálásra. Ebbe nem kerülnek be a szervezeti széf elemek.", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Csak$ORGANIZATION$ névvel társított szervezeti széf elemek kerülnek exportálásra. Ebbe nem kerülnek be a személyes és más szervezeti széf elemek.", "placeholders": { diff --git a/apps/web/src/locales/id/messages.json b/apps/web/src/locales/id/messages.json index 22b4e3a6132..dc3ba77328f 100644 --- a/apps/web/src/locales/id/messages.json +++ b/apps/web/src/locales/id/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/it/messages.json b/apps/web/src/locales/it/messages.json index 0cbc425d588..853c580c82d 100644 --- a/apps/web/src/locales/it/messages.json +++ b/apps/web/src/locales/it/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Solo la cassaforte dell'organizzazione associata a $ORGANIZATION$ sarà esportata. Elementi nelle casseforti individuali o in altre organizzazioni non saranno inclusi.", "placeholders": { diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index 6860b30b360..d445184774c 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -474,7 +474,7 @@ "message": "フォルダーを編集" }, "editWithName": { - "message": "Edit $ITEM$: $NAME$", + "message": "$ITEM$: $NAME$ を編集", "placeholders": { "item": { "content": "$1", @@ -1202,7 +1202,7 @@ "message": "デバイスとは何ですか?" }, "aDeviceIs": { - "message": "A device is a unique installation of the Bitwarden app where you have logged in. Reinstalling, clearing app data, or clearing your cookies could result in a device appearing multiple times." + "message": "デバイスとは、あなたがログインしている Bitwarden アプリの一意なインストールです。 再インストールや、アプリデータの消去、 Cookie の消去をすると、同じデバイスが複数回表示される場合があります。" }, "logInInitiated": { "message": "ログイン開始" @@ -1894,22 +1894,22 @@ "message": "新しいデバイスからのログイン" }, "turnOffNewDeviceLoginProtection": { - "message": "Turn off new device login protection" + "message": "新しいデバイスからのログイン保護をオフにする" }, "turnOnNewDeviceLoginProtection": { - "message": "Turn on new device login protection" + "message": "新しいデバイスからのログイン保護をオンにする" }, "turnOffNewDeviceLoginProtectionModalDesc": { - "message": "Proceed below to turn off the verification emails bitwarden sends when you login from a new device." + "message": "続行すると、新しいデバイスからログインしたときに Bitwarden が送信する認証メールをオフにします。" }, "turnOnNewDeviceLoginProtectionModalDesc": { - "message": "Proceed below to have bitwarden send you verification emails when you login from a new device." + "message": "続行すると、新しいデバイスからログインする際に Bitwarden から認証メールを送信します。" }, "turnOffNewDeviceLoginProtectionWarning": { - "message": "With new device login protection turned off, anyone with your master password can access your account from any device. To protect your account without verification emails, set up two-step login." + "message": "新しいデバイスからのログイン保護をオフにすると、マスターパスワードを持つ人は誰でも、どのデバイスからでもあなたのアカウントにアクセスできます。認証メールなしでアカウントを保護するには、2段階認証によるログインを設定してください。" }, "accountNewDeviceLoginProtectionSaved": { - "message": "New device login protection changes saved" + "message": "新しいデバイスからのログイン保護の変更が保存されました" }, "sessionsDeauthorized": { "message": "全てのセッションを無効化" @@ -2175,7 +2175,7 @@ "message": "2段階認証を有効にすると Bitwarden アカウントから永久に閉め出されてしまうことがあります。リカバリーコードがあれば、通常の2段階認証プロバイダを使えなくなったとき (デバイスの紛失等) でもアカウントにアクセスできます。アカウントにアクセスできなくなっても Bitwarden はサポート出来ないため、リカバリーコードを書き出すか印刷し安全な場所で保管しておくことを推奨します。" }, "yourSingleUseRecoveryCode": { - "message": "Your single-use recovery code can be used to turn off two-step login in the event that you lose access to your two-step login provider. Bitwarden recommends you write down the recovery code and keep it in a safe place." + "message": "2段階認証プロバイダーへのアクセスを失った場合は、使い捨てのリカバリーコードを使用して2段階認証をオフにできます。 Bitwarden では、リカバリーコードを書き留めて安全な場所に保管することをお勧めしています。" }, "viewRecoveryCode": { "message": "リカバリーコードを確認" @@ -2216,7 +2216,7 @@ "message": "管理" }, "manageCollection": { - "message": "Manage collection" + "message": "コレクションの管理" }, "viewItems": { "message": "アイテムを表示" @@ -2429,7 +2429,7 @@ "message": "セキュリティキーの読み取り中に問題が発生しました。もう一度やり直して下さい。" }, "twoFactorWebAuthnWarning1": { - "message": "Due to platform limitations, WebAuthn cannot be used on all Bitwarden applications. You should set up another two-step login provider so that you can access your account when WebAuthn cannot be used." + "message": "プラットフォームの制限により、 WebAuthn は全ての Bitwarden アプリケーションで使用できるわけではありません。 WebAuthn が使用できない場合に備えて、他の2段階認証プロバイダーを設定しておくことをおすすめします。" }, "twoFactorRecoveryYourCode": { "message": "二段階認証のリカバリーコード" @@ -3396,10 +3396,10 @@ } }, "inviteSingleEmailDesc": { - "message": "You have 1 invite remaining." + "message": "招待は残り 1 個です。" }, "inviteZeroEmailDesc": { - "message": "You have 0 invites remaining." + "message": "招待は残り 0 個です。" }, "userUsingTwoStep": { "message": "このユーザーはアカウントを保護するため二段階認証を利用しています。" @@ -3853,7 +3853,7 @@ } }, "unlinkedSso": { - "message": "Unlinked SSO." + "message": "SSO のリンクを解除しました。" }, "unlinkedSsoUser": { "message": "ユーザー $ID$ にリンクされていない SSO", @@ -3904,22 +3904,22 @@ "message": "デバイス" }, "loginStatus": { - "message": "Login status" + "message": "ログイン状態" }, "firstLogin": { - "message": "First login" + "message": "初回ログイン" }, "trusted": { - "message": "Trusted" + "message": "信頼済み" }, "needsApproval": { - "message": "Needs approval" + "message": "承認が必要" }, "areYouTryingtoLogin": { - "message": "Are you trying to log in?" + "message": "ログインしようとしていますか?" }, "logInAttemptBy": { - "message": "Login attempt by $EMAIL$", + "message": "$EMAIL$ によるログインの試行", "placeholders": { "email": { "content": "$1", @@ -3928,7 +3928,7 @@ } }, "deviceType": { - "message": "Device Type" + "message": "デバイスタイプ" }, "ipAddress": { "message": "IP アドレス" @@ -3965,7 +3965,7 @@ "message": "たった今" }, "requestedXMinutesAgo": { - "message": "Requested $MINUTES$ minutes ago", + "message": "$MINUTES$ 分前に要求されました", "placeholders": { "minutes": { "content": "$1", @@ -4097,10 +4097,10 @@ "message": "サポートされていないブラウザを使用しています。ウェブ保管庫が正しく動作しないかもしれません。" }, "youHaveAPendingLoginRequest": { - "message": "You have a pending login request from another device." + "message": "別のデバイスからの保留中のログインリクエストがあります。" }, "reviewLoginRequest": { - "message": "Review login request" + "message": "ログインリクエストの内容を確認" }, "freeTrialEndPromptCount": { "message": "無料体験はあと $COUNT$ 日で終了します。", @@ -4197,7 +4197,7 @@ "message": "もし通常の二段階認証の方法でアカウントにアクセスできなくなった場合、リカバリーコードにより全ての二段階認証プロバイダを無効化することができます。" }, "logInBelowUsingYourSingleUseRecoveryCode": { - "message": "Log in below using your single-use recovery code. This will turn off all two-step providers on your account." + "message": "使い捨てのリカバリーコードを使用して以下からログインしてください。これにより、アカウントのすべての2段階認証プロバイダーが無効になります。" }, "recoverAccountTwoStep": { "message": "二段階認証ログインの回復" @@ -4509,7 +4509,7 @@ } }, "reorderFieldUp": { - "message": "$LABEL$ moved up, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ を上に移動しました。$INDEX$ / $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4526,7 +4526,7 @@ } }, "reorderFieldDown": { - "message": "$LABEL$ moved down, position $INDEX$ of $LENGTH$", + "message": "$LABEL$ を下に移動しました。$INDEX$ / $LENGTH$", "placeholders": { "label": { "content": "$1", @@ -4814,7 +4814,7 @@ "message": "マスターパスワードの強度に最低要件を設定する。" }, "passwordStrengthScore": { - "message": "Password strength score $SCORE$", + "message": "パスワードの強度スコア $SCORE$", "placeholders": { "score": { "content": "$1", @@ -5103,14 +5103,14 @@ "message": "組織の所有者および管理者は、このポリシーの執行から除外されます。" }, "limitSendViews": { - "message": "Limit views" + "message": "表示の制限" }, "limitSendViewsHint": { - "message": "No one can view this Send after the limit is reached.", + "message": "上限に達すると、誰もこの Send を表示できなくなります。", "description": "Displayed under the limit views field on Send" }, "limitSendViewsCount": { - "message": "$ACCESSCOUNT$ views left", + "message": "残り $ACCESSCOUNT$ 回", "description": "Displayed under the limit views field on Send", "placeholders": { "accessCount": { @@ -5120,11 +5120,11 @@ } }, "sendDetails": { - "message": "Send details", + "message": "Send の詳細", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "sendTypeTextToShare": { - "message": "Text to share" + "message": "共有するテキスト" }, "sendTypeFile": { "message": "ファイル" @@ -5133,7 +5133,7 @@ "message": "テキスト" }, "sendPasswordDescV3": { - "message": "Add an optional password for recipients to access this Send.", + "message": "必要に応じて、受信者がこの Send にアクセスするためのパスワードを追加します。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "createSend": { @@ -5161,14 +5161,14 @@ "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deleteSendPermanentConfirmation": { - "message": "Are you sure you want to permanently delete this Send?", + "message": "この Send を完全に削除してもよろしいですか?", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "deletionDate": { "message": "削除日時" }, "deletionDateDescV2": { - "message": "The Send will be permanently deleted on this date.", + "message": "この Send はこの期間ののち、完全に削除されます。", "description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated." }, "expirationDate": { @@ -5218,7 +5218,7 @@ "message": "保留中の削除" }, "hideTextByDefault": { - "message": "Hide text by default" + "message": "デフォルトでテキストを隠す" }, "expired": { "message": "期限切れ" @@ -5689,7 +5689,7 @@ "message": "削除と有効期限の保存中にエラーが発生しました。" }, "hideYourEmail": { - "message": "Hide your email address from viewers." + "message": "閲覧者にメールアドレスを見せないようにします。" }, "webAuthnFallbackMsg": { "message": "二段階認証を確認するには、下のボタンをクリックしてください。" @@ -5698,10 +5698,10 @@ "message": "WebAuthn の認証" }, "readSecurityKey": { - "message": "Read security key" + "message": "セキュリティキーの読み取り" }, "awaitingSecurityKeyInteraction": { - "message": "Awaiting security key interaction..." + "message": "セキュリティキーとの通信を待ち受け中…" }, "webAuthnNotSupported": { "message": "WebAuthn はこのブラウザではサポートされていません。" @@ -5917,17 +5917,17 @@ "message": "エラー" }, "decryptionError": { - "message": "Decryption error" + "message": "復号エラー" }, "couldNotDecryptVaultItemsBelow": { - "message": "Bitwarden could not decrypt the vault item(s) listed below." + "message": "Bitwarden は以下の保管庫のアイテムを復号できませんでした。" }, "contactCSToAvoidDataLossPart1": { - "message": "Contact customer success", + "message": "カスタマーサクセスに問い合わせて、", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "contactCSToAvoidDataLossPart2": { - "message": "to avoid additional data loss.", + "message": "さらなるデータ損失を回避してください。", "description": "This is part of a larger sentence. The full sentence will read 'Contact customer success to avoid additional data loss.'" }, "accountRecoveryManageUsers": { @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "$EMAIL$ に関連付けられた個人用保管庫のアイテムのみが、添付ファイルを含めてエクスポートされます。組織用保管庫のアイテムは含まれません。", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "$ORGANIZATION$ に関連付けられた組織保管庫のみがエクスポートされます。個々の保管庫または他の組織にあるアイテムは含まれません。", "placeholders": { @@ -6845,7 +6854,7 @@ "message": "ドメインに設定されたキャッチオール受信トレイを使用します。" }, "useThisEmail": { - "message": "Use this email" + "message": "このメールアドレスを使う" }, "random": { "message": "ランダム", @@ -6997,7 +7006,7 @@ } }, "forwaderInvalidOperation": { - "message": "$SERVICENAME$ refused your request. Please contact your service provider for assistance.", + "message": "$SERVICENAME$ はリクエストを拒否しました。サービスプロバイダーにお問い合わせください。", "description": "Displayed when the user is forbidden from using the API by the forwarding service.", "placeholders": { "servicename": { @@ -7007,7 +7016,7 @@ } }, "forwaderInvalidOperationWithMessage": { - "message": "$SERVICENAME$ refused your request: $ERRORMESSAGE$", + "message": "$SERVICENAME$ があなたのリクエストを拒否しました: $ERRORMESSAGE$", "description": "Displayed when the user is forbidden from using the API by the forwarding service with an error message.", "placeholders": { "servicename": { @@ -10159,7 +10168,7 @@ } }, "userLeftOrganization": { - "message": "User $ID$ left organization", + "message": "ユーザー $ID$ が組織から脱退しました", "placeholders": { "id": { "content": "$1", @@ -10168,7 +10177,7 @@ } }, "suspendedOrganizationTitle": { - "message": "The $ORGANIZATION$ is suspended", + "message": "$ORGANIZATION$ は一時停止されています", "placeholders": { "organization": { "content": "$1", @@ -10177,25 +10186,25 @@ } }, "suspendedUserOrgMessage": { - "message": "Contact your organization owner for assistance." + "message": "組織の所有者にお問い合わせください。" }, "suspendedOwnerOrgMessage": { - "message": "To regain access to your organization, add a payment method." + "message": "組織へのアクセスを取り戻すには、支払い方法を追加してください。" }, "deleteMembers": { - "message": "Delete members" + "message": "メンバーを削除" }, "noSelectedMembersApplicable": { - "message": "This action is not applicable to any of the selected members." + "message": "この操作は、選択されたメンバーには適用できません。" }, "deletedSuccessfully": { - "message": "Deleted successfully" + "message": "正常に削除されました" }, "freeFamiliesSponsorship": { - "message": "Remove Free Bitwarden Families sponsorship" + "message": "Bitwarden ファミリープランの無償利用へのスポンサーを解除" }, "freeFamiliesSponsorshipPolicyDesc": { - "message": "Do not allow members to redeem a Families plan through this organization." + "message": "メンバーがこの組織を通じてファミリープランを引き換えられないようにします。" }, "verifyBankAccountWithStatementDescriptorWarning": { "message": "Payment with a bank account is only available to customers in the United States. You will be required to verify your bank account. We will make a micro-deposit within the next 1-2 business days. Enter the statement descriptor code from this deposit on the organization's billing page to verify the bank account. Failure to verify the bank account will result in a missed payment and your subscription being suspended." @@ -10545,6 +10554,6 @@ "message": "These events are examples only and do not reflect real events within your Bitwarden organization." }, "cannotCreateCollection": { - "message": "Free organizations may have up to 2 collections. Upgrade to a paid plan to add more collections." + "message": "無料版の組織ではコレクションは 2 つまでです。さらにコレクションを追加するには有料プランにアップグレードしてください。" } } diff --git a/apps/web/src/locales/ka/messages.json b/apps/web/src/locales/ka/messages.json index f5f4bfb3ae1..5ace08617ff 100644 --- a/apps/web/src/locales/ka/messages.json +++ b/apps/web/src/locales/ka/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/km/messages.json b/apps/web/src/locales/km/messages.json index f334131b69b..59eac9b372b 100644 --- a/apps/web/src/locales/km/messages.json +++ b/apps/web/src/locales/km/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/kn/messages.json b/apps/web/src/locales/kn/messages.json index dbf2cab3bb5..8132c9a2db5 100644 --- a/apps/web/src/locales/kn/messages.json +++ b/apps/web/src/locales/kn/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/ko/messages.json b/apps/web/src/locales/ko/messages.json index 1f3bbda3736..6e59f0ccf88 100644 --- a/apps/web/src/locales/ko/messages.json +++ b/apps/web/src/locales/ko/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "$ORGANIZATION$ 조직과 연관된 조직 보관함만 내보내기됩니다. 개인 보관함이나 다른 조직의 항목은 포함되지 않습니다.", "placeholders": { diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index 7c8c3b2831e..e59f6078bf5 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Tiks izdoti tikai atsevišķi glabātavas vienumi, tajā skaitā pielikumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Tiks izgūta tikai apvienības glabātava, kas ir saistīta ar $ORGANIZATION$. Atsevišķu glabātavu vai citu apvienību vienumi netiks iekļauti.", "placeholders": { diff --git a/apps/web/src/locales/ml/messages.json b/apps/web/src/locales/ml/messages.json index 46ce3b62533..10ae27a2139 100644 --- a/apps/web/src/locales/ml/messages.json +++ b/apps/web/src/locales/ml/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/mr/messages.json b/apps/web/src/locales/mr/messages.json index f334131b69b..59eac9b372b 100644 --- a/apps/web/src/locales/mr/messages.json +++ b/apps/web/src/locales/mr/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/my/messages.json b/apps/web/src/locales/my/messages.json index f334131b69b..59eac9b372b 100644 --- a/apps/web/src/locales/my/messages.json +++ b/apps/web/src/locales/my/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/nb/messages.json b/apps/web/src/locales/nb/messages.json index 24285b8cb9f..bc36ba82ff1 100644 --- a/apps/web/src/locales/nb/messages.json +++ b/apps/web/src/locales/nb/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/ne/messages.json b/apps/web/src/locales/ne/messages.json index 8183efd5f9b..c947c0bb716 100644 --- a/apps/web/src/locales/ne/messages.json +++ b/apps/web/src/locales/ne/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/nl/messages.json b/apps/web/src/locales/nl/messages.json index 6b752b5a195..1bc731e3ceb 100644 --- a/apps/web/src/locales/nl/messages.json +++ b/apps/web/src/locales/nl/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Exporteert alleen de persoonlijke kluis-items, inclusief attachments, gerelateerd aan $EMAIL$. Geen kluis-items van de organisatie", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Exporteert alleen de organisatiekluis van $ORGANIZATION$. Geen persoonlijke kluis-items of items van andere organisaties.", "placeholders": { diff --git a/apps/web/src/locales/nn/messages.json b/apps/web/src/locales/nn/messages.json index 23d4d3b3089..ae64568bd79 100644 --- a/apps/web/src/locales/nn/messages.json +++ b/apps/web/src/locales/nn/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/or/messages.json b/apps/web/src/locales/or/messages.json index f334131b69b..59eac9b372b 100644 --- a/apps/web/src/locales/or/messages.json +++ b/apps/web/src/locales/or/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index 9ef5c95bf86..f793b249148 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Tylko poszczególne elementy sejfu łącznie z załącznikami powiązanymi z $EMAIL$ zostaną wyeksportowane. Elementy sejfu organizacji nie będą dołączone", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Tylko sejf organizacji powiązany z $ORGANIZATION$ zostanie wyeksportowany. Pozycje w poszczególnych sejfach lub innych organizacji nie będą uwzględnione.", "placeholders": { diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index ea43fd4eae6..3ac5afa3110 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Apenas o cofre da organização associado com $ORGANIZATION$ será exportado. Itens do cofre pessoal e itens de outras organizações não serão incluídos.", "placeholders": { diff --git a/apps/web/src/locales/pt_PT/messages.json b/apps/web/src/locales/pt_PT/messages.json index 9bbda05c93f..1cd3f9c9b1b 100644 --- a/apps/web/src/locales/pt_PT/messages.json +++ b/apps/web/src/locales/pt_PT/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Apenas os itens individuais do cofre, incluindo os anexos associados a $EMAIL$, serão exportados. Os itens do cofre da organização não serão incluídos", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Apenas o cofre da organização associado a $ORGANIZATION$ será exportado. Os itens em cofres individuais ou noutras organizações não serão incluídos.", "placeholders": { diff --git a/apps/web/src/locales/ro/messages.json b/apps/web/src/locales/ro/messages.json index c57ad26d251..f67c9550655 100644 --- a/apps/web/src/locales/ro/messages.json +++ b/apps/web/src/locales/ro/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index a31d13d227e..2bdaeb63206 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Будут экспортированы только отдельные элементы хранилища, включая вложения, связанные с $EMAIL$. Элементы хранилища организации включены не будут", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Будет экспортировано только хранилище организации, связанное с $ORGANIZATION$. Элементы из личных хранилищ и из других организаций включены не будут.", "placeholders": { diff --git a/apps/web/src/locales/si/messages.json b/apps/web/src/locales/si/messages.json index fc79da1352b..bbb01d1aa49 100644 --- a/apps/web/src/locales/si/messages.json +++ b/apps/web/src/locales/si/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index fdf57456a4c..339a73bbffb 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Exportované budú iba položy osobného trezora spojené s $EMAIL$. Položky trezora organizácie nebudú zahrnuté v exporte", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Exportované budú iba položky trezora organizácie spojené s $ORGANIZATION$. Položky osobného trezora a položky z iných organizácií nebudú zahrnuté.", "placeholders": { diff --git a/apps/web/src/locales/sl/messages.json b/apps/web/src/locales/sl/messages.json index 1652841b650..d14b4f13ecc 100644 --- a/apps/web/src/locales/sl/messages.json +++ b/apps/web/src/locales/sl/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index 005fa7602b5..2ac4a713189 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Биће извезен само сеф организације повезан са $ORGANIZATION$. Ставке у појединачним сефовима или другим организацијама неће бити укључене.", "placeholders": { diff --git a/apps/web/src/locales/sr_CS/messages.json b/apps/web/src/locales/sr_CS/messages.json index d141d8301fc..d84f3192dea 100644 --- a/apps/web/src/locales/sr_CS/messages.json +++ b/apps/web/src/locales/sr_CS/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/sv/messages.json b/apps/web/src/locales/sv/messages.json index f7d6414c36c..e4cc2cdeb67 100644 --- a/apps/web/src/locales/sv/messages.json +++ b/apps/web/src/locales/sv/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/te/messages.json b/apps/web/src/locales/te/messages.json index f334131b69b..59eac9b372b 100644 --- a/apps/web/src/locales/te/messages.json +++ b/apps/web/src/locales/te/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/th/messages.json b/apps/web/src/locales/th/messages.json index 7d2685807b3..3b05ffc9000 100644 --- a/apps/web/src/locales/th/messages.json +++ b/apps/web/src/locales/th/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/tr/messages.json b/apps/web/src/locales/tr/messages.json index 030fd0dd9b2..ef8701ce4b1 100644 --- a/apps/web/src/locales/tr/messages.json +++ b/apps/web/src/locales/tr/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Yalnızca $EMAIL$ ile ilişkili kişisel kasadaki kayıtlar ve dosyalar dışa aktarılacaktır. Kuruluş kasasındaki kayıtlar dahil edilmeyecektir", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index 7d9eb316821..e175fe99db8 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Буде експортовано лише сховище організації, пов'язане з $ORGANIZATION$. Записи особистих сховищ або інших організацій не будуть включені.", "placeholders": { diff --git a/apps/web/src/locales/vi/messages.json b/apps/web/src/locales/vi/messages.json index f0a0215f823..f7e8f9f4037 100644 --- a/apps/web/src/locales/vi/messages.json +++ b/apps/web/src/locales/vi/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", "placeholders": { diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index 00bf9bc5973..6bb79aa1971 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -2958,7 +2958,7 @@ "description": "Past tense status of an invoice. ex. Paid or unpaid." }, "unpaid": { - "message": "待支付", + "message": "未支付", "description": "Past tense status of an invoice. ex. Paid or unpaid." }, "transactions": { @@ -4799,7 +4799,7 @@ "message": "您必须至少选择一个集合。" }, "couldNotChargeCardPayInvoice": { - "message": "我们无法从您的支付卡中扣款。请查看并支付下面列出的待支付账单。" + "message": "我们无法从您的支付卡中扣款。请查看并支付下面列出的未支付账单。" }, "minLength": { "message": "最小长度" @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "仅会导出与 $EMAIL$ 关联的个人密码库项目(包括附件)。不包括组织密码库项目。", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "仅会导出与 $ORGANIZATION$ 关联的组织密码库数据。不包括个人密码库和其他组织中的项目。", "placeholders": { diff --git a/apps/web/src/locales/zh_TW/messages.json b/apps/web/src/locales/zh_TW/messages.json index beca8f74485..c23def1464d 100644 --- a/apps/web/src/locales/zh_TW/messages.json +++ b/apps/web/src/locales/zh_TW/messages.json @@ -6741,6 +6741,15 @@ } } }, + "exportingIndividualVaultWithAttachmentsDescription": { + "message": "Only the individual vault items including attachments associated with $EMAIL$ will be exported. Organization vault items will not be included", + "placeholders": { + "email": { + "content": "$1", + "example": "name@example.com" + } + } + }, "exportingOrganizationVaultDesc": { "message": "僅匯出與 $ORGANIZATION$ 相關的組織密碼庫項目。個人密碼庫項目或其他組織中的項目將不包括在内。", "placeholders": { From 7ed21453937eb18ed9af96b9b57342f8f54f5f7d Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Fri, 28 Mar 2025 16:20:36 +0100 Subject: [PATCH 12/16] Set correct filename extensions on vault-export (#14018) Co-authored-by: Daniel James Smith --- .../src/services/individual-vault-export.service.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 0fc1f336b90..765de042d32 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 @@ -81,7 +81,7 @@ export class IndividualVaultExportService return { type: "text/plain", data: await this.buildPasswordExport(exportVault.data, password), - fileName: ExportHelper.getFileName("json"), + fileName: ExportHelper.getFileName("", "encrypted_json"), } as ExportedVaultAsString; } @@ -126,7 +126,7 @@ export class IndividualVaultExportService return { type: "application/zip", data: blobData, - fileName: ExportHelper.getFileName("json"), + fileName: ExportHelper.getFileName("", "json"), } as ExportedVaultAsBlob; } @@ -185,14 +185,14 @@ export class IndividualVaultExportService return { type: "text/plain", data: this.buildCsvExport(decFolders, decCiphers), - fileName: ExportHelper.getFileName("csv"), + fileName: ExportHelper.getFileName("", "csv"), } as ExportedVaultAsString; } return { type: "text/plain", data: this.buildJsonExport(decFolders, decCiphers), - fileName: ExportHelper.getFileName("json"), + fileName: ExportHelper.getFileName("", "json"), } as ExportedVaultAsString; } @@ -250,7 +250,7 @@ export class IndividualVaultExportService return { type: "text/plain", data: JSON.stringify(jsonDoc, null, " "), - fileName: ExportHelper.getFileName("json"), + fileName: ExportHelper.getFileName("", "json"), } as ExportedVaultAsString; } From 6204e2a092c50ed192532a0caac2cbbe2283ba4b Mon Sep 17 00:00:00 2001 From: Vicki League Date: Fri, 28 Mar 2025 13:41:53 -0400 Subject: [PATCH 13/16] [CL-550] Update cipher form story (#14019) --- libs/vault/src/cipher-form/cipher-form.mdx | 3 ++ .../src/cipher-form/cipher-form.stories.ts | 50 +++++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/libs/vault/src/cipher-form/cipher-form.mdx b/libs/vault/src/cipher-form/cipher-form.mdx index ed2e799b9f3..658fcd38d11 100644 --- a/libs/vault/src/cipher-form/cipher-form.mdx +++ b/libs/vault/src/cipher-form/cipher-form.mdx @@ -12,6 +12,9 @@ It is configured via a `CipherFormConfig` object that is passed to the component create it. A default implementation of the `CipherFormConfigService` exists in the `@bitwarden/vault` library. +The cipher form has a slot for `attachment-button`, which should be included when the form is in +`edit` mode. + diff --git a/libs/vault/src/cipher-form/cipher-form.stories.ts b/libs/vault/src/cipher-form/cipher-form.stories.ts index 5d6464b4c79..52d70e8652a 100644 --- a/libs/vault/src/cipher-form/cipher-form.stories.ts +++ b/libs/vault/src/cipher-form/cipher-form.stories.ts @@ -29,7 +29,7 @@ import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; -import { AsyncActionsModule, ButtonModule, ToastService } from "@bitwarden/components"; +import { AsyncActionsModule, ButtonModule, ItemModule, ToastService } from "@bitwarden/components"; import { CipherFormConfig, CipherFormGenerationService, @@ -131,7 +131,7 @@ export default { component: CipherFormComponent, decorators: [ moduleMetadata({ - imports: [CipherFormModule, AsyncActionsModule, ButtonModule], + imports: [CipherFormModule, AsyncActionsModule, ButtonModule, ItemModule], providers: [ { provide: CipherFormService, @@ -246,7 +246,7 @@ export default { type Story = StoryObj; -export const Default: Story = { +export const Add: Story = { render: (args) => { return { props: { @@ -254,15 +254,28 @@ export const Default: Story = { ...args, }, template: /*html*/ ` - - + `, }; }, }; export const Edit: Story = { - ...Default, + render: (args) => { + return { + props: { + onSave: actionsData.onSave, + ...args, + }, + template: /*html*/ ` + + + + + + `, + }; + }, args: { config: { ...defaultConfig, @@ -273,7 +286,7 @@ export const Edit: Story = { }; export const PartialEdit: Story = { - ...Default, + ...Add, args: { config: { ...defaultConfig, @@ -284,7 +297,7 @@ export const PartialEdit: Story = { }; export const Clone: Story = { - ...Default, + ...Add, args: { config: { ...defaultConfig, @@ -294,8 +307,27 @@ export const Clone: Story = { }, }; +export const WithSubmitButton: Story = { + render: (args) => { + return { + props: { + onSave: actionsData.onSave, + ...args, + }, + template: /*html*/ ` +
+ +
+
+ +
+ `, + }; + }, +}; + export const NoPersonalOwnership: Story = { - ...Default, + ...Add, args: { config: { ...defaultConfig, From d5f033efa2a50e82780dd140b0431eb7bb455def Mon Sep 17 00:00:00 2001 From: Alec Rippberger <127791530+alec-livefront@users.noreply.github.com> Date: Fri, 28 Mar 2025 12:51:20 -0500 Subject: [PATCH 14/16] refactor(auth): [PM-9179] remove deprecated TwoFactorComponents Remove deprecated TwoFactorComponentsV1 and TwoFactorOptionsComponentV1 components, related functionality (unauthUiRefreshSwap) and orphaned styles/translation messages. --- apps/browser/src/_locales/en/messages.json | 36 -- .../two-factor-options-v1.component.html | 29 - .../popup/two-factor-options-v1.component.ts | 56 -- .../auth/popup/two-factor-v1.component.html | 196 ------- .../src/auth/popup/two-factor-v1.component.ts | 260 --------- apps/browser/src/popup/app-routing.module.ts | 53 +- apps/browser/src/popup/app.module.ts | 4 - apps/browser/src/popup/scss/misc.scss | 10 - apps/desktop/src/app/app-routing.module.ts | 39 +- apps/desktop/src/app/app.module.ts | 4 - .../auth/two-factor-options-v1.component.html | 33 -- .../auth/two-factor-options-v1.component.ts | 24 - .../src/auth/two-factor-v1.component.html | 175 ------ .../src/auth/two-factor-v1.component.ts | 190 ------- apps/desktop/src/locales/en/messages.json | 27 - apps/desktop/src/scss/pages.scss | 2 - .../auth/two-factor-options-v1.component.html | 45 -- .../auth/two-factor-options-v1.component.ts | 52 -- .../src/app/auth/two-factor-v1.component.html | 106 ---- .../src/app/auth/two-factor-v1.component.ts | 164 ------ apps/web/src/app/oss-routing.module.ts | 69 +-- .../src/app/shared/loose-components.module.ts | 6 - apps/web/src/locales/en/messages.json | 28 +- .../two-factor-options-v1.component.ts | 44 -- .../two-factor-v1.component.spec.ts | 505 ----------------- .../components/two-factor-v1.component.ts | 514 ------------------ .../functions/unauth-ui-refresh-route-swap.ts | 36 -- 27 files changed, 55 insertions(+), 2652 deletions(-) delete mode 100644 apps/browser/src/auth/popup/two-factor-options-v1.component.html delete mode 100644 apps/browser/src/auth/popup/two-factor-options-v1.component.ts delete mode 100644 apps/browser/src/auth/popup/two-factor-v1.component.html delete mode 100644 apps/browser/src/auth/popup/two-factor-v1.component.ts delete mode 100644 apps/desktop/src/auth/two-factor-options-v1.component.html delete mode 100644 apps/desktop/src/auth/two-factor-options-v1.component.ts delete mode 100644 apps/desktop/src/auth/two-factor-v1.component.html delete mode 100644 apps/desktop/src/auth/two-factor-v1.component.ts delete mode 100644 apps/web/src/app/auth/two-factor-options-v1.component.html delete mode 100644 apps/web/src/app/auth/two-factor-options-v1.component.ts delete mode 100644 apps/web/src/app/auth/two-factor-v1.component.html delete mode 100644 apps/web/src/app/auth/two-factor-v1.component.ts delete mode 100644 libs/angular/src/auth/components/two-factor-options-v1.component.ts delete mode 100644 libs/angular/src/auth/components/two-factor-v1.component.spec.ts delete mode 100644 libs/angular/src/auth/components/two-factor-v1.component.ts delete mode 100644 libs/angular/src/auth/functions/unauth-ui-refresh-route-swap.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 2c940ccdf5a..8c47db0d331 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1391,24 +1391,12 @@ "premiumRequiredDesc": { "message": "A Premium membership is required to use this feature." }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, "authenticationTimeout": { "message": "Authentication timeout" }, "authenticationSessionTimedOut": { "message": "The authentication session timed out. Please restart the login process." }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1418,18 +1406,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1437,18 +1416,9 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, - "webAuthnNewTab": { - "message": "To start the WebAuthn 2FA verification. Click the button below to open a new tab and follow the instructions provided in the new tab." - }, - "webAuthnNewTabOpen": { - "message": "Open new tab" - }, "openInNewTab": { "message": "Open in new tab" }, @@ -3848,15 +3818,9 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredForAccount": { "message": "Duo two-step login is required for your account." }, - "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." - }, "popoutExtension": { "message": "Popout extension" }, diff --git a/apps/browser/src/auth/popup/two-factor-options-v1.component.html b/apps/browser/src/auth/popup/two-factor-options-v1.component.html deleted file mode 100644 index f25944aba65..00000000000 --- a/apps/browser/src/auth/popup/two-factor-options-v1.component.html +++ /dev/null @@ -1,29 +0,0 @@ -
-
- -
-

- {{ "twoStepOptions" | i18n }} -

-
-
-
-
-
- - -
-
-
diff --git a/apps/browser/src/auth/popup/two-factor-options-v1.component.ts b/apps/browser/src/auth/popup/two-factor-options-v1.component.ts deleted file mode 100644 index 0c71421fc04..00000000000 --- a/apps/browser/src/auth/popup/two-factor-options-v1.component.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Component } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; - -import { TwoFactorOptionsComponentV1 as BaseTwoFactorOptionsComponent } from "@bitwarden/angular/auth/components/two-factor-options-v1.component"; -import { - TwoFactorProviderDetails, - TwoFactorService, -} from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; - -@Component({ - selector: "app-two-factor-options", - templateUrl: "two-factor-options-v1.component.html", -}) -export class TwoFactorOptionsComponentV1 extends BaseTwoFactorOptionsComponent { - constructor( - twoFactorService: TwoFactorService, - router: Router, - i18nService: I18nService, - platformUtilsService: PlatformUtilsService, - environmentService: EnvironmentService, - private activatedRoute: ActivatedRoute, - ) { - super(twoFactorService, router, i18nService, platformUtilsService, window, environmentService); - } - - close() { - this.navigateTo2FA(); - } - - override async choose(p: TwoFactorProviderDetails) { - await super.choose(p); - await this.twoFactorService.setSelectedProvider(p.type); - - this.navigateTo2FA(); - } - - navigateTo2FA() { - const sso = this.activatedRoute.snapshot.queryParamMap.get("sso") === "true"; - - if (sso) { - // Persist SSO flag back to the 2FA comp if it exists - // in order for successful login logic to work properly for - // SSO + 2FA in browser extension - // 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(["2fa"], { queryParams: { sso: true } }); - } 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(["2fa"]); - } - } -} diff --git a/apps/browser/src/auth/popup/two-factor-v1.component.html b/apps/browser/src/auth/popup/two-factor-v1.component.html deleted file mode 100644 index 126b0ea5a99..00000000000 --- a/apps/browser/src/auth/popup/two-factor-v1.component.html +++ /dev/null @@ -1,196 +0,0 @@ -
-
-
- -
-

- {{ title }} -

-
- -
-
-
- - -
- - {{ "enterVerificationCodeApp" | i18n }} - - - {{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }} - -
-
-
-
- - -
-
- - -
-
-
-
- - -
-

{{ "insertYubiKey" | i18n }}

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

{{ "webAuthnNewTab" | i18n }}

- -
-
- - -
-

- {{ "duoRequiredForAccount" | i18n }} -

- -

- {{ "popoutTheExtensionToCompleteLogin" | i18n }} -

- - -

{{ "launchDuoAndFollowStepsToFinishLoggingIn" | i18n }}

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

{{ "noTwoStepProviders" | i18n }}

-

{{ "noTwoStepProviders2" | i18n }}

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

- -

-
-
-
diff --git a/apps/browser/src/auth/popup/two-factor-v1.component.ts b/apps/browser/src/auth/popup/two-factor-v1.component.ts deleted file mode 100644 index 884e42bf73a..00000000000 --- a/apps/browser/src/auth/popup/two-factor-v1.component.ts +++ /dev/null @@ -1,260 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, Inject, OnDestroy, OnInit } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { Subject, Subscription, firstValueFrom } from "rxjs"; -import { filter, first, takeUntil } from "rxjs/operators"; - -import { TwoFactorComponentV1 as BaseTwoFactorComponent } from "@bitwarden/angular/auth/components/two-factor-v1.component"; -import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; -import { - LoginStrategyServiceAbstraction, - LoginEmailServiceAbstraction, - UserDecryptionOptionsServiceAbstraction, -} from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; -import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; -import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.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 { 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 { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { DialogService, ToastService } from "@bitwarden/components"; - -import { BrowserApi } from "../../platform/browser/browser-api"; -import { ZonedMessageListenerService } from "../../platform/browser/zoned-message-listener.service"; -import BrowserPopupUtils from "../../platform/popup/browser-popup-utils"; - -import { closeTwoFactorAuthWebAuthnPopout } from "./utils/auth-popout-window"; - -@Component({ - selector: "app-two-factor", - templateUrl: "two-factor-v1.component.html", -}) -export class TwoFactorComponentV1 extends BaseTwoFactorComponent implements OnInit, OnDestroy { - private destroy$ = new Subject(); - inPopout = BrowserPopupUtils.inPopout(window); - - constructor( - loginStrategyService: LoginStrategyServiceAbstraction, - router: Router, - i18nService: I18nService, - apiService: ApiService, - platformUtilsService: PlatformUtilsService, - private syncService: SyncService, - environmentService: EnvironmentService, - stateService: StateService, - route: ActivatedRoute, - private messagingService: MessagingService, - logService: LogService, - twoFactorService: TwoFactorService, - appIdService: AppIdService, - loginEmailService: LoginEmailServiceAbstraction, - userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, - configService: ConfigService, - ssoLoginService: SsoLoginServiceAbstraction, - private dialogService: DialogService, - masterPasswordService: InternalMasterPasswordServiceAbstraction, - accountService: AccountService, - toastService: ToastService, - @Inject(WINDOW) protected win: Window, - private browserMessagingApi: ZonedMessageListenerService, - ) { - super( - loginStrategyService, - router, - i18nService, - apiService, - platformUtilsService, - win, - environmentService, - stateService, - route, - logService, - twoFactorService, - appIdService, - loginEmailService, - userDecryptionOptionsService, - ssoLoginService, - configService, - masterPasswordService, - accountService, - toastService, - ); - this.onSuccessfulLogin = async () => { - // 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 - syncService.fullSync(true); - }; - - this.onSuccessfulLoginTde = async () => { - // 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 - syncService.fullSync(true); - }; - - this.onSuccessfulLoginTdeNavigate = async () => { - this.win.close(); - }; - - this.successRoute = "/tabs/vault"; - // FIXME: Chromium 110 has broken WebAuthn support in extensions via an iframe - this.webAuthnNewTab = true; - } - - async ngOnInit() { - if (this.route.snapshot.paramMap.has("webAuthnResponse")) { - // WebAuthn fallback response - this.selectedProviderType = TwoFactorProviderType.WebAuthn; - this.token = this.route.snapshot.paramMap.get("webAuthnResponse"); - this.onSuccessfulLogin = async () => { - // 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.syncService.fullSync(true); - this.messagingService.send("reloadPopup"); - window.close(); - }; - this.remember = this.route.snapshot.paramMap.get("remember") === "true"; - await this.doSubmit(); - return; - } - - await super.ngOnInit(); - if (this.selectedProviderType == null) { - return; - } - - // WebAuthn prompt appears inside the popup on linux, and requires a larger popup width - // than usual to avoid cutting off the dialog. - if (this.selectedProviderType === TwoFactorProviderType.WebAuthn && (await this.isLinux())) { - document.body.classList.add("linux-webauthn"); - } - - if ( - this.selectedProviderType === TwoFactorProviderType.Email && - BrowserPopupUtils.inPopup(window) - ) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: { key: "warning" }, - content: { key: "popup2faCloseMessage" }, - type: "warning", - }); - 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 - BrowserPopupUtils.openCurrentPagePopout(window); - } - } - - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.queryParams.pipe(first()).subscribe(async (qParams) => { - if (qParams.sso === "true") { - this.onSuccessfulLogin = async () => { - // This is not awaited so we don't pause the application while the sync is happening. - // This call is executed by the service that lives in the background script so it will continue - // the sync even if this tab closes. - // 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.syncService.fullSync(true); - - // Force sidebars (FF && Opera) to reload while exempting current window - // because we are just going to close the current window. - BrowserApi.reloadOpenWindows(true); - - // We don't need this window anymore because the intent is for the user to be left - // on the web vault screen which tells them to continue in the browser extension (sidebar or popup) - await closeTwoFactorAuthWebAuthnPopout(); - }; - } - }); - } - - async ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - - if (this.selectedProviderType === TwoFactorProviderType.WebAuthn && (await this.isLinux())) { - document.body.classList.remove("linux-webauthn"); - } - super.ngOnDestroy(); - } - - anotherMethod() { - const sso = this.route.snapshot.queryParamMap.get("sso") === "true"; - - if (sso) { - // We must persist this so when the user returns to the 2FA comp, the - // proper onSuccessfulLogin logic is executed. - // 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(["2fa-options"], { queryParams: { sso: true } }); - } 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(["2fa-options"]); - } - } - - async popoutCurrentPage() { - await BrowserPopupUtils.openCurrentPagePopout(window); - } - - async isLinux() { - return (await BrowserApi.getPlatformInfo()).os === "linux"; - } - - duoResultSubscription: Subscription; - protected override setupDuoResultListener() { - if (!this.duoResultSubscription) { - this.duoResultSubscription = this.browserMessagingApi - .messageListener$() - .pipe( - filter((msg: any) => msg.command === "duoResult"), - takeUntil(this.destroy$), - ) - .subscribe((msg: { command: string; code: string; state: string }) => { - this.token = msg.code + "|" + msg.state; - // This floating promise is intentional. We don't need to await the submit + awaiting in a subscription is not recommended. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.submit(); - }); - } - } - - override async launchDuoFrameless() { - if (this.duoFramelessUrl === null) { - this.toastService.showToast({ - variant: "error", - title: null, - message: this.i18nService.t("duoHealthCheckResultsInNullAuthUrlError"), - }); - return; - } - - const duoHandOffMessage = { - title: this.i18nService.t("youSuccessfullyLoggedIn"), - message: this.i18nService.t("youMayCloseThisWindow"), - isCountdown: false, - }; - - // we're using the connector here as a way to set a cookie with translations - // before continuing to the duo frameless url - const env = await firstValueFrom(this.environmentService.environment$); - const launchUrl = - env.getWebVaultUrl() + - "/duo-redirect-connector.html" + - "?duoFramelessUrl=" + - encodeURIComponent(this.duoFramelessUrl) + - "&handOffMessage=" + - encodeURIComponent(JSON.stringify(duoHandOffMessage)); - this.platformUtilsService.launchUri(launchUrl); - } -} diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index e73f56fa2f6..9948b450e17 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -7,7 +7,6 @@ import { EnvironmentSelectorRouteData, ExtensionDefaultOverlayPosition, } from "@bitwarden/angular/auth/components/environment-selector.component"; -import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap"; import { activeAuthGuard, authGuard, @@ -59,8 +58,6 @@ import { import { RemovePasswordComponent } from "../auth/popup/remove-password.component"; import { SetPasswordComponent } from "../auth/popup/set-password.component"; import { AccountSecurityComponent } from "../auth/popup/settings/account-security.component"; -import { TwoFactorOptionsComponentV1 } from "../auth/popup/two-factor-options-v1.component"; -import { TwoFactorComponentV1 } from "../auth/popup/two-factor-v1.component"; import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component"; import { Fido2Component } from "../autofill/popup/fido2/fido2.component"; import { AutofillComponent } from "../autofill/popup/settings/autofill.component"; @@ -142,32 +139,6 @@ const routes: Routes = [ canActivate: [fido2AuthGuard], data: { elevation: 1 } satisfies RouteDataProperties, }, - ...unauthUiRefreshSwap( - TwoFactorComponentV1, - ExtensionAnonLayoutWrapperComponent, - { - path: "2fa", - canActivate: [unauthGuardFn(unauthRouteOverrides)], - data: { elevation: 1 } satisfies RouteDataProperties, - }, - { - path: "2fa", - canActivate: [unauthGuardFn(unauthRouteOverrides), TwoFactorAuthGuard], - children: [ - { - path: "", - component: TwoFactorAuthComponent, - }, - ], - data: { - elevation: 1, - pageTitle: { - key: "verifyYourIdentity", - }, - showBackButton: true, - } satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData, - }, - ), { path: "", component: ExtensionAnonLayoutWrapperComponent, @@ -191,12 +162,6 @@ const routes: Routes = [ }, ], }, - { - path: "2fa-options", - component: TwoFactorOptionsComponentV1, - canActivate: [unauthGuardFn(unauthRouteOverrides)], - data: { elevation: 1 } satisfies RouteDataProperties, - }, { path: "device-verification", component: ExtensionAnonLayoutWrapperComponent, @@ -371,7 +336,6 @@ const routes: Routes = [ canActivate: [authGuard], data: { elevation: 1 } satisfies RouteDataProperties, }, - { path: "", component: ExtensionAnonLayoutWrapperComponent, @@ -567,6 +531,23 @@ const routes: Routes = [ }, ], }, + { + path: "2fa", + canActivate: [unauthGuardFn(unauthRouteOverrides), TwoFactorAuthGuard], + children: [ + { + path: "", + component: TwoFactorAuthComponent, + }, + ], + data: { + elevation: 1, + pageTitle: { + key: "verifyYourIdentity", + }, + showBackButton: true, + } satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData, + }, ], }, { diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index 80cffa03b17..b2542679e06 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -25,8 +25,6 @@ import { SetPasswordComponent } from "../auth/popup/set-password.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"; -import { TwoFactorOptionsComponentV1 } from "../auth/popup/two-factor-options-v1.component"; -import { TwoFactorComponentV1 } from "../auth/popup/two-factor-v1.component"; import { UpdateTempPasswordComponent } from "../auth/popup/update-temp-password.component"; import { AutofillComponent } from "../autofill/popup/settings/autofill.component"; import { NotificationsSettingsComponent } from "../autofill/popup/settings/notifications.component"; @@ -93,8 +91,6 @@ import "../platform/popup/locales"; SetPasswordComponent, SsoComponentV1, TabsV2Component, - TwoFactorComponentV1, - TwoFactorOptionsComponentV1, UpdateTempPasswordComponent, UserVerificationComponent, VaultTimeoutInputComponent, diff --git a/apps/browser/src/popup/scss/misc.scss b/apps/browser/src/popup/scss/misc.scss index d1308d26180..8aace90d0a6 100644 --- a/apps/browser/src/popup/scss/misc.scss +++ b/apps/browser/src/popup/scss/misc.scss @@ -103,16 +103,6 @@ p.lead { margin: 0 !important; } -.no-vmargin { - margin-top: 0 !important; - margin-bottom: 0 !important; -} - -.no-vpad { - padding-top: 0 !important; - padding-bottom: 0 !important; -} - .display-block { display: block !important; } diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index 3bb130d321d..cd5064a87e4 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -6,7 +6,6 @@ import { DesktopDefaultOverlayPosition, EnvironmentSelectorComponent, } from "@bitwarden/angular/auth/components/environment-selector.component"; -import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap"; import { authGuard, lockGuard, @@ -53,7 +52,6 @@ import { AccessibilityCookieComponent } from "../auth/accessibility-cookie.compo import { maxAccountsGuardFn } from "../auth/guards/max-accounts.guard"; import { RemovePasswordComponent } from "../auth/remove-password.component"; import { SetPasswordComponent } from "../auth/set-password.component"; -import { TwoFactorComponentV1 } from "../auth/two-factor-v1.component"; import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component"; import { VaultComponent } from "../vault/app/vault/vault.component"; @@ -76,28 +74,6 @@ const routes: Routes = [ children: [], // Children lets us have an empty component. canActivate: [redirectGuard({ loggedIn: "/vault", loggedOut: "/login", locked: "/lock" })], }, - ...unauthUiRefreshSwap( - TwoFactorComponentV1, - AnonLayoutWrapperComponent, - { - path: "2fa", - }, - { - path: "2fa", - canActivate: [unauthGuardFn(), TwoFactorAuthGuard], - children: [ - { - path: "", - component: TwoFactorAuthComponent, - }, - ], - data: { - pageTitle: { - key: "verifyYourIdentity", - }, - } satisfies RouteDataProperties & AnonLayoutWrapperData, - }, - ), { path: "authentication-timeout", component: AnonLayoutWrapperComponent, @@ -360,6 +336,21 @@ const routes: Routes = [ }, } satisfies AnonLayoutWrapperData, }, + { + path: "2fa", + canActivate: [unauthGuardFn(), TwoFactorAuthGuard], + children: [ + { + path: "", + component: TwoFactorAuthComponent, + }, + ], + data: { + pageTitle: { + key: "verifyYourIdentity", + }, + } satisfies RouteDataProperties & AnonLayoutWrapperData, + }, ], }, ]; diff --git a/apps/desktop/src/app/app.module.ts b/apps/desktop/src/app/app.module.ts index b1b2864af5a..b717afe4a41 100644 --- a/apps/desktop/src/app/app.module.ts +++ b/apps/desktop/src/app/app.module.ts @@ -16,8 +16,6 @@ import { LoginModule } from "../auth/login/login.module"; import { RemovePasswordComponent } from "../auth/remove-password.component"; import { SetPasswordComponent } from "../auth/set-password.component"; import { SsoComponentV1 } from "../auth/sso-v1.component"; -import { TwoFactorOptionsComponentV1 } from "../auth/two-factor-options-v1.component"; -import { TwoFactorComponentV1 } from "../auth/two-factor-v1.component"; import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component"; import { SshAgentService } from "../autofill/services/ssh-agent.service"; import { PremiumComponent } from "../billing/app/accounts/premium.component"; @@ -78,9 +76,7 @@ import { SharedModule } from "./shared/shared.module"; SetPasswordComponent, SettingsComponent, ShareComponent, - TwoFactorComponentV1, SsoComponentV1, - TwoFactorOptionsComponentV1, UpdateTempPasswordComponent, VaultComponent, VaultTimeoutInputComponent, diff --git a/apps/desktop/src/auth/two-factor-options-v1.component.html b/apps/desktop/src/auth/two-factor-options-v1.component.html deleted file mode 100644 index 6f87c666215..00000000000 --- a/apps/desktop/src/auth/two-factor-options-v1.component.html +++ /dev/null @@ -1,33 +0,0 @@ - diff --git a/apps/desktop/src/auth/two-factor-options-v1.component.ts b/apps/desktop/src/auth/two-factor-options-v1.component.ts deleted file mode 100644 index 1cb440a5f5f..00000000000 --- a/apps/desktop/src/auth/two-factor-options-v1.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Component } from "@angular/core"; -import { Router } from "@angular/router"; - -import { TwoFactorOptionsComponentV1 as BaseTwoFactorOptionsComponentV1 } from "@bitwarden/angular/auth/components/two-factor-options-v1.component"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; - -@Component({ - selector: "app-two-factor-options", - templateUrl: "two-factor-options-v1.component.html", -}) -export class TwoFactorOptionsComponentV1 extends BaseTwoFactorOptionsComponentV1 { - constructor( - twoFactorService: TwoFactorService, - router: Router, - i18nService: I18nService, - platformUtilsService: PlatformUtilsService, - environmentService: EnvironmentService, - ) { - super(twoFactorService, router, i18nService, platformUtilsService, window, environmentService); - } -} diff --git a/apps/desktop/src/auth/two-factor-v1.component.html b/apps/desktop/src/auth/two-factor-v1.component.html deleted file mode 100644 index 1f65d5070f6..00000000000 --- a/apps/desktop/src/auth/two-factor-v1.component.html +++ /dev/null @@ -1,175 +0,0 @@ -
-
-
- Bitwarden -

{{ title }}

- -
- - -

- {{ "enterVerificationCodeApp" | i18n }} -

-

- {{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }} -

-
-
- - -
-
- - - {{ "sendVerificationCodeEmailAgain" | i18n }} - - -
- - - -

{{ "insertYubiKey" | i18n }}

- - - - - -
-
-
- - -
-
-
-
- - - -
-
- -
-
-
- - - -
- - {{ "duoRequiredByOrgForAccount" | i18n }} - - {{ "launchDuoAndFollowStepsToFinishLoggingIn" | i18n }} -
-
-
- -
-
-
-

{{ "noTwoStepProviders" | i18n }}

-

{{ "noTwoStepProviders2" | i18n }}

-
-
-
- -
-
-
- - -
-
-
- - -
- -
- - -
-
- -
-
- -
-
- -
-
-
- -
-
-
-
- diff --git a/apps/desktop/src/auth/two-factor-v1.component.ts b/apps/desktop/src/auth/two-factor-v1.component.ts deleted file mode 100644 index 13c7d0a452b..00000000000 --- a/apps/desktop/src/auth/two-factor-v1.component.ts +++ /dev/null @@ -1,190 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, Inject, NgZone, OnDestroy, ViewChild, ViewContainerRef } from "@angular/core"; -import { ActivatedRoute, Router } from "@angular/router"; -import { firstValueFrom } from "rxjs"; - -import { TwoFactorComponentV1 as BaseTwoFactorComponent } from "@bitwarden/angular/auth/components/two-factor-v1.component"; -import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; -import { - LoginStrategyServiceAbstraction, - LoginEmailServiceAbstraction, - UserDecryptionOptionsServiceAbstraction, -} from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; -import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; -import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; -import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.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 { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; -import { ToastService } from "@bitwarden/components"; - -import { TwoFactorOptionsComponentV1 } from "./two-factor-options-v1.component"; - -const BroadcasterSubscriptionId = "TwoFactorComponent"; - -@Component({ - selector: "app-two-factor", - templateUrl: "two-factor-v1.component.html", -}) -export class TwoFactorComponentV1 extends BaseTwoFactorComponent implements OnDestroy { - @ViewChild("twoFactorOptions", { read: ViewContainerRef, static: true }) - twoFactorOptionsModal: ViewContainerRef; - - showingModal = false; - duoCallbackSubscriptionEnabled: boolean = false; - - constructor( - loginStrategyService: LoginStrategyServiceAbstraction, - router: Router, - i18nService: I18nService, - apiService: ApiService, - platformUtilsService: PlatformUtilsService, - syncService: SyncService, - environmentService: EnvironmentService, - private broadcasterService: BroadcasterService, - private modalService: ModalService, - stateService: StateService, - private ngZone: NgZone, - route: ActivatedRoute, - logService: LogService, - twoFactorService: TwoFactorService, - appIdService: AppIdService, - loginEmailService: LoginEmailServiceAbstraction, - userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, - ssoLoginService: SsoLoginServiceAbstraction, - configService: ConfigService, - masterPasswordService: InternalMasterPasswordServiceAbstraction, - accountService: AccountService, - toastService: ToastService, - @Inject(WINDOW) protected win: Window, - ) { - super( - loginStrategyService, - router, - i18nService, - apiService, - platformUtilsService, - win, - environmentService, - stateService, - route, - logService, - twoFactorService, - appIdService, - loginEmailService, - userDecryptionOptionsService, - ssoLoginService, - configService, - masterPasswordService, - accountService, - toastService, - ); - this.onSuccessfulLogin = async () => { - // 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 - syncService.fullSync(true); - }; - - this.onSuccessfulLoginTde = async () => { - // 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 - syncService.fullSync(true); - }; - } - - async anotherMethod() { - const [modal, childComponent] = await this.modalService.openViewRef( - TwoFactorOptionsComponentV1, - this.twoFactorOptionsModal, - ); - - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - modal.onShown.subscribe(() => { - this.showingModal = true; - }); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - modal.onClosed.subscribe(() => { - this.showingModal = false; - }); - - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - childComponent.onProviderSelected.subscribe(async (provider: TwoFactorProviderType) => { - modal.close(); - this.selectedProviderType = provider; - await this.init(); - }); - // eslint-disable-next-line rxjs-angular/prefer-takeuntil - childComponent.onRecoverSelected.subscribe(() => { - modal.close(); - }); - } - - async submit() { - await super.submit(); - if (this.captchaSiteKey) { - const content = document.getElementById("content") as HTMLDivElement; - content.setAttribute("style", "width:335px"); - } - } - - protected override setupDuoResultListener() { - if (!this.duoCallbackSubscriptionEnabled) { - this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => { - await this.ngZone.run(async () => { - if (message.command === "duoCallback") { - this.token = message.code + "|" + message.state; - await this.submit(); - } - }); - }); - this.duoCallbackSubscriptionEnabled = true; - } - } - - override async launchDuoFrameless() { - if (this.duoFramelessUrl === null) { - this.toastService.showToast({ - variant: "error", - title: null, - message: this.i18nService.t("duoHealthCheckResultsInNullAuthUrlError"), - }); - return; - } - - const duoHandOffMessage = { - title: this.i18nService.t("youSuccessfullyLoggedIn"), - message: this.i18nService.t("youMayCloseThisWindow"), - isCountdown: false, - }; - - // we're using the connector here as a way to set a cookie with translations - // before continuing to the duo frameless url - const env = await firstValueFrom(this.environmentService.environment$); - const launchUrl = - env.getWebVaultUrl() + - "/duo-redirect-connector.html" + - "?duoFramelessUrl=" + - encodeURIComponent(this.duoFramelessUrl) + - "&handOffMessage=" + - encodeURIComponent(JSON.stringify(duoHandOffMessage)); - this.platformUtilsService.launchUri(launchUrl); - } - - ngOnDestroy(): void { - if (this.duoCallbackSubscriptionEnabled) { - this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); - this.duoCallbackSubscriptionEnabled = false; - } - } -} diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 07404b37fcd..42eebd98223 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -833,18 +833,6 @@ "continue": { "message": "Continue" }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -854,18 +842,9 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -873,9 +852,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -3224,9 +3200,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, diff --git a/apps/desktop/src/scss/pages.scss b/apps/desktop/src/scss/pages.scss index b9559e13a26..ecb36aae662 100644 --- a/apps/desktop/src/scss/pages.scss +++ b/apps/desktop/src/scss/pages.scss @@ -27,7 +27,6 @@ #accessibility-cookie-page, #register-page, #hint-page, -#two-factor-page, #update-temp-password-page, #remove-password-page { padding-top: 20px; @@ -48,7 +47,6 @@ #accessibility-cookie-page, #register-page, #hint-page, -#two-factor-page, #lock-page, #update-temp-password-page { .content { diff --git a/apps/web/src/app/auth/two-factor-options-v1.component.html b/apps/web/src/app/auth/two-factor-options-v1.component.html deleted file mode 100644 index 43c054060ea..00000000000 --- a/apps/web/src/app/auth/two-factor-options-v1.component.html +++ /dev/null @@ -1,45 +0,0 @@ - - - {{ "twoStepOptions" | i18n }} - - -
-
-
- -
-
-

{{ p.name }}

-

{{ p.description }}

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

{{ "recoveryCodeTitle" | i18n }}

-

{{ "recoveryCodeDesc" | i18n }}

-
-
- -
-
-
-
- - - -
diff --git a/apps/web/src/app/auth/two-factor-options-v1.component.ts b/apps/web/src/app/auth/two-factor-options-v1.component.ts deleted file mode 100644 index 08665dcfcdd..00000000000 --- a/apps/web/src/app/auth/two-factor-options-v1.component.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { DialogRef } from "@angular/cdk/dialog"; -import { Component } from "@angular/core"; -import { Router } from "@angular/router"; - -import { TwoFactorOptionsComponentV1 as BaseTwoFactorOptionsComponentV1 } from "@bitwarden/angular/auth/components/two-factor-options-v1.component"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { DialogService } from "@bitwarden/components"; - -export enum TwoFactorOptionsDialogResult { - Provider = "Provider selected", - Recover = "Recover selected", -} - -export type TwoFactorOptionsDialogResultType = { - result: TwoFactorOptionsDialogResult; - type: TwoFactorProviderType; -}; - -@Component({ - selector: "app-two-factor-options", - templateUrl: "two-factor-options-v1.component.html", -}) -export class TwoFactorOptionsComponentV1 extends BaseTwoFactorOptionsComponentV1 { - constructor( - twoFactorService: TwoFactorService, - router: Router, - i18nService: I18nService, - platformUtilsService: PlatformUtilsService, - environmentService: EnvironmentService, - private dialogRef: DialogRef, - ) { - super(twoFactorService, router, i18nService, platformUtilsService, window, environmentService); - } - - async choose(p: any) { - await super.choose(p); - this.dialogRef.close({ result: TwoFactorOptionsDialogResult.Provider, type: p.type }); - } - - async recover() { - await super.recover(); - this.dialogRef.close({ result: TwoFactorOptionsDialogResult.Recover }); - } - - static open(dialogService: DialogService) { - return dialogService.open(TwoFactorOptionsComponentV1); - } -} diff --git a/apps/web/src/app/auth/two-factor-v1.component.html b/apps/web/src/app/auth/two-factor-v1.component.html deleted file mode 100644 index b78747e04c2..00000000000 --- a/apps/web/src/app/auth/two-factor-v1.component.html +++ /dev/null @@ -1,106 +0,0 @@ -
-
- -

- {{ "enterVerificationCodeApp" | i18n }} -

-

- {{ "enterVerificationCodeEmail" | i18n: twoFactorEmail }} -

- - {{ "verificationCode" | i18n }} - - - - {{ "sendVerificationCodeEmailAgain" | i18n }} - - -
- -

{{ "insertYubiKey" | i18n }}

- - - - - - - {{ "verificationCode" | i18n }} - - -
- -
- -
-
- - -

- {{ "duoRequiredByOrgForAccount" | i18n }} -

-

{{ "launchDuoAndFollowStepsToFinishLoggingIn" | i18n }}

-
- - {{ "rememberMe" | i18n }} - - - -

{{ "noTwoStepProviders" | i18n }}

-

{{ "noTwoStepProviders2" | i18n }}

-
-
-
- -
- -
- - - - {{ "cancel" | i18n }} - -
- -
-
diff --git a/apps/web/src/app/auth/two-factor-v1.component.ts b/apps/web/src/app/auth/two-factor-v1.component.ts deleted file mode 100644 index 9a9fab02de3..00000000000 --- a/apps/web/src/app/auth/two-factor-v1.component.ts +++ /dev/null @@ -1,164 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Component, Inject, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; -import { FormBuilder, Validators } from "@angular/forms"; -import { ActivatedRoute, Router } from "@angular/router"; -import { Subject, takeUntil, lastValueFrom } from "rxjs"; - -import { TwoFactorComponentV1 as BaseTwoFactorComponent } from "@bitwarden/angular/auth/components/two-factor-v1.component"; -import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; -import { - LoginStrategyServiceAbstraction, - LoginEmailServiceAbstraction, - UserDecryptionOptionsServiceAbstraction, -} from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; -import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; -import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.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, ToastService } from "@bitwarden/components"; - -import { - TwoFactorOptionsDialogResult, - TwoFactorOptionsComponentV1, - TwoFactorOptionsDialogResultType, -} from "./two-factor-options-v1.component"; - -@Component({ - selector: "app-two-factor", - templateUrl: "two-factor-v1.component.html", -}) -export class TwoFactorComponentV1 extends BaseTwoFactorComponent implements OnInit, OnDestroy { - @ViewChild("twoFactorOptions", { read: ViewContainerRef, static: true }) - twoFactorOptionsModal: ViewContainerRef; - formGroup = this.formBuilder.group({ - token: [ - "", - { - validators: [Validators.required], - updateOn: "submit", - }, - ], - remember: [false], - }); - private destroy$ = new Subject(); - constructor( - loginStrategyService: LoginStrategyServiceAbstraction, - router: Router, - i18nService: I18nService, - apiService: ApiService, - platformUtilsService: PlatformUtilsService, - stateService: StateService, - environmentService: EnvironmentService, - private dialogService: DialogService, - route: ActivatedRoute, - logService: LogService, - twoFactorService: TwoFactorService, - appIdService: AppIdService, - loginEmailService: LoginEmailServiceAbstraction, - userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, - ssoLoginService: SsoLoginServiceAbstraction, - configService: ConfigService, - masterPasswordService: InternalMasterPasswordServiceAbstraction, - accountService: AccountService, - toastService: ToastService, - private formBuilder: FormBuilder, - @Inject(WINDOW) protected win: Window, - ) { - super( - loginStrategyService, - router, - i18nService, - apiService, - platformUtilsService, - win, - environmentService, - stateService, - route, - logService, - twoFactorService, - appIdService, - loginEmailService, - userDecryptionOptionsService, - ssoLoginService, - configService, - masterPasswordService, - accountService, - toastService, - ); - this.onSuccessfulLoginNavigate = this.goAfterLogIn; - } - async ngOnInit() { - await super.ngOnInit(); - this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((value) => { - this.token = value.token; - this.remember = value.remember; - }); - } - submitForm = async () => { - await this.submit(); - }; - - async anotherMethod() { - const dialogRef = TwoFactorOptionsComponentV1.open(this.dialogService); - const response: TwoFactorOptionsDialogResultType = await lastValueFrom(dialogRef.closed); - if (response.result === TwoFactorOptionsDialogResult.Provider) { - this.selectedProviderType = response.type; - await this.init(); - } - } - - protected override handleMigrateEncryptionKey(result: AuthResult): boolean { - if (!result.requiresEncryptionKeyMigration) { - 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(["migrate-legacy-encryption"]); - return true; - } - - goAfterLogIn = async () => { - this.loginEmailService.clearValues(); - // 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([this.successRoute], { - queryParams: { - identifier: this.orgIdentifier, - }, - }); - }; - - private duoResultChannel: BroadcastChannel; - - protected override setupDuoResultListener() { - if (!this.duoResultChannel) { - this.duoResultChannel = new BroadcastChannel("duoResult"); - this.duoResultChannel.addEventListener("message", this.handleDuoResultMessage); - } - } - - private handleDuoResultMessage = async (msg: { data: { code: string; state: string } }) => { - this.token = msg.data.code + "|" + msg.data.state; - await this.submit(); - }; - - async ngOnDestroy() { - super.ngOnDestroy(); - - if (this.duoResultChannel) { - // clean up duo listener if it was initialized. - this.duoResultChannel.removeEventListener("message", this.handleDuoResultMessage); - this.duoResultChannel.close(); - } - } -} diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index c531f358b34..0334519516a 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -2,7 +2,6 @@ import { NgModule } from "@angular/core"; import { Route, RouterModule, Routes } from "@angular/router"; import { AuthenticationTimeoutComponent } from "@bitwarden/angular/auth/components/authentication-timeout.component"; -import { unauthUiRefreshSwap } from "@bitwarden/angular/auth/functions/unauth-ui-refresh-route-swap"; import { authGuard, lockGuard, @@ -65,7 +64,6 @@ import { AccountComponent } from "./auth/settings/account/account.component"; import { EmergencyAccessComponent } from "./auth/settings/emergency-access/emergency-access.component"; import { EmergencyAccessViewComponent } from "./auth/settings/emergency-access/view/emergency-access-view.component"; import { SecurityRoutingModule } from "./auth/settings/security/security-routing.module"; -import { TwoFactorComponentV1 } from "./auth/two-factor-v1.component"; import { UpdatePasswordComponent } from "./auth/update-password.component"; import { UpdateTempPasswordComponent } from "./auth/update-temp-password.component"; import { VerifyEmailTokenComponent } from "./auth/verify-email-token.component"; @@ -378,51 +376,28 @@ const routes: Routes = [ }, ], }, - ...unauthUiRefreshSwap( - TwoFactorComponentV1, - TwoFactorAuthComponent, - { - path: "2fa", - canActivate: [unauthGuardFn()], - children: [ - { - path: "", - component: TwoFactorComponentV1, - }, - { - path: "", - component: EnvironmentSelectorComponent, - outlet: "environment-selector", - }, - ], - data: { - pageTitle: { - key: "verifyYourIdentity", - }, - } satisfies RouteDataProperties & AnonLayoutWrapperData, - }, - { - path: "2fa", - canActivate: [unauthGuardFn(), TwoFactorAuthGuard], - children: [ - { - path: "", - component: TwoFactorAuthComponent, - }, - { - path: "", - component: EnvironmentSelectorComponent, - outlet: "environment-selector", - }, - ], - data: { - pageTitle: { - key: "verifyYourIdentity", - }, - titleAreaMaxWidth: "md", - } satisfies RouteDataProperties & AnonLayoutWrapperData, - }, - ), + { + path: "2fa", + component: TwoFactorAuthComponent, + canActivate: [unauthGuardFn(), TwoFactorAuthGuard], + children: [ + { + path: "", + component: TwoFactorAuthComponent, + }, + { + path: "", + component: EnvironmentSelectorComponent, + outlet: "environment-selector", + }, + ], + data: { + pageTitle: { + key: "verifyYourIdentity", + }, + titleAreaMaxWidth: "md", + } satisfies RouteDataProperties & AnonLayoutWrapperData, + }, { path: "lock", canActivate: [deepLinkGuard(), lockGuard()], diff --git a/apps/web/src/app/shared/loose-components.module.ts b/apps/web/src/app/shared/loose-components.module.ts index f21a9338491..70dbf63f1f8 100644 --- a/apps/web/src/app/shared/loose-components.module.ts +++ b/apps/web/src/app/shared/loose-components.module.ts @@ -43,8 +43,6 @@ import { TwoFactorSetupComponent } from "../auth/settings/two-factor/two-factor- import { TwoFactorVerifyComponent } from "../auth/settings/two-factor/two-factor-verify.component"; import { UserVerificationModule } from "../auth/shared/components/user-verification"; import { SsoComponentV1 } from "../auth/sso-v1.component"; -import { TwoFactorOptionsComponentV1 } from "../auth/two-factor-options-v1.component"; -import { TwoFactorComponentV1 } from "../auth/two-factor-v1.component"; import { UpdatePasswordComponent } from "../auth/update-password.component"; import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component"; import { VerifyEmailTokenComponent } from "../auth/verify-email-token.component"; @@ -148,12 +146,10 @@ import { SharedModule } from "./shared.module"; SetPasswordComponent, SponsoredFamiliesComponent, SponsoringOrgRowComponent, - TwoFactorComponentV1, SsoComponentV1, TwoFactorSetupAuthenticatorComponent, TwoFactorSetupDuoComponent, TwoFactorSetupEmailComponent, - TwoFactorOptionsComponentV1, TwoFactorRecoveryComponent, TwoFactorSetupComponent, TwoFactorVerifyComponent, @@ -210,12 +206,10 @@ import { SharedModule } from "./shared.module"; SetPasswordComponent, SponsoredFamiliesComponent, SponsoringOrgRowComponent, - TwoFactorComponentV1, SsoComponentV1, TwoFactorSetupAuthenticatorComponent, TwoFactorSetupDuoComponent, TwoFactorSetupEmailComponent, - TwoFactorOptionsComponentV1, TwoFactorSetupComponent, TwoFactorVerifyComponent, TwoFactorSetupWebAuthnComponent, diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index b9ead1df44d..4133062a047 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -1456,18 +1456,6 @@ } } }, - "enterVerificationCodeApp": { - "message": "Enter the 6 digit verification code from your authenticator app." - }, - "enterVerificationCodeEmail": { - "message": "Enter the 6 digit verification code that was emailed to $EMAIL$.", - "placeholders": { - "email": { - "content": "$1", - "example": "example@gmail.com" - } - } - }, "verificationCodeEmailSent": { "message": "Verification email sent to $EMAIL$.", "placeholders": { @@ -1477,18 +1465,10 @@ } } }, - "rememberMe": { - "message": "Remember me" - }, + "dontAskAgainOnThisDeviceFor30Days": { "message": "Don't ask again on this device for 30 days" }, - "sendVerificationCodeEmailAgain": { - "message": "Send verification code email again" - }, - "useAnotherTwoStepMethod": { - "message": "Use another two-step login method" - }, "selectAnotherMethod": { "message": "Select another method", "description": "Select another two-step login method" @@ -1496,9 +1476,6 @@ "useYourRecoveryCode": { "message": "Use your recovery code" }, - "insertYubiKey": { - "message": "Insert your YubiKey into your computer's USB port, then touch its button." - }, "insertU2f": { "message": "Insert your security key into your computer's USB port. If it has a button, touch it." }, @@ -7273,9 +7250,6 @@ "duoHealthCheckResultsInNullAuthUrlError": { "message": "Error connecting with the Duo service. Use a different two-step login method or contact Duo for assistance." }, - "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." - }, "duoRequiredByOrgForAccount": { "message": "Duo two-step login is required for your account." }, diff --git a/libs/angular/src/auth/components/two-factor-options-v1.component.ts b/libs/angular/src/auth/components/two-factor-options-v1.component.ts deleted file mode 100644 index f02eabcc156..00000000000 --- a/libs/angular/src/auth/components/two-factor-options-v1.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Directive, EventEmitter, OnInit, Output } from "@angular/core"; -import { Router } from "@angular/router"; -import { firstValueFrom } from "rxjs"; - -import { - TwoFactorProviderDetails, - TwoFactorService, -} from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; - -@Directive() -export class TwoFactorOptionsComponentV1 implements OnInit { - @Output() onProviderSelected = new EventEmitter(); - @Output() onRecoverSelected = new EventEmitter(); - - providers: any[] = []; - - constructor( - protected twoFactorService: TwoFactorService, - protected router: Router, - protected i18nService: I18nService, - protected platformUtilsService: PlatformUtilsService, - protected win: Window, - protected environmentService: EnvironmentService, - ) {} - - async ngOnInit() { - this.providers = await this.twoFactorService.getSupportedProviders(this.win); - } - - async choose(p: TwoFactorProviderDetails) { - this.onProviderSelected.emit(p.type); - } - - async recover() { - const env = await firstValueFrom(this.environmentService.environment$); - const webVault = env.getWebVaultUrl(); - this.platformUtilsService.launchUri(webVault + "/#/recover-2fa"); - this.onRecoverSelected.emit(); - } -} diff --git a/libs/angular/src/auth/components/two-factor-v1.component.spec.ts b/libs/angular/src/auth/components/two-factor-v1.component.spec.ts deleted file mode 100644 index 47075acc758..00000000000 --- a/libs/angular/src/auth/components/two-factor-v1.component.spec.ts +++ /dev/null @@ -1,505 +0,0 @@ -import { Component } from "@angular/core"; -import { ComponentFixture, TestBed } from "@angular/core/testing"; -import { ActivatedRoute, convertToParamMap, Router } from "@angular/router"; -import { mock, MockProxy } from "jest-mock-extended"; -import { BehaviorSubject } from "rxjs"; - -import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; -import { - LoginStrategyServiceAbstraction, - LoginEmailServiceAbstraction, - FakeKeyConnectorUserDecryptionOption as KeyConnectorUserDecryptionOption, - FakeTrustedDeviceUserDecryptionOption as TrustedDeviceUserDecryptionOption, - FakeUserDecryptionOptions as UserDecryptionOptions, - UserDecryptionOptionsServiceAbstraction, -} from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; -import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; -import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request"; -import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; -import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service"; -import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.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 { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; -import { UserId } from "@bitwarden/common/types/guid"; -import { ToastService } from "@bitwarden/components"; - -import { TwoFactorComponentV1 } from "./two-factor-v1.component"; - -// test component that extends the TwoFactorComponent -@Component({}) -class TestTwoFactorComponent extends TwoFactorComponentV1 {} - -interface TwoFactorComponentProtected { - trustedDeviceEncRoute: string; - changePasswordRoute: string; - forcePasswordResetRoute: string; - successRoute: string; -} - -describe("TwoFactorComponent", () => { - let component: TestTwoFactorComponent; - let _component: TwoFactorComponentProtected; - - let fixture: ComponentFixture; - const userId = "userId" as UserId; - - // Mock Services - let mockLoginStrategyService: MockProxy; - let mockRouter: MockProxy; - let mockI18nService: MockProxy; - let mockApiService: MockProxy; - let mockPlatformUtilsService: MockProxy; - let mockWin: MockProxy; - let mockEnvironmentService: MockProxy; - let mockStateService: MockProxy; - let mockLogService: MockProxy; - let mockTwoFactorService: MockProxy; - let mockAppIdService: MockProxy; - let mockLoginEmailService: MockProxy; - let mockUserDecryptionOptionsService: MockProxy; - let mockSsoLoginService: MockProxy; - let mockConfigService: MockProxy; - let mockMasterPasswordService: FakeMasterPasswordService; - let mockAccountService: FakeAccountService; - let mockToastService: MockProxy; - - let mockUserDecryptionOpts: { - noMasterPassword: UserDecryptionOptions; - withMasterPassword: UserDecryptionOptions; - withMasterPasswordAndTrustedDevice: UserDecryptionOptions; - withMasterPasswordAndTrustedDeviceWithManageResetPassword: UserDecryptionOptions; - withMasterPasswordAndKeyConnector: UserDecryptionOptions; - noMasterPasswordWithTrustedDevice: UserDecryptionOptions; - noMasterPasswordWithTrustedDeviceWithManageResetPassword: UserDecryptionOptions; - noMasterPasswordWithKeyConnector: UserDecryptionOptions; - }; - - let selectedUserDecryptionOptions: BehaviorSubject; - let authenticationSessionTimeoutSubject: BehaviorSubject; - - beforeEach(() => { - authenticationSessionTimeoutSubject = new BehaviorSubject(false); - mockLoginStrategyService = mock(); - mockLoginStrategyService.authenticationSessionTimeout$ = authenticationSessionTimeoutSubject; - mockRouter = mock(); - mockI18nService = mock(); - mockApiService = mock(); - mockPlatformUtilsService = mock(); - mockWin = mock(); - mockEnvironmentService = mock(); - mockStateService = mock(); - mockLogService = mock(); - mockTwoFactorService = mock(); - mockAppIdService = mock(); - mockLoginEmailService = mock(); - mockUserDecryptionOptionsService = mock(); - mockSsoLoginService = mock(); - mockConfigService = mock(); - mockAccountService = mockAccountServiceWith(userId); - mockToastService = mock(); - mockMasterPasswordService = new FakeMasterPasswordService(); - - mockUserDecryptionOpts = { - noMasterPassword: new UserDecryptionOptions({ - hasMasterPassword: false, - trustedDeviceOption: undefined, - keyConnectorOption: undefined, - }), - withMasterPassword: new UserDecryptionOptions({ - hasMasterPassword: true, - trustedDeviceOption: undefined, - keyConnectorOption: undefined, - }), - withMasterPasswordAndTrustedDevice: new UserDecryptionOptions({ - hasMasterPassword: true, - trustedDeviceOption: new TrustedDeviceUserDecryptionOption(true, false, false, false), - keyConnectorOption: undefined, - }), - withMasterPasswordAndTrustedDeviceWithManageResetPassword: new UserDecryptionOptions({ - hasMasterPassword: true, - trustedDeviceOption: new TrustedDeviceUserDecryptionOption(true, false, true, false), - keyConnectorOption: undefined, - }), - withMasterPasswordAndKeyConnector: new UserDecryptionOptions({ - hasMasterPassword: true, - trustedDeviceOption: undefined, - keyConnectorOption: new KeyConnectorUserDecryptionOption("http://example.com"), - }), - noMasterPasswordWithTrustedDevice: new UserDecryptionOptions({ - hasMasterPassword: false, - trustedDeviceOption: new TrustedDeviceUserDecryptionOption(true, false, false, false), - keyConnectorOption: undefined, - }), - noMasterPasswordWithTrustedDeviceWithManageResetPassword: new UserDecryptionOptions({ - hasMasterPassword: false, - trustedDeviceOption: new TrustedDeviceUserDecryptionOption(true, false, true, false), - keyConnectorOption: undefined, - }), - noMasterPasswordWithKeyConnector: new UserDecryptionOptions({ - hasMasterPassword: false, - trustedDeviceOption: undefined, - keyConnectorOption: new KeyConnectorUserDecryptionOption("http://example.com"), - }), - }; - - selectedUserDecryptionOptions = new BehaviorSubject( - mockUserDecryptionOpts.withMasterPassword, - ); - mockUserDecryptionOptionsService.userDecryptionOptions$ = selectedUserDecryptionOptions; - - TestBed.configureTestingModule({ - declarations: [TestTwoFactorComponent], - providers: [ - { provide: LoginStrategyServiceAbstraction, useValue: mockLoginStrategyService }, - { provide: Router, useValue: mockRouter }, - { provide: I18nService, useValue: mockI18nService }, - { provide: ApiService, useValue: mockApiService }, - { provide: PlatformUtilsService, useValue: mockPlatformUtilsService }, - { provide: WINDOW, useValue: mockWin }, - { provide: EnvironmentService, useValue: mockEnvironmentService }, - { provide: StateService, useValue: mockStateService }, - { - provide: ActivatedRoute, - useValue: { - snapshot: { - // Default to standard 2FA flow - not SSO + 2FA - queryParamMap: convertToParamMap({ sso: "false" }), - }, - }, - }, - { provide: LogService, useValue: mockLogService }, - { provide: TwoFactorService, useValue: mockTwoFactorService }, - { provide: AppIdService, useValue: mockAppIdService }, - { provide: LoginEmailServiceAbstraction, useValue: mockLoginEmailService }, - { - provide: UserDecryptionOptionsServiceAbstraction, - useValue: mockUserDecryptionOptionsService, - }, - { provide: SsoLoginServiceAbstraction, useValue: mockSsoLoginService }, - { provide: ConfigService, useValue: mockConfigService }, - { provide: InternalMasterPasswordServiceAbstraction, useValue: mockMasterPasswordService }, - { provide: AccountService, useValue: mockAccountService }, - { provide: ToastService, useValue: mockToastService }, - ], - }); - - fixture = TestBed.createComponent(TestTwoFactorComponent); - component = fixture.componentInstance; - _component = component as any; - }); - - afterEach(() => { - // Reset all mocks after each test - jest.resetAllMocks(); - }); - - it("should create", () => { - expect(component).toBeTruthy(); - }); - - // Shared tests - const testChangePasswordOnSuccessfulLogin = () => { - it("navigates to the component's defined change password route when user doesn't have a MP and key connector isn't enabled", async () => { - // Act - await component.doSubmit(); - - // Assert - expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate).toHaveBeenCalledWith([_component.changePasswordRoute], { - queryParams: { - identifier: component.orgIdentifier, - }, - }); - }); - }; - - const testForceResetOnSuccessfulLogin = (reasonString: string) => { - it(`navigates to the component's defined forcePasswordResetRoute route when response.forcePasswordReset is ${reasonString}`, async () => { - // Act - await component.doSubmit(); - - // expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate).toHaveBeenCalledWith([_component.forcePasswordResetRoute], { - queryParams: { - identifier: component.orgIdentifier, - }, - }); - }); - }; - - describe("Standard 2FA scenarios", () => { - describe("doSubmit", () => { - const token = "testToken"; - const remember = false; - const captchaToken = "testCaptchaToken"; - - beforeEach(() => { - component.token = token; - component.remember = remember; - component.captchaToken = captchaToken; - - selectedUserDecryptionOptions.next(mockUserDecryptionOpts.withMasterPassword); - }); - - it("calls authService.logInTwoFactor with correct parameters when form is submitted", async () => { - // Arrange - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(new AuthResult()); - - // Act - await component.doSubmit(); - - // Assert - expect(mockLoginStrategyService.logInTwoFactor).toHaveBeenCalledWith( - new TokenTwoFactorRequest(component.selectedProviderType, token, remember), - captchaToken, - ); - }); - - it("should return when handleCaptchaRequired returns true", async () => { - // Arrange - const captchaSiteKey = "testCaptchaSiteKey"; - const authResult = new AuthResult(); - authResult.captchaSiteKey = captchaSiteKey; - - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(authResult); - - // Note: the any casts are required b/c typescript cant recognize that - // handleCaptureRequired is a method on TwoFactorComponent b/c it is inherited - // from the CaptchaProtectedComponent - const handleCaptchaRequiredSpy = jest - .spyOn(component, "handleCaptchaRequired") - .mockReturnValue(true); - - // Act - const result = await component.doSubmit(); - - // Assert - expect(handleCaptchaRequiredSpy).toHaveBeenCalled(); - expect(result).toBeUndefined(); - }); - - it("calls onSuccessfulLogin when defined", async () => { - // Arrange - component.onSuccessfulLogin = jest.fn().mockResolvedValue(undefined); - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(new AuthResult()); - - // Act - await component.doSubmit(); - - // Assert - expect(component.onSuccessfulLogin).toHaveBeenCalled(); - }); - - it("calls loginEmailService.clearValues() when login is successful", async () => { - // Arrange - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(new AuthResult()); - // spy on loginEmailService.clearValues - const clearValuesSpy = jest.spyOn(mockLoginEmailService, "clearValues"); - - // Act - await component.doSubmit(); - - // Assert - expect(clearValuesSpy).toHaveBeenCalled(); - }); - - describe("Set Master Password scenarios", () => { - beforeEach(() => { - const authResult = new AuthResult(); - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(authResult); - }); - - describe("Given user needs to set a master password", () => { - beforeEach(() => { - // Only need to test the case where the user has no master password to test the primary change mp flow here - selectedUserDecryptionOptions.next(mockUserDecryptionOpts.noMasterPassword); - }); - - testChangePasswordOnSuccessfulLogin(); - }); - - it("does not navigate to the change password route when the user has key connector even if user has no master password", async () => { - selectedUserDecryptionOptions.next( - mockUserDecryptionOpts.noMasterPasswordWithKeyConnector, - ); - - await component.doSubmit(); - - expect(mockRouter.navigate).not.toHaveBeenCalledWith([_component.changePasswordRoute], { - queryParams: { - identifier: component.orgIdentifier, - }, - }); - }); - }); - - describe("Force Master Password Reset scenarios", () => { - [ - ForceSetPasswordReason.AdminForcePasswordReset, - ForceSetPasswordReason.WeakMasterPassword, - ].forEach((forceResetPasswordReason) => { - const reasonString = ForceSetPasswordReason[forceResetPasswordReason]; - - beforeEach(() => { - // use standard user with MP because this test is not concerned with password reset. - selectedUserDecryptionOptions.next(mockUserDecryptionOpts.withMasterPassword); - - const authResult = new AuthResult(); - authResult.forcePasswordReset = forceResetPasswordReason; - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(authResult); - }); - - testForceResetOnSuccessfulLogin(reasonString); - }); - }); - - it("calls onSuccessfulLoginNavigate when the callback is defined", async () => { - // Arrange - component.onSuccessfulLoginNavigate = jest.fn().mockResolvedValue(undefined); - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(new AuthResult()); - - // Act - await component.doSubmit(); - - // Assert - expect(component.onSuccessfulLoginNavigate).toHaveBeenCalled(); - }); - - it("navigates to the component's defined success route when the login is successful and onSuccessfulLoginNavigate is undefined", async () => { - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(new AuthResult()); - - // Act - await component.doSubmit(); - - // Assert - expect(component.onSuccessfulLoginNavigate).not.toBeDefined(); - - expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate).toHaveBeenCalledWith([_component.successRoute], undefined); - }); - }); - }); - - describe("SSO > 2FA scenarios", () => { - beforeEach(() => { - const mockActivatedRoute = TestBed.inject(ActivatedRoute); - mockActivatedRoute.snapshot.queryParamMap.get = jest.fn().mockReturnValue("true"); - }); - - describe("doSubmit", () => { - const token = "testToken"; - const remember = false; - const captchaToken = "testCaptchaToken"; - - beforeEach(() => { - component.token = token; - component.remember = remember; - component.captchaToken = captchaToken; - }); - - describe("Trusted Device Encryption scenarios", () => { - beforeEach(() => { - mockConfigService.getFeatureFlag.mockResolvedValue(true); - }); - - describe("Given Trusted Device Encryption is enabled and user needs to set a master password", () => { - beforeEach(() => { - selectedUserDecryptionOptions.next( - mockUserDecryptionOpts.noMasterPasswordWithTrustedDeviceWithManageResetPassword, - ); - - const authResult = new AuthResult(); - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(authResult); - }); - - it("navigates to the component's defined trusted device encryption route and sets correct flag when user doesn't have a MP and key connector isn't enabled", async () => { - // Act - await component.doSubmit(); - - // Assert - expect(mockMasterPasswordService.mock.setForceSetPasswordReason).toHaveBeenCalledWith( - ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission, - userId, - ); - - expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate).toHaveBeenCalledWith( - [_component.trustedDeviceEncRoute], - undefined, - ); - }); - }); - - describe("Given Trusted Device Encryption is enabled, user doesn't need to set a MP, and forcePasswordReset is required", () => { - [ - ForceSetPasswordReason.AdminForcePasswordReset, - ForceSetPasswordReason.WeakMasterPassword, - ].forEach((forceResetPasswordReason) => { - const reasonString = ForceSetPasswordReason[forceResetPasswordReason]; - - beforeEach(() => { - // use standard user with MP because this test is not concerned with password reset. - selectedUserDecryptionOptions.next( - mockUserDecryptionOpts.withMasterPasswordAndTrustedDevice, - ); - - const authResult = new AuthResult(); - authResult.forcePasswordReset = forceResetPasswordReason; - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(authResult); - }); - - testForceResetOnSuccessfulLogin(reasonString); - }); - }); - - describe("Given Trusted Device Encryption is enabled, user doesn't need to set a MP, and forcePasswordReset is not required", () => { - let authResult; - beforeEach(() => { - selectedUserDecryptionOptions.next( - mockUserDecryptionOpts.withMasterPasswordAndTrustedDevice, - ); - - authResult = new AuthResult(); - authResult.forcePasswordReset = ForceSetPasswordReason.None; - mockLoginStrategyService.logInTwoFactor.mockResolvedValue(authResult); - }); - - it("navigates to the component's defined trusted device encryption route when login is successful and onSuccessfulLoginTdeNavigate is undefined", async () => { - await component.doSubmit(); - - expect(mockRouter.navigate).toHaveBeenCalledTimes(1); - expect(mockRouter.navigate).toHaveBeenCalledWith( - [_component.trustedDeviceEncRoute], - undefined, - ); - }); - - it("calls onSuccessfulLoginTdeNavigate instead of router.navigate when the callback is defined", async () => { - component.onSuccessfulLoginTdeNavigate = jest.fn().mockResolvedValue(undefined); - - await component.doSubmit(); - - expect(mockRouter.navigate).not.toHaveBeenCalled(); - expect(component.onSuccessfulLoginTdeNavigate).toHaveBeenCalled(); - }); - }); - }); - }); - }); - - it("navigates to the timeout route when timeout expires", async () => { - authenticationSessionTimeoutSubject.next(true); - - expect(mockRouter.navigate).toHaveBeenCalledWith(["authentication-timeout"]); - }); -}); diff --git a/libs/angular/src/auth/components/two-factor-v1.component.ts b/libs/angular/src/auth/components/two-factor-v1.component.ts deleted file mode 100644 index 3fda2685f5e..00000000000 --- a/libs/angular/src/auth/components/two-factor-v1.component.ts +++ /dev/null @@ -1,514 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { Directive, Inject, OnInit, OnDestroy } from "@angular/core"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { ActivatedRoute, NavigationExtras, Router } from "@angular/router"; -import { firstValueFrom } from "rxjs"; -import { first } from "rxjs/operators"; - -import { WINDOW } from "@bitwarden/angular/services/injection-tokens"; -import { - LoginStrategyServiceAbstraction, - LoginEmailServiceAbstraction, - TrustedDeviceUserDecryptionOption, - UserDecryptionOptions, - UserDecryptionOptionsServiceAbstraction, -} from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; -import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type"; -import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; -import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; -import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; -import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request"; -import { TwoFactorEmailRequest } from "@bitwarden/common/auth/models/request/two-factor-email.request"; -import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.service"; -import { WebAuthnIFrame } from "@bitwarden/common/auth/webauthn-iframe"; -import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; -import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.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 { ToastService } from "@bitwarden/components"; - -import { CaptchaProtectedComponent } from "./captcha-protected.component"; - -@Directive() -export class TwoFactorComponentV1 extends CaptchaProtectedComponent implements OnInit, OnDestroy { - token = ""; - remember = false; - webAuthnReady = false; - webAuthnNewTab = false; - providers = TwoFactorProviders; - providerType = TwoFactorProviderType; - selectedProviderType: TwoFactorProviderType = TwoFactorProviderType.Authenticator; - webAuthnSupported = false; - webAuthn: WebAuthnIFrame = null; - title = ""; - twoFactorEmail: string = null; - formPromise: Promise; - emailPromise: Promise; - orgIdentifier: string = null; - - duoFramelessUrl: string = null; - duoResultListenerInitialized = false; - - onSuccessfulLogin: () => Promise; - onSuccessfulLoginNavigate: () => Promise; - - onSuccessfulLoginTde: () => Promise; - onSuccessfulLoginTdeNavigate: () => Promise; - - protected loginRoute = "login"; - - protected trustedDeviceEncRoute = "login-initiated"; - protected changePasswordRoute = "set-password"; - protected forcePasswordResetRoute = "update-temp-password"; - protected successRoute = "vault"; - protected twoFactorTimeoutRoute = "authentication-timeout"; - - get isDuoProvider(): boolean { - return ( - this.selectedProviderType === TwoFactorProviderType.Duo || - this.selectedProviderType === TwoFactorProviderType.OrganizationDuo - ); - } - - constructor( - protected loginStrategyService: LoginStrategyServiceAbstraction, - protected router: Router, - protected i18nService: I18nService, - protected apiService: ApiService, - protected platformUtilsService: PlatformUtilsService, - @Inject(WINDOW) protected win: Window, - protected environmentService: EnvironmentService, - protected stateService: StateService, - protected route: ActivatedRoute, - protected logService: LogService, - protected twoFactorService: TwoFactorService, - protected appIdService: AppIdService, - protected loginEmailService: LoginEmailServiceAbstraction, - protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, - protected ssoLoginService: SsoLoginServiceAbstraction, - protected configService: ConfigService, - protected masterPasswordService: InternalMasterPasswordServiceAbstraction, - protected accountService: AccountService, - protected toastService: ToastService, - ) { - super(environmentService, i18nService, platformUtilsService, toastService); - - this.webAuthnSupported = this.platformUtilsService.supportsWebAuthn(win); - - // Add subscription to authenticationSessionTimeout$ and navigate to twoFactorTimeoutRoute if expired - this.loginStrategyService.authenticationSessionTimeout$ - .pipe(takeUntilDestroyed()) - .subscribe(async (expired) => { - if (!expired) { - return; - } - - try { - await this.router.navigate([this.twoFactorTimeoutRoute]); - } catch (err) { - this.logService.error(`Failed to navigate to ${this.twoFactorTimeoutRoute} route`, err); - } - }); - } - - async ngOnInit() { - if (!(await this.authing()) || (await this.twoFactorService.getProviders()) == 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([this.loginRoute]); - return; - } - - this.route.queryParams.pipe(first()).subscribe((qParams) => { - if (qParams.identifier != null) { - this.orgIdentifier = qParams.identifier; - } - }); - - if (await this.needsLock()) { - this.successRoute = "lock"; - } - - if (this.win != null && this.webAuthnSupported) { - const env = await firstValueFrom(this.environmentService.environment$); - const webVaultUrl = env.getWebVaultUrl(); - this.webAuthn = new WebAuthnIFrame( - this.win, - webVaultUrl, - this.webAuthnNewTab, - this.platformUtilsService, - this.i18nService, - (token: string) => { - this.token = token; - // 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.submit(); - }, - (error: string) => { - this.toastService.showToast({ - variant: "error", - title: this.i18nService.t("errorOccurred"), - message: this.i18nService.t("webauthnCancelOrTimeout"), - }); - }, - (info: string) => { - if (info === "ready") { - this.webAuthnReady = true; - } - }, - ); - } - - this.selectedProviderType = await this.twoFactorService.getDefaultProvider( - this.webAuthnSupported, - ); - await this.init(); - } - - ngOnDestroy(): void { - this.cleanupWebAuthn(); - this.webAuthn = null; - } - - async init() { - if (this.selectedProviderType == null) { - this.title = this.i18nService.t("loginUnavailable"); - return; - } - - this.cleanupWebAuthn(); - this.title = (TwoFactorProviders as any)[this.selectedProviderType].name; - const providerData = await this.twoFactorService.getProviders().then((providers) => { - return providers.get(this.selectedProviderType); - }); - switch (this.selectedProviderType) { - case TwoFactorProviderType.WebAuthn: - if (!this.webAuthnNewTab) { - setTimeout(async () => { - await this.authWebAuthn(); - }, 500); - } - break; - case TwoFactorProviderType.Duo: - case TwoFactorProviderType.OrganizationDuo: - // Setup listener for duo-redirect.ts connector to send back the code - if (!this.duoResultListenerInitialized) { - // setup client specific duo result listener - this.setupDuoResultListener(); - this.duoResultListenerInitialized = true; - } - // flow must be launched by user so they can choose to remember the device or not. - this.duoFramelessUrl = providerData.AuthUrl; - break; - case TwoFactorProviderType.Email: - this.twoFactorEmail = providerData.Email; - if ((await this.twoFactorService.getProviders()).size > 1) { - await this.sendEmail(false); - } - break; - default: - break; - } - } - - async submit() { - await this.setupCaptcha(); - - if (this.token == null || this.token === "") { - this.toastService.showToast({ - variant: "error", - title: this.i18nService.t("errorOccurred"), - message: this.i18nService.t("verificationCodeRequired"), - }); - return; - } - - if (this.selectedProviderType === TwoFactorProviderType.WebAuthn) { - if (this.webAuthn != null) { - this.webAuthn.stop(); - } else { - return; - } - } else if ( - this.selectedProviderType === TwoFactorProviderType.Email || - this.selectedProviderType === TwoFactorProviderType.Authenticator - ) { - this.token = this.token.replace(" ", "").trim(); - } - - await this.doSubmit(); - if (this.selectedProviderType === TwoFactorProviderType.WebAuthn && this.webAuthn != null) { - this.webAuthn.start(); - } - } - - async doSubmit() { - this.formPromise = this.loginStrategyService.logInTwoFactor( - new TokenTwoFactorRequest(this.selectedProviderType, this.token, this.remember), - this.captchaToken, - ); - const authResult: AuthResult = await this.formPromise; - - await this.handleLoginResponse(authResult); - } - - protected handleMigrateEncryptionKey(result: AuthResult): boolean { - if (!result.requiresEncryptionKeyMigration) { - return false; - } - - this.toastService.showToast({ - variant: "error", - title: this.i18nService.t("errorOccured"), - message: this.i18nService.t("encryptionKeyMigrationRequired"), - }); - return true; - } - - // Each client will have own implementation - protected setupDuoResultListener(): void {} - - private async handleLoginResponse(authResult: AuthResult) { - if (this.handleCaptchaRequired(authResult)) { - return; - } else if (this.handleMigrateEncryptionKey(authResult)) { - return; - } - - // Save off the OrgSsoIdentifier for use in the TDE flows - // - TDE login decryption options component - // - Browser SSO on extension open - const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; - await this.ssoLoginService.setActiveUserOrganizationSsoIdentifier(this.orgIdentifier, userId); - this.loginEmailService.clearValues(); - - // note: this flow affects both TDE & standard users - if (this.isForcePasswordResetRequired(authResult)) { - return await this.handleForcePasswordReset(this.orgIdentifier); - } - - const userDecryptionOpts = await firstValueFrom( - this.userDecryptionOptionsService.userDecryptionOptions$, - ); - - const tdeEnabled = await this.isTrustedDeviceEncEnabled(userDecryptionOpts.trustedDeviceOption); - - if (tdeEnabled) { - return await this.handleTrustedDeviceEncryptionEnabled( - authResult, - this.orgIdentifier, - userDecryptionOpts, - ); - } - - // User must set password if they don't have one and they aren't using either TDE or key connector. - const requireSetPassword = - !userDecryptionOpts.hasMasterPassword && userDecryptionOpts.keyConnectorOption === undefined; - - if (requireSetPassword || authResult.resetMasterPassword) { - // Change implies going no password -> password in this case - return await this.handleChangePasswordRequired(this.orgIdentifier); - } - - return await this.handleSuccessfulLogin(); - } - - private async isTrustedDeviceEncEnabled( - trustedDeviceOption: TrustedDeviceUserDecryptionOption, - ): Promise { - const ssoTo2faFlowActive = this.route.snapshot.queryParamMap.get("sso") === "true"; - - return ssoTo2faFlowActive && trustedDeviceOption !== undefined; - } - - private async handleTrustedDeviceEncryptionEnabled( - authResult: AuthResult, - orgIdentifier: string, - userDecryptionOpts: UserDecryptionOptions, - ): Promise { - // If user doesn't have a MP, but has reset password permission, they must set a MP - if ( - !userDecryptionOpts.hasMasterPassword && - userDecryptionOpts.trustedDeviceOption.hasManageResetPasswordPermission - ) { - // Set flag so that auth guard can redirect to set password screen after decryption (trusted or untrusted device) - // Note: we cannot directly navigate to the set password screen in this scenario as we are in a pre-decryption state, and - // if you try to set a new MP before decrypting, you will invalidate the user's data by making a new user key. - const userId = (await firstValueFrom(this.accountService.activeAccount$))?.id; - await this.masterPasswordService.setForceSetPasswordReason( - ForceSetPasswordReason.TdeUserWithoutPasswordHasPasswordResetPermission, - userId, - ); - } - - if (this.onSuccessfulLoginTde != null) { - // Note: awaiting this will currently cause a hang on desktop & browser as they will wait for a full sync to complete - // before navigating to the success route. - // 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.onSuccessfulLoginTde(); - } - - // 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.navigateViaCallbackOrRoute( - this.onSuccessfulLoginTdeNavigate, - // Navigate to TDE page (if user was on trusted device and TDE has decrypted - // their user key, the login-initiated guard will redirect them to the vault) - [this.trustedDeviceEncRoute], - ); - } - - private async handleChangePasswordRequired(orgIdentifier: string) { - await this.router.navigate([this.changePasswordRoute], { - queryParams: { - identifier: orgIdentifier, - }, - }); - } - - /** - * Determines if a user needs to reset their password based on certain conditions. - * Users can be forced to reset their password via an admin or org policy disallowing weak passwords. - * Note: this is different from the SSO component login flow as a user can - * login with MP and then have to pass 2FA to finish login and we can actually - * evaluate if they have a weak password at that time. - * - * @param {AuthResult} authResult - The authentication result. - * @returns {boolean} Returns true if a password reset is required, false otherwise. - */ - private isForcePasswordResetRequired(authResult: AuthResult): boolean { - const forceResetReasons = [ - ForceSetPasswordReason.AdminForcePasswordReset, - ForceSetPasswordReason.WeakMasterPassword, - ]; - - return forceResetReasons.includes(authResult.forcePasswordReset); - } - - private async handleForcePasswordReset(orgIdentifier: string) { - // 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([this.forcePasswordResetRoute], { - queryParams: { - identifier: orgIdentifier, - }, - }); - } - - private async handleSuccessfulLogin() { - if (this.onSuccessfulLogin != null) { - // Note: awaiting this will currently cause a hang on desktop & browser as they will wait for a full sync to complete - // before navigating to the success route. - // 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.onSuccessfulLogin(); - } - await this.navigateViaCallbackOrRoute(this.onSuccessfulLoginNavigate, [this.successRoute]); - } - - private async navigateViaCallbackOrRoute( - callback: () => Promise, - commands: unknown[], - extras?: NavigationExtras, - ): Promise { - if (callback) { - await callback(); - } else { - await this.router.navigate(commands, extras); - } - } - - async sendEmail(doToast: boolean) { - if (this.selectedProviderType !== TwoFactorProviderType.Email) { - return; - } - - if (this.emailPromise != null) { - return; - } - - if ((await this.loginStrategyService.getEmail()) == null) { - this.toastService.showToast({ - variant: "error", - title: this.i18nService.t("errorOccurred"), - message: this.i18nService.t("sessionTimeout"), - }); - return; - } - - try { - const request = new TwoFactorEmailRequest(); - request.email = await this.loginStrategyService.getEmail(); - request.masterPasswordHash = await this.loginStrategyService.getMasterPasswordHash(); - request.ssoEmail2FaSessionToken = - await this.loginStrategyService.getSsoEmail2FaSessionToken(); - request.deviceIdentifier = await this.appIdService.getAppId(); - request.authRequestAccessCode = await this.loginStrategyService.getAccessCode(); - request.authRequestId = await this.loginStrategyService.getAuthRequestId(); - this.emailPromise = this.apiService.postTwoFactorEmail(request); - await this.emailPromise; - if (doToast) { - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("verificationCodeEmailSent", this.twoFactorEmail), - }); - } - } catch (e) { - this.logService.error(e); - } - - this.emailPromise = null; - } - - async authWebAuthn() { - const providerData = await this.twoFactorService.getProviders().then((providers) => { - return providers.get(this.selectedProviderType); - }); - - if (!this.webAuthnSupported || this.webAuthn == null) { - return; - } - - this.webAuthn.init(providerData); - } - - private cleanupWebAuthn() { - if (this.webAuthn != null) { - this.webAuthn.stop(); - this.webAuthn.cleanup(); - } - } - - private async authing(): Promise { - return (await firstValueFrom(this.loginStrategyService.currentAuthType$)) !== null; - } - - private async needsLock(): Promise { - const authType = await firstValueFrom(this.loginStrategyService.currentAuthType$); - return authType == AuthenticationType.Sso || authType == AuthenticationType.UserApiKey; - } - - async launchDuoFrameless() { - if (this.duoFramelessUrl === null) { - this.toastService.showToast({ - variant: "error", - title: null, - message: this.i18nService.t("duoHealthCheckResultsInNullAuthUrlError"), - }); - return; - } - - this.platformUtilsService.launchUri(this.duoFramelessUrl); - } -} diff --git a/libs/angular/src/auth/functions/unauth-ui-refresh-route-swap.ts b/libs/angular/src/auth/functions/unauth-ui-refresh-route-swap.ts deleted file mode 100644 index b19e73a7412..00000000000 --- a/libs/angular/src/auth/functions/unauth-ui-refresh-route-swap.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Type, inject } from "@angular/core"; -import { Route, Routes } from "@angular/router"; - -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; - -import { componentRouteSwap } from "../../utils/component-route-swap"; - -/** - * Helper function to swap between two components based on the UnauthenticatedExtensionUIRefresh feature flag. - * We need this because the auth teams's authenticated UI will be refreshed as part of the MVP but the - * unauthenticated UIs will not necessarily make the cut. - * Note: Even though this is primarily an extension refresh initiative, this will be used across clients - * as we are consolidating the unauthenticated UIs into single libs/auth components which affects all clients. - * @param defaultComponent - The current non-refreshed component to render. - * @param refreshedComponent - The new refreshed component to render. - * @param options - The shared route options to apply to both components. - * @param altOptions - The alt route options to apply to the alt component. If not provided, the base options will be used. - */ -export function unauthUiRefreshSwap( - defaultComponent: Type, - refreshedComponent: Type, - options: Route, - altOptions?: Route, -): Routes { - return componentRouteSwap( - defaultComponent, - refreshedComponent, - async () => { - const configService = inject(ConfigService); - return configService.getFeatureFlag(FeatureFlag.UnauthenticatedExtensionUIRefresh); - }, - options, - altOptions, - ); -} From f759e62aeb9e10ac0bcc7aba6e892025e6ebdb9d Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Fri, 28 Mar 2025 14:17:18 -0400 Subject: [PATCH 15/16] fix(browser): restore timer based background syncs (#14031) * docs: fix a typo * fix(browser): restore timer-based background syncs The browser extension was not performing scheduled background syncs every 30 minutes as expected. This was due to missing task scheduling code that was accidentally removed during the web push implementation (PR #11346). This commit: - Creates a new BackgroundSyncService to manage sync scheduling - Properly initializes the sync interval in main.background.ts - Adds a test to ensure the sync initialization code isn't accidentally removed again - Organizes platform module structure to support the new service Fixes PM-19396 * review: remove unecassary await keyword --- .../src/background/main.background.spec.ts | 13 +++ .../browser/src/background/main.background.ts | 10 +- apps/browser/tsconfig.json | 1 + .../scheduling/task-scheduler.service.ts | 2 +- .../background-sync.service.spec.ts | 107 ++++++++++++++++++ .../background-sync.service.ts | 44 +++++++ libs/platform/src/background-sync/index.ts | 1 + libs/platform/src/index.ts | 1 + libs/platform/tsconfig.json | 4 +- tsconfig.json | 1 + 10 files changed, 178 insertions(+), 6 deletions(-) create mode 100644 apps/browser/src/background/main.background.spec.ts create mode 100644 libs/platform/src/background-sync/background-sync.service.spec.ts create mode 100644 libs/platform/src/background-sync/background-sync.service.ts create mode 100644 libs/platform/src/background-sync/index.ts diff --git a/apps/browser/src/background/main.background.spec.ts b/apps/browser/src/background/main.background.spec.ts new file mode 100644 index 00000000000..c2cd38b7a30 --- /dev/null +++ b/apps/browser/src/background/main.background.spec.ts @@ -0,0 +1,13 @@ +// This test skips all the initilization of the background script and just +// focuses on making sure we don't accidently delete the initilization of +// background vault syncing. This has happened before! +describe("MainBackground sync task scheduling", () => { + it("includes code to schedule the sync interval task", () => { + // Get the bootstrap method source code as string + const { default: MainBackground } = jest.requireActual("./main.background"); + const bootstrapSource = MainBackground.prototype.bootstrap.toString(); + + // Check that the source includes the critical sync interval scheduling code + expect(bootstrapSource).toContain("this.backgroundSyncService.init();"); + }); +}); diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index e1f0b8bfc64..cae554c872c 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -127,7 +127,6 @@ import { WebPushNotificationsApiService, WorkerWebPushConnectionService, } from "@bitwarden/common/platform/notifications/internal"; -import { ScheduledTaskNames } from "@bitwarden/common/platform/scheduling"; import { AppIdService } from "@bitwarden/common/platform/services/app-id.service"; import { ConfigApiService } from "@bitwarden/common/platform/services/config/config-api.service"; import { DefaultConfigService } from "@bitwarden/common/platform/services/config/default-config.service"; @@ -222,6 +221,7 @@ import { KdfConfigService, KeyService as KeyServiceAbstraction, } from "@bitwarden/key-management"; +import { BackgroundSyncService } from "@bitwarden/platform/background-sync"; import { IndividualVaultExportService, IndividualVaultExportServiceAbstraction, @@ -391,6 +391,7 @@ export default class MainBackground { offscreenDocumentService: OffscreenDocumentService; syncServiceListener: SyncServiceListener; browserInitialInstallService: BrowserInitialInstallService; + backgroundSyncService: BackgroundSyncService; webPushConnectionService: WorkerWebPushConnectionService | UnsupportedWebPushConnectionService; themeStateService: DefaultThemeStateService; @@ -585,9 +586,9 @@ export default class MainBackground { this.logService, this.stateProvider, ); - this.taskSchedulerService.registerTaskHandler(ScheduledTaskNames.scheduleNextSyncInterval, () => - this.fullSync(), - ); + + this.backgroundSyncService = new BackgroundSyncService(this.taskSchedulerService); + this.backgroundSyncService.register(() => this.fullSync()); this.environmentService = new BrowserEnvironmentService( this.logService, @@ -1368,6 +1369,7 @@ export default class MainBackground { setTimeout(async () => { await this.refreshBadge(); await this.fullSync(false); + this.backgroundSyncService.init(); this.notificationsService.startListening(); resolve(); }, 500); diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json index e836af1327c..e24985f58af 100644 --- a/apps/browser/tsconfig.json +++ b/apps/browser/tsconfig.json @@ -29,6 +29,7 @@ "@bitwarden/key-management": ["../../libs/key-management/src"], "@bitwarden/key-management-ui": ["../../libs/key-management-ui/src"], "@bitwarden/platform": ["../../libs/platform/src"], + "@bitwarden/platform/*": ["../../libs/platform/src/*"], "@bitwarden/send-ui": ["../../libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["../../libs/tools/card/src"], "@bitwarden/ui-common": ["../../libs/ui/common/src"], diff --git a/libs/common/src/platform/scheduling/task-scheduler.service.ts b/libs/common/src/platform/scheduling/task-scheduler.service.ts index 35a577dda7d..3ea80c3ee0a 100644 --- a/libs/common/src/platform/scheduling/task-scheduler.service.ts +++ b/libs/common/src/platform/scheduling/task-scheduler.service.ts @@ -11,7 +11,7 @@ import { ScheduledTaskName } from "./scheduled-task-name.enum"; * in the future but the task that is ran is NOT the remainder of your RXJS pipeline. The * task you want ran must instead be registered in a location reachable on a service worker * startup (on browser). An example of an acceptible location is the constructor of a service - * you know is created in `MainBackground`. Uses of this API is other clients _can_ have the + * you know is created in `MainBackground`. Uses of this API in other clients _can_ have the * `registerTaskHandler` call in more places, but in order to have it work across clients * it is recommended to register it according to the rules of browser. * diff --git a/libs/platform/src/background-sync/background-sync.service.spec.ts b/libs/platform/src/background-sync/background-sync.service.spec.ts new file mode 100644 index 00000000000..1deb907b151 --- /dev/null +++ b/libs/platform/src/background-sync/background-sync.service.spec.ts @@ -0,0 +1,107 @@ +import { mock, MockProxy } from "jest-mock-extended"; + +import { TaskSchedulerService, ScheduledTaskNames } from "@bitwarden/common/platform/scheduling"; + +import { BackgroundSyncService, DEFAULT_SYNC_INTERVAL_MS } from "./background-sync.service"; + +describe("BackgroundSyncService", () => { + let taskSchedulerService: MockProxy; + let backgroundSyncService: BackgroundSyncService; + + beforeEach(() => { + taskSchedulerService = mock(); + backgroundSyncService = new BackgroundSyncService(taskSchedulerService); + }); + + describe("register", () => { + it("registers a task handler with the correct task name", () => { + // Arrange + const syncCallback = jest.fn().mockResolvedValue(undefined); + + // Act + backgroundSyncService.register(syncCallback); + + // Assert + expect(taskSchedulerService.registerTaskHandler).toHaveBeenCalledTimes(1); + expect(taskSchedulerService.registerTaskHandler).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + syncCallback, + ); + }); + }); + + describe("init", () => { + it("schedules the sync interval task with default interval", () => { + // Act + backgroundSyncService.init(); + + // Assert + expect(taskSchedulerService.setInterval).toHaveBeenCalledTimes(1); + expect(taskSchedulerService.setInterval).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + DEFAULT_SYNC_INTERVAL_MS, + ); + }); + + it("schedules the sync interval task with custom interval", () => { + // Arrange + const customInterval = 60000; // 1 minute + + // Act + backgroundSyncService.init(customInterval); + + // Assert + expect(taskSchedulerService.setInterval).toHaveBeenCalledTimes(1); + expect(taskSchedulerService.setInterval).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + customInterval, + ); + }); + + it("correctly handles zero interval by using default", () => { + // Act + backgroundSyncService.init(0); + + // Assert + expect(taskSchedulerService.setInterval).toHaveBeenCalledTimes(1); + expect(taskSchedulerService.setInterval).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + DEFAULT_SYNC_INTERVAL_MS, + ); + }); + + it("correctly handles negative interval by using default", () => { + // Act + backgroundSyncService.init(-1000); + + // Assert + expect(taskSchedulerService.setInterval).toHaveBeenCalledTimes(1); + expect(taskSchedulerService.setInterval).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + DEFAULT_SYNC_INTERVAL_MS, + ); + }); + }); + + describe("full integration", () => { + it("registers and initializes correctly in sequence", () => { + // Arrange + const syncCallback = jest.fn().mockResolvedValue(undefined); + const customInterval = 45000; // 45 seconds + + // Act + backgroundSyncService.register(syncCallback); + backgroundSyncService.init(customInterval); + + // Assert + expect(taskSchedulerService.registerTaskHandler).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + syncCallback, + ); + expect(taskSchedulerService.setInterval).toHaveBeenCalledWith( + ScheduledTaskNames.scheduleNextSyncInterval, + customInterval, + ); + }); + }); +}); diff --git a/libs/platform/src/background-sync/background-sync.service.ts b/libs/platform/src/background-sync/background-sync.service.ts new file mode 100644 index 00000000000..dc1b49d399e --- /dev/null +++ b/libs/platform/src/background-sync/background-sync.service.ts @@ -0,0 +1,44 @@ +import { TaskSchedulerService, ScheduledTaskNames } from "@bitwarden/common/platform/scheduling"; + +/** + * The default interval between background syncs. + * 300,000ms = 5 minutes + */ +export const DEFAULT_SYNC_INTERVAL_MS = 300000; + +/** + * Service responsible for registering and managing background synchronization for the browser extension. + * Handles scheduling of periodic sync operations using the task scheduler infrastructure. + */ + +export class BackgroundSyncService { + /** + * Creates a new instance of BackgroundSyncService. + * @param taskSchedulerService - Service that handles scheduling and execution of periodic tasks + */ + constructor(private taskSchedulerService: TaskSchedulerService) {} + + /** + * Registers a callback function to be executed when the sync interval task is triggered. + * This associates the sync task name with the provided callback in the task scheduler. + * + * @param syncCallback - The function to execute when the sync task is triggered + */ + register(syncCallback: () => Promise) { + this.taskSchedulerService.registerTaskHandler( + ScheduledTaskNames.scheduleNextSyncInterval, + syncCallback, + ); + } + + /** + * Initializes the background sync service by scheduling the sync interval task. + * This sets up a recurring timer that triggers the registered sync callback at regular intervals. + * + * @param intervalMs - The interval in milliseconds between sync operations (defaults to 300000ms/5 minutes) + */ + init(intervalMs: number = DEFAULT_SYNC_INTERVAL_MS) { + intervalMs = intervalMs < 1 ? DEFAULT_SYNC_INTERVAL_MS : intervalMs; + this.taskSchedulerService.setInterval(ScheduledTaskNames.scheduleNextSyncInterval, intervalMs); + } +} diff --git a/libs/platform/src/background-sync/index.ts b/libs/platform/src/background-sync/index.ts new file mode 100644 index 00000000000..adfeec608be --- /dev/null +++ b/libs/platform/src/background-sync/index.ts @@ -0,0 +1 @@ +export * from "./background-sync.service"; diff --git a/libs/platform/src/index.ts b/libs/platform/src/index.ts index f11ec102845..3fabe3fad1a 100644 --- a/libs/platform/src/index.ts +++ b/libs/platform/src/index.ts @@ -1 +1,2 @@ export * from "./services/browser-service"; +export * from "./background-sync"; diff --git a/libs/platform/tsconfig.json b/libs/platform/tsconfig.json index eaa021247d8..898f9e41c6a 100644 --- a/libs/platform/tsconfig.json +++ b/libs/platform/tsconfig.json @@ -1,7 +1,9 @@ { "extends": "../shared/tsconfig", "compilerOptions": { - "paths": {} + "paths": { + "@bitwarden/common/*": ["../common/src/*"] + } }, "include": ["src", "spec"], "exclude": ["node_modules", "dist"] diff --git a/tsconfig.json b/tsconfig.json index fb50f1e7033..c82851d50c8 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -35,6 +35,7 @@ "@bitwarden/key-management-ui": ["./libs/key-management-ui/src"], "@bitwarden/node/*": ["./libs/node/src/*"], "@bitwarden/platform": ["./libs/platform/src"], + "@bitwarden/platform/*": ["./libs/platform/src/*"], "@bitwarden/send-ui": ["./libs/tools/send/send-ui/src"], "@bitwarden/tools-card": ["./libs/tools/card/src"], "@bitwarden/ui-common": ["./libs/ui/common/src"], From 66a914badfd65046ce5969163e957ef8f919f5a8 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Fri, 28 Mar 2025 15:50:30 -0400 Subject: [PATCH 16/16] [PM-19654] add hideIcon option to extension anon layout (#14045) --- .../extension-anon-layout-wrapper.component.html | 1 + .../extension-anon-layout-wrapper.component.ts | 10 ++++++++++ .../extension-anon-layout-wrapper.stories.ts | 2 ++ .../anon-layout/anon-layout.component.html | 2 +- .../angular/anon-layout/anon-layout.component.ts | 1 + .../angular/anon-layout/anon-layout.stories.ts | 16 ++++++++++++++++ 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html index 88a3b1c3076..54cb5203a87 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.html @@ -21,6 +21,7 @@ [hideLogo]="true" [maxWidth]="maxWidth" [hideFooter]="hideFooter" + [hideIcon]="hideIcon" > diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts index 10ef65d0654..51dbb6503d7 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.component.ts @@ -26,6 +26,7 @@ export interface ExtensionAnonLayoutWrapperData extends AnonLayoutWrapperData { showBackButton?: boolean; showLogo?: boolean; hideFooter?: boolean; + hideIcon?: boolean; } @Component({ @@ -48,6 +49,7 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy { protected showAcctSwitcher: boolean; protected showBackButton: boolean; protected showLogo: boolean = true; + protected hideIcon: boolean = false; protected pageTitle: string; protected pageSubtitle: string; @@ -129,6 +131,10 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy { if (firstChildRouteData["showLogo"] !== undefined) { this.showLogo = Boolean(firstChildRouteData["showLogo"]); } + + if (firstChildRouteData["hideIcon"] !== undefined) { + this.hideIcon = Boolean(firstChildRouteData["hideIcon"]); + } } private listenForServiceDataChanges() { @@ -180,6 +186,10 @@ export class ExtensionAnonLayoutWrapperComponent implements OnInit, OnDestroy { if (data.showLogo !== undefined) { this.showLogo = data.showLogo; } + + if (data.hideIcon !== undefined) { + this.hideIcon = data.hideIcon; + } } private handleStringOrTranslation(value: string | Translation): string { diff --git a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts index 841eefda0ad..a0990485d49 100644 --- a/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts +++ b/apps/browser/src/auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper.stories.ts @@ -242,6 +242,7 @@ const initialData: ExtensionAnonLayoutWrapperData = { showAcctSwitcher: true, showBackButton: true, showLogo: true, + hideIcon: false, }; const changedData: ExtensionAnonLayoutWrapperData = { @@ -255,6 +256,7 @@ const changedData: ExtensionAnonLayoutWrapperData = { showAcctSwitcher: false, showBackButton: false, showLogo: false, + hideIcon: false, }; @Component({ diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.html b/libs/auth/src/angular/anon-layout/anon-layout.component.html index 4120ea59002..f31a5500b43 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.html +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.html @@ -17,7 +17,7 @@ class="tw-text-center tw-mb-4 sm:tw-mb-6" [ngClass]="{ 'tw-max-w-md tw-mx-auto': titleAreaMaxWidth === 'md' }" > -
+
diff --git a/libs/auth/src/angular/anon-layout/anon-layout.component.ts b/libs/auth/src/angular/anon-layout/anon-layout.component.ts index 05ddb9614f1..1ca4ccd2432 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.component.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout.component.ts @@ -39,6 +39,7 @@ export class AnonLayoutComponent implements OnInit, OnChanges { @Input() showReadonlyHostname: boolean; @Input() hideLogo: boolean = false; @Input() hideFooter: boolean = false; + @Input() hideIcon: boolean = false; /** * Max width of the title area content diff --git a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts index c7e15d9dcfa..34d561d5210 100644 --- a/libs/auth/src/angular/anon-layout/anon-layout.stories.ts +++ b/libs/auth/src/angular/anon-layout/anon-layout.stories.ts @@ -163,6 +163,22 @@ export const WithCustomIcon: Story = { }), }; +export const HideIcon: Story = { + render: (args) => ({ + props: args, + template: + // Projected content (the
) and styling is just a sample and can be replaced with any content/styling. + ` + +
+
Primary Projected Content Area (customizable)
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus illum vero, placeat recusandae esse ratione eius minima veniam nemo, quas beatae! Impedit molestiae alias sapiente explicabo. Sapiente corporis ipsa numquam?
+
+
+ `, + }), +}; + export const HideLogo: Story = { render: (args) => ({ props: args,