diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 000000000000..ff3f1ffc4c7c
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1 @@
+> 0.5%, last 3 major versions, Firefox ESR, not dead
diff --git a/.eslintrc.json b/.eslintrc.json
index ce9c4a33426c..1a3849aee30b 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -97,6 +97,11 @@
// Node
"./libs/node/**/*",
+ //Generator
+ "./libs/tools/generator/components/**/*",
+ "./libs/tools/generator/core/**/*",
+ "./libs/tools/generator/extensions/**/*",
+
// Import/export
"./libs/importer/**/*",
"./libs/tools/export/vault-export/vault-export-core/**/*"
@@ -182,6 +187,33 @@
]
}
},
+ {
+ "files": ["libs/tools/generator/components/src/**/*.ts"],
+ "rules": {
+ "no-restricted-imports": [
+ "error",
+ { "patterns": ["@bitwarden/generator-components/*", "src/**/*"] }
+ ]
+ }
+ },
+ {
+ "files": ["libs/tools/generator/core/src/**/*.ts"],
+ "rules": {
+ "no-restricted-imports": [
+ "error",
+ { "patterns": ["@bitwarden/generator-core/*", "src/**/*"] }
+ ]
+ }
+ },
+ {
+ "files": ["libs/tools/generator/extensions/src/**/*.ts"],
+ "rules": {
+ "no-restricted-imports": [
+ "error",
+ { "patterns": ["@bitwarden/generator-extensions/*", "src/**/*"] }
+ ]
+ }
+ },
{
"files": ["libs/tools/export/vault-export/vault-export-core/src/**/*.ts"],
"rules": {
diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml
index 47ebaf5189c3..5e333b3b58ae 100644
--- a/.github/workflows/build-cli.yml
+++ b/.github/workflows/build-cli.yml
@@ -13,6 +13,7 @@ on:
- '!*.md'
- '!*.txt'
- '.github/workflows/build-cli.yml'
+ - 'bitwarden_license/bit-cli/**'
push:
branches:
- 'main'
@@ -25,6 +26,7 @@ on:
- '!*.md'
- '!*.txt'
- '.github/workflows/build-cli.yml'
+ - 'bitwarden_license/bit-cli/**'
workflow_dispatch:
inputs: {}
@@ -65,7 +67,7 @@ jobs:
os:
[
{ base: "linux", distro: "ubuntu-22.04" },
- { base: "mac", distro: "macos-11" }
+ { base: "mac", distro: "macos-13" }
]
license_type:
[
diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml
index e73f882bb40f..caf3d8cda51f 100644
--- a/.github/workflows/build-desktop.yml
+++ b/.github/workflows/build-desktop.yml
@@ -152,7 +152,7 @@ jobs:
- name: Set up environment
run: |
sudo apt-get update
- sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev rpm musl-dev musl-tools
+ sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev rpm musl-dev musl-tools libssl-dev
- name: Set up Snap
run: sudo snap install snapcraft --classic
@@ -444,10 +444,7 @@ jobs:
macos-build:
name: MacOS Build
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs: setup
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
@@ -605,10 +602,7 @@ jobs:
macos-package-github:
name: MacOS Package GitHub Release Assets
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs:
- browser-build
- macos-build
@@ -814,10 +808,7 @@ jobs:
macos-package-mas:
name: MacOS Package Prod Release Asset
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs:
- browser-build
- macos-build
@@ -1014,11 +1005,7 @@ jobs:
macos-package-dev:
name: MacOS Package Dev Release Asset
- if: false # We need to look into how code signing works for dev
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs:
- browser-build
- macos-build
@@ -1188,14 +1175,15 @@ jobs:
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
- name: Zip masdev asset
- working-directory: ./dist/mas-dev-universal
- run: zip -r Bitwarden-${{ env.PACKAGE_VERSION }}-masdev-universal.zip Bitwarden.app
+ run: |
+ cd dist/mas-dev-universal
+ zip -r Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip Bitwarden.app
- name: Upload masdev artifact
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
- path: apps/desktop/dist/mas-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
+ path: apps/desktop/dist/mas-dev-universal/Bitwarden-${{ env._PACKAGE_VERSION }}-masdev-universal.zip
if-no-files-found: error
diff --git a/.github/workflows/release-desktop-beta.yml b/.github/workflows/release-desktop-beta.yml
index 46f4ffad57da..0013234faa35 100644
--- a/.github/workflows/release-desktop-beta.yml
+++ b/.github/workflows/release-desktop-beta.yml
@@ -393,10 +393,7 @@ jobs:
macos-build:
name: MacOS Build
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs: setup
env:
_PACKAGE_VERSION: ${{ needs.setup.outputs.release-version }}
@@ -457,7 +454,7 @@ jobs:
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
-
+
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
@@ -525,10 +522,7 @@ jobs:
macos-package-github:
name: MacOS Package GitHub Release Assets
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs:
- setup
- macos-build
@@ -596,7 +590,7 @@ jobs:
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
-
+
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
@@ -665,7 +659,7 @@ jobs:
- name: Download artifact from hotfix-rc
if: github.ref == 'refs/heads/hotfix-rc'
- uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
+ uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -674,7 +668,7 @@ jobs:
- name: Download artifact from rc
if: github.ref == 'refs/heads/rc'
- uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
+ uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -683,7 +677,7 @@ jobs:
- name: Download artifacts from main
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
- uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
+ uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -738,10 +732,7 @@ jobs:
macos-package-mas:
name: MacOS Package Prod Release Asset
- # Note, this workflow is running on macOS 11 to maintain compatibility with macOS 10.15 Catalina,
- # as the newer versions will case the native modules to be incompatible with older macOS systems
- # This version should stay pinned until we drop support for macOS 10.15, or we drop the native modules
- runs-on: macos-11
+ runs-on: macos-13
needs:
- setup
- macos-build
@@ -804,7 +795,7 @@ jobs:
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/bitwarden-desktop-key |
jq -r .value | base64 -d > $HOME/certificates/bitwarden-desktop-key.p12
-
+
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/appstore-app-cert |
jq -r .value | base64 -d > $HOME/certificates/appstore-app-cert.p12
@@ -873,7 +864,7 @@ jobs:
- name: Download artifact from hotfix-rc
if: github.ref == 'refs/heads/hotfix-rc'
- uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
+ uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -882,7 +873,7 @@ jobs:
- name: Download artifact from rc
if: github.ref == 'refs/heads/rc'
- uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
+ uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
@@ -891,7 +882,7 @@ jobs:
- name: Download artifact from main
if: ${{ github.ref != 'refs/heads/rc' && github.ref != 'refs/heads/hotfix-rc' }}
- uses: dawidd6/action-download-artifact@71072fbb1229e1317f1a8de6b04206afb461bd67 # v3.1.2
+ uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build-browser.yml
workflow_conclusion: success
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3c650d8a6224..12649b91ea92 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -48,10 +48,12 @@ jobs:
# Tests in apps/ are typechecked when their app is built, so we just do it here for libs/
# See https://bitwarden.atlassian.net/browse/EC-497
- name: Run typechecking
- run: npm run test:types --coverage
+ run: npm run test:types
- name: Run tests
- run: npm run test --coverage
+ # maxWorkers is a workaround for a memory leak that crashes tests in CI:
+ # https://github.com/facebook/jest/issues/9430#issuecomment-1149882002
+ run: npm test -- --coverage --maxWorkers=3
- name: Report test results
uses: dorny/test-reporter@eaa763f6ffc21c7a37837f56cd5f9737f27fc6c8 # v1.8.0
diff --git a/apps/browser/package.json b/apps/browser/package.json
index 25912c4832f6..a295a0f5bfed 100644
--- a/apps/browser/package.json
+++ b/apps/browser/package.json
@@ -1,6 +1,6 @@
{
"name": "@bitwarden/browser",
- "version": "2024.5.1",
+ "version": "2024.6.0",
"scripts": {
"build": "cross-env MANIFEST_VERSION=3 webpack",
"build:mv2": "webpack",
diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json
index c4a07015412b..c42516264013 100644
--- a/apps/browser/src/_locales/ar/messages.json
+++ b/apps/browser/src/_locales/ar/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "إلغاء القفل"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "إظهار خيارات قائمة السياق"
},
@@ -799,12 +802,39 @@
"message": "داكن مُشمس",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "تصدير الخزنة"
},
"fileFormat": {
"message": "صيغة الملف"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "تحذير",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "خطأ"
},
diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json
index 8b3632da1ba3..129aac00ee2b 100644
--- a/apps/browser/src/_locales/az/messages.json
+++ b/apps/browser/src/_locales/az/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Kilidi aç"
},
+ "additionalOptions": {
+ "message": "Əlavə seçimlər"
+ },
"enableContextMenuItem": {
"message": "Konteks menyu seçimlərini göstər"
},
@@ -799,12 +802,39 @@
"message": "Günəşli tünd",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Buradan xaricə köçür"
+ },
"exportVault": {
"message": "Anbarı xaricə köçür"
},
"fileFormat": {
"message": "Fayl formatı"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Bu faylın xaricə köçürülməsi, parolla qorunacaq və şifrəsini açmaq üçün fayl parolu tələb olunacaq."
+ },
+ "filePassword": {
+ "message": "Fayl parolu"
+ },
+ "exportPasswordDescription": {
+ "message": "Bu parol, bu faylı daxilə və xaricə köçürmək üçün istifadə olunacaq"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Xaricə köçürməni şifrələmək və daxilə köçürməni yalnız mövcud Bitwarden hesabı ilə məhdudlaşdırmaq üçün hesabınızın istifadəçi adı və Ana Parolundan əldə edilən hesab şifrələmə açarınızı istifadə edin."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Xaricə köçürməni şifrələmək üçün bir fayl parolu təyin edin və şifrəni açma parolunu istifadə edərək bunu istənilən Bitwarden hesabına köçürün."
+ },
+ "exportTypeHeading": {
+ "message": "Xaricə köçürmə növü"
+ },
+ "accountRestricted": {
+ "message": "Hesab məhdudlaşdırıldı"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Fayl parolu\" və \"Fayl parolunu təsdiqlə\" uyuşmur."
+ },
"warning": {
"message": "XƏBƏRDARLIQ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Təşkilat anbarını xaricə köçürmə"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Yalnız $ORGANIZATION$ ilə əlaqələndirilmiş təşkilat anbarı ixrac ediləcək. Fərdi anbardakı və digər təşkilat elementlər daxil edilmir.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Xəta"
},
diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json
index 5409816accf5..6ee3fffdfa5c 100644
--- a/apps/browser/src/_locales/be/messages.json
+++ b/apps/browser/src/_locales/be/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Разблакіраваць"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Паказваць параметры кантэкстнага меню"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Экспартаваць сховішча"
},
"fileFormat": {
"message": "Фармат файла"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ПАПЯРЭДЖАННЕ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Памылка"
},
diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json
index e6f6cfc14d8e..337467ddfe92 100644
--- a/apps/browser/src/_locales/bg/messages.json
+++ b/apps/browser/src/_locales/bg/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Отключване"
},
+ "additionalOptions": {
+ "message": "Допълнителни настройки"
+ },
"enableContextMenuItem": {
"message": "Показване на опции в контекстното меню"
},
@@ -799,12 +802,39 @@
"message": "Преекспонирано тъмен",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Изнасяне от"
+ },
"exportVault": {
"message": "Изнасяне на трезора"
},
"fileFormat": {
"message": "Формат на файла"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Изнесеният файл ще бъде защитен с парола, която ще бъде необходима за дешифриране на файла."
+ },
+ "filePassword": {
+ "message": "Парола на файла"
+ },
+ "exportPasswordDescription": {
+ "message": "Парола ще се използва при изнасянето и при внасянето на този файл"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Използвайте ключа си за шифриране, който се получава чрез комбиниране на потребителското име на регистрацията Ви и главната парола. С него изнасянето ще се шифрира и внасянето ще бъда възможно само в текущата регистрация в Битуорден."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Задайте парола за файла, за да шифровате изнесените данни. Ще можете да внесете данните във всяка регистрация в Битуорден използвайки паролата за дешифриране."
+ },
+ "exportTypeHeading": {
+ "message": "Вид изнасяне"
+ },
+ "accountRestricted": {
+ "message": "Регистрацията е ограничена"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "Дънните в полетата „Парола на файла“ и „Потвърждаване на паролата на файла“ не съвпадат."
+ },
"warning": {
"message": "ВНИМАНИЕ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Изнасяне на трезора на организацията"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Ще бъдат изнесени само записите от трезора свързан с $ORGANIZATION$. Записите в отделните лични трезори и тези в други организации няма да бъдат включени.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Грешка"
},
diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json
index 1635de5bb8b7..541bebd427be 100644
--- a/apps/browser/src/_locales/bn/messages.json
+++ b/apps/browser/src/_locales/bn/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "ভল্ট রফতানি"
},
"fileFormat": {
"message": "ফাইলের ধরণ"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "সতর্কতা",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json
index db55f4784e4a..cd82d91cefcd 100644
--- a/apps/browser/src/_locales/bs/messages.json
+++ b/apps/browser/src/_locales/bs/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json
index 01f66bffd641..fe2a25e65950 100644
--- a/apps/browser/src/_locales/ca/messages.json
+++ b/apps/browser/src/_locales/ca/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Desbloqueja"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Mostra les opcions del menú contextual"
},
@@ -799,12 +802,39 @@
"message": "Solaritzat fosc",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exporta caixa forta"
},
"fileFormat": {
"message": "Format de fitxer"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ADVERTIMENT",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json
index 2939bba14684..3b9507fdf215 100644
--- a/apps/browser/src/_locales/cs/messages.json
+++ b/apps/browser/src/_locales/cs/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Odemknout"
},
+ "additionalOptions": {
+ "message": "Další volby"
+ },
"enableContextMenuItem": {
"message": "Zobrazit volby v kontextovém menu"
},
@@ -799,12 +802,39 @@
"message": "Tmavý (solarizovaný)",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exportovat z"
+ },
"exportVault": {
"message": "Exportovat trezor"
},
"fileFormat": {
"message": "Formát souboru"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Tento soubor exportu bude chráněn heslem a k dešifrování bude vyžadovat heslo souboru."
+ },
+ "filePassword": {
+ "message": "Heslo souboru"
+ },
+ "exportPasswordDescription": {
+ "message": "Toto heslo bude použito pro export a import tohoto souboru"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Pro zašifrování exportu a omezení importu pouze na aktuální účet Bitwardenu použijte šifrovací klíč Vašeho účtu odvozený z uživatelského jména a hlavního hesla."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Nastavte heslo pro šifrování exportu a importujte ho do libovolného účtu Bitwardenu pomocí hesla pro dešifrování."
+ },
+ "exportTypeHeading": {
+ "message": "Typ exportu"
+ },
+ "accountRestricted": {
+ "message": "Účet je omezený"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Heslo souboru\" a \"Potvrzení hesla souboru\" se neshodují."
+ },
"warning": {
"message": "VAROVÁNÍ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exportování trezoru organizace"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Chyba"
},
diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json
index 58f7bc954468..6bfa7de69f3b 100644
--- a/apps/browser/src/_locales/cy/messages.json
+++ b/apps/browser/src/_locales/cy/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Datgloi"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Allforio'r gell"
},
"fileFormat": {
"message": "Fformat y ffeil"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "RHYBUDD",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Gwall"
},
diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json
index 8f27f95be024..32266ceb31fa 100644
--- a/apps/browser/src/_locales/da/messages.json
+++ b/apps/browser/src/_locales/da/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Oplås"
},
+ "additionalOptions": {
+ "message": "Yderligere indstillinger"
+ },
"enableContextMenuItem": {
"message": "Vis indstillinger i kontekstmenuen"
},
@@ -799,12 +802,39 @@
"message": "Solariseret mørk",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Eksportér fra"
+ },
"exportVault": {
"message": "Eksportér boks"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Denne fileksport vil være adgangskodebeskyttet og kræve filadgangskoden at dekryptere."
+ },
+ "filePassword": {
+ "message": "Filadgangskode"
+ },
+ "exportPasswordDescription": {
+ "message": "Denne adgangskode vil blive brugt ved eksport og import af denne fil"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Brug kontokrypteringsnøglen, dannet af kontobrugernavn og Hovedadgangskode, for at kryptere eksporten og hindre import til andre end den aktuelle Bitwarden-konto."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Opsæt en adgangskode til både at kryptere eksporten samt dekryptere denne ved import til enhver Bitwarden-konto."
+ },
+ "exportTypeHeading": {
+ "message": "Eksporttype"
+ },
+ "accountRestricted": {
+ "message": "Konto begrænset"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“Filadgangskode” og “Bekræft filadgangskode“ matcher ikke."
+ },
"warning": {
"message": "ADVARSEL",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Eksport af organisationsboks"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Kun organisationsboksen tilknyttet $ORGANIZATION$ eksporteres. Emner i individuelle bokse eller andre organisationer medtages ikke.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Fejl"
},
diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json
index 8a7c3e0067dc..bec6702ae280 100644
--- a/apps/browser/src/_locales/de/messages.json
+++ b/apps/browser/src/_locales/de/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Entsperren"
},
+ "additionalOptions": {
+ "message": "Weitere Optionen"
+ },
"enableContextMenuItem": {
"message": "Kontextmenüoptionen anzeigen"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export aus"
+ },
"exportVault": {
"message": "Tresor exportieren"
},
"fileFormat": {
"message": "Dateiformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Dieser Datei-Export ist passwortgeschützt und erfordert das Dateipasswort zum Entschlüsseln."
+ },
+ "filePassword": {
+ "message": "Dateipasswort"
+ },
+ "exportPasswordDescription": {
+ "message": "Dieses Passwort wird zum Exportieren und Importieren dieser Datei verwendet"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Verwende den Verschlüsselungsschlüssel deines Kontos, abgeleitet vom Benutzernamen und Master-Passwort, um den Export zu verschlüsseln und den Import auf das aktuelle Bitwarden-Konto zu beschränken."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Lege ein Dateipasswort fest, um den Export zu verschlüsseln und importiere ihn in ein beliebiges Bitwarden-Konto, wobei das Passwort zum Entschlüsseln genutzt wird."
+ },
+ "exportTypeHeading": {
+ "message": "Exporttyp"
+ },
+ "accountRestricted": {
+ "message": "Konto eingeschränkt"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "„Dateipasswort“ und „Dateipasswort bestätigen“ stimmen nicht überein."
+ },
"warning": {
"message": "ACHTUNG",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Tresor der Organisation wird exportiert"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Nur der mit $ORGANIZATION$ verbundene Organisationstresor wird exportiert. Einträge in persönlichen Tresoren oder anderen Organisationen werden nicht berücksichtigt.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Fehler"
},
diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json
index 365f8475a07b..da376f6c6a0d 100644
--- a/apps/browser/src/_locales/el/messages.json
+++ b/apps/browser/src/_locales/el/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Ξεκλείδωμα"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Εμφάνιση επιλογών μενού περιβάλλοντος"
},
@@ -799,12 +802,39 @@
"message": "Solarized Σκούρο",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Εξαγωγή Vault"
},
"fileFormat": {
"message": "Μορφή αρχείου"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ΠΡΟΕΙΔΟΠΟΙΗΣΗ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Σφάλμα"
},
diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json
index 8d0f6fe31eb4..231637d7af33 100644
--- a/apps/browser/src/_locales/en/messages.json
+++ b/apps/browser/src/_locales/en/messages.json
@@ -185,7 +185,7 @@
"message": "Continue to browser extension store?"
},
"continueToBrowserExtensionStoreDesc": {
- "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now."
+ "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now."
},
"changeMasterPasswordOnWebConfirmation": {
"message": "You can change your master password on the Bitwarden web app."
@@ -224,7 +224,7 @@
},
"continueToAuthenticatorPageDesc": {
"message": "Bitwarden Authenticator allows you to store authenticator keys and generate TOTP codes for 2-step verification flows. Learn more on the bitwarden.com website"
- },
+ },
"bitwardenSecretsManager": {
"message": "Bitwarden Secrets Manager"
},
@@ -389,6 +389,9 @@
"favorite": {
"message": "Favorite"
},
+ "unfavorite": {
+ "message": "Unfavorite"
+ },
"notes": {
"message": "Notes"
},
@@ -410,6 +413,9 @@
"launch": {
"message": "Launch"
},
+ "launchWebsite": {
+ "message": "Launch website"
+ },
"website": {
"message": "Website"
},
@@ -599,6 +605,9 @@
"loggedOut": {
"message": "Logged out"
},
+ "loggedOutDesc": {
+ "message": "You have been logged out of your account."
+ },
"loginExpired": {
"message": "Your login session has expired."
},
@@ -762,6 +771,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -816,7 +828,7 @@
},
"exportPasswordDescription": {
"message": "This password will be used to export and import this file"
- },
+ },
"accountRestrictedOptionDescription": {
"message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
},
@@ -1104,6 +1116,15 @@
"selfHostedEnvironmentFooter": {
"message": "Specify the base URL of your on-premises hosted Bitwarden installation."
},
+ "selfHostedBaseUrlHint": {
+ "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com"
+ },
+ "selfHostedCustomEnvHeader" :{
+ "message": "For advanced configuration, you can specify the base URL of each service independently."
+ },
+ "selfHostedEnvFormInvalid" :{
+ "message": "You must add either the base Server URL or at least one custom environment."
+ },
"customEnvironment": {
"message": "Custom environment"
},
@@ -1416,6 +1437,15 @@
"collections": {
"message": "Collections"
},
+ "nCollections": {
+ "message": "$COUNT$ collections",
+ "placeholders": {
+ "count": {
+ "content": "$1",
+ "example": "2"
+ }
+ }
+ },
"favorites": {
"message": "Favorites"
},
@@ -1645,6 +1675,9 @@
"autoFillAndSave": {
"message": "Auto-fill and save"
},
+ "fillAndSave": {
+ "message": "Fill and save"
+ },
"autoFillSuccessAndSavedUri": {
"message": "Item auto-filled and URI saved"
},
@@ -1741,6 +1774,12 @@
"ok": {
"message": "Ok"
},
+ "errorRefreshingAccessToken":{
+ "message": "Access Token Refresh Error"
+ },
+ "errorRefreshingAccessTokenDesc":{
+ "message": "No refresh token or API keys found. Please try logging out and logging back in."
+ },
"desktopSyncVerificationTitle": {
"message": "Desktop sync verification"
},
@@ -3260,7 +3299,7 @@
"clearFiltersOrTryAnother": {
"message": "Clear filters or try another search term"
},
- "copyInfo": {
+ "copyInfoLabel": {
"message": "Copy info, $ITEMNAME$",
"description": "Aria label for a button that opens a menu with options to copy information from an item.",
"placeholders": {
@@ -3270,7 +3309,37 @@
}
}
},
- "moreOptions": {
+ "copyInfoTitle": {
+ "message": "Copy info - $ITEMNAME$",
+ "description": "Title for a button that opens a menu with options to copy information from an item.",
+ "placeholders": {
+ "itemname": {
+ "content": "$1",
+ "example": "Secret Item"
+ }
+ }
+ },
+ "copyNoteLabel": {
+ "message": "Copy Note, $ITEMNAME$",
+ "description": "Aria label for a button copies a note to the clipboard.",
+ "placeholders": {
+ "itemname": {
+ "content": "$1",
+ "example": "Secret Note Item"
+ }
+ }
+ },
+ "copyNoteTitle": {
+ "message": "Copy Note - $ITEMNAME$",
+ "description": "Title for a button copies a note to the clipboard.",
+ "placeholders": {
+ "itemname": {
+ "content": "$1",
+ "example": "Secret Note Item"
+ }
+ }
+ },
+ "moreOptionsLabel": {
"message": "More options, $ITEMNAME$",
"description": "Aria label for a button that opens a menu with more options for an item.",
"placeholders": {
@@ -3280,6 +3349,38 @@
}
}
},
+ "moreOptionsTitle": {
+ "message": "More options - $ITEMNAME$",
+ "description": "Title for a button that opens a menu with more options for an item.",
+ "placeholders": {
+ "itemname": {
+ "content": "$1",
+ "example": "Secret Item"
+ }
+ }
+ },
+ "viewItemTitle": {
+ "message": "View item - $ITEMNAME$",
+ "description": "Title for a link that opens a view for an item.",
+ "placeholders": {
+ "itemname": {
+ "content": "$1",
+ "example": "Secret Item"
+ }
+ }
+ },
+ "assignCollections": {
+ "message": "Assign collections"
+ },
+ "copyEmail": {
+ "message": "Copy email"
+ },
+ "copyPhone": {
+ "message": "Copy phone"
+ },
+ "copyAddress": {
+ "message": "Copy address"
+ },
"adminConsole": {
"message": "Admin Console"
},
@@ -3330,5 +3431,14 @@
"example": "Work"
}
}
+ },
+ "itemsWithNoFolder": {
+ "message": "Items with no folder"
+ },
+ "organizationIsDeactivated": {
+ "message": "Organization is deactivated"
+ },
+ "contactYourOrgAdmin": {
+ "message": "Items in deactivated organizations cannot be accessed. Contact your organization owner for assistance."
}
}
diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json
index ffde447604bc..0ff4085900c0 100644
--- a/apps/browser/src/_locales/en_GB/messages.json
+++ b/apps/browser/src/_locales/en_GB/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organisation vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organisation vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organisations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json
index 3ceedc40deb1..bb1ae5f73184 100644
--- a/apps/browser/src/_locales/en_IN/messages.json
+++ b/apps/browser/src/_locales/en_IN/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarised Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organisation vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organisation vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organisations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json
index 3550fa68c03a..1134f9415130 100644
--- a/apps/browser/src/_locales/es/messages.json
+++ b/apps/browser/src/_locales/es/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Desbloquear"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Mostrar las opciones de menú contextuales"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exportar desde"
+ },
"exportVault": {
"message": "Exportar caja fuerte"
},
"fileFormat": {
"message": "Formato de archivo"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Esta exportación de archivo estará protegida por contraseña y requerirá la contraseña del archivo para descifrarla."
+ },
+ "filePassword": {
+ "message": "Contraseña del archivo"
+ },
+ "exportPasswordDescription": {
+ "message": "Esta contraseña se utilizará para exportar e importar este archivo"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Utiliza la clave de cifrado de tu cuenta, derivada del nombre de usuario y la contraseña maestra de tu cuenta, para cifrar la exportación y restringir la importación solo a la cuenta actual de Bitwarden."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Establece una contraseña de archivo para cifrar la exportación e importarlo a cualquier cuenta de Bitwarden utilizando la contraseña para el descifrado."
+ },
+ "exportTypeHeading": {
+ "message": "Tipo de exportación"
+ },
+ "accountRestricted": {
+ "message": "Cuenta restringida"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Contraseña de archivo\" y \"Confirmar contraseña de archivo\" no coinciden."
+ },
"warning": {
"message": "ADVERTENCIA",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exportando caja fuerte de la organización"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Solo se exportará la caja fuerte de la organización asociada a $ORGANIZATION$. Los elementos en las cajas fuertes individuales o de otras organizaciones no serán incluidos.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json
index 8fb5274c52fe..03267c79d7b7 100644
--- a/apps/browser/src/_locales/et/messages.json
+++ b/apps/browser/src/_locales/et/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Lukusta lahti"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Kuva parema kliki menüü valikud"
},
@@ -799,12 +802,39 @@
"message": "Solarized tume",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Ekspordi hoidla"
},
"fileFormat": {
"message": "Failivorming"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "HOIATUS",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Viga"
},
diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json
index 60339f16b14f..3d0e37f4147d 100644
--- a/apps/browser/src/_locales/eu/messages.json
+++ b/apps/browser/src/_locales/eu/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Erakutsi laster-menuko aukerak"
},
@@ -799,12 +802,39 @@
"message": "Solarized iluna",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Esportatu kutxa gotorra"
},
"fileFormat": {
"message": "Fitxategiaren formatua"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "KONTUZ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Akatsa"
},
diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json
index a493a1c24bfd..5b55561a6a8e 100644
--- a/apps/browser/src/_locales/fa/messages.json
+++ b/apps/browser/src/_locales/fa/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "باز کردن قفل"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "نمایش گزینههای منوی زمینه"
},
@@ -799,12 +802,39 @@
"message": "تاریک خورشیدی",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "برون ریزی گاوصندوق"
},
"fileFormat": {
"message": "فرمت پرونده"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "اخطار",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "خطا"
},
diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json
index 05d2d3ed952f..42251e9e42b2 100644
--- a/apps/browser/src/_locales/fi/messages.json
+++ b/apps/browser/src/_locales/fi/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Avaa"
},
+ "additionalOptions": {
+ "message": "Lisäasetukset"
+ },
"enableContextMenuItem": {
"message": "Näytä sisältövalikon valinnat"
},
@@ -799,12 +802,39 @@
"message": "Solarized, tumma",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Vie lähteestä"
+ },
"exportVault": {
"message": "Vie holvi"
},
"fileFormat": {
"message": "Tiedostomuoto"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Tämä vientitiedosto suojataan salasanalla, joka on syötettävä ja salauksen purkamiseksi."
+ },
+ "filePassword": {
+ "message": "Tiedoston salasana"
+ },
+ "exportPasswordDescription": {
+ "message": "Tätä salasanaa käytetään tämän tiedoston viennissä ja tuonnissa"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Salaa vienti ja rajoita tuonti vain nykyiselle Bitwarden-tilille tilisi käyttäjätunnukseen ja pääsalasanaan pohjautuvalla salausavaimella."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Salaa vientitiedosto salasanalla, joka mahdollistaa sen tuonnin mille tahansa Bitwarden-tilille."
+ },
+ "exportTypeHeading": {
+ "message": "Viennin tyyppi"
+ },
+ "accountRestricted": {
+ "message": "Rajoitettu tilille"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Tiedoston salasana\" ja \"Vahvista tiedoston salasana\" eivät täsmää."
+ },
"warning": {
"message": "VAROITUS",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Organisaation holvin vienti"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Vain organisaatioon $ORGANIZATION$ liitetyn holvin kohteet viedään. Yksityisen holvin ja muiden organisaatioiden kohteita ei sisällytetä.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Virhe"
},
diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json
index 061da97446b8..86f8209e1cd6 100644
--- a/apps/browser/src/_locales/fil/messages.json
+++ b/apps/browser/src/_locales/fil/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "I-unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Ipakita ang mga opsyon ng menu ng konteksto"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "I-export vault"
},
"fileFormat": {
"message": "Format ng file"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "BABALA",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Mali"
},
diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json
index c062390f228a..53df48d00041 100644
--- a/apps/browser/src/_locales/fr/messages.json
+++ b/apps/browser/src/_locales/fr/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Déverrouiller"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Afficher les options du menu contextuel"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exporter le coffre"
},
"fileFormat": {
"message": "Format de fichier"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "AVERTISSEMENT",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Erreur"
},
diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json
index b92e05269ebb..dd29c8a071cd 100644
--- a/apps/browser/src/_locales/gl/messages.json
+++ b/apps/browser/src/_locales/gl/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Desbloquear"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarizado escuro",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exportar caixa forte"
},
"fileFormat": {
"message": "Formato de ficheiro"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ADVERTENCIA",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Erro"
},
diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json
index fd49f7e55e8c..c191df36bf86 100644
--- a/apps/browser/src/_locales/he/messages.json
+++ b/apps/browser/src/_locales/he/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "יצוא כספת"
},
"fileFormat": {
"message": "פורמט קובץ"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "אזהרה",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "שגיאה"
},
diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json
index 48c55b30a83f..d6ac94bec327 100644
--- a/apps/browser/src/_locales/hi/messages.json
+++ b/apps/browser/src/_locales/hi/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "संदर्भ मेनू विकल्प दिखाएं"
},
@@ -799,12 +802,39 @@
"message": "सौरीकृत अंधेरा",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export Vault"
},
"fileFormat": {
"message": "File Format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "चेतावनी",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "एरर"
},
diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json
index ac452af85ee7..8b9f96fa5c4a 100644
--- a/apps/browser/src/_locales/hr/messages.json
+++ b/apps/browser/src/_locales/hr/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Otključaj"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Prikaži opcije kotekstualnog izbornika"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Izvezi trezor"
},
"fileFormat": {
"message": "Format datoteke"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "UPOZORENJE",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Pogreška"
},
diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json
index 8b937375a638..8ff50ea4f085 100644
--- a/apps/browser/src/_locales/hu/messages.json
+++ b/apps/browser/src/_locales/hu/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Feloldás"
},
+ "additionalOptions": {
+ "message": "Kiegészítő opciók"
+ },
"enableContextMenuItem": {
"message": "Helyi menü opciók megjelenítése"
},
@@ -799,12 +802,39 @@
"message": "Szolarizált sötét",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exportálás innen:"
+ },
"exportVault": {
"message": "Széf exportálása"
},
"fileFormat": {
"message": "Fájlformátum"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Ez a fájl exportálás jelszóval védett és a visszafejtéshez a fájl jelszó megadása szükséges."
+ },
+ "filePassword": {
+ "message": "Fájl jelszó"
+ },
+ "exportPasswordDescription": {
+ "message": "Ezt a jelszó kerül használatba a fájl exportálására és importálására."
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Használjuk a fiók felhasználónevéből és mesterjelszavából származó fióktitkosítási kulcsot az exportálás titkosításához és az importálást csak az aktuális Bitwarden fiókra korlátozzuk."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Állítsunk be egy fájl jelszót az exportálás titkosításához és importáljuk azt bármely Bitwarden fiókba a visszafejtéshez használt jelszó használatával."
+ },
+ "exportTypeHeading": {
+ "message": "Exportálási típus"
+ },
+ "accountRestricted": {
+ "message": "Korlátozott fiók"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "A “Fájl jelszó” és a “Fájl jelszó megerősítés“ nem egyezik."
+ },
"warning": {
"message": "FIGYELEM",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Szervezeti széf exportálása"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Csak $ORGANIZATION$ névvel társított szervezeti széf kerül exportálásra. Ebbe nem kerülnek be a személyes és más szervezeti széf elemek.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Hiba"
},
diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json
index b151dbbf21fc..19770da2782a 100644
--- a/apps/browser/src/_locales/id/messages.json
+++ b/apps/browser/src/_locales/id/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Gelap Solarized",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Ekspor Brankas"
},
"fileFormat": {
"message": "Format Berkas"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "PERINGATAN",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Galat"
},
diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json
index 938eb7671e09..614068b1f4d5 100644
--- a/apps/browser/src/_locales/it/messages.json
+++ b/apps/browser/src/_locales/it/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Sblocca"
},
+ "additionalOptions": {
+ "message": "Opzioni aggiuntive"
+ },
"enableContextMenuItem": {
"message": "Mostra opzioni nel menu contestuale"
},
@@ -799,12 +802,39 @@
"message": "Scuro solarizzato",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Esporta da"
+ },
"exportVault": {
"message": "Esporta cassaforte"
},
"fileFormat": {
"message": "Formato file"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Questo file esportato sarà protetto e richiederà la password del file per decifrarlo."
+ },
+ "filePassword": {
+ "message": "Password del file"
+ },
+ "exportPasswordDescription": {
+ "message": "La password sarà utilizzata per importare ed esportare questo file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Usa la chiave di crittografia dell'account, derivata dal nome utente e dalla password principale del tuo account, per crittografare il file di esportazione e limitare l'importazione solo all'account Bitwarden corrente."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Imposta una password del file per crittografare il file esportato e importarlo in qualsiasi account Bitwarden usando la password per decrittografarlo."
+ },
+ "exportTypeHeading": {
+ "message": "Tipo di esportazione"
+ },
+ "accountRestricted": {
+ "message": "Account limitato"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "Le due password del file non corrispondono."
+ },
"warning": {
"message": "ATTENZIONE",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Esportando cassaforte dell'organizzazione"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Solo la cassaforte dell'organizzazione associata a $ORGANIZATION$ sarà esportata. Elementi nelle casseforti individuali o in altre organizzazioni non saranno inclusi.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Errore"
},
diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json
index cb78bd7fda5e..9113b95a7d3d 100644
--- a/apps/browser/src/_locales/ja/messages.json
+++ b/apps/browser/src/_locales/ja/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "ロック解除"
},
+ "additionalOptions": {
+ "message": "追加オプション"
+ },
"enableContextMenuItem": {
"message": "コンテキストメニューオプションを表示"
},
@@ -799,12 +802,39 @@
"message": "Solarized ダーク",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "エクスポート元"
+ },
"exportVault": {
"message": "保管庫のエクスポート"
},
"fileFormat": {
"message": "ファイル形式"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "エクスポートするファイルはパスワードで保護され、復号するにはファイルパスワードが必要になります。"
+ },
+ "filePassword": {
+ "message": "ファイルパスワード"
+ },
+ "exportPasswordDescription": {
+ "message": "このパスワードはこのファイルのエクスポートとインポート時に使用します"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "アカウントのユーザー名とマスターパスワードから得られる暗号化キーを使用してエクスポートするデータを暗号化し、現在の Bitwarden アカウントのみがインポートできるよう制限します。"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "エクスポートを暗号化するためのファイルパスワードを設定します。そのパスワードを使用して、任意の Bitwarden アカウントにインポートします。"
+ },
+ "exportTypeHeading": {
+ "message": "エクスポートの種類"
+ },
+ "accountRestricted": {
+ "message": "アカウント制限"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "「ファイルパスワード」と「ファイルパスワードの確認」が一致しません。"
+ },
"warning": {
"message": "警告",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "組織保管庫のエクスポート"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "$ORGANIZATION$ に関連付けられた組織保管庫のみがエクスポートされます。個々の保管庫または他の組織にあるアイテムは含まれません。",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "エラー"
},
diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json
index 62347f4acf45..6abd24dafc86 100644
--- a/apps/browser/src/_locales/ka/messages.json
+++ b/apps/browser/src/_locales/ka/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json
index 64f3623b5af3..c3f03166b255 100644
--- a/apps/browser/src/_locales/km/messages.json
+++ b/apps/browser/src/_locales/km/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json
index 7556ee6afd60..e5e1f708f66d 100644
--- a/apps/browser/src/_locales/kn/messages.json
+++ b/apps/browser/src/_locales/kn/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "ಡಾರ್ಕ್ ಸೌರ",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "ರಫ್ತು ವಾಲ್ಟ್"
},
"fileFormat": {
"message": "ಕಡತದ ಮಾದರಿ"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ಎಚ್ಚರಿಕೆ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json
index 86295d469a75..552446ef7669 100644
--- a/apps/browser/src/_locales/ko/messages.json
+++ b/apps/browser/src/_locales/ko/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "잠금 해제"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "보관함 내보내기"
},
"fileFormat": {
"message": "파일 형식"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "경고",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "오류"
},
diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json
index 6f0fc1bbb62e..5b426e47d159 100644
--- a/apps/browser/src/_locales/lt/messages.json
+++ b/apps/browser/src/_locales/lt/messages.json
@@ -423,7 +423,7 @@
"message": "Kita"
},
"unlockMethods": {
- "message": "Unlock options"
+ "message": "Atrakinti parinktis"
},
"unlockMethodNeededToChangeTimeoutActionDesc": {
"message": "Nustatyk atrakinimo būdą, kad pakeistum saugyklos laiko limito veiksmą."
@@ -432,10 +432,10 @@
"message": "Nustatykite nustatymuose atrakinimo metodą"
},
"sessionTimeoutHeader": {
- "message": "Session timeout"
+ "message": "Baigėsi seanso laikas"
},
"otherOptions": {
- "message": "Other options"
+ "message": "Kitos parinktys"
},
"rateExtension": {
"message": "Įvertinkite šį plėtinį"
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Atrakinti"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Rodyti kontekstinio meniu pasririnkimus"
},
@@ -799,12 +802,39 @@
"message": "Saulėtas tamsą",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Eksportuoti saugyklą"
},
"fileFormat": {
"message": "Failo formatas"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ĮSPĖJIMAS",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Klaida"
},
@@ -2232,7 +2274,7 @@
"message": "Sugeneruoti el. pašto slapyvardį su išorine persiuntimo paslauga."
},
"forwarderError": {
- "message": "$SERVICENAME$ error: $ERRORMESSAGE$",
+ "message": "„$SERVICENAME$“ klaida: $ERRORMESSAGE$.",
"description": "Reports an error returned by a forwarding service to the user.",
"placeholders": {
"servicename": {
@@ -2246,11 +2288,11 @@
}
},
"forwarderGeneratedBy": {
- "message": "Generated by Bitwarden.",
+ "message": "Sugeneravo „Bitwarden“.",
"description": "Displayed with the address on the forwarding service's configuration screen."
},
"forwarderGeneratedByWithWebsite": {
- "message": "Website: $WEBSITE$. Generated by Bitwarden.",
+ "message": "Svetainė: $WEBSITE$. Sugeneravo „Bitwarden“.",
"description": "Displayed with the address on the forwarding service's configuration screen.",
"placeholders": {
"WEBSITE": {
@@ -2260,7 +2302,7 @@
}
},
"forwaderInvalidToken": {
- "message": "Invalid $SERVICENAME$ API token",
+ "message": "Netinkamas „$SERVICENAME$“ API prieigos raktas.",
"description": "Displayed when the user's API token is empty or rejected by the forwarding service.",
"placeholders": {
"servicename": {
@@ -2270,7 +2312,7 @@
}
},
"forwaderInvalidTokenWithMessage": {
- "message": "Invalid $SERVICENAME$ API token: $ERRORMESSAGE$",
+ "message": "Netinkamas „$SERVICENAME$“ API prieigos raktas: $ERRORMESSAGE$.",
"description": "Displayed when the user's API token is rejected by the forwarding service with an error message.",
"placeholders": {
"servicename": {
@@ -2284,7 +2326,7 @@
}
},
"forwarderNoAccountId": {
- "message": "Unable to obtain $SERVICENAME$ masked email account ID.",
+ "message": "Nepavyksta gauti „$SERVICENAME$“ užmaskuoto el. pašto paskyros ID.",
"description": "Displayed when the forwarding service fails to return an account ID.",
"placeholders": {
"servicename": {
@@ -2294,7 +2336,7 @@
}
},
"forwarderNoDomain": {
- "message": "Invalid $SERVICENAME$ domain.",
+ "message": "Netinkamas „$SERVICENAME$“ domenas.",
"description": "Displayed when the domain is empty or domain authorization failed at the forwarding service.",
"placeholders": {
"servicename": {
@@ -2304,7 +2346,7 @@
}
},
"forwarderNoUrl": {
- "message": "Invalid $SERVICENAME$ url.",
+ "message": "Netinkamas „$SERVICENAME$“ URL.",
"description": "Displayed when the url of the forwarding service wasn't supplied.",
"placeholders": {
"servicename": {
@@ -2314,7 +2356,7 @@
}
},
"forwarderUnknownError": {
- "message": "Unknown $SERVICENAME$ error occurred.",
+ "message": "Įvyko nežinoma „$SERVICENAME$“ klaida.",
"description": "Displayed when the forwarding service failed due to an unknown error.",
"placeholders": {
"servicename": {
@@ -2324,7 +2366,7 @@
}
},
"forwarderUnknownForwarder": {
- "message": "Unknown forwarder: '$SERVICENAME$'.",
+ "message": "Nežinomas persiuntėjas: „$SERVICENAME$“.",
"description": "Displayed when the forwarding service is not supported.",
"placeholders": {
"servicename": {
@@ -3245,13 +3287,13 @@
"message": "Administratoriaus konsolės"
},
"accountSecurity": {
- "message": "Account security"
+ "message": "Paskyros saugumas"
},
"notifications": {
- "message": "Notifications"
+ "message": "Pranešimai"
},
"appearance": {
- "message": "Appearance"
+ "message": "Išvaizda"
},
"errorAssigningTargetCollection": {
"message": "Klaida priskiriant tikslinę kolekciją."
diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json
index a7b50ae2a473..ac202682bab0 100644
--- a/apps/browser/src/_locales/lv/messages.json
+++ b/apps/browser/src/_locales/lv/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Atslēgt"
},
+ "additionalOptions": {
+ "message": "Papildu iespējas"
+ },
"enableContextMenuItem": {
"message": "Rādīt konteksta izvēlnes iespējas"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Izgūt no"
+ },
"exportVault": {
"message": "Izgūt glabātavas saturu"
},
"fileFormat": {
"message": "Datnes veids"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Šī datņu izgūšana būs aizsargāta ar paroli, un būs nepieciešama datnes parole, lai to atšifrētu."
+ },
+ "filePassword": {
+ "message": "Datnes parole"
+ },
+ "exportPasswordDescription": {
+ "message": "Šī parole tiks izmantota, lai izgūtu un ievietotu šo datni"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Jāizmanto konta šifrēšanas atslēga, kas iegūta no lietotājvārda un galvenās paroles, lai šifrētu izguvi un atļautu ievietošanu tikai pašreizējā Bitwarden kontā."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Uzstādīt paroli, lai šifrētu izguvi un tad to ievietotu jebkurā Bitwarden kontā, izmantojot atšifrēšanas paroli."
+ },
+ "exportTypeHeading": {
+ "message": "Izgūšanas veids"
+ },
+ "accountRestricted": {
+ "message": "Konts ir ierobežots"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Datnes parole\" un \"Apstiprināt datnes paroli\" vērtības nesakrīt."
+ },
"warning": {
"message": "UZMANĪBU",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -813,7 +843,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ā). Izdzēst to 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."
@@ -2171,7 +2201,7 @@
"message": "Sesijai iestājās noildze. Lūgums mēģināt pieteikties vēlreiz."
},
"exportingPersonalVaultTitle": {
- "message": "Izdod personīgo glabātavu"
+ "message": "Izgūst personīgo glabātavu"
},
"exportingIndividualVaultDescription": {
"message": "Tiks izgūti tikai atsevišķi glabātavas vienumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti. Tiks izgūta tikai glabātavas vienumu informācija, un saistītie pielikumi netiks iekļauti.",
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Izgūst apvienības glabātavu"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Kļūda"
},
@@ -2907,7 +2949,7 @@
"message": "Kļūda izguves datnes atšifrēšanā. Izmantotā atslēga neatbilst tai, kas tika izmantota satura izgūšanai."
},
"invalidFilePassword": {
- "message": "Nederīga datnes parole, lūgums izmantot to paroli, kas tika ievadīta izdošanas datnes izveidošanas brīdī."
+ "message": "Nederīga datnes parole, lūgums izmantot to paroli, kas tika ievadīta izgūšanas datnes izveidošanas brīdī."
},
"importDestination": {
"message": "Ievietošanas galamērķis"
diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json
index fba3e5486a50..d2a9b2db3898 100644
--- a/apps/browser/src/_locales/ml/messages.json
+++ b/apps/browser/src/_locales/ml/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "വാൾട് എക്സ്പോർട്"
},
"fileFormat": {
"message": "ഫയൽ ഫോർമാറ്റ്"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "മുന്നറിയിപ്പ്",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json
index fe984cb83026..6407be2c68db 100644
--- a/apps/browser/src/_locales/mr/messages.json
+++ b/apps/browser/src/_locales/mr/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json
index 64f3623b5af3..c3f03166b255 100644
--- a/apps/browser/src/_locales/my/messages.json
+++ b/apps/browser/src/_locales/my/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json
index 6993e1f648c2..d2feb8798e52 100644
--- a/apps/browser/src/_locales/nb/messages.json
+++ b/apps/browser/src/_locales/nb/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Lås opp"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Vis alternativer for kontekstmeny"
},
@@ -799,12 +802,39 @@
"message": "Solarisert mørk",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Eksporter hvelvet"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "ADVARSEL",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Feil"
},
diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json
index 64f3623b5af3..c3f03166b255 100644
--- a/apps/browser/src/_locales/ne/messages.json
+++ b/apps/browser/src/_locales/ne/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json
index 36a8ad9470ae..07c69ec596cf 100644
--- a/apps/browser/src/_locales/nl/messages.json
+++ b/apps/browser/src/_locales/nl/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Ontgrendelen"
},
+ "additionalOptions": {
+ "message": "Extra instellingen"
+ },
"enableContextMenuItem": {
"message": "Contextmenu-opties weergeven"
},
@@ -799,12 +802,39 @@
"message": "Overbelicht donker",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exporteren vanuit"
+ },
"exportVault": {
"message": "Kluis exporteren"
},
"fileFormat": {
"message": "Bestandsindeling"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "We beveiligen deze bestandsexport met een wachtwoord beveiligd, je hebt het bestandswachtwoord nodig om het te decoderen."
+ },
+ "filePassword": {
+ "message": "Bestandswachtwoord"
+ },
+ "exportPasswordDescription": {
+ "message": "We gebruiken dit wachtwoord bij het exporteren en importeren van dit bestand"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Gebruik de encryptiesleutel van je account, afgeleid van je gebruikersnaam en hoodfwachtwoord, om de export te versleutelen en importeren te beperken tot het huidige Bitwarden-account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Stel een bestandswachtwoord in om de export te versleutelen en te importeren naar een willekeurig Bitwarden-account met het wachtwoord voor decoderen."
+ },
+ "exportTypeHeading": {
+ "message": "Exporttype"
+ },
+ "accountRestricted": {
+ "message": "Account beperkt"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Bestandswachtwoord\" en \"Bestandswachtwoord bevestigen\" komen niet overeen."
+ },
"warning": {
"message": "WAARSCHUWING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Organisatiekluis exporteren"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Exporteert alleen de organisatiekluis van $ORGANIZATION$. Geen persoonlijke kluis-items of items van andere organisaties.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Fout"
},
diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json
index 64f3623b5af3..c3f03166b255 100644
--- a/apps/browser/src/_locales/nn/messages.json
+++ b/apps/browser/src/_locales/nn/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json
index 64f3623b5af3..c3f03166b255 100644
--- a/apps/browser/src/_locales/or/messages.json
+++ b/apps/browser/src/_locales/or/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json
index d5e3940682f8..c9959508c95b 100644
--- a/apps/browser/src/_locales/pl/messages.json
+++ b/apps/browser/src/_locales/pl/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Odblokuj"
},
+ "additionalOptions": {
+ "message": "Dodatkowe opcje"
+ },
"enableContextMenuItem": {
"message": "Pokaż opcje menu kontekstowego"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Eksportuj z"
+ },
"exportVault": {
"message": "Eksportuj sejf"
},
"fileFormat": {
"message": "Format pliku"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Plik będzie chroniony hasłem, które będzie wymagane do odszyfrowania pliku."
+ },
+ "filePassword": {
+ "message": "Hasło do pliku"
+ },
+ "exportPasswordDescription": {
+ "message": "Hasło będzie używane do eksportowania i importowania pliku"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Użyj klucza szyfrowania konta, pochodzącego z nazwy użytkownika konta i hasła głównego, aby zaszyfrować eksport i ograniczyć import tylko do bieżącego konta Bitwarden."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Ustaw hasło dla pliku, aby zaszyfrować eksport i zaimportować je na dowolne konto Bitwarden przy użyciu hasła do odszyfrowania."
+ },
+ "exportTypeHeading": {
+ "message": "Rodzaj eksportu"
+ },
+ "accountRestricted": {
+ "message": "Konto ograniczone"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“Hasło pliku” i “Potwierdź hasło pliku“ nie pasują do siebie."
+ },
"warning": {
"message": "UWAGA",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Eksportowanie sejfu organizacji"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Błąd"
},
diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json
index 0a65acf9586e..7f247311df6e 100644
--- a/apps/browser/src/_locales/pt_BR/messages.json
+++ b/apps/browser/src/_locales/pt_BR/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Desbloquear"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Mostrar opções de menu de contexto"
},
@@ -799,12 +802,39 @@
"message": "Solarized (escuro)",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exportar Cofre"
},
"fileFormat": {
"message": "Formato de arquivo"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "AVISO",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Erro"
},
diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json
index 7f4b488fa378..bcbddaff0a22 100644
--- a/apps/browser/src/_locales/pt_PT/messages.json
+++ b/apps/browser/src/_locales/pt_PT/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Desbloquear"
},
+ "additionalOptions": {
+ "message": "Opções adicionais"
+ },
"enableContextMenuItem": {
"message": "Mostrar opções do menu de contexto"
},
@@ -799,12 +802,39 @@
"message": "Solarized (escuro)",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exportar de"
+ },
"exportVault": {
"message": "Exportar cofre"
},
"fileFormat": {
"message": "Formato do ficheiro"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "A exportação deste ficheiro será protegida por uma palavra-passe e exigirá a palavra-passe do ficheiro para ser desencriptada."
+ },
+ "filePassword": {
+ "message": "Palavra-passe do ficheiro"
+ },
+ "exportPasswordDescription": {
+ "message": "Esta palavra-passe será utilizada para exportar e importar este ficheiro"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Utilize a chave de encriptação da sua conta, derivada do nome de utilizador e da palavra-passe mestra da sua conta, para encriptar a exportação e restringir a importação apenas à conta Bitwarden atual."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Defina uma palavra-passe do ficheiro para encriptar a exportação e importe-a para qualquer conta Bitwarden utilizando a palavra-passe de desencriptação."
+ },
+ "exportTypeHeading": {
+ "message": "Tipo de exportação"
+ },
+ "accountRestricted": {
+ "message": "Conta restringida"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Palavra-passe do ficheiro\" e \"Confirmar palavra-passe do ficheiro\" não correspondem."
+ },
"warning": {
"message": "AVISO",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "A exportar o cofre da organização"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Erro"
},
diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json
index 7c5cd8a3acdc..a9dae9496b6b 100644
--- a/apps/browser/src/_locales/ro/messages.json
+++ b/apps/browser/src/_locales/ro/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Deblocare"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Afișați opțiunile meniului contextual"
},
@@ -799,12 +802,39 @@
"message": "Întuneric solarizat",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export seif"
},
"fileFormat": {
"message": "Format fișier"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "AVERTISMENT",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Eroare"
},
diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json
index cbabda5066a0..438a04e96396 100644
--- a/apps/browser/src/_locales/ru/messages.json
+++ b/apps/browser/src/_locales/ru/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Разблокировать"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Показать опции контекстного меню"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Экспорт из"
+ },
"exportVault": {
"message": "Экспорт хранилища"
},
"fileFormat": {
"message": "Формат файла"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Экспорт этого файла будет защищен паролем, и для расшифровки потребуется пароль файла."
+ },
+ "filePassword": {
+ "message": "Пароль к файлу"
+ },
+ "exportPasswordDescription": {
+ "message": "Этот пароль будет использоваться для экспорта и импорта этого файла"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Использовать ключ шифрования вашего аккаунта, полученный из имени пользователя и мастер-пароля, для шифрования экспорта и ограничения импорта только для текущего аккаунта Bitwarden."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Установите пароль файла для шифрования экспорта и импортируйте его в любую учетную запись Bitwarden, используя пароль для расшифровки."
+ },
+ "exportTypeHeading": {
+ "message": "Тип экспорта"
+ },
+ "accountRestricted": {
+ "message": "Ограничено аккаунтом"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Пароль к файлу\" и \"Подтверждение пароля к файлу\" не совпадают."
+ },
"warning": {
"message": "ВНИМАНИЕ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Экспорт хранилища организации"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Будет экспортировано только хранилище организации, связанное с $ORGANIZATION$. Элементы из личных хранилищ и из других организаций включены не будут.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Ошибка"
},
diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json
index b9078c4c0f82..9fa1bb2339ca 100644
--- a/apps/browser/src/_locales/si/messages.json
+++ b/apps/browser/src/_locales/si/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "අඳුරු අඳුරු",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "අපනයන සුරක්ෂිතාගාරය"
},
"fileFormat": {
"message": "ගොනු ආකෘතිය"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "අවවාදයයි",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json
index 63bc7a317c0d..b9d7ec78cda5 100644
--- a/apps/browser/src/_locales/sk/messages.json
+++ b/apps/browser/src/_locales/sk/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Odomknúť"
},
+ "additionalOptions": {
+ "message": "Ďalšie možnosti"
+ },
"enableContextMenuItem": {
"message": "Zobraziť možnosti kontextovej ponuky"
},
@@ -799,12 +802,39 @@
"message": "Solarized – tmavý",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exportovať z"
+ },
"exportVault": {
"message": "Export trezoru"
},
"fileFormat": {
"message": "Formát Súboru"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Tento exportovaný súbor bude chránený heslom a na dešifrovanie bude potrebné heslo súboru."
+ },
+ "filePassword": {
+ "message": "Heslo súboru"
+ },
+ "exportPasswordDescription": {
+ "message": "Toto heslo sa použije na export a import tohto súboru"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Na zašifrovanie exportu a obmedzenie importu len na aktuálny účet Bitwarden použite šifrovací kľúč účtu odvodený z používateľského mena a hlavného hesla účtu."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Nastavte heslo súboru na zašifrovanie exportu a importujte ho do akéhokoľvek účtu Bitwarden pomocou hesla na dešifrovanie."
+ },
+ "exportTypeHeading": {
+ "message": "Typ exportu"
+ },
+ "accountRestricted": {
+ "message": "Obmedzený účet"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Heslo súboru\" a \"Potvrdiť heslo súboru\" sa nezhodujú."
+ },
"warning": {
"message": "UPOZORNENIE",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exportovanie trezora organizácie"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Chyba"
},
diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json
index c12a31436fd5..7333c0d91cc4 100644
--- a/apps/browser/src/_locales/sl/messages.json
+++ b/apps/browser/src/_locales/sl/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Prikaži možnosti kontekstnega menuja"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Izvoz trezorja"
},
"fileFormat": {
"message": "Format datoteke"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "OPOZORILO",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Napaka"
},
diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json
index 941b38132a4f..3d15f2464991 100644
--- a/apps/browser/src/_locales/sr/messages.json
+++ b/apps/browser/src/_locales/sr/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Откључај"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Прикажи контекстни мени"
},
@@ -799,12 +802,39 @@
"message": "Solarized црно",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Извоз сефа"
},
"fileFormat": {
"message": "Формат датотеке"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "УПОЗОРЕЊЕ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Грешка"
},
diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json
index 585d8e2d9a03..deb7fda04b33 100644
--- a/apps/browser/src/_locales/sv/messages.json
+++ b/apps/browser/src/_locales/sv/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Lås upp"
},
+ "additionalOptions": {
+ "message": "Ytterligare alternativ"
+ },
"enableContextMenuItem": {
"message": "Visa alternativ för snabbmenyn"
},
@@ -799,12 +802,39 @@
"message": "Solarized mörk",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Exportera från"
+ },
"exportVault": {
"message": "Exportera valv"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "Fillösenord"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Exporttyp"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "VARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Fel"
},
diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json
index 64f3623b5af3..c3f03166b255 100644
--- a/apps/browser/src/_locales/te/messages.json
+++ b/apps/browser/src/_locales/te/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Show context menu options"
},
@@ -799,12 +802,39 @@
"message": "Solarized dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "WARNING",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json
index bd708d0d6e4c..f6fc2f4c1de5 100644
--- a/apps/browser/src/_locales/th/messages.json
+++ b/apps/browser/src/_locales/th/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Unlock"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "แสดงตัวเลือกเมนูบริบท"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export Vault"
},
"fileFormat": {
"message": "File Format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "คำเตือน",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Error"
},
diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json
index 596e779913a9..4bee651cdbeb 100644
--- a/apps/browser/src/_locales/tr/messages.json
+++ b/apps/browser/src/_locales/tr/messages.json
@@ -185,7 +185,7 @@
"message": "Tarayıcınızın uzantı sitesine gitmek ister misiniz?"
},
"continueToBrowserExtensionStoreDesc": {
- "message": "Help others find out if Bitwarden is right for them. Visit your browser's extension store and leave a rating now."
+ "message": "Bitwarden'ı başkalarına da tanımak ister misiniz? Tarayıcınızın uzantı mağazasını ziyaret edip Bitwarden'ı değerlendirin."
},
"changeMasterPasswordOnWebConfirmation": {
"message": "Ana parolanızı Bitwarden web uygulamasında değiştirebilirsiniz."
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Kilidi aç"
},
+ "additionalOptions": {
+ "message": "Ek seçenekler"
+ },
"enableContextMenuItem": {
"message": "Bağlam menüsü seçeneklerini göster"
},
@@ -799,12 +802,39 @@
"message": "Solarized koyu",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Kasayı dışa aktar"
},
"fileFormat": {
"message": "Dosya biçimi"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "Dosya parolası"
+ },
+ "exportPasswordDescription": {
+ "message": "Bu parola, bu dosyayı dışa ve içe aktarmak için kullanılacaktır"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Dışa aktarmayı şifrelemek ve içe aktarmayı yalnızca mevcut Bitwarden hesabıyla kısıtlamak için, hesabınızın kullanıcı adı ve ana parolasından türetilen hesap şifreleme anahtarınızı kullanın."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Dışa aktardığınız dosyayı şifrelemek ve bir Bitwarden hesabına içe aktarmak için kullanacağınız parolayı belirleyin."
+ },
+ "exportTypeHeading": {
+ "message": "Dışa aktarma türü"
+ },
+ "accountRestricted": {
+ "message": "Hesap kısıtlı"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Dosya parolası\" ile \"Dosya parolasını onaylayın\" eşleşmiyor."
+ },
"warning": {
"message": "UYARI",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Kuruluş kasasını dışa aktarma"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Hata"
},
@@ -2548,7 +2590,7 @@
"message": "Creating account on"
},
"checkYourEmail": {
- "message": "Check your email"
+ "message": "E-postanızı kontrol edin"
},
"followTheLinkInTheEmailSentTo": {
"message": "Follow the link in the email sent to"
@@ -2560,10 +2602,10 @@
"message": "No email?"
},
"goBack": {
- "message": "Go back"
+ "message": "Geri dönüp"
},
"toEditYourEmailAddress": {
- "message": "to edit your email address."
+ "message": "e-posta adresinizi düzenleyin."
},
"eu": {
"message": "AB",
diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json
index 43861e99e938..a97d9626a4f8 100644
--- a/apps/browser/src/_locales/uk/messages.json
+++ b/apps/browser/src/_locales/uk/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Розблокувати"
},
+ "additionalOptions": {
+ "message": "Додаткові налаштування"
+ },
"enableContextMenuItem": {
"message": "Показувати в контекстному меню"
},
@@ -799,12 +802,39 @@
"message": "Solarized темна",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Експортувати з"
+ },
"exportVault": {
"message": "Експортувати сховище"
},
"fileFormat": {
"message": "Формат файлу"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Цей експортований файл буде захищений паролем, який необхідно ввести для його розшифрування."
+ },
+ "filePassword": {
+ "message": "Пароль файлу"
+ },
+ "exportPasswordDescription": {
+ "message": "Цей пароль буде використано для експортування та імпортування цього файлу"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Використовуйте ключ шифрування свого облікового запису, створений на основі імені користувача й головного пароля, щоб зашифрувати експортовані дані та обмежити можливість імпортування лише до поточного облікового запису Bitwarden."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Встановіть пароль файлу, щоб зашифрувати експортовані дані та імпортувати до будь-якого облікового запису Bitwarden за допомогою цього пароля."
+ },
+ "exportTypeHeading": {
+ "message": "Тип експорту"
+ },
+ "accountRestricted": {
+ "message": "Обмежено обліковим записом"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "Пароль файлу та підтвердження пароля відрізняються."
+ },
"warning": {
"message": "ПОПЕРЕДЖЕННЯ",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Експортування сховища організації"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Буде експортовано лише сховище організації, пов'язане з $ORGANIZATION$. Елементи особистих сховищ або інших організацій не будуть включені.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Помилка"
},
diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json
index 3d6bd434b1a5..c8469e97dc6a 100644
--- a/apps/browser/src/_locales/vi/messages.json
+++ b/apps/browser/src/_locales/vi/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "Mở khóa"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "Hiển thị tuỳ chọn menu ngữ cảnh"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Xuất kho lưu trữ"
},
"fileFormat": {
"message": "File Format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "CẢNH BÁO",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "Lỗi"
},
diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json
index f8464f892f84..609275567b86 100644
--- a/apps/browser/src/_locales/zh_CN/messages.json
+++ b/apps/browser/src/_locales/zh_CN/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "解锁"
},
+ "additionalOptions": {
+ "message": "附加选项"
+ },
"enableContextMenuItem": {
"message": "显示上下文菜单选项"
},
@@ -799,12 +802,39 @@
"message": "过曝暗",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "导出自"
+ },
"exportVault": {
"message": "导出密码库"
},
"fileFormat": {
"message": "文件格式"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "此文件导出将受密码保护,需要文件密码才能解密。"
+ },
+ "filePassword": {
+ "message": "文件密码"
+ },
+ "exportPasswordDescription": {
+ "message": "此密码将用于导出和导入此文件"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "使用衍生自您账户的用户名和主密码的账户加密密钥,以加密此导出并限制只能导入到当前的 Bitwarden 账户。"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "设置一个文件密码用来加密此导出,并使用此密码解密以导入到任意 Bitwarden 账户。"
+ },
+ "exportTypeHeading": {
+ "message": "导出类型"
+ },
+ "accountRestricted": {
+ "message": "账户受限"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "「文件密码」与「确认文件密码」不一致。"
+ },
"warning": {
"message": "警告",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "正在导出组织密码库"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "仅会导出与 $ORGANIZATION$ 关联的组织密码库数据。不包括个人密码库和其他组织中的项目。",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "错误"
},
diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json
index a3a7bbfb6863..79d8b51382ee 100644
--- a/apps/browser/src/_locales/zh_TW/messages.json
+++ b/apps/browser/src/_locales/zh_TW/messages.json
@@ -762,6 +762,9 @@
"notificationUnlock": {
"message": "解鎖"
},
+ "additionalOptions": {
+ "message": "Additional options"
+ },
"enableContextMenuItem": {
"message": "顯示內容選單選項"
},
@@ -799,12 +802,39 @@
"message": "Solarized Dark 主題",
"description": "'Solarized' is a noun and the name of a color scheme. It should not be translated."
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "匯出密碼庫"
},
"fileFormat": {
"message": "檔案格式"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"warning": {
"message": "警告",
"description": "WARNING (should stay in capitalized letters if the language permits)"
@@ -2182,6 +2212,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"error": {
"message": "錯誤"
},
diff --git a/apps/browser/src/autofill/background/abstractions/overlay.background.ts b/apps/browser/src/autofill/background/abstractions/overlay.background.ts
index c9b230fe18cb..aa62194af5c5 100644
--- a/apps/browser/src/autofill/background/abstractions/overlay.background.ts
+++ b/apps/browser/src/autofill/background/abstractions/overlay.background.ts
@@ -77,7 +77,9 @@ type OverlayBackgroundExtensionMessageHandlers = {
updateFocusedFieldData: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
collectPageDetailsResponse: ({ message, sender }: BackgroundOnMessageHandlerParams) => void;
unlockCompleted: ({ message }: BackgroundMessageParam) => void;
+ addedCipher: () => void;
addEditCipherSubmitted: () => void;
+ editedCipher: () => void;
deletedCipher: () => void;
};
diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts
index c469eb7dbbc1..df4867640f43 100644
--- a/apps/browser/src/autofill/background/overlay.background.spec.ts
+++ b/apps/browser/src/autofill/background/overlay.background.spec.ts
@@ -1000,29 +1000,23 @@ describe("OverlayBackground", () => {
});
});
- describe("addEditCipherSubmitted message handler", () => {
- it("updates the overlay ciphers", () => {
- const message = {
- command: "addEditCipherSubmitted",
- };
- jest.spyOn(overlayBackground as any, "updateOverlayCiphers").mockImplementation();
-
- sendMockExtensionMessage(message);
+ describe("extension messages that trigger an update of the inline menu ciphers", () => {
+ const extensionMessages = [
+ "addedCipher",
+ "addEditCipherSubmitted",
+ "editedCipher",
+ "deletedCipher",
+ ];
- expect(overlayBackground["updateOverlayCiphers"]).toHaveBeenCalled();
+ beforeEach(() => {
+ jest.spyOn(overlayBackground, "updateOverlayCiphers").mockImplementation();
});
- });
- describe("deletedCipher message handler", () => {
- it("updates the overlay ciphers", () => {
- const message = {
- command: "deletedCipher",
- };
- jest.spyOn(overlayBackground as any, "updateOverlayCiphers").mockImplementation();
-
- sendMockExtensionMessage(message);
-
- expect(overlayBackground["updateOverlayCiphers"]).toHaveBeenCalled();
+ extensionMessages.forEach((message) => {
+ it(`triggers an update of the overlay ciphers when the ${message} message is received`, () => {
+ sendMockExtensionMessage({ command: message });
+ expect(overlayBackground.updateOverlayCiphers).toHaveBeenCalled();
+ });
});
});
});
diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts
index 56f6a3a2158b..bf954c3419f7 100644
--- a/apps/browser/src/autofill/background/overlay.background.ts
+++ b/apps/browser/src/autofill/background/overlay.background.ts
@@ -72,7 +72,9 @@ class OverlayBackground implements OverlayBackgroundInterface {
updateFocusedFieldData: ({ message, sender }) => this.setFocusedFieldData(message, sender),
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
unlockCompleted: ({ message }) => this.unlockCompleted(message),
+ addedCipher: () => this.updateOverlayCiphers(),
addEditCipherSubmitted: () => this.updateOverlayCiphers(),
+ editedCipher: () => this.updateOverlayCiphers(),
deletedCipher: () => this.updateOverlayCiphers(),
};
private readonly overlayButtonPortMessageHandlers: OverlayButtonPortMessageHandlers = {
diff --git a/apps/browser/src/autofill/content/autofill-init.spec.ts b/apps/browser/src/autofill/content/autofill-init.spec.ts
index 4ea66edb3e16..302b520e336f 100644
--- a/apps/browser/src/autofill/content/autofill-init.spec.ts
+++ b/apps/browser/src/autofill/content/autofill-init.spec.ts
@@ -144,7 +144,7 @@ describe("AutofillInit", () => {
.mockResolvedValue(pageDetails);
const response = await autofillInit["handleExtensionMessage"](message, sender, sendResponse);
- await Promise.resolve(response);
+ await flushPromises();
expect(response).toBe(true);
expect(sendResponse).toHaveBeenCalledWith(pageDetails);
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html
index 56c67fba0936..30e00d4e641a 100644
--- a/apps/browser/src/autofill/popup/settings/autofill.component.html
+++ b/apps/browser/src/autofill/popup/settings/autofill.component.html
@@ -122,6 +122,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -139,5 +187,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.ts b/apps/browser/src/autofill/popup/settings/autofill.component.ts
index 1c6583331f42..7b8a1c32b449 100644
--- a/apps/browser/src/autofill/popup/settings/autofill.component.ts
+++ b/apps/browser/src/autofill/popup/settings/autofill.component.ts
@@ -4,13 +4,18 @@ import { firstValueFrom } from "rxjs";
import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants";
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
-import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types";
+import {
+ InlineMenuVisibilitySetting,
+ ClearClipboardDelaySetting,
+} from "@bitwarden/common/autofill/types";
import {
UriMatchStrategy,
UriMatchStrategySetting,
} from "@bitwarden/common/models/domain/domain-service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
import { DialogService } from "@bitwarden/components";
import { BrowserApi } from "../../../platform/browser/browser-api";
@@ -30,8 +35,14 @@ export class AutofillComponent implements OnInit {
enableAutoFillOnPageLoad = false;
autoFillOnPageLoadDefault = false;
autoFillOnPageLoadOptions: any[];
+ enableContextMenuItem = false;
+ enableAutoTotpCopy = false; // TODO: Does it matter if this is set to false or true?
+ clearClipboard: ClearClipboardDelaySetting;
+ clearClipboardOptions: any[];
defaultUriMatch: UriMatchStrategySetting = UriMatchStrategy.Domain;
uriMatchOptions: any[];
+ showCardsCurrentTab = false;
+ showIdentitiesCurrentTab = false;
autofillKeyboardHelperText: string;
accountSwitcherEnabled = false;
@@ -42,6 +53,8 @@ export class AutofillComponent implements OnInit {
private autofillService: AutofillService,
private dialogService: DialogService,
private autofillSettingsService: AutofillSettingsServiceAbstraction,
+ private messagingService: MessagingService,
+ private vaultSettingsService: VaultSettingsService,
) {
this.autoFillOverlayVisibilityOptions = [
{
@@ -61,6 +74,15 @@ export class AutofillComponent implements OnInit {
{ name: i18nService.t("autoFillOnPageLoadYes"), value: true },
{ name: i18nService.t("autoFillOnPageLoadNo"), value: false },
];
+ this.clearClipboardOptions = [
+ { name: i18nService.t("never"), value: null },
+ { name: i18nService.t("tenSeconds"), value: 10 },
+ { name: i18nService.t("twentySeconds"), value: 20 },
+ { name: i18nService.t("thirtySeconds"), value: 30 },
+ { name: i18nService.t("oneMinute"), value: 60 },
+ { name: i18nService.t("twoMinutes"), value: 120 },
+ { name: i18nService.t("fiveMinutes"), value: 300 },
+ ];
this.uriMatchOptions = [
{ name: i18nService.t("baseDomain"), value: UriMatchStrategy.Domain },
{ name: i18nService.t("host"), value: UriMatchStrategy.Host },
@@ -95,6 +117,14 @@ export class AutofillComponent implements OnInit {
this.autofillSettingsService.autofillOnPageLoadDefault$,
);
+ this.enableContextMenuItem = await firstValueFrom(
+ this.autofillSettingsService.enableContextMenu$,
+ );
+
+ this.enableAutoTotpCopy = await firstValueFrom(this.autofillSettingsService.autoCopyTotp$);
+
+ this.clearClipboard = await firstValueFrom(this.autofillSettingsService.clearClipboardDelay$);
+
const defaultUriMatch = await firstValueFrom(
this.domainSettingsService.defaultUriMatchStrategy$,
);
@@ -102,6 +132,12 @@ export class AutofillComponent implements OnInit {
const command = await this.platformUtilsService.getAutofillKeyboardShortcut();
await this.setAutofillKeyboardHelperText(command);
+
+ this.showCardsCurrentTab = await firstValueFrom(this.vaultSettingsService.showCardsCurrentTab$);
+
+ this.showIdentitiesCurrentTab = await firstValueFrom(
+ this.vaultSettingsService.showIdentitiesCurrentTab$,
+ );
}
async updateAutoFillOverlayVisibility() {
@@ -241,4 +277,25 @@ export class AutofillComponent implements OnInit {
async privacyPermissionGranted(): Promise
{
return await BrowserApi.permissionsGranted(["privacy"]);
}
+
+ async updateContextMenuItem() {
+ await this.autofillSettingsService.setEnableContextMenu(this.enableContextMenuItem);
+ this.messagingService.send("bgUpdateContextMenu");
+ }
+
+ async updateAutoTotpCopy() {
+ await this.autofillSettingsService.setAutoCopyTotp(this.enableAutoTotpCopy);
+ }
+
+ async saveClearClipboard() {
+ await this.autofillSettingsService.setClearClipboardDelay(this.clearClipboard);
+ }
+
+ async updateShowCardsCurrentTab() {
+ await this.vaultSettingsService.setShowCardsCurrentTab(this.showCardsCurrentTab);
+ }
+
+ async updateShowIdentitiesCurrentTab() {
+ await this.vaultSettingsService.setShowIdentitiesCurrentTab(this.showIdentitiesCurrentTab);
+ }
}
diff --git a/apps/browser/src/autofill/utils/index.spec.ts b/apps/browser/src/autofill/utils/index.spec.ts
index af67d4160155..dcb5aa646960 100644
--- a/apps/browser/src/autofill/utils/index.spec.ts
+++ b/apps/browser/src/autofill/utils/index.spec.ts
@@ -37,14 +37,29 @@ describe("generateRandomCustomElementName", () => {
});
describe("sendExtensionMessage", () => {
- it("sends a message to the extention", () => {
- const extensionMessageResponse = sendExtensionMessage("updateAutofillOverlayHidden", {
+ it("sends a message to the extension", async () => {
+ const extensionMessagePromise = sendExtensionMessage("updateAutofillOverlayHidden", {
display: "none",
});
- jest.spyOn(chrome.runtime, "sendMessage");
- expect(chrome.runtime.sendMessage).toHaveBeenCalled();
- expect(extensionMessageResponse).toEqual(Promise.resolve({}));
+ // Jest doesn't give anyway to select the typed overload of "sendMessage",
+ // a cast is needed to get the correct spy type.
+ const sendMessageSpy = jest.spyOn(chrome.runtime, "sendMessage") as unknown as jest.SpyInstance<
+ void,
+ [message: string, responseCallback: (response: string) => void],
+ unknown
+ >;
+
+ expect(sendMessageSpy).toHaveBeenCalled();
+
+ const [latestCall] = sendMessageSpy.mock.calls;
+ const responseCallback = latestCall[1];
+
+ responseCallback("sendMessageResponse");
+
+ const response = await extensionMessagePromise;
+
+ expect(response).toEqual("sendMessageResponse");
});
});
diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts
index 274649ef1303..a8654c92f032 100644
--- a/apps/browser/src/background/main.background.ts
+++ b/apps/browser/src/background/main.background.ts
@@ -9,6 +9,7 @@ import {
AuthRequestService,
LoginEmailServiceAbstraction,
LoginEmailService,
+ LogoutReason,
} from "@bitwarden/auth/common";
import { ApiService as ApiServiceAbstraction } from "@bitwarden/common/abstractions/api.service";
import { AuditService as AuditServiceAbstraction } from "@bitwarden/common/abstractions/audit.service";
@@ -135,6 +136,9 @@ import { DefaultStateProvider } from "@bitwarden/common/platform/state/implement
import { InlineDerivedStateProvider } from "@bitwarden/common/platform/state/implementations/inline-derived-state";
import { StateEventRegistrarService } from "@bitwarden/common/platform/state/state-event-registrar.service";
/* eslint-enable import/no-restricted-paths */
+import { SyncService } from "@bitwarden/common/platform/sync";
+// eslint-disable-next-line no-restricted-imports -- Needed for service creation
+import { DefaultSyncService } from "@bitwarden/common/platform/sync/internal";
import { DefaultThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service";
import { ApiService } from "@bitwarden/common/services/api.service";
import { AuditService } from "@bitwarden/common/services/audit.service";
@@ -165,8 +169,6 @@ import { CollectionService as CollectionServiceAbstraction } from "@bitwarden/co
import { CipherFileUploadService as CipherFileUploadServiceAbstraction } from "@bitwarden/common/vault/abstractions/file-upload/cipher-file-upload.service";
import { FolderApiServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder-api.service.abstraction";
import { InternalFolderService as InternalFolderServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
-import { SyncNotifierService as SyncNotifierServiceAbstraction } from "@bitwarden/common/vault/abstractions/sync/sync-notifier.service.abstraction";
-import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/abstractions/totp.service";
import { VaultSettingsService as VaultSettingsServiceAbstraction } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
@@ -175,8 +177,6 @@ import { CollectionService } from "@bitwarden/common/vault/services/collection.s
import { CipherFileUploadService } from "@bitwarden/common/vault/services/file-upload/cipher-file-upload.service";
import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder-api.service";
import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service";
-import { SyncNotifierService } from "@bitwarden/common/vault/services/sync/sync-notifier.service";
-import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service";
import { TotpService } from "@bitwarden/common/vault/services/totp.service";
import { VaultSettingsService } from "@bitwarden/common/vault/services/vault-settings/vault-settings.service";
import {
@@ -267,7 +267,7 @@ export default class MainBackground {
collectionService: CollectionServiceAbstraction;
vaultTimeoutService: VaultTimeoutService;
vaultTimeoutSettingsService: VaultTimeoutSettingsServiceAbstraction;
- syncService: SyncServiceAbstraction;
+ syncService: SyncService;
passwordGenerationService: PasswordGenerationServiceAbstraction;
passwordStrengthService: PasswordStrengthServiceAbstraction;
totpService: TotpServiceAbstraction;
@@ -305,7 +305,6 @@ export default class MainBackground {
policyApiService: PolicyApiServiceAbstraction;
sendApiService: SendApiServiceAbstraction;
userVerificationApiService: UserVerificationApiServiceAbstraction;
- syncNotifierService: SyncNotifierServiceAbstraction;
fido2UserInterfaceService: Fido2UserInterfaceServiceAbstraction;
fido2AuthenticatorService: Fido2AuthenticatorServiceAbstraction;
fido2ClientService: Fido2ClientServiceAbstraction;
@@ -375,8 +374,17 @@ export default class MainBackground {
}
};
- const logoutCallback = async (expired: boolean, userId?: UserId) =>
- await this.logout(expired, userId);
+ const logoutCallback = async (logoutReason: LogoutReason, userId?: UserId) =>
+ await this.logout(logoutReason, userId);
+
+ const refreshAccessTokenErrorCallback = () => {
+ // Send toast to popup
+ this.messagingService.send("showToast", {
+ type: "error",
+ title: this.i18nService.t("errorRefreshingAccessToken"),
+ message: this.i18nService.t("errorRefreshingAccessTokenDesc"),
+ });
+ };
const isDev = process.env.ENV === "development";
this.logService = new ConsoleLogService(isDev);
@@ -523,6 +531,7 @@ export default class MainBackground {
this.keyGenerationService,
this.encryptService,
this.logService,
+ logoutCallback,
);
const migrationRunner = new MigrationRunner(
@@ -608,9 +617,12 @@ export default class MainBackground {
this.platformUtilsService,
this.environmentService,
this.appIdService,
+ refreshAccessTokenErrorCallback,
+ this.logService,
+ (logoutReason: LogoutReason, userId?: UserId) => this.logout(logoutReason, userId),
this.vaultTimeoutSettingsService,
- (expired: boolean) => this.logout(expired),
);
+
this.domainSettingsService = new DefaultDomainSettingsService(this.stateProvider);
this.fileUploadService = new FileUploadService(this.logService);
this.cipherFileUploadService = new CipherFileUploadService(
@@ -624,7 +636,6 @@ export default class MainBackground {
this.i18nService,
this.stateProvider,
);
- this.syncNotifierService = new SyncNotifierService();
this.autofillSettingsService = new AutofillSettingsService(
this.stateProvider,
@@ -813,7 +824,7 @@ export default class MainBackground {
messageListener,
);
} else {
- this.syncService = new SyncService(
+ this.syncService = new DefaultSyncService(
this.masterPasswordService,
this.accountService,
this.apiService,
@@ -1283,7 +1294,7 @@ export default class MainBackground {
}
}
- async logout(expired: boolean, userId?: UserId) {
+ async logout(logoutReason: LogoutReason, userId?: UserId) {
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(
map((a) => a?.id),
@@ -1349,7 +1360,7 @@ export default class MainBackground {
await logoutPromise;
this.messagingService.send("doneLoggingOut", {
- expired: expired,
+ logoutReason: logoutReason,
userId: userBeingLoggedOut,
});
diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json
index 0c1bd2905ade..623e5d1b145c 100644
--- a/apps/browser/src/manifest.json
+++ b/apps/browser/src/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "__MSG_extName__",
"short_name": "__MSG_appName__",
- "version": "2024.5.1",
+ "version": "2024.6.0",
"description": "__MSG_extDesc__",
"default_locale": "en",
"author": "Bitwarden Inc.",
diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json
index 952396758df1..9b7dc42732f7 100644
--- a/apps/browser/src/manifest.v3.json
+++ b/apps/browser/src/manifest.v3.json
@@ -3,7 +3,7 @@
"minimum_chrome_version": "102.0",
"name": "__MSG_extName__",
"short_name": "__MSG_appName__",
- "version": "2024.5.1",
+ "version": "2024.6.0",
"description": "__MSG_extDesc__",
"default_locale": "en",
"author": "Bitwarden Inc.",
diff --git a/apps/browser/src/platform/popup/layout/popup-page.component.html b/apps/browser/src/platform/popup/layout/popup-page.component.html
index ece6be4c63ea..b3dcd626ae3e 100644
--- a/apps/browser/src/platform/popup/layout/popup-page.component.html
+++ b/apps/browser/src/platform/popup/layout/popup-page.component.html
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/apps/browser/src/platform/popup/popup-section-header/popup-section-header.component.html b/apps/browser/src/platform/popup/popup-section-header/popup-section-header.component.html
deleted file mode 100644
index 4fdbb8231209..000000000000
--- a/apps/browser/src/platform/popup/popup-section-header/popup-section-header.component.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/apps/browser/src/platform/popup/popup-section-header/popup-section-header.component.ts b/apps/browser/src/platform/popup/popup-section-header/popup-section-header.component.ts
deleted file mode 100644
index b33a2a0f330e..000000000000
--- a/apps/browser/src/platform/popup/popup-section-header/popup-section-header.component.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Component, Input } from "@angular/core";
-
-import { TypographyModule } from "@bitwarden/components";
-
-@Component({
- standalone: true,
- selector: "popup-section-header",
- templateUrl: "./popup-section-header.component.html",
- imports: [TypographyModule],
-})
-export class PopupSectionHeaderComponent {
- @Input() title: string;
-}
diff --git a/apps/browser/src/platform/popup/popup-section-header/popup-section-header.stories.ts b/apps/browser/src/platform/popup/popup-section-header/popup-section-header.stories.ts
deleted file mode 100644
index f5cb472a59c2..000000000000
--- a/apps/browser/src/platform/popup/popup-section-header/popup-section-header.stories.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Meta, moduleMetadata, StoryObj } from "@storybook/angular";
-
-import {
- CardComponent,
- IconButtonModule,
- SectionComponent,
- TypographyModule,
-} from "@bitwarden/components";
-
-import { PopupSectionHeaderComponent } from "./popup-section-header.component";
-
-export default {
- title: "Browser/Popup Section Header",
- component: PopupSectionHeaderComponent,
- args: {
- title: "Title",
- },
- decorators: [
- moduleMetadata({
- imports: [SectionComponent, CardComponent, TypographyModule, IconButtonModule],
- }),
- ],
-} as Meta
;
-
-type Story = StoryObj;
-
-export const OnlyTitle: Story = {
- render: (args) => ({
- props: args,
- template: `
-
- `,
- }),
- args: {
- title: "Only Title",
- },
-};
-
-export const TrailingText: Story = {
- render: (args) => ({
- props: args,
- template: `
-
- 13
-
- `,
- }),
- args: {
- title: "Trailing Text",
- },
-};
-
-export const TailingIcon: Story = {
- render: (args) => ({
- props: args,
- template: `
-
-
-
- `,
- }),
- args: {
- title: "Trailing Icon",
- },
-};
-
-export const TitleSuffix: Story = {
- render: (args) => ({
- props: args,
- template: `
-
-
-
- `,
- }),
- args: {
- title: "Title Suffix",
- },
-};
-
-export const WithSections: Story = {
- render: () => ({
- template: `
-
-
-
-
-
-
- Card 1 Content
-
-
-
-
-
-
-
- Card 2 Content
-
-
-
- `,
- }),
-};
diff --git a/apps/browser/src/popup/app-routing.animations.ts b/apps/browser/src/popup/app-routing.animations.ts
index b2fa53caba8c..065331bd414b 100644
--- a/apps/browser/src/popup/app-routing.animations.ts
+++ b/apps/browser/src/popup/app-routing.animations.ts
@@ -196,9 +196,6 @@ export const routerTransition = trigger("routerTransition", [
transition("vault-settings => sync", inSlideLeft),
transition("sync => vault-settings", outSlideRight),
- transition("tabs => options", inSlideLeft),
- transition("options => tabs", outSlideRight),
-
// Appearance settings
transition("tabs => appearance", inSlideLeft),
transition("appearance => tabs", outSlideRight),
diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts
index 9e0377a2f9a0..934bf0759a21 100644
--- a/apps/browser/src/popup/app-routing.module.ts
+++ b/apps/browser/src/popup/app-routing.module.ts
@@ -65,7 +65,6 @@ import { VaultSettingsComponent } from "../vault/popup/settings/vault-settings.c
import { extensionRefreshRedirect, extensionRefreshSwap } from "./extension-refresh-route-utils";
import { debounceNavigationGuard } from "./services/debounce-navigation.service";
-import { OptionsComponent } from "./settings/options.component";
import { TabsV2Component } from "./tabs-v2.component";
import { TabsComponent } from "./tabs.component";
@@ -309,12 +308,6 @@ const routes: Routes = [
canActivate: [AuthGuard],
data: { state: "premium" },
},
- {
- path: "options",
- component: OptionsComponent,
- canActivate: [AuthGuard],
- data: { state: "options" },
- },
{
path: "appearance",
component: AppearanceComponent,
diff --git a/apps/browser/src/popup/app.component.ts b/apps/browser/src/popup/app.component.ts
index 7e94e84ef5db..b70a5564ed92 100644
--- a/apps/browser/src/popup/app.component.ts
+++ b/apps/browser/src/popup/app.component.ts
@@ -2,6 +2,7 @@ import { ChangeDetectorRef, Component, NgZone, OnDestroy, OnInit } from "@angula
import { NavigationEnd, Router, RouterOutlet } from "@angular/router";
import { Subject, takeUntil, firstValueFrom, concatMap, filter, tap } from "rxjs";
+import { LogoutReason } from "@bitwarden/auth/common";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
@@ -10,7 +11,12 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { MessageListener } from "@bitwarden/common/platform/messaging";
import { UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
-import { DialogService, SimpleDialogOptions, ToastService } from "@bitwarden/components";
+import {
+ DialogService,
+ SimpleDialogOptions,
+ ToastOptions,
+ ToastService,
+} from "@bitwarden/components";
import { BrowserApi } from "../platform/browser/browser-api";
import { BrowserStateService } from "../platform/services/abstractions/browser-state.service";
@@ -83,13 +89,10 @@ export class AppComponent implements OnInit, OnDestroy {
.pipe(
tap((msg: any) => {
if (msg.command === "doneLoggingOut") {
+ // TODO: PM-8544 - why do we call logout in the popup after receiving the doneLoggingOut message? Hasn't this already completeted logout?
this.authService.logOut(async () => {
- if (msg.expired) {
- this.toastService.showToast({
- variant: "warning",
- title: this.i18nService.t("loggedOut"),
- message: this.i18nService.t("loginExpired"),
- });
+ if (msg.logoutReason) {
+ await this.displayLogoutReason(msg.logoutReason);
}
});
this.changeDetectorRef.detectChanges();
@@ -233,4 +236,23 @@ export class AppComponent implements OnInit, OnDestroy {
this.browserSendStateService.setBrowserSendTypeComponentState(null),
]);
}
+
+ // Displaying toasts isn't super useful on the popup due to the reloads we do.
+ // However, it is visible for a moment on the FF sidebar logout.
+ private async displayLogoutReason(logoutReason: LogoutReason) {
+ let toastOptions: ToastOptions;
+ switch (logoutReason) {
+ case "invalidSecurityStamp":
+ case "sessionExpired": {
+ toastOptions = {
+ variant: "warning",
+ title: this.i18nService.t("loggedOut"),
+ message: this.i18nService.t("loginExpired"),
+ };
+ break;
+ }
+ }
+
+ this.toastService.showToast(toastOptions);
+ }
}
diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts
index e16c33de3ae2..3c7f45e55f76 100644
--- a/apps/browser/src/popup/app.module.ts
+++ b/apps/browser/src/popup/app.module.ts
@@ -46,7 +46,6 @@ import { PopupFooterComponent } from "../platform/popup/layout/popup-footer.comp
import { PopupHeaderComponent } from "../platform/popup/layout/popup-header.component";
import { PopupPageComponent } from "../platform/popup/layout/popup-page.component";
import { PopupTabNavigationComponent } from "../platform/popup/layout/popup-tab-navigation.component";
-import { PopupSectionHeaderComponent } from "../platform/popup/popup-section-header/popup-section-header.component";
import { FilePopoutCalloutComponent } from "../tools/popup/components/file-popout-callout.component";
import { GeneratorComponent } from "../tools/popup/generator/generator.component";
import { PasswordGeneratorHistoryComponent } from "../tools/popup/generator/password-generator-history.component";
@@ -82,7 +81,6 @@ import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { UserVerificationComponent } from "./components/user-verification.component";
import { ServicesModule } from "./services/services.module";
-import { OptionsComponent } from "./settings/options.component";
import { TabsV2Component } from "./tabs-v2.component";
import { TabsComponent } from "./tabs.component";
@@ -120,7 +118,6 @@ import "../platform/popup/locales";
PopupFooterComponent,
PopupHeaderComponent,
UserVerificationDialogComponent,
- PopupSectionHeaderComponent,
CurrentAccountComponent,
],
declarations: [
@@ -149,7 +146,6 @@ import "../platform/popup/locales";
LoginComponent,
LoginViaAuthRequestComponent,
LoginDecryptionOptionsComponent,
- OptionsComponent,
NotificationsSettingsComponent,
AppearanceComponent,
GeneratorComponent,
diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts
index ace9af3dfa80..d61fa3b19c02 100644
--- a/apps/browser/src/popup/services/services.module.ts
+++ b/apps/browser/src/popup/services/services.module.ts
@@ -80,11 +80,11 @@ import {
} from "@bitwarden/common/platform/state";
// eslint-disable-next-line import/no-restricted-paths -- Used for dependency injection
import { InlineDerivedStateProvider } from "@bitwarden/common/platform/state/implementations/inline-derived-state";
+import { SyncService } from "@bitwarden/common/platform/sync";
import { VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
import { FolderService as FolderServiceAbstraction } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
-import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/abstractions/totp.service";
import { TotpService } from "@bitwarden/common/vault/services/totp.service";
import { DialogService, ToastService } from "@bitwarden/components";
diff --git a/apps/browser/src/popup/settings/options.component.html b/apps/browser/src/popup/settings/options.component.html
deleted file mode 100644
index 0382eb5b8665..000000000000
--- a/apps/browser/src/popup/settings/options.component.html
+++ /dev/null
@@ -1,135 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/browser/src/popup/settings/options.component.ts b/apps/browser/src/popup/settings/options.component.ts
deleted file mode 100644
index cfcc81bb22c6..000000000000
--- a/apps/browser/src/popup/settings/options.component.ts
+++ /dev/null
@@ -1,126 +0,0 @@
-import { Component, OnInit } from "@angular/core";
-import { firstValueFrom } from "rxjs";
-
-import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
-import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
-import { ClearClipboardDelaySetting } from "@bitwarden/common/autofill/types";
-import {
- UriMatchStrategy,
- UriMatchStrategySetting,
-} from "@bitwarden/common/models/domain/domain-service";
-import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
-import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
-import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
-
-import { enableAccountSwitching } from "../../platform/flags";
-
-@Component({
- selector: "app-options",
- templateUrl: "options.component.html",
-})
-export class OptionsComponent implements OnInit {
- enableAutoFillOnPageLoad = false;
- autoFillOnPageLoadDefault = false;
- autoFillOnPageLoadOptions: any[];
- enableAutoTotpCopy = false; // TODO: Does it matter if this is set to false or true?
- enableContextMenuItem = false;
- showCardsCurrentTab = false;
- showIdentitiesCurrentTab = false;
- showClearClipboard = true;
- defaultUriMatch: UriMatchStrategySetting = UriMatchStrategy.Domain;
- uriMatchOptions: any[];
- clearClipboard: ClearClipboardDelaySetting;
- clearClipboardOptions: any[];
- showGeneral = true;
- showDisplay = true;
- accountSwitcherEnabled = false;
-
- constructor(
- private messagingService: MessagingService,
- private autofillSettingsService: AutofillSettingsServiceAbstraction,
- private domainSettingsService: DomainSettingsService,
- i18nService: I18nService,
- private vaultSettingsService: VaultSettingsService,
- ) {
- this.uriMatchOptions = [
- { name: i18nService.t("baseDomain"), value: UriMatchStrategy.Domain },
- { name: i18nService.t("host"), value: UriMatchStrategy.Host },
- { name: i18nService.t("startsWith"), value: UriMatchStrategy.StartsWith },
- { name: i18nService.t("regEx"), value: UriMatchStrategy.RegularExpression },
- { name: i18nService.t("exact"), value: UriMatchStrategy.Exact },
- { name: i18nService.t("never"), value: UriMatchStrategy.Never },
- ];
- this.clearClipboardOptions = [
- { name: i18nService.t("never"), value: null },
- { name: i18nService.t("tenSeconds"), value: 10 },
- { name: i18nService.t("twentySeconds"), value: 20 },
- { name: i18nService.t("thirtySeconds"), value: 30 },
- { name: i18nService.t("oneMinute"), value: 60 },
- { name: i18nService.t("twoMinutes"), value: 120 },
- { name: i18nService.t("fiveMinutes"), value: 300 },
- ];
- this.autoFillOnPageLoadOptions = [
- { name: i18nService.t("autoFillOnPageLoadYes"), value: true },
- { name: i18nService.t("autoFillOnPageLoadNo"), value: false },
- ];
-
- this.accountSwitcherEnabled = enableAccountSwitching();
- }
-
- async ngOnInit() {
- this.enableAutoFillOnPageLoad = await firstValueFrom(
- this.autofillSettingsService.autofillOnPageLoad$,
- );
-
- this.autoFillOnPageLoadDefault = await firstValueFrom(
- this.autofillSettingsService.autofillOnPageLoadDefault$,
- );
-
- this.enableContextMenuItem = await firstValueFrom(
- this.autofillSettingsService.enableContextMenu$,
- );
-
- this.showCardsCurrentTab = await firstValueFrom(this.vaultSettingsService.showCardsCurrentTab$);
- this.showIdentitiesCurrentTab = await firstValueFrom(
- this.vaultSettingsService.showIdentitiesCurrentTab$,
- );
-
- this.enableAutoTotpCopy = await firstValueFrom(this.autofillSettingsService.autoCopyTotp$);
-
- const defaultUriMatch = await firstValueFrom(
- this.domainSettingsService.defaultUriMatchStrategy$,
- );
- this.defaultUriMatch = defaultUriMatch == null ? UriMatchStrategy.Domain : defaultUriMatch;
-
- this.clearClipboard = await firstValueFrom(this.autofillSettingsService.clearClipboardDelay$);
- }
-
- async updateContextMenuItem() {
- await this.autofillSettingsService.setEnableContextMenu(this.enableContextMenuItem);
- this.messagingService.send("bgUpdateContextMenu");
- }
-
- async updateAutoTotpCopy() {
- await this.autofillSettingsService.setAutoCopyTotp(this.enableAutoTotpCopy);
- }
-
- async updateAutoFillOnPageLoad() {
- await this.autofillSettingsService.setAutofillOnPageLoad(this.enableAutoFillOnPageLoad);
- }
-
- async updateAutoFillOnPageLoadDefault() {
- await this.autofillSettingsService.setAutofillOnPageLoadDefault(this.autoFillOnPageLoadDefault);
- }
-
- async updateShowCardsCurrentTab() {
- await this.vaultSettingsService.setShowCardsCurrentTab(this.showCardsCurrentTab);
- }
-
- async updateShowIdentitiesCurrentTab() {
- await this.vaultSettingsService.setShowIdentitiesCurrentTab(this.showIdentitiesCurrentTab);
- }
-
- async saveClearClipboard() {
- await this.autofillSettingsService.setClearClipboardDelay(this.clearClipboard);
- }
-}
diff --git a/apps/browser/src/tools/popup/settings/settings.component.html b/apps/browser/src/tools/popup/settings/settings.component.html
index 7dba3d0a3de5..c547229653e1 100644
--- a/apps/browser/src/tools/popup/settings/settings.component.html
+++ b/apps/browser/src/tools/popup/settings/settings.component.html
@@ -42,14 +42,6 @@
{{ "vault" | i18n }}
-
-
+
-
-
+
-
+
{{ "noItemsMatchSearch" | i18n }}
{{ "clearFiltersOrTryAnother" | i18n }}
-
+
+
+ {{ "organizationIsDeactivated" | i18n }}
+ {{ "contactYourOrgAdmin" | i18n }}
+
+
+
+
{
+ let testBed: TestBed;
let service: VaultPopupItemsService;
let allCiphers: Record;
let autoFillCiphers: CipherView[];
+ let mockOrg: Organization;
+ let mockCollections: CollectionView[];
+
const cipherServiceMock = mock();
const vaultSettingsServiceMock = mock();
+ const organizationServiceMock = mock();
+ const vaultPopupListFiltersServiceMock = mock();
const searchService = mock();
+ const collectionService = mock();
beforeEach(() => {
allCiphers = cipherFactory(10);
@@ -35,31 +50,109 @@ describe("VaultPopupItemsService", () => {
cipherList[2].favorite = true;
cipherList[3].favorite = true;
- cipherServiceMock.cipherViews$ = new BehaviorSubject(allCiphers).asObservable();
- searchService.searchCiphers.mockImplementation(async () => cipherList);
- cipherServiceMock.filterCiphersForUrl.mockImplementation(async () => autoFillCiphers);
- vaultSettingsServiceMock.showCardsCurrentTab$ = new BehaviorSubject(false).asObservable();
- vaultSettingsServiceMock.showIdentitiesCurrentTab$ = new BehaviorSubject(false).asObservable();
+ cipherServiceMock.getAllDecrypted.mockResolvedValue(cipherList);
+ cipherServiceMock.ciphers$ = new BehaviorSubject(null);
+ cipherServiceMock.localData$ = new BehaviorSubject(null);
+ searchService.searchCiphers.mockImplementation(async (_, __, ciphers) => ciphers);
+ cipherServiceMock.filterCiphersForUrl.mockImplementation(async (ciphers) =>
+ ciphers.filter((c) => ["0", "1"].includes(c.id)),
+ );
+ vaultSettingsServiceMock.showCardsCurrentTab$ = new BehaviorSubject(false);
+ vaultSettingsServiceMock.showIdentitiesCurrentTab$ = new BehaviorSubject(false);
+
+ vaultPopupListFiltersServiceMock.filters$ = new BehaviorSubject({
+ organization: null,
+ collection: null,
+ cipherType: null,
+ folder: null,
+ });
+ // Return all ciphers, `filterFunction$` will be tested in `VaultPopupListFiltersService`
+ vaultPopupListFiltersServiceMock.filterFunction$ = new BehaviorSubject(
+ (ciphers: CipherView[]) => ciphers,
+ );
jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(false);
jest
.spyOn(BrowserApi, "getTabFromCurrentWindow")
.mockResolvedValue({ url: "https://example.com" } as chrome.tabs.Tab);
- service = new VaultPopupItemsService(
- cipherServiceMock,
- vaultSettingsServiceMock,
- searchService,
- );
+
+ mockOrg = {
+ id: "org1",
+ name: "Organization 1",
+ planProductType: ProductType.Enterprise,
+ } as Organization;
+
+ mockCollections = [
+ { id: "col1", name: "Collection 1" } as CollectionView,
+ { id: "col2", name: "Collection 2" } as CollectionView,
+ ];
+
+ organizationServiceMock.organizations$ = new BehaviorSubject([mockOrg]);
+ collectionService.decryptedCollections$ = new BehaviorSubject(mockCollections);
+
+ testBed = TestBed.configureTestingModule({
+ providers: [
+ { provide: CipherService, useValue: cipherServiceMock },
+ { provide: VaultSettingsService, useValue: vaultSettingsServiceMock },
+ { provide: SearchService, useValue: searchService },
+ { provide: OrganizationService, useValue: organizationServiceMock },
+ { provide: VaultPopupListFiltersService, useValue: vaultPopupListFiltersServiceMock },
+ { provide: CollectionService, useValue: collectionService },
+ ],
+ });
+
+ service = testBed.inject(VaultPopupItemsService);
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
});
it("should be created", () => {
- service = new VaultPopupItemsService(
- cipherServiceMock,
- vaultSettingsServiceMock,
- searchService,
- );
+ service = testBed.inject(VaultPopupItemsService);
expect(service).toBeTruthy();
});
+ it("should merge cipher views with collections and organization", (done) => {
+ const cipherList = Object.values(allCiphers);
+ cipherList[0].organizationId = "org1";
+ cipherList[0].collectionIds = ["col1", "col2"];
+
+ service.autoFillCiphers$.subscribe((ciphers) => {
+ expect(ciphers[0].organization).toEqual(mockOrg);
+ expect(ciphers[0].collections).toContain(mockCollections[0]);
+ expect(ciphers[0].collections).toContain(mockCollections[1]);
+ done();
+ });
+ });
+
+ it("should update cipher list when cipherService.ciphers$ emits", async () => {
+ const tracker = new ObservableTracker(service.autoFillCiphers$);
+
+ await tracker.expectEmission();
+
+ (cipherServiceMock.ciphers$ as BehaviorSubject).next(null);
+
+ await tracker.expectEmission();
+
+ // Should only emit twice
+ expect(tracker.emissions.length).toBe(2);
+ await expect(tracker.pauseUntilReceived(3)).rejects.toThrow("Timeout exceeded");
+ });
+
+ it("should update cipher list when cipherService.localData$ emits", async () => {
+ const tracker = new ObservableTracker(service.autoFillCiphers$);
+
+ await tracker.expectEmission();
+
+ (cipherServiceMock.localData$ as BehaviorSubject).next(null);
+
+ await tracker.expectEmission();
+
+ // Should only emit twice
+ expect(tracker.emissions.length).toBe(2);
+ await expect(tracker.pauseUntilReceived(3)).rejects.toThrow("Timeout exceeded");
+ });
+
describe("autoFillCiphers$", () => {
it("should return empty array if there is no current tab", (done) => {
jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(null);
@@ -80,16 +173,10 @@ describe("VaultPopupItemsService", () => {
it("should filter ciphers for the current tab and types", (done) => {
const currentTab = { url: "https://example.com" } as chrome.tabs.Tab;
- vaultSettingsServiceMock.showCardsCurrentTab$ = new BehaviorSubject(true).asObservable();
- vaultSettingsServiceMock.showIdentitiesCurrentTab$ = new BehaviorSubject(true).asObservable();
+ (vaultSettingsServiceMock.showCardsCurrentTab$ as BehaviorSubject).next(true);
+ (vaultSettingsServiceMock.showIdentitiesCurrentTab$ as BehaviorSubject).next(true);
jest.spyOn(BrowserApi, "getTabFromCurrentWindow").mockResolvedValue(currentTab);
- service = new VaultPopupItemsService(
- cipherServiceMock,
- vaultSettingsServiceMock,
- searchService,
- );
-
service.autoFillCiphers$.subscribe((ciphers) => {
expect(cipherServiceMock.filterCiphersForUrl.mock.calls.length).toBe(1);
expect(cipherServiceMock.filterCiphersForUrl).toHaveBeenCalledWith(
@@ -114,12 +201,6 @@ describe("VaultPopupItemsService", () => {
Object.values(allCiphers),
);
- service = new VaultPopupItemsService(
- cipherServiceMock,
- vaultSettingsServiceMock,
- searchService,
- );
-
service.autoFillCiphers$.subscribe((ciphers) => {
expect(ciphers.length).toBe(10);
@@ -135,19 +216,18 @@ describe("VaultPopupItemsService", () => {
});
it("should filter autoFillCiphers$ down to search term", (done) => {
- const cipherList = Object.values(allCiphers);
const searchText = "Login";
- searchService.searchCiphers.mockImplementation(async () => {
- return cipherList.filter((cipher) => {
+ searchService.searchCiphers.mockImplementation(async (q, _, ciphers) => {
+ return ciphers.filter((cipher) => {
return cipher.name.includes(searchText);
});
});
- // there is only 1 Login returned for filteredCiphers. but two results expected because of other autofill types
+ // there is only 1 Login returned for filteredCiphers.
service.autoFillCiphers$.subscribe((ciphers) => {
expect(ciphers[0].name.includes(searchText)).toBe(true);
- expect(ciphers.length).toBe(2);
+ expect(ciphers.length).toBe(1);
done();
});
});
@@ -224,12 +304,7 @@ describe("VaultPopupItemsService", () => {
describe("emptyVault$", () => {
it("should return true if there are no ciphers", (done) => {
- cipherServiceMock.cipherViews$ = new BehaviorSubject({}).asObservable();
- service = new VaultPopupItemsService(
- cipherServiceMock,
- vaultSettingsServiceMock,
- searchService,
- );
+ cipherServiceMock.getAllDecrypted.mockResolvedValue([]);
service.emptyVault$.subscribe((empty) => {
expect(empty).toBe(true);
done();
diff --git a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts
index 9a66ada08c5f..189ce2c09f99 100644
--- a/apps/browser/src/vault/popup/services/vault-popup-items.service.ts
+++ b/apps/browser/src/vault/popup/services/vault-popup-items.service.ts
@@ -1,8 +1,11 @@
-import { Injectable } from "@angular/core";
+import { inject, Injectable, NgZone } from "@angular/core";
import {
BehaviorSubject,
combineLatest,
+ distinctUntilKeyChanged,
+ from,
map,
+ merge,
Observable,
of,
shareReplay,
@@ -12,13 +15,21 @@ import {
} from "rxjs";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
+import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
+import { Utils } from "@bitwarden/common/platform/misc/utils";
+import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
+import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
import { CipherType } from "@bitwarden/common/vault/enums";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import { BrowserApi } from "../../../platform/browser/browser-api";
+import { runInsideAngular } from "../../../platform/browser/run-inside-angular.operator";
import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils";
+import { PopupCipherView } from "../views/popup-cipher.view";
+
+import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-filters.service";
/**
* Service for managing the various item lists on the new Vault tab in the browser popup.
@@ -28,7 +39,8 @@ import BrowserPopupUtils from "../../../platform/popup/browser-popup-utils";
})
export class VaultPopupItemsService {
private _refreshCurrentTab$ = new Subject();
- private searchText$ = new BehaviorSubject("");
+ private _searchText$ = new BehaviorSubject("");
+ latestSearchText$: Observable = this._searchText$.asObservable();
/**
* Observable that contains the list of other cipher types that should be shown
@@ -67,14 +79,46 @@ export class VaultPopupItemsService {
* Observable that contains the list of all decrypted ciphers.
* @private
*/
- private _cipherList$: Observable = this.cipherService.cipherViews$.pipe(
- map((ciphers) => Object.values(ciphers)),
- shareReplay({ refCount: false, bufferSize: 1 }),
+ private _cipherList$: Observable = merge(
+ this.cipherService.ciphers$,
+ this.cipherService.localData$,
+ ).pipe(
+ runInsideAngular(inject(NgZone)), // Workaround to ensure cipher$ state provider emissions are run inside Angular
+ switchMap(() => Utils.asyncToObservable(() => this.cipherService.getAllDecrypted())),
+ switchMap((ciphers) =>
+ combineLatest([
+ this.organizationService.organizations$,
+ this.collectionService.decryptedCollections$,
+ ]).pipe(
+ map(([organizations, collections]) => {
+ const orgMap = Object.fromEntries(organizations.map((org) => [org.id, org]));
+ const collectionMap = Object.fromEntries(collections.map((col) => [col.id, col]));
+ return ciphers.map(
+ (cipher) =>
+ new PopupCipherView(
+ cipher,
+ cipher.collectionIds?.map((colId) => collectionMap[colId as CollectionId]),
+ orgMap[cipher.organizationId as OrganizationId],
+ ),
+ );
+ }),
+ ),
+ ),
+ shareReplay({ refCount: true, bufferSize: 1 }),
);
- private _filteredCipherList$ = combineLatest([this._cipherList$, this.searchText$]).pipe(
- switchMap(([ciphers, searchText]) =>
- this.searchService.searchCiphers(searchText, null, ciphers),
+ private _filteredCipherList$: Observable = combineLatest([
+ this._cipherList$,
+ this._searchText$,
+ this.vaultPopupListFiltersService.filterFunction$,
+ ]).pipe(
+ map(([ciphers, searchText, filterFunction]): [CipherView[], string] => [
+ filterFunction(ciphers),
+ searchText,
+ ]),
+ switchMap(
+ ([ciphers, searchText]) =>
+ this.searchService.searchCiphers(searchText, null, ciphers) as Promise,
),
shareReplay({ refCount: true, bufferSize: 1 }),
);
@@ -85,7 +129,7 @@ export class VaultPopupItemsService {
*
* See {@link refreshCurrentTab} to trigger re-evaluation of the current tab.
*/
- autoFillCiphers$: Observable = combineLatest([
+ autoFillCiphers$: Observable = combineLatest([
this._filteredCipherList$,
this._otherAutoFillTypes$,
this._currentAutofillTab$,
@@ -104,7 +148,7 @@ export class VaultPopupItemsService {
* List of favorite ciphers that are not currently suggested for autofill.
* Ciphers are sorted by last used date, then by name.
*/
- favoriteCiphers$: Observable = combineLatest([
+ favoriteCiphers$: Observable = combineLatest([
this.autoFillCiphers$,
this._filteredCipherList$,
]).pipe(
@@ -121,7 +165,7 @@ export class VaultPopupItemsService {
* List of all remaining ciphers that are not currently suggested for autofill or marked as favorite.
* Ciphers are sorted by name.
*/
- remainingCiphers$: Observable = combineLatest([
+ remainingCiphers$: Observable = combineLatest([
this.autoFillCiphers$,
this.favoriteCiphers$,
this._filteredCipherList$,
@@ -137,10 +181,19 @@ export class VaultPopupItemsService {
/**
* Observable that indicates whether a filter is currently applied to the ciphers.
- * @todo Implement filter/search functionality in PM-6824 and PM-6826.
*/
- hasFilterApplied$: Observable = this.searchText$.pipe(
- switchMap((text) => this.searchService.isSearchable(text)),
+ hasFilterApplied$ = combineLatest([
+ this._searchText$,
+ this.vaultPopupListFiltersService.filters$,
+ ]).pipe(
+ switchMap(([searchText, filters]) => {
+ return from(this.searchService.isSearchable(searchText)).pipe(
+ map(
+ (isSearchable) =>
+ isSearchable || Object.values(filters).some((filter) => filter !== null),
+ ),
+ );
+ }),
);
/**
@@ -156,16 +209,33 @@ export class VaultPopupItemsService {
/**
* Observable that indicates whether there are no ciphers to show with the current filter.
- * @todo Implement filter/search functionality in PM-6824 and PM-6826.
*/
noFilteredResults$: Observable = this._filteredCipherList$.pipe(
map((ciphers) => !ciphers.length),
);
+ /** Observable that indicates when the user should see the deactivated org state */
+ showDeactivatedOrg$: Observable = combineLatest([
+ this.vaultPopupListFiltersService.filters$.pipe(distinctUntilKeyChanged("organization")),
+ this.organizationService.organizations$,
+ ]).pipe(
+ map(([filters, orgs]) => {
+ if (!filters.organization || filters.organization.id === MY_VAULT_ID) {
+ return false;
+ }
+
+ const org = orgs.find((o) => o.id === filters.organization.id);
+ return org ? !org.enabled : false;
+ }),
+ );
+
constructor(
private cipherService: CipherService,
private vaultSettingsService: VaultSettingsService,
+ private vaultPopupListFiltersService: VaultPopupListFiltersService,
+ private organizationService: OrganizationService,
private searchService: SearchService,
+ private collectionService: CollectionService,
) {}
/**
@@ -176,7 +246,7 @@ export class VaultPopupItemsService {
}
applyFilter(newSearchText: string) {
- this.searchText$.next(newSearchText);
+ this._searchText$.next(newSearchText);
}
/**
diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts
new file mode 100644
index 000000000000..42626b52918d
--- /dev/null
+++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.spec.ts
@@ -0,0 +1,321 @@
+import { TestBed } from "@angular/core/testing";
+import { FormBuilder } from "@angular/forms";
+import { BehaviorSubject, skipWhile } from "rxjs";
+
+import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
+import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
+import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
+import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
+import { CipherType } from "@bitwarden/common/vault/enums";
+import { Collection } from "@bitwarden/common/vault/models/domain/collection";
+import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
+import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
+import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
+
+import { MY_VAULT_ID, VaultPopupListFiltersService } from "./vault-popup-list-filters.service";
+
+describe("VaultPopupListFiltersService", () => {
+ let service: VaultPopupListFiltersService;
+ const memberOrganizations$ = new BehaviorSubject<{ name: string; id: string }[]>([]);
+ const folderViews$ = new BehaviorSubject([]);
+ const cipherViews$ = new BehaviorSubject({});
+ const decryptedCollections$ = new BehaviorSubject([]);
+
+ const collectionService = {
+ decryptedCollections$,
+ getAllNested: () => Promise.resolve([]),
+ } as unknown as CollectionService;
+
+ const folderService = {
+ folderViews$,
+ } as unknown as FolderService;
+
+ const cipherService = {
+ cipherViews$,
+ } as unknown as CipherService;
+
+ const organizationService = {
+ memberOrganizations$,
+ } as unknown as OrganizationService;
+
+ const i18nService = {
+ t: (key: string) => key,
+ } as I18nService;
+
+ beforeEach(() => {
+ memberOrganizations$.next([]);
+ decryptedCollections$.next([]);
+
+ collectionService.getAllNested = () => Promise.resolve([]);
+ TestBed.configureTestingModule({
+ providers: [
+ {
+ provide: FolderService,
+ useValue: folderService,
+ },
+ {
+ provide: CipherService,
+ useValue: cipherService,
+ },
+ {
+ provide: OrganizationService,
+ useValue: organizationService,
+ },
+ {
+ provide: I18nService,
+ useValue: i18nService,
+ },
+ {
+ provide: CollectionService,
+ useValue: collectionService,
+ },
+ { provide: FormBuilder, useClass: FormBuilder },
+ ],
+ });
+
+ service = TestBed.inject(VaultPopupListFiltersService);
+ });
+
+ describe("cipherTypes", () => {
+ it("returns all cipher types", () => {
+ expect(service.cipherTypes.map((c) => c.value)).toEqual([
+ CipherType.Login,
+ CipherType.Card,
+ CipherType.Identity,
+ CipherType.SecureNote,
+ ]);
+ });
+ });
+
+ describe("organizations$", () => {
+ it('does not add "myVault" to the list of organizations when there are no organizations', (done) => {
+ memberOrganizations$.next([]);
+
+ service.organizations$.subscribe((organizations) => {
+ expect(organizations.map((o) => o.label)).toEqual([]);
+ done();
+ });
+ });
+
+ it('adds "myVault" to the list of organizations when there are other organizations', (done) => {
+ memberOrganizations$.next([{ name: "bobby's org", id: "1234-3323-23223" }]);
+
+ service.organizations$.subscribe((organizations) => {
+ expect(organizations.map((o) => o.label)).toEqual(["myVault", "bobby's org"]);
+ done();
+ });
+ });
+
+ it("sorts organizations by name", (done) => {
+ memberOrganizations$.next([
+ { name: "bobby's org", id: "1234-3323-23223" },
+ { name: "alice's org", id: "2223-4343-99888" },
+ ]);
+
+ service.organizations$.subscribe((organizations) => {
+ expect(organizations.map((o) => o.label)).toEqual([
+ "myVault",
+ "alice's org",
+ "bobby's org",
+ ]);
+ done();
+ });
+ });
+ });
+
+ describe("collections$", () => {
+ const testCollection = {
+ id: "14cbf8e9-7a2a-4105-9bf6-b15c01203cef",
+ name: "Test collection",
+ organizationId: "3f860945-b237-40bc-a51e-b15c01203ccf",
+ } as CollectionView;
+
+ const testCollection2 = {
+ id: "b15c0120-7a2a-4105-9bf6-b15c01203ceg",
+ name: "Test collection 2",
+ organizationId: "1203ccf-2432-123-acdd-b15c01203ccf",
+ } as CollectionView;
+
+ const testCollections = [testCollection, testCollection2];
+
+ beforeEach(() => {
+ decryptedCollections$.next(testCollections);
+
+ collectionService.getAllNested = () =>
+ Promise.resolve(
+ testCollections.map((c) => ({
+ children: [],
+ node: c,
+ parent: null,
+ })),
+ );
+ });
+
+ it("returns all collections", (done) => {
+ service.collections$.subscribe((collections) => {
+ expect(collections.map((c) => c.label)).toEqual(["Test collection", "Test collection 2"]);
+ done();
+ });
+ });
+
+ it("filters out collections that do not belong to an organization", () => {
+ service.filterForm.patchValue({
+ organization: { id: testCollection2.organizationId } as Organization,
+ });
+
+ service.collections$.subscribe((collections) => {
+ expect(collections.map((c) => c.label)).toEqual(["Test collection 2"]);
+ });
+ });
+
+ it("sets collection icon", (done) => {
+ service.collections$.subscribe((collections) => {
+ expect(collections.every(({ icon }) => icon === "bwi-collection")).toBeTruthy();
+ done();
+ });
+ });
+ });
+
+ describe("folders$", () => {
+ it('returns no folders when "No Folder" is the only option', (done) => {
+ folderViews$.next([{ id: null, name: "No Folder" }]);
+
+ service.folders$.subscribe((folders) => {
+ expect(folders).toEqual([]);
+ done();
+ });
+ });
+
+ it('moves "No Folder" to the end of the list', (done) => {
+ folderViews$.next([
+ { id: null, name: "No Folder" },
+ { id: "2345", name: "Folder 2" },
+ { id: "1234", name: "Folder 1" },
+ ]);
+
+ service.folders$.subscribe((folders) => {
+ expect(folders.map((f) => f.label)).toEqual(["Folder 1", "Folder 2", "itemsWithNoFolder"]);
+ done();
+ });
+ });
+
+ it("returns all folders when MyVault is selected", (done) => {
+ service.filterForm.patchValue({
+ organization: { id: MY_VAULT_ID } as Organization,
+ });
+
+ folderViews$.next([
+ { id: "1234", name: "Folder 1" },
+ { id: "2345", name: "Folder 2" },
+ ]);
+
+ service.folders$.subscribe((folders) => {
+ expect(folders.map((f) => f.label)).toEqual(["Folder 1", "Folder 2"]);
+ done();
+ });
+ });
+
+ it("sets folder icon", (done) => {
+ service.filterForm.patchValue({
+ organization: { id: MY_VAULT_ID } as Organization,
+ });
+
+ folderViews$.next([
+ { id: "1234", name: "Folder 1" },
+ { id: "2345", name: "Folder 2" },
+ ]);
+
+ service.folders$.subscribe((folders) => {
+ expect(folders.every(({ icon }) => icon === "bwi-folder")).toBeTruthy();
+ done();
+ });
+ });
+
+ it("returns folders that have ciphers within the selected organization", (done) => {
+ service.folders$.pipe(skipWhile((folders) => folders.length === 2)).subscribe((folders) => {
+ expect(folders.map((f) => f.label)).toEqual(["Folder 1"]);
+ done();
+ });
+
+ service.filterForm.patchValue({
+ organization: { id: "1234" } as Organization,
+ });
+
+ folderViews$.next([
+ { id: "1234", name: "Folder 1" },
+ { id: "2345", name: "Folder 2" },
+ ]);
+
+ cipherViews$.next({
+ "1": { folderId: "1234", organizationId: "1234" },
+ "2": { folderId: "2345", organizationId: "56789" },
+ });
+ });
+ });
+
+ describe("filterFunction$", () => {
+ const ciphers = [
+ { type: CipherType.Login, collectionIds: [], organizationId: null },
+ { type: CipherType.Card, collectionIds: ["1234"], organizationId: "8978" },
+ { type: CipherType.Identity, collectionIds: [], folderId: "5432", organizationId: null },
+ { type: CipherType.SecureNote, collectionIds: [], organizationId: null },
+ ] as CipherView[];
+
+ it("filters by cipherType", (done) => {
+ service.filterFunction$.subscribe((filterFunction) => {
+ expect(filterFunction(ciphers)).toEqual([ciphers[0]]);
+ done();
+ });
+
+ service.filterForm.patchValue({ cipherType: CipherType.Login });
+ });
+
+ it("filters by collection", (done) => {
+ const collection = { id: "1234" } as Collection;
+
+ service.filterFunction$.subscribe((filterFunction) => {
+ expect(filterFunction(ciphers)).toEqual([ciphers[1]]);
+ done();
+ });
+
+ service.filterForm.patchValue({ collection });
+ });
+
+ it("filters by folder", (done) => {
+ const folder = { id: "5432" } as FolderView;
+
+ service.filterFunction$.subscribe((filterFunction) => {
+ expect(filterFunction(ciphers)).toEqual([ciphers[2]]);
+ done();
+ });
+
+ service.filterForm.patchValue({ folder });
+ });
+
+ describe("organizationId", () => {
+ it("filters out ciphers that belong to an organization when MyVault is selected", (done) => {
+ const organization = { id: MY_VAULT_ID } as Organization;
+
+ service.filterFunction$.subscribe((filterFunction) => {
+ expect(filterFunction(ciphers)).toEqual([ciphers[0], ciphers[2], ciphers[3]]);
+ done();
+ });
+
+ service.filterForm.patchValue({ organization });
+ });
+
+ it("filters out ciphers that do not belong to the selected organization", (done) => {
+ const organization = { id: "8978" } as Organization;
+
+ service.filterFunction$.subscribe((filterFunction) => {
+ expect(filterFunction(ciphers)).toEqual([ciphers[1]]);
+ done();
+ });
+
+ service.filterForm.patchValue({ organization });
+ });
+ });
+ });
+});
diff --git a/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts
new file mode 100644
index 000000000000..69a7039e2acc
--- /dev/null
+++ b/apps/browser/src/vault/popup/services/vault-popup-list-filters.service.ts
@@ -0,0 +1,376 @@
+import { Injectable } from "@angular/core";
+import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
+import { FormBuilder } from "@angular/forms";
+import {
+ Observable,
+ combineLatest,
+ distinctUntilChanged,
+ map,
+ startWith,
+ switchMap,
+ tap,
+} from "rxjs";
+
+import { DynamicTreeNode } from "@bitwarden/angular/vault/vault-filter/models/dynamic-tree-node.model";
+import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
+import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
+import { ProductType } from "@bitwarden/common/enums";
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { Utils } from "@bitwarden/common/platform/misc/utils";
+import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
+import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
+import { FolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
+import { CipherType } from "@bitwarden/common/vault/enums";
+import { Collection } from "@bitwarden/common/vault/models/domain/collection";
+import { ITreeNodeObject, TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
+import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
+import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
+import { FolderView } from "@bitwarden/common/vault/models/view/folder.view";
+import { ServiceUtils } from "@bitwarden/common/vault/service-utils";
+import { ChipSelectOption } from "@bitwarden/components";
+
+/** All available cipher filters */
+export type PopupListFilter = {
+ organization: Organization | null;
+ collection: Collection | null;
+ folder: FolderView | null;
+ cipherType: CipherType | null;
+};
+
+/** Delimiter that denotes a level of nesting */
+const NESTING_DELIMITER = "/";
+
+/** Id assigned to the "My vault" organization */
+export const MY_VAULT_ID = "MyVault";
+
+const INITIAL_FILTERS: PopupListFilter = {
+ organization: null,
+ collection: null,
+ folder: null,
+ cipherType: null,
+};
+
+@Injectable({
+ providedIn: "root",
+})
+export class VaultPopupListFiltersService {
+ /**
+ * UI form for all filters
+ */
+ filterForm = this.formBuilder.group(INITIAL_FILTERS);
+
+ /**
+ * Observable for `filterForm` value
+ */
+ filters$ = this.filterForm.valueChanges.pipe(
+ startWith(INITIAL_FILTERS),
+ ) as Observable;
+
+ /**
+ * Static list of ciphers views used in synchronous context
+ */
+ private cipherViews: CipherView[] = [];
+
+ /**
+ * Observable of cipher views
+ */
+ private cipherViews$: Observable = this.cipherService.cipherViews$.pipe(
+ tap((cipherViews) => {
+ this.cipherViews = Object.values(cipherViews);
+ }),
+ map((ciphers) => Object.values(ciphers)),
+ );
+
+ constructor(
+ private folderService: FolderService,
+ private cipherService: CipherService,
+ private organizationService: OrganizationService,
+ private i18nService: I18nService,
+ private collectionService: CollectionService,
+ private formBuilder: FormBuilder,
+ ) {
+ this.filterForm.controls.organization.valueChanges
+ .pipe(takeUntilDestroyed())
+ .subscribe(this.validateOrganizationChange.bind(this));
+ }
+
+ /**
+ * Observable whose value is a function that filters an array of `CipherView` objects based on the current filters
+ */
+ filterFunction$: Observable<(ciphers: CipherView[]) => CipherView[]> = this.filters$.pipe(
+ map(
+ (filters) => (ciphers: CipherView[]) =>
+ ciphers.filter((cipher) => {
+ if (filters.cipherType !== null && cipher.type !== filters.cipherType) {
+ return false;
+ }
+
+ if (
+ filters.collection !== null &&
+ !cipher.collectionIds.includes(filters.collection.id)
+ ) {
+ return false;
+ }
+
+ if (filters.folder !== null && cipher.folderId !== filters.folder.id) {
+ return false;
+ }
+
+ const isMyVault = filters.organization?.id === MY_VAULT_ID;
+
+ if (isMyVault) {
+ if (cipher.organizationId !== null) {
+ return false;
+ }
+ } else if (filters.organization !== null) {
+ if (cipher.organizationId !== filters.organization.id) {
+ return false;
+ }
+ }
+
+ return true;
+ }),
+ ),
+ );
+
+ /**
+ * All available cipher types
+ */
+ readonly cipherTypes: ChipSelectOption[] = [
+ {
+ value: CipherType.Login,
+ label: this.i18nService.t("typeLogin"),
+ icon: "bwi-globe",
+ },
+ {
+ value: CipherType.Card,
+ label: this.i18nService.t("typeCard"),
+ icon: "bwi-credit-card",
+ },
+ {
+ value: CipherType.Identity,
+ label: this.i18nService.t("typeIdentity"),
+ icon: "bwi-id-card",
+ },
+ {
+ value: CipherType.SecureNote,
+ label: this.i18nService.t("note"),
+ icon: "bwi-sticky-note",
+ },
+ ];
+
+ /** Resets `filterForm` to the original state */
+ resetFilterForm(): void {
+ this.filterForm.reset(INITIAL_FILTERS);
+ }
+
+ /**
+ * Organization array structured to be directly passed to `ChipSelectComponent`
+ */
+ organizations$: Observable[]> =
+ this.organizationService.memberOrganizations$.pipe(
+ map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))),
+ map((orgs) => {
+ if (!orgs.length) {
+ return [];
+ }
+
+ return [
+ // When the user is a member of an organization, make the "My Vault" option available
+ {
+ value: { id: MY_VAULT_ID } as Organization,
+ label: this.i18nService.t("myVault"),
+ icon: "bwi-user",
+ },
+ ...orgs.map((org) => {
+ let icon = "bwi-business";
+
+ if (!org.enabled) {
+ // Show a warning icon if the organization is deactivated
+ icon = "bwi-exclamation-triangle tw-text-danger";
+ } else if (org.planProductType === ProductType.Families) {
+ // Show a family icon if the organization is a family org
+ icon = "bwi-family";
+ }
+
+ return {
+ value: org,
+ label: org.name,
+ icon,
+ };
+ }),
+ ];
+ }),
+ );
+
+ /**
+ * Folder array structured to be directly passed to `ChipSelectComponent`
+ */
+ folders$: Observable[]> = combineLatest([
+ this.filters$.pipe(
+ distinctUntilChanged(
+ (previousFilter, currentFilter) =>
+ // Only update the collections when the organizationId filter changes
+ previousFilter.organization?.id === currentFilter.organization?.id,
+ ),
+ ),
+ this.folderService.folderViews$,
+ this.cipherViews$,
+ ]).pipe(
+ map(([filters, folders, cipherViews]): [PopupListFilter, FolderView[], CipherView[]] => {
+ if (folders.length === 1 && folders[0].id === null) {
+ // Do not display folder selections when only the "no folder" option is available.
+ return [filters, [], cipherViews];
+ }
+
+ // Sort folders by alphabetic name
+ folders.sort(Utils.getSortFunction(this.i18nService, "name"));
+ let arrangedFolders = folders;
+
+ const noFolder = folders.find((f) => f.id === null);
+
+ if (noFolder) {
+ // Update `name` of the "no folder" option to "Items with no folder"
+ noFolder.name = this.i18nService.t("itemsWithNoFolder");
+
+ // Move the "no folder" option to the end of the list
+ arrangedFolders = [...folders.filter((f) => f.id !== null), noFolder];
+ }
+ return [filters, arrangedFolders, cipherViews];
+ }),
+ map(([filters, folders, cipherViews]) => {
+ const organizationId = filters.organization?.id ?? null;
+
+ // When no org or "My vault" is selected, return all folders
+ if (organizationId === null || organizationId === MY_VAULT_ID) {
+ return folders;
+ }
+
+ const orgCiphers = cipherViews.filter((c) => c.organizationId === organizationId);
+
+ // Return only the folders that have ciphers within the filtered organization
+ return folders.filter((f) => orgCiphers.some((oc) => oc.folderId === f.id));
+ }),
+ map((folders) => {
+ const nestedFolders = this.getAllFoldersNested(folders);
+ return new DynamicTreeNode({
+ fullList: folders,
+ nestedList: nestedFolders,
+ });
+ }),
+ map((folders) =>
+ folders.nestedList.map((f) => this.convertToChipSelectOption(f, "bwi-folder")),
+ ),
+ );
+
+ /**
+ * Collection array structured to be directly passed to `ChipSelectComponent`
+ */
+ collections$: Observable[]> = combineLatest([
+ this.filters$.pipe(
+ distinctUntilChanged(
+ (previousFilter, currentFilter) =>
+ // Only update the collections when the organizationId filter changes
+ previousFilter.organization?.id === currentFilter.organization?.id,
+ ),
+ ),
+ this.collectionService.decryptedCollections$,
+ ]).pipe(
+ map(([filters, allCollections]) => {
+ const organizationId = filters.organization?.id ?? null;
+ // When the organization filter is selected, filter out collections that do not belong to the selected organization
+ const collections =
+ organizationId === null
+ ? allCollections
+ : allCollections.filter((c) => c.organizationId === organizationId);
+
+ return collections;
+ }),
+ switchMap(async (collections) => {
+ const nestedCollections = await this.collectionService.getAllNested(collections);
+
+ return new DynamicTreeNode({
+ fullList: collections,
+ nestedList: nestedCollections,
+ });
+ }),
+ map((collections) =>
+ collections.nestedList.map((c) => this.convertToChipSelectOption(c, "bwi-collection")),
+ ),
+ );
+
+ /**
+ * Converts the given item into the `ChipSelectOption` structure
+ */
+ private convertToChipSelectOption(
+ item: TreeNode,
+ icon: string,
+ ): ChipSelectOption {
+ return {
+ value: item.node,
+ label: item.node.name,
+ icon,
+ children: item.children
+ ? item.children.map((i) => this.convertToChipSelectOption(i, icon))
+ : undefined,
+ };
+ }
+
+ /**
+ * Returns a nested folder structure based on the input FolderView array
+ */
+ private getAllFoldersNested(folders: FolderView[]): TreeNode[] {
+ const nodes: TreeNode[] = [];
+
+ folders.forEach((f) => {
+ const folderCopy = new FolderView();
+ folderCopy.id = f.id;
+ folderCopy.revisionDate = f.revisionDate;
+
+ // Remove "/" from beginning and end of the folder name
+ // then split the folder name by the delimiter
+ const parts = f.name != null ? f.name.replace(/^\/+|\/+$/g, "").split(NESTING_DELIMITER) : [];
+ ServiceUtils.nestedTraverse(nodes, 0, parts, folderCopy, null, NESTING_DELIMITER);
+ });
+
+ return nodes;
+ }
+
+ /**
+ * Validate collection & folder filters when the organization filter changes
+ */
+ private validateOrganizationChange(organization: Organization | null): void {
+ if (!organization) {
+ return;
+ }
+
+ const currentFilters = this.filterForm.getRawValue();
+
+ // When the organization filter changes and a collection is already selected,
+ // reset the collection filter if the collection does not belong to the new organization filter
+ if (currentFilters.collection && currentFilters.collection.organizationId !== organization.id) {
+ this.filterForm.get("collection").setValue(null);
+ }
+
+ // When the organization filter changes and a folder is already selected,
+ // reset the folder filter if the folder does not belong to the new organization filter
+ if (
+ currentFilters.folder &&
+ currentFilters.folder.id !== null &&
+ organization.id !== MY_VAULT_ID
+ ) {
+ // Get all ciphers that belong to the new organization
+ const orgCiphers = this.cipherViews.filter((c) => c.organizationId === organization.id);
+
+ // Find any ciphers within the organization that belong to the current folder
+ const newOrgContainsFolder = orgCiphers.some(
+ (oc) => oc.folderId === currentFilters.folder.id,
+ );
+
+ // If the new organization does not contain the current folder, reset the folder filter
+ if (!newOrgContainsFolder) {
+ this.filterForm.get("folder").setValue(null);
+ }
+ }
+ }
+}
diff --git a/apps/browser/src/vault/popup/settings/sync.component.ts b/apps/browser/src/vault/popup/settings/sync.component.ts
index 3fe4de9eb51a..16f388804bb4 100644
--- a/apps/browser/src/vault/popup/settings/sync.component.ts
+++ b/apps/browser/src/vault/popup/settings/sync.component.ts
@@ -2,7 +2,7 @@ import { Component, OnInit } from "@angular/core";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
+import { SyncService } from "@bitwarden/common/platform/sync";
@Component({
selector: "app-sync",
diff --git a/apps/browser/src/vault/popup/views/popup-cipher.view.ts b/apps/browser/src/vault/popup/views/popup-cipher.view.ts
new file mode 100644
index 000000000000..4707eb9eb0f6
--- /dev/null
+++ b/apps/browser/src/vault/popup/views/popup-cipher.view.ts
@@ -0,0 +1,41 @@
+import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
+import { ProductType } from "@bitwarden/common/enums";
+import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
+import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view";
+
+/**
+ * Extended cipher view for the popup. Includes the associated collections and organization
+ * if applicable.
+ */
+export class PopupCipherView extends CipherView {
+ collections?: CollectionView[];
+ organization?: Organization;
+
+ constructor(
+ cipher: CipherView,
+ collections: CollectionView[] = null,
+ organization: Organization = null,
+ ) {
+ super();
+ Object.assign(this, cipher);
+ this.collections = collections;
+ this.organization = organization;
+ }
+
+ /**
+ * Get the bwi icon for the cipher according to the organization type.
+ */
+ get orgIcon(): "bwi-family" | "bwi-business" | null {
+ switch (this.organization?.planProductType) {
+ case ProductType.Free:
+ case ProductType.Families:
+ return "bwi-family";
+ case ProductType.Teams:
+ case ProductType.Enterprise:
+ case ProductType.TeamsStarter:
+ return "bwi-business";
+ default:
+ return null;
+ }
+ }
+}
diff --git a/apps/browser/test.setup.ts b/apps/browser/test.setup.ts
index 4800b4c17f3e..5435c6fd7fed 100644
--- a/apps/browser/test.setup.ts
+++ b/apps/browser/test.setup.ts
@@ -1,3 +1,5 @@
+import "jest-preset-angular/setup-jest";
+
// Add chrome storage api
const QUOTA_BYTES = 10;
const storage = {
diff --git a/apps/browser/tsconfig.json b/apps/browser/tsconfig.json
index eb2c02fd3fd1..39f9c8211c7b 100644
--- a/apps/browser/tsconfig.json
+++ b/apps/browser/tsconfig.json
@@ -19,6 +19,9 @@
"@bitwarden/billing": ["../../libs/billing/src"],
"@bitwarden/common/*": ["../../libs/common/src/*"],
"@bitwarden/components": ["../../libs/components/src"],
+ "@bitwarden/generator-components": ["../../libs/tools/generator/components/src"],
+ "@bitwarden/generator-core": ["../../libs/tools/generator/core/src"],
+ "@bitwarden/generator-extensions": ["../../libs/tools/generator/extensions/src"],
"@bitwarden/vault-export-core": [
"../../libs/tools/export/vault-export/vault-export-core/src"
],
diff --git a/apps/browser/webpack.config.js b/apps/browser/webpack.config.js
index 2756ab4395fe..a0b86f06d5de 100644
--- a/apps/browser/webpack.config.js
+++ b/apps/browser/webpack.config.js
@@ -66,8 +66,7 @@ const moduleRules = [
{
loader: "babel-loader",
options: {
- configFile: false,
- plugins: ["@angular/compiler-cli/linker/babel"],
+ configFile: "../../babel.config.json",
},
},
],
diff --git a/apps/cli/package.json b/apps/cli/package.json
index d8ddde3d670c..1ad09cc17a54 100644
--- a/apps/cli/package.json
+++ b/apps/cli/package.json
@@ -1,7 +1,7 @@
{
"name": "@bitwarden/cli",
"description": "A secure and free password manager for all of your devices.",
- "version": "2024.5.0",
+ "version": "2024.6.0",
"keywords": [
"bitwarden",
"password",
diff --git a/apps/cli/src/platform/services/node-api.service.ts b/apps/cli/src/platform/services/node-api.service.ts
index 4849aef1512e..c480d9d1aff7 100644
--- a/apps/cli/src/platform/services/node-api.service.ts
+++ b/apps/cli/src/platform/services/node-api.service.ts
@@ -6,6 +6,7 @@ import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vaul
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
+import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { ApiService } from "@bitwarden/common/services/api.service";
@@ -21,8 +22,10 @@ export class NodeApiService extends ApiService {
platformUtilsService: PlatformUtilsService,
environmentService: EnvironmentService,
appIdService: AppIdService,
+ refreshAccessTokenErrorCallback: () => Promise,
+ logService: LogService,
+ logoutCallback: () => Promise,
vaultTimeoutSettingsService: VaultTimeoutSettingsService,
- logoutCallback: (expired: boolean) => Promise,
customUserAgent: string = null,
) {
super(
@@ -30,8 +33,10 @@ export class NodeApiService extends ApiService {
platformUtilsService,
environmentService,
appIdService,
- vaultTimeoutSettingsService,
+ refreshAccessTokenErrorCallback,
+ logService,
logoutCallback,
+ vaultTimeoutSettingsService,
customUserAgent,
);
}
diff --git a/apps/cli/src/program.ts b/apps/cli/src/program.ts
index e0311beb247f..597b388a05b1 100644
--- a/apps/cli/src/program.ts
+++ b/apps/cli/src/program.ts
@@ -83,6 +83,11 @@ export class Program extends BaseProgram {
});
program.on("--help", () => {
+ writeLn(
+ chalk.yellowBright(
+ "\n Tip: Managing and retrieving secrets for dev environments is easier with Bitwarden Secrets Manager. Learn more under https://bitwarden.com/products/secrets-manager/",
+ ),
+ );
writeLn("\n Examples:");
writeLn("");
writeLn(" bw login");
diff --git a/apps/cli/src/service-container.ts b/apps/cli/src/service-container.ts
index 882791ef9c9a..ff4eb52b84e5 100644
--- a/apps/cli/src/service-container.ts
+++ b/apps/cli/src/service-container.ts
@@ -97,6 +97,9 @@ import { DefaultStateProvider } from "@bitwarden/common/platform/state/implement
import { StateEventRegistrarService } from "@bitwarden/common/platform/state/state-event-registrar.service";
import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service";
/* eslint-enable import/no-restricted-paths */
+import { SyncService } from "@bitwarden/common/platform/sync";
+// eslint-disable-next-line no-restricted-imports -- Needed for service construction
+import { DefaultSyncService } from "@bitwarden/common/platform/sync/internal";
import { AuditService } from "@bitwarden/common/services/audit.service";
import { EventCollectionService } from "@bitwarden/common/services/event/event-collection.service";
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
@@ -120,8 +123,6 @@ import { CollectionService } from "@bitwarden/common/vault/services/collection.s
import { CipherFileUploadService } from "@bitwarden/common/vault/services/file-upload/cipher-file-upload.service";
import { FolderApiService } from "@bitwarden/common/vault/services/folder/folder-api.service";
import { FolderService } from "@bitwarden/common/vault/services/folder/folder.service";
-import { SyncNotifierService } from "@bitwarden/common/vault/services/sync/sync-notifier.service";
-import { SyncService } from "@bitwarden/common/vault/services/sync/sync.service";
import { TotpService } from "@bitwarden/common/vault/services/totp.service";
import {
ImportApiService,
@@ -216,7 +217,6 @@ export class ServiceContainer {
folderApiService: FolderApiService;
userVerificationApiService: UserVerificationApiService;
organizationApiService: OrganizationApiServiceAbstraction;
- syncNotifierService: SyncNotifierService;
sendApiService: SendApiService;
devicesApiService: DevicesApiServiceAbstraction;
deviceTrustService: DeviceTrustServiceAbstraction;
@@ -255,6 +255,8 @@ export class ServiceContainer {
p = path.join(process.env.HOME, ".config/Bitwarden CLI");
}
+ const logoutCallback = async () => await this.logout();
+
this.platformUtilsService = new CliPlatformUtilsService(ClientType.Cli, packageJson);
this.logService = new ConsoleLogService(
this.platformUtilsService.isDev(),
@@ -337,6 +339,7 @@ export class ServiceContainer {
this.keyGenerationService,
this.encryptService,
this.logService,
+ logoutCallback,
);
const migrationRunner = new MigrationRunner(
@@ -421,18 +424,22 @@ export class ServiceContainer {
VaultTimeoutStringType.Never, // default vault timeout
);
+ const refreshAccessTokenErrorCallback = () => {
+ throw new Error("Refresh Access token error");
+ };
+
this.apiService = new NodeApiService(
this.tokenService,
this.platformUtilsService,
this.environmentService,
this.appIdService,
+ refreshAccessTokenErrorCallback,
+ this.logService,
+ logoutCallback,
this.vaultTimeoutSettingsService,
- async (expired: boolean) => await this.logout(),
customUserAgent,
);
- this.syncNotifierService = new SyncNotifierService();
-
this.organizationApiService = new OrganizationApiService(this.apiService, this.syncService);
this.containerService = new ContainerService(this.cryptoService, this.encryptService);
@@ -485,7 +492,7 @@ export class ServiceContainer {
this.logService,
this.organizationService,
this.keyGenerationService,
- async (expired: boolean) => await this.logout(),
+ logoutCallback,
this.stateProvider,
);
@@ -639,7 +646,7 @@ export class ServiceContainer {
this.avatarService = new AvatarService(this.apiService, this.stateProvider);
- this.syncService = new SyncService(
+ this.syncService = new DefaultSyncService(
this.masterPasswordService,
this.accountService,
this.apiService,
@@ -660,7 +667,7 @@ export class ServiceContainer {
this.sendApiService,
this.userDecryptionOptionsService,
this.avatarService,
- async (expired: boolean) => await this.logout(),
+ logoutCallback,
this.billingAccountProfileStateService,
this.tokenService,
this.authService,
diff --git a/apps/cli/src/vault/sync.command.ts b/apps/cli/src/vault/sync.command.ts
index 073b9b5df48a..c3c6f6375384 100644
--- a/apps/cli/src/vault/sync.command.ts
+++ b/apps/cli/src/vault/sync.command.ts
@@ -1,4 +1,4 @@
-import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
+import { SyncService } from "@bitwarden/common/platform/sync";
import { Response } from "../models/response";
import { MessageResponse } from "../models/response/message.response";
diff --git a/apps/desktop/desktop_native/Cargo.lock b/apps/desktop/desktop_native/Cargo.lock
index c637ea044463..9353b6d44f82 100644
--- a/apps/desktop/desktop_native/Cargo.lock
+++ b/apps/desktop/desktop_native/Cargo.lock
@@ -39,9 +39,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.80"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "arboard"
@@ -169,7 +169,7 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
name = "base64"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64urlsafedata"
diff --git a/apps/desktop/desktop_native/Cargo.toml b/apps/desktop/desktop_native/Cargo.toml
index d6bf1ac58c76..7b960757cffb 100644
--- a/apps/desktop/desktop_native/Cargo.toml
+++ b/apps/desktop/desktop_native/Cargo.toml
@@ -14,9 +14,9 @@ manual_test = []
[dependencies]
aes = "=0.8.4"
-anyhow = "=1.0.80"
+anyhow = "=1.0.86"
arboard = { version = "=3.3.2", default-features = false, features = ["wayland-data-control"] }
-base64 = "=0.22.0"
+base64 = "=0.22.1"
cbc = { version = "=0.1.2", features = ["alloc"] }
futures = "0.3.30"
napi = { version = "=2.16.0", features = ["async", "tokio_rt"] }
diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json
index ef0927296a0e..39c62998a675 100644
--- a/apps/desktop/electron-builder.json
+++ b/apps/desktop/electron-builder.json
@@ -127,7 +127,7 @@
"entitlementsLoginHelper": "resources/entitlements.mas.loginhelper.plist",
"hardenedRuntime": false,
"extendInfo": {
- "LSMinimumSystemVersion": "10.15.0",
+ "LSMinimumSystemVersion": "12",
"ElectronTeamID": "LTZ2PFU5D6"
}
},
diff --git a/apps/desktop/native-messaging-test-runner/package-lock.json b/apps/desktop/native-messaging-test-runner/package-lock.json
index 747d8ec98118..ac12731398b6 100644
--- a/apps/desktop/native-messaging-test-runner/package-lock.json
+++ b/apps/desktop/native-messaging-test-runner/package-lock.json
@@ -18,8 +18,7 @@
"yargs": "17.7.2"
},
"devDependencies": {
- "@tsconfig/node16": "1.0.4",
- "@types/node": "18.19.29",
+ "@types/node": "20.14.1",
"@types/node-ipc": "9.2.3",
"typescript": "4.7.4"
}
@@ -99,9 +98,10 @@
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
},
"node_modules/@types/node": {
- "version": "18.19.29",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.29.tgz",
- "integrity": "sha512-5pAX7ggTmWZdhUrhRWLPf+5oM7F80bcKVCBbr0zwEkTNzTJL2CWQjznpFgHYy6GrzkYi2Yjy7DHKoynFxqPV8g==",
+ "version": "20.14.1",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.1.tgz",
+ "integrity": "sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==",
+ "license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
diff --git a/apps/desktop/native-messaging-test-runner/package.json b/apps/desktop/native-messaging-test-runner/package.json
index 72b2587a4ae0..0f92d5b0b3de 100644
--- a/apps/desktop/native-messaging-test-runner/package.json
+++ b/apps/desktop/native-messaging-test-runner/package.json
@@ -23,8 +23,7 @@
"yargs": "17.7.2"
},
"devDependencies": {
- "@tsconfig/node16": "1.0.4",
- "@types/node": "18.19.29",
+ "@types/node": "20.14.1",
"@types/node-ipc": "9.2.3",
"typescript": "4.7.4"
},
diff --git a/apps/desktop/package.json b/apps/desktop/package.json
index 90d9841a6183..129e9c43f09b 100644
--- a/apps/desktop/package.json
+++ b/apps/desktop/package.json
@@ -1,7 +1,7 @@
{
"name": "@bitwarden/desktop",
"description": "A secure and free password manager for all of your devices.",
- "version": "2024.5.0",
+ "version": "2024.6.0",
"keywords": [
"bitwarden",
"password",
diff --git a/apps/desktop/src/app/app.component.ts b/apps/desktop/src/app/app.component.ts
index 7feea649c306..e4fdd17dc158 100644
--- a/apps/desktop/src/app/app.component.ts
+++ b/apps/desktop/src/app/app.component.ts
@@ -1,3 +1,4 @@
+import { DialogRef } from "@angular/cdk/dialog";
import {
Component,
NgZone,
@@ -13,6 +14,7 @@ import { filter, firstValueFrom, map, Subject, takeUntil, timeout } from "rxjs";
import { ModalRef } from "@bitwarden/angular/components/modal/modal.ref";
import { ModalService } from "@bitwarden/angular/services/modal.service";
import { FingerprintDialogComponent } from "@bitwarden/auth/angular";
+import { LogoutReason } from "@bitwarden/auth/common";
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
@@ -40,15 +42,15 @@ import { SystemService } from "@bitwarden/common/platform/abstractions/system.se
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
import { clearCaches } from "@bitwarden/common/platform/misc/sequentialize";
import { StateEventRunnerService } from "@bitwarden/common/platform/state";
+import { SyncService } from "@bitwarden/common/platform/sync";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { UserId } from "@bitwarden/common/types/guid";
import { VaultTimeout, VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
-import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { CipherType } from "@bitwarden/common/vault/enums";
-import { DialogService, ToastService } from "@bitwarden/components";
+import { DialogService, ToastOptions, ToastService } from "@bitwarden/components";
import { DeleteAccountComponent } from "../auth/delete-account.component";
import { LoginApprovalComponent } from "../auth/login/login-approval.component";
@@ -108,6 +110,7 @@ export class AppComponent implements OnInit, OnDestroy {
private idleTimer: number = null;
private isIdle = false;
private activeUserId: UserId = null;
+ private activeSimpleDialog: DialogRef = null;
private destroy$ = new Subject();
@@ -207,7 +210,7 @@ export class AppComponent implements OnInit, OnDestroy {
break;
case "logout":
this.loading = message.userId == null || message.userId === this.activeUserId;
- await this.logOut(!!message.expired, message.userId);
+ await this.logOut(message.logoutReason, message.userId);
this.loading = false;
break;
case "lockVault":
@@ -545,9 +548,73 @@ export class AppComponent implements OnInit, OnDestroy {
this.messagingService.send("updateAppMenu", { updateRequest: updateRequest });
}
+ private async displayLogoutReason(logoutReason: LogoutReason) {
+ let toastOptions: ToastOptions;
+
+ switch (logoutReason) {
+ case "invalidSecurityStamp":
+ case "sessionExpired": {
+ toastOptions = {
+ variant: "warning",
+ title: this.i18nService.t("loggedOut"),
+ message: this.i18nService.t("loginExpired"),
+ };
+ break;
+ }
+ // We don't expect these scenarios to be common, but we want the user to
+ // understand why they are being logged out before a process reload.
+ case "accessTokenUnableToBeDecrypted": {
+ // Don't create multiple dialogs if this fires multiple times
+ if (this.activeSimpleDialog) {
+ // Let the caller of this function listen for the dialog to close
+ return firstValueFrom(this.activeSimpleDialog.closed);
+ }
+
+ this.activeSimpleDialog = this.dialogService.openSimpleDialogRef({
+ title: { key: "loggedOut" },
+ content: { key: "accessTokenUnableToBeDecrypted" },
+ acceptButtonText: { key: "ok" },
+ cancelButtonText: null,
+ type: "danger",
+ });
+
+ await firstValueFrom(this.activeSimpleDialog.closed);
+ this.activeSimpleDialog = null;
+
+ break;
+ }
+ case "refreshTokenSecureStorageRetrievalFailure": {
+ // Don't create multiple dialogs if this fires multiple times
+ if (this.activeSimpleDialog) {
+ // Let the caller of this function listen for the dialog to close
+ return firstValueFrom(this.activeSimpleDialog.closed);
+ }
+
+ this.activeSimpleDialog = this.dialogService.openSimpleDialogRef({
+ title: { key: "loggedOut" },
+ content: { key: "refreshTokenSecureStorageRetrievalFailure" },
+ acceptButtonText: { key: "ok" },
+ cancelButtonText: null,
+ type: "danger",
+ });
+
+ await firstValueFrom(this.activeSimpleDialog.closed);
+ this.activeSimpleDialog = null;
+
+ break;
+ }
+ }
+
+ if (toastOptions) {
+ this.toastService.showToast(toastOptions);
+ }
+ }
+
// Even though the userId parameter is no longer optional doesn't mean a message couldn't be
// passing null-ish values to us.
- private async logOut(expired: boolean, userId: UserId) {
+ private async logOut(logoutReason: LogoutReason, userId: UserId) {
+ await this.displayLogoutReason(logoutReason);
+
const activeUserId = await firstValueFrom(
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
);
@@ -620,15 +687,7 @@ export class AppComponent implements OnInit, OnDestroy {
// This must come last otherwise the logout will prematurely trigger
// a process reload before all the state service user data can be cleaned up
if (userBeingLoggedOut === activeUserId) {
- this.authService.logOut(async () => {
- if (expired) {
- this.platformUtilsService.showToast(
- "warning",
- this.i18nService.t("loggedOut"),
- this.i18nService.t("loginExpired"),
- );
- }
- });
+ this.authService.logOut(async () => {});
}
}
@@ -710,7 +769,7 @@ export class AppComponent implements OnInit, OnDestroy {
// 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
options[1] === "logOut"
- ? this.logOut(false, userId as UserId)
+ ? this.logOut("vaultTimeout", userId as UserId)
: await this.vaultTimeoutService.lock(userId);
}
}
diff --git a/apps/desktop/src/app/services/init.service.ts b/apps/desktop/src/app/services/init.service.ts
index 0452e9be837e..8793587300fe 100644
--- a/apps/desktop/src/app/services/init.service.ts
+++ b/apps/desktop/src/app/services/init.service.ts
@@ -15,10 +15,10 @@ import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@bitwar
import { StateService as StateServiceAbstraction } from "@bitwarden/common/platform/abstractions/state.service";
import { ContainerService } from "@bitwarden/common/platform/services/container.service";
import { UserAutoUnlockKeyService } from "@bitwarden/common/platform/services/user-auto-unlock-key.service";
+import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/platform/sync";
import { EventUploadService } from "@bitwarden/common/services/event/event-upload.service";
import { VaultTimeoutService } from "@bitwarden/common/services/vault-timeout/vault-timeout.service";
import { UserId } from "@bitwarden/common/types/guid";
-import { SyncService as SyncServiceAbstraction } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
import { I18nRendererService } from "../../platform/services/i18n.renderer.service";
import { NativeMessagingService } from "../../services/native-messaging.service";
diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json
index 28efbc7de4ef..27d0977a2e10 100644
--- a/apps/desktop/src/locales/af/messages.json
+++ b/apps/desktop/src/locales/af/messages.json
@@ -1299,12 +1299,42 @@
"message": "Wagwoord bygewerk",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Stuur Kluis Uit"
},
"fileFormat": {
"message": "Lêerformaat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha-bronadres",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Vergrendel"
},
diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json
index 25a91b95b6c8..a800840dd4a2 100644
--- a/apps/desktop/src/locales/ar/messages.json
+++ b/apps/desktop/src/locales/ar/messages.json
@@ -1299,12 +1299,42 @@
"message": "تم تحديث كلمة المرور",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "تصدير الخزنة"
},
"fileFormat": {
"message": "صيغة الملف"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "رابط hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "مقفل"
},
diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json
index c26e49d743c8..0143e6c2745f 100644
--- a/apps/desktop/src/locales/az/messages.json
+++ b/apps/desktop/src/locales/az/messages.json
@@ -1299,12 +1299,42 @@
"message": "Parol güncəlləndi",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Buradan xaricə köçür"
+ },
"exportVault": {
"message": "Anbarı xaricə köçür"
},
"fileFormat": {
"message": "Fayl formatı"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Bu faylın xaricə köçürülməsi, parolla qorunacaq və şifrəsini açmaq üçün fayl parolu tələb olunacaq."
+ },
+ "filePassword": {
+ "message": "Fayl parolu"
+ },
+ "exportPasswordDescription": {
+ "message": "Bu parol, bu faylı daxilə və xaricə köçürmək üçün istifadə olunacaq"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Xaricə köçürməni şifrələmək və daxilə köçürməni yalnız mövcud Bitwarden hesabı ilə məhdudlaşdırmaq üçün hesabınızın istifadəçi adı və Ana Parolundan əldə edilən hesab şifrələmə açarınızı istifadə edin."
+ },
+ "passwordProtected": {
+ "message": "Parolla qorunan"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Xaricə köçürməni şifrələmək üçün bir fayl parolu təyin edin və şifrəni açma parolunu istifadə edərək bunu istənilən Bitwarden hesabına köçürün."
+ },
+ "exportTypeHeading": {
+ "message": "Xaricə köçürmə növü"
+ },
+ "accountRestricted": {
+ "message": "Hesab məhdudlaşdırıldı"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Fayl parolu\" və \"Fayl parolunu təsdiqlə\" uyuşmur."
+ },
"hCaptchaUrl": {
"message": "hCaptcha ünvanı",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Təşkilat anbarını xaricə köçürmə"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Yalnız $ORGANIZATION$ ilə əlaqələndirilmiş təşkilat anbarı ixrac ediləcək. Fərdi anbardakı və digər təşkilat elementlər daxil edilmir.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Kilidli"
},
diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json
index 0371f3bcebbc..4adb3be3e5a4 100644
--- a/apps/desktop/src/locales/be/messages.json
+++ b/apps/desktop/src/locales/be/messages.json
@@ -1299,12 +1299,42 @@
"message": "Пароль абноўлены",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Экспартаваць сховішча"
},
"fileFormat": {
"message": "Фармат файла"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "URL-адрас hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Заблакіравана"
},
diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json
index 071399419c75..7471bebe0299 100644
--- a/apps/desktop/src/locales/bg/messages.json
+++ b/apps/desktop/src/locales/bg/messages.json
@@ -1299,12 +1299,42 @@
"message": "Обновена парола",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Изнасяне от"
+ },
"exportVault": {
"message": "Изнасяне на трезора"
},
"fileFormat": {
"message": "Формат на файла"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Изнесеният файл ще бъде защитен с парола, която ще бъде необходима за дешифриране на файла."
+ },
+ "filePassword": {
+ "message": "Парола на файла"
+ },
+ "exportPasswordDescription": {
+ "message": "Парола ще се използва при изнасянето и при внасянето на този файл"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Използвайте ключа си за шифриране, който се получава чрез комбиниране на потребителското име на регистрацията Ви и главната парола. С него изнасянето ще се шифрира и внасянето ще бъда възможно само в текущата регистрация в Битуорден."
+ },
+ "passwordProtected": {
+ "message": "Защита с парола"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Задайте парола за файла, за да шифровате изнесените данни. Ще можете да внесете данните във всяка регистрация в Битуорден използвайки паролата за дешифриране."
+ },
+ "exportTypeHeading": {
+ "message": "Вид изнасяне"
+ },
+ "accountRestricted": {
+ "message": "Регистрацията е ограничена"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "Дънните в полетата „Парола на файла“ и „Потвърждаване на паролата на файла“ не съвпадат."
+ },
"hCaptchaUrl": {
"message": "Адрес за hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Изнасяне на трезора на организацията"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Ще бъдат изнесени само записите от трезора свързан с $ORGANIZATION$. Записите в отделните лични трезори и тези в други организации няма да бъдат включени.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Заключено"
},
diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json
index a6f0e712063f..71749add465f 100644
--- a/apps/desktop/src/locales/bn/messages.json
+++ b/apps/desktop/src/locales/bn/messages.json
@@ -1299,12 +1299,42 @@
"message": "পাসওয়ার্ড হালনাগাদকৃত",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "ভল্ট রফতানি"
},
"fileFormat": {
"message": "ফাইলের ধরণ"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json
index 1a489ea397df..a11dbb7e9b9f 100644
--- a/apps/desktop/src/locales/bs/messages.json
+++ b/apps/desktop/src/locales/bs/messages.json
@@ -1299,12 +1299,42 @@
"message": "Lozinka ažurirana",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Izvezi trezor"
},
"fileFormat": {
"message": "Format datoteke"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json
index e55128ceeb45..abee9ac2ff09 100644
--- a/apps/desktop/src/locales/ca/messages.json
+++ b/apps/desktop/src/locales/ca/messages.json
@@ -1299,12 +1299,42 @@
"message": "Contrasenya actualitzada",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exporta caixa forta"
},
"fileFormat": {
"message": "Format de fitxer"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "Url hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Bloquejat"
},
diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json
index b5f2a4f5f0cb..bcb08de2bea9 100644
--- a/apps/desktop/src/locales/cs/messages.json
+++ b/apps/desktop/src/locales/cs/messages.json
@@ -1299,12 +1299,42 @@
"message": "Heslo bylo aktualizováno",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Exportovat z"
+ },
"exportVault": {
"message": "Exportovat trezor"
},
"fileFormat": {
"message": "Formát souboru"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Tento soubor exportu bude chráněn heslem a k dešifrování bude vyžadovat heslo souboru."
+ },
+ "filePassword": {
+ "message": "Heslo souboru"
+ },
+ "exportPasswordDescription": {
+ "message": "Toto heslo bude použito pro export a import tohoto souboru"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Pro zašifrování exportu a omezení importu pouze na aktuální účet Bitwardenu použijte šifrovací klíč Vašeho účtu odvozený z uživatelského jména a hlavního hesla."
+ },
+ "passwordProtected": {
+ "message": "Chráněno heslem"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Nastavte heslo pro šifrování exportu a importujte ho do libovolného účtu Bitwardenu pomocí hesla pro dešifrování."
+ },
+ "exportTypeHeading": {
+ "message": "Typ exportu"
+ },
+ "accountRestricted": {
+ "message": "Účet je omezený"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Heslo souboru\" a \"Potvrzení hesla souboru\" se neshodují."
+ },
"hCaptchaUrl": {
"message": "URL hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exportování trezoru organizace"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Uzamčeno"
},
@@ -2379,7 +2421,7 @@
"message": "Tento požadavek již není platný."
},
"approveLoginRequestDesc": {
- "message": "Použijte toto zařízení pro schvalování žádostí o přihlášení z jiných zařízení."
+ "message": "Použije toto zařízení pro schvalování žádostí o přihlášení z jiných zařízení."
},
"confirmLoginAtemptForMail": {
"message": "Potvrďte pokus o přihlášení z $EMAIL$",
diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json
index aeb76cba5522..5085234b826d 100644
--- a/apps/desktop/src/locales/cy/messages.json
+++ b/apps/desktop/src/locales/cy/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json
index 8965c8e2a120..e851f1df4511 100644
--- a/apps/desktop/src/locales/da/messages.json
+++ b/apps/desktop/src/locales/da/messages.json
@@ -1299,12 +1299,42 @@
"message": "Adgangskode opdateret",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Eksportér fra"
+ },
"exportVault": {
"message": "Eksportér boks"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Denne fileksport vil være adgangskodebeskyttet og kræve filadgangskoden at dekryptere."
+ },
+ "filePassword": {
+ "message": "Filadgangskode"
+ },
+ "exportPasswordDescription": {
+ "message": "Denne adgangskode vil blive brugt ved eksport og import af denne fil"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Brug kontokrypteringsnøglen, dannet af kontobrugernavn og Hovedadgangskode, for at kryptere eksporten og hindre import til andre end den aktuelle Bitwarden-konto."
+ },
+ "passwordProtected": {
+ "message": "Adgangskodebeskyttet"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Opsæt en adgangskode til både at kryptere eksporten samt dekryptere denne ved import til enhver Bitwarden-konto."
+ },
+ "exportTypeHeading": {
+ "message": "Eksporttype"
+ },
+ "accountRestricted": {
+ "message": "Konto begrænset"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“Filadgangskode” og “Bekræft filadgangskode“ matcher ikke."
+ },
"hCaptchaUrl": {
"message": "hCaptcha-URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Eksport af organisationsboks"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Kun organisationsboksen tilknyttet $ORGANIZATION$ eksporteres. Emner i individuelle bokse eller andre organisationer medtages ikke.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Låst"
},
diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json
index d544b10bb64a..e5abc4437239 100644
--- a/apps/desktop/src/locales/de/messages.json
+++ b/apps/desktop/src/locales/de/messages.json
@@ -1299,12 +1299,42 @@
"message": "Passwort aktualisiert",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export aus"
+ },
"exportVault": {
"message": "Tresor exportieren"
},
"fileFormat": {
"message": "Dateiformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Dieser Datei-Export ist passwortgeschützt und erfordert das Dateipasswort zum Entschlüsseln."
+ },
+ "filePassword": {
+ "message": "Dateipasswort"
+ },
+ "exportPasswordDescription": {
+ "message": "Dieses Passwort wird zum Exportieren und Importieren dieser Datei verwendet"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Verwende den Verschlüsselungsschlüssel deines Kontos, abgeleitet vom Benutzernamen und Master-Passwort, um den Export zu verschlüsseln und den Import auf das aktuelle Bitwarden-Konto zu beschränken."
+ },
+ "passwordProtected": {
+ "message": "Passwortgeschützt"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Lege ein Dateipasswort fest, um den Export zu verschlüsseln und importiere ihn in ein beliebiges Bitwarden-Konto, wobei das Passwort zum Entschlüsseln genutzt wird."
+ },
+ "exportTypeHeading": {
+ "message": "Exporttyp"
+ },
+ "accountRestricted": {
+ "message": "Konto eingeschränkt"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "„Dateipasswort“ und „Dateipasswort bestätigen“ stimmen nicht überein."
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Tresor der Organisation wird exportiert"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Nur der mit $ORGANIZATION$ verbundene Organisationstresor wird exportiert. Einträge in persönlichen Tresoren oder anderen Organisationen werden nicht berücksichtigt.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Gesperrt"
},
diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json
index 03c7d2183c04..af932beb008a 100644
--- a/apps/desktop/src/locales/el/messages.json
+++ b/apps/desktop/src/locales/el/messages.json
@@ -1299,12 +1299,42 @@
"message": "Ο Κωδικός Ενημερώθηκε",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Εξαγωγή Vault"
},
"fileFormat": {
"message": "Μορφή Αρχείου"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Κλειδωμένο"
},
diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json
index d27f2735f4c0..709994fb98b1 100644
--- a/apps/desktop/src/locales/en/messages.json
+++ b/apps/desktop/src/locales/en/messages.json
@@ -695,6 +695,15 @@
"selfHostedEnvironmentFooter": {
"message": "Specify the base URL of your on-premises hosted Bitwarden installation."
},
+ "selfHostedBaseUrlHint": {
+ "message": "Specify the base URL of your on-premises hosted Bitwarden installation. Example: https://bitwarden.company.com"
+ },
+ "selfHostedCustomEnvHeader" :{
+ "message": "For advanced configuration, you can specify the base URL of each service independently."
+ },
+ "selfHostedEnvFormInvalid" :{
+ "message": "You must add either the base Server URL or at least one custom environment."
+ },
"customEnvironment": {
"message": "Custom environment"
},
@@ -743,6 +752,9 @@
"loggedOut": {
"message": "Logged out"
},
+ "loggedOutDesc": {
+ "message": "You have been logged out of your account."
+ },
"loginExpired": {
"message": "Your login session has expired."
},
@@ -1212,6 +1224,12 @@
}
}
},
+ "errorRefreshingAccessToken":{
+ "message": "Access Token Refresh Error"
+ },
+ "errorRefreshingAccessTokenDesc":{
+ "message": "No refresh token or API keys found. Please try logging out and logging back in."
+ },
"help": {
"message": "Help"
},
@@ -2480,6 +2498,12 @@
"important": {
"message": "Important:"
},
+ "accessTokenUnableToBeDecrypted": {
+ "message": "You have been logged out because your access token could not be decrypted. Please log in again to resolve this issue."
+ },
+ "refreshTokenSecureStorageRetrievalFailure": {
+ "message": "You have been logged out because your refresh token could not be retrieved. Please log in again to resolve this issue."
+ },
"masterPasswordHint": {
"message": "Your master password cannot be recovered if you forget it!"
},
diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json
index 5e337875324b..45b724e47e42 100644
--- a/apps/desktop/src/locales/en_GB/messages.json
+++ b/apps/desktop/src/locales/en_GB/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organisation vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organisation vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organisations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json
index efc498921453..da4dca84e4a6 100644
--- a/apps/desktop/src/locales/en_IN/messages.json
+++ b/apps/desktop/src/locales/en_IN/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organisation vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organisation vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organisations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json
index 0b6c91a92123..55e9daa72b3b 100644
--- a/apps/desktop/src/locales/eo/messages.json
+++ b/apps/desktop/src/locales/eo/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json
index a6a8b2a8027e..130c18b391e4 100644
--- a/apps/desktop/src/locales/es/messages.json
+++ b/apps/desktop/src/locales/es/messages.json
@@ -1299,12 +1299,42 @@
"message": "Contraseña actualizada",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exportar caja fuerte"
},
"fileFormat": {
"message": "Formato de archivo"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Bloqueado"
},
diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json
index 7217568b5102..d26fc6521319 100644
--- a/apps/desktop/src/locales/et/messages.json
+++ b/apps/desktop/src/locales/et/messages.json
@@ -1299,12 +1299,42 @@
"message": "Parool on uuendatud",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Ekspordi hoidla"
},
"fileFormat": {
"message": "Failivorming"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Lukustatud"
},
diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json
index 0f41c667e91a..82406869f5a8 100644
--- a/apps/desktop/src/locales/eu/messages.json
+++ b/apps/desktop/src/locales/eu/messages.json
@@ -1299,12 +1299,42 @@
"message": "Pasahitza eguneratu da",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Esportatu kutxa gotorra"
},
"fileFormat": {
"message": "Fitxategiaren formatua"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Blokeatuta"
},
diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json
index f5a5c3575ce5..3c5fb785b7fc 100644
--- a/apps/desktop/src/locales/fa/messages.json
+++ b/apps/desktop/src/locales/fa/messages.json
@@ -1299,12 +1299,42 @@
"message": "کلمه عبور بهروزرسانی شد",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "برون ریزی گاوصندوق"
},
"fileFormat": {
"message": "فرمت پرونده"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "نشانی اینترنتی hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "قفل شده"
},
diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json
index 893da1309f3b..084476144337 100644
--- a/apps/desktop/src/locales/fi/messages.json
+++ b/apps/desktop/src/locales/fi/messages.json
@@ -1299,12 +1299,42 @@
"message": "Salasana vaihdettiin",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Vie lähteestä"
+ },
"exportVault": {
"message": "Vie holvi"
},
"fileFormat": {
"message": "Tiedostomuoto"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Tämä vientitiedosto suojataan salasanalla, joka on syötettävä ja salauksen purkamiseksi."
+ },
+ "filePassword": {
+ "message": "Tiedoston salasana"
+ },
+ "exportPasswordDescription": {
+ "message": "Tätä salasanaa käytetään tämän tiedoston viennissä ja tuonnissa"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Salaa vienti ja rajoita tuonti vain nykyiselle Bitwarden-tilille tilisi käyttäjätunnukseen ja pääsalasanaan pohjautuvalla salausavaimella."
+ },
+ "passwordProtected": {
+ "message": "Salasanasuojattu"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Salaa vientitiedosto salasanalla, joka mahdollistaa sen tuonnin mille tahansa Bitwarden-tilille."
+ },
+ "exportTypeHeading": {
+ "message": "Viennin tyyppi"
+ },
+ "accountRestricted": {
+ "message": "Tiliä on rajoitettu"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Tiedoston salasana\" ja \"Vahvista tiedoston salasana\" eivät täsmää."
+ },
"hCaptchaUrl": {
"message": "hCaptcha-URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Organisaation holvin vienti"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Vain organisaatioon $ORGANIZATION$ liitetyn holvin kohteet viedään. Yksityisen holvin ja muiden organisaatioiden kohteita ei sisällytetä.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Lukittu"
},
diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json
index e45770ab1801..0180d46959ea 100644
--- a/apps/desktop/src/locales/fil/messages.json
+++ b/apps/desktop/src/locales/fil/messages.json
@@ -1299,12 +1299,42 @@
"message": "Na-update ang password",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "I-export vault"
},
"fileFormat": {
"message": "Format ng file"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Naka-lock"
},
diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json
index 163bc548acf0..ef8f783dd310 100644
--- a/apps/desktop/src/locales/fr/messages.json
+++ b/apps/desktop/src/locales/fr/messages.json
@@ -1299,12 +1299,42 @@
"message": "Mot de passe mis à jour",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exporter le coffre"
},
"fileFormat": {
"message": "Format de fichier"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "URL hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Verrouillé"
},
diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json
index c489ab726024..7b9cd9ef0f17 100644
--- a/apps/desktop/src/locales/gl/messages.json
+++ b/apps/desktop/src/locales/gl/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json
index 7a28b04d2e07..0f664ed02e7d 100644
--- a/apps/desktop/src/locales/he/messages.json
+++ b/apps/desktop/src/locales/he/messages.json
@@ -1299,12 +1299,42 @@
"message": "הסיסמה עודכנה",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "יצוא כספת"
},
"fileFormat": {
"message": "תבנית קובץ"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "כתובת אתר hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "נָעוּל"
},
diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json
index 3e752df95eb3..765510dc32e8 100644
--- a/apps/desktop/src/locales/hi/messages.json
+++ b/apps/desktop/src/locales/hi/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json
index be3c7c28e37a..d1d4a4672b58 100644
--- a/apps/desktop/src/locales/hr/messages.json
+++ b/apps/desktop/src/locales/hr/messages.json
@@ -1299,12 +1299,42 @@
"message": "Lozinka ažurirana",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Izvezi trezor"
},
"fileFormat": {
"message": "Format datoteke"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Zaključano"
},
diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json
index 927fe8590093..869b92167f61 100644
--- a/apps/desktop/src/locales/hu/messages.json
+++ b/apps/desktop/src/locales/hu/messages.json
@@ -1299,12 +1299,42 @@
"message": "A jelszó frissítésre került.",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Exportálás innen:"
+ },
"exportVault": {
"message": "Széf exportálása"
},
"fileFormat": {
"message": "Fájlformátum"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Ez a fájl exportálás jelszóval védett és a visszafejtéshez a fájl jelszó megadása szükséges."
+ },
+ "filePassword": {
+ "message": "Fájl jelszó"
+ },
+ "exportPasswordDescription": {
+ "message": "Ezt a jelszó kerül használatba a fájl exportálására és importálására."
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Használjuk a fiók felhasználónevéből és mesterjelszavából származó fióktitkosítási kulcsot az exportálás titkosításához és az importálást csak az aktuális Bitwarden fiókra korlátozzuk."
+ },
+ "passwordProtected": {
+ "message": "Jelszóval védett"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Állítsunk be egy fájl jelszót az exportálás titkosításához és importáljuk azt bármely Bitwarden fiókba a visszafejtéshez használt jelszó használatával."
+ },
+ "exportTypeHeading": {
+ "message": "Exportálási típus"
+ },
+ "accountRestricted": {
+ "message": "Korlátozott fiók"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "A “Fájl jelszó” és a “Fájl jelszó megerősítés“ nem egyezik."
+ },
"hCaptchaUrl": {
"message": "hCaptcha webcím",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Szervezeti széf exportálása"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Csak $ORGANIZATION$ névvel társított szervezeti széf kerül exportálásra. Ebbe nem kerülnek be a személyes és más szervezeti széf elemek.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Lezárva"
},
diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json
index 46735671f04f..cc25a1c73ff2 100644
--- a/apps/desktop/src/locales/id/messages.json
+++ b/apps/desktop/src/locales/id/messages.json
@@ -1299,12 +1299,42 @@
"message": "Kata Sandi telah Diperbarui",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Ekspor Brankas"
},
"fileFormat": {
"message": "File Format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Terkunci"
},
diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json
index 7ab75fd98150..b016dc5e4800 100644
--- a/apps/desktop/src/locales/it/messages.json
+++ b/apps/desktop/src/locales/it/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password aggiornata",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Esporta da"
+ },
"exportVault": {
"message": "Esporta cassaforte"
},
"fileFormat": {
"message": "Formato file"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Questo file esportato sarà protetto e richiederà la password del file per decifrarlo."
+ },
+ "filePassword": {
+ "message": "Password del file"
+ },
+ "exportPasswordDescription": {
+ "message": "La password sarà utilizzata per importare ed esportare questo file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Usa la chiave di crittografia dell'account, derivata dal nome utente e dalla password principale del tuo account, per crittografare il file di esportazione e limitare l'importazione solo all'account Bitwarden corrente."
+ },
+ "passwordProtected": {
+ "message": "Protetto da password"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Imposta una password del file per crittografare il file esportato e importarlo in qualsiasi account Bitwarden usando la password per decrittografarlo."
+ },
+ "exportTypeHeading": {
+ "message": "Tipo di esportazione"
+ },
+ "accountRestricted": {
+ "message": "Account limitato"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "Le due password del file non corrispondono."
+ },
"hCaptchaUrl": {
"message": "URL hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Esportando cassaforte dell'organizzazione"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Solo la cassaforte dell'organizzazione associata a $ORGANIZATION$ sarà esportata. Elementi nelle casseforti individuali o in altre organizzazioni non saranno inclusi.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Bloccato"
},
diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json
index e5a3fbcfb939..0be6aea461f2 100644
--- a/apps/desktop/src/locales/ja/messages.json
+++ b/apps/desktop/src/locales/ja/messages.json
@@ -1299,12 +1299,42 @@
"message": "パスワード更新日",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "エクスポート元"
+ },
"exportVault": {
"message": "保管庫のエクスポート"
},
"fileFormat": {
"message": "ファイル形式"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "エクスポートするファイルはパスワードで保護され、復号するにはファイルパスワードが必要になります。"
+ },
+ "filePassword": {
+ "message": "ファイルパスワード"
+ },
+ "exportPasswordDescription": {
+ "message": "このパスワードはこのファイルのエクスポートとインポート時に使用します"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "アカウントのユーザー名とマスターパスワードから得られる暗号化キーを使用してエクスポートするデータを暗号化し、現在の Bitwarden アカウントのみがインポートできるよう制限します。"
+ },
+ "passwordProtected": {
+ "message": "パスワード保護あり"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "エクスポートを暗号化するためのファイルパスワードを設定します。そのパスワードを使用して、任意の Bitwarden アカウントにインポートします。"
+ },
+ "exportTypeHeading": {
+ "message": "エクスポートの種類"
+ },
+ "accountRestricted": {
+ "message": "アカウント制限"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "「ファイルパスワード」と「ファイルパスワードの確認」が一致しません。"
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "組織保管庫のエクスポート"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "$ORGANIZATION$ に関連付けられた組織保管庫のみがエクスポートされます。個々の保管庫または他の組織にあるアイテムは含まれません。",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "ロック中"
},
diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json
index c489ab726024..7b9cd9ef0f17 100644
--- a/apps/desktop/src/locales/ka/messages.json
+++ b/apps/desktop/src/locales/ka/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json
index c489ab726024..7b9cd9ef0f17 100644
--- a/apps/desktop/src/locales/km/messages.json
+++ b/apps/desktop/src/locales/km/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json
index 8379628c437e..63f2d0326d0c 100644
--- a/apps/desktop/src/locales/kn/messages.json
+++ b/apps/desktop/src/locales/kn/messages.json
@@ -1299,12 +1299,42 @@
"message": "ಪಾಸ್ವರ್ಡ್ ನವೀಕರಿಸಲಾಗಿದೆ",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "ರಫ್ತು ವಾಲ್ಟ್"
},
"fileFormat": {
"message": "ಕಡತದ ಮಾದರಿ"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json
index 5b1bcafa425f..1a5e6353520c 100644
--- a/apps/desktop/src/locales/ko/messages.json
+++ b/apps/desktop/src/locales/ko/messages.json
@@ -1299,12 +1299,42 @@
"message": "비밀번호 업데이트됨",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "보관함 내보내기"
},
"fileFormat": {
"message": "파일 형식"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "잠김"
},
diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json
index e24f4b78f8a3..edb15332c220 100644
--- a/apps/desktop/src/locales/lt/messages.json
+++ b/apps/desktop/src/locales/lt/messages.json
@@ -1299,12 +1299,42 @@
"message": "Slaptažodis atnaujintas",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Eksportuoti saugyklą"
},
"fileFormat": {
"message": "Failo formatas"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha nuoroda",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Užrakinta"
},
diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json
index d93dc9e8599b..4a91e491a546 100644
--- a/apps/desktop/src/locales/lv/messages.json
+++ b/apps/desktop/src/locales/lv/messages.json
@@ -1299,12 +1299,42 @@
"message": "Parole atjaunināta",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Izgūt no"
+ },
"exportVault": {
"message": "Izgūt glabātavas saturu"
},
"fileFormat": {
"message": "Datnes veids"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Šī datņu izgūšana būs aizsargāta ar paroli, un būs nepieciešama datnes parole, lai to atšifrētu."
+ },
+ "filePassword": {
+ "message": "Datnes parole"
+ },
+ "exportPasswordDescription": {
+ "message": "Šī parole tiks izmantota, lai izgūtu un ievietotu šo datni"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Jāizmanto konta šifrēšanas atslēga, kas iegūta no lietotājvārda un galvenās paroles, lai šifrētu izguvi un atļautu ievietošanu tikai pašreizējā Bitwarden kontā."
+ },
+ "passwordProtected": {
+ "message": "Aizsargāts ar paroli"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Uzstādīt paroli, lai šifrētu izguvi un tad to ievietotu jebkurā Bitwarden kontā, izmantojot atšifrēšanas paroli."
+ },
+ "exportTypeHeading": {
+ "message": "Izgūšanas veids"
+ },
+ "accountRestricted": {
+ "message": "Konts ir ierobežots"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Datnes parole\" un \"Apstiprināt datnes paroli\" vērtības nesakrīt."
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -1347,7 +1377,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ā). Izdzēst to uzreiz pēc izmantošanas."
+ "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."
},
"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."
@@ -2060,7 +2090,7 @@
"message": "Sesijai iestājās noildze. Lūgums mēģināt pieteikties vēlreiz."
},
"exportingPersonalVaultTitle": {
- "message": "Izdod personīgo glabātavu"
+ "message": "Izgūst personīgo glabātavu"
},
"exportingIndividualVaultDescription": {
"message": "Tiks izgūti tikai atsevišķi glabātavas vienumi, kas ir saistīti ar $EMAIL$. Apvienības glabātavas vienumi netiks iekļauti. Tiks izgūta tikai glabātavas vienumu informācija, un saistītie pielikumi netiks iekļauti.",
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Izgūst apvienības glabātavu"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Aizslēgta"
},
@@ -2685,7 +2727,7 @@
"message": "Kļūda izguves datnes atšifrēšanā. Izmantotā atslēga neatbilst tai, kas tika izmantota satura izgūšanai."
},
"invalidFilePassword": {
- "message": "Nederīga datnes parole, lūgums izmantot to paroli, kas tika ievadīta izdošanas datnes izveidošanas brīdī."
+ "message": "Nederīga datnes parole, lūgums izmantot to paroli, kas tika ievadīta izgūšanas datnes izveidošanas brīdī."
},
"importDestination": {
"message": "Ievietošanas galamērķis"
diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json
index a19623dbf9ef..400fc1bba9e6 100644
--- a/apps/desktop/src/locales/me/messages.json
+++ b/apps/desktop/src/locales/me/messages.json
@@ -1299,12 +1299,42 @@
"message": "Lozinka ažurirana",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Izvezi trezor"
},
"fileFormat": {
"message": "Format datoteke"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json
index d1a20855478c..fec41cd119c7 100644
--- a/apps/desktop/src/locales/ml/messages.json
+++ b/apps/desktop/src/locales/ml/messages.json
@@ -1299,12 +1299,42 @@
"message": "പാസ്വേഡ് പുതുക്കി",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "വാൾട് എക്സ്പോർട്"
},
"fileFormat": {
"message": "ഫയൽ ഫോർമാറ്റ്"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json
index c489ab726024..7b9cd9ef0f17 100644
--- a/apps/desktop/src/locales/mr/messages.json
+++ b/apps/desktop/src/locales/mr/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json
index 2f19a2f513f3..54f943a72c80 100644
--- a/apps/desktop/src/locales/my/messages.json
+++ b/apps/desktop/src/locales/my/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json
index 5af3025f0e52..1f6c7fed6468 100644
--- a/apps/desktop/src/locales/nb/messages.json
+++ b/apps/desktop/src/locales/nb/messages.json
@@ -1299,12 +1299,42 @@
"message": "Passordet ble oppdatert den",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Eksporter hvelvet"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Låst"
},
diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json
index 6f6f7d95989d..a766c4bb6e5c 100644
--- a/apps/desktop/src/locales/ne/messages.json
+++ b/apps/desktop/src/locales/ne/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json
index 7d5132c872f0..f3fe4886abc0 100644
--- a/apps/desktop/src/locales/nl/messages.json
+++ b/apps/desktop/src/locales/nl/messages.json
@@ -1299,12 +1299,42 @@
"message": "Wachtwoord bijgewerkt",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Exporteren vanuit"
+ },
"exportVault": {
"message": "Kluis exporteren"
},
"fileFormat": {
"message": "Bestandsindeling"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "We beveiligen deze bestandsexport met een wachtwoord beveiligd, je hebt het bestandswachtwoord nodig om het te decoderen."
+ },
+ "filePassword": {
+ "message": "Bestandswachtwoord"
+ },
+ "exportPasswordDescription": {
+ "message": "We gebruiken dit wachtwoord bij het exporteren en importeren van dit bestand"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Gebruik de encryptiesleutel van je account, afgeleid van je gebruikersnaam en hoodfwachtwoord, om de export te versleutelen en importeren te beperken tot het huidige Bitwarden-account."
+ },
+ "passwordProtected": {
+ "message": "Beveiligd met wachtwoord"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Stel een bestandswachtwoord in om de export te versleutelen en te importeren naar een willekeurig Bitwarden-account met het wachtwoord voor decoderen."
+ },
+ "exportTypeHeading": {
+ "message": "Exporttype"
+ },
+ "accountRestricted": {
+ "message": "Account beperkt"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Bestandswachtwoord\" en \"Bestandswachtwoord bevestigen\" komen niet overeen."
+ },
"hCaptchaUrl": {
"message": "hCaptcha-URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Organisatiekluis exporteren"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Exporteert alleen de organisatiekluis van $ORGANIZATION$. Geen persoonlijke kluis-items of items van andere organisaties.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Vergrendeld"
},
diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json
index 0de15cbe56bd..10016168346c 100644
--- a/apps/desktop/src/locales/nn/messages.json
+++ b/apps/desktop/src/locales/nn/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha-nettadresse",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json
index bcc358730aee..8146636277bb 100644
--- a/apps/desktop/src/locales/or/messages.json
+++ b/apps/desktop/src/locales/or/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json
index 237d94faa381..01fe7622e718 100644
--- a/apps/desktop/src/locales/pl/messages.json
+++ b/apps/desktop/src/locales/pl/messages.json
@@ -1299,12 +1299,42 @@
"message": "Hasło zostało zaktualizowane",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Eksportuj z"
+ },
"exportVault": {
"message": "Eksportuj sejf"
},
"fileFormat": {
"message": "Format pliku"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Plik będzie chroniony hasłem, które będzie wymagane do odszyfrowania pliku."
+ },
+ "filePassword": {
+ "message": "Hasło do pliku"
+ },
+ "exportPasswordDescription": {
+ "message": "Hasło będzie używane do eksportowania i importowania pliku"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Użyj klucza szyfrowania konta, pochodzącego z nazwy użytkownika konta i hasła głównego, aby zaszyfrować eksport i ograniczyć import tylko do bieżącego konta Bitwarden."
+ },
+ "passwordProtected": {
+ "message": "Chroniona hasłem"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Ustaw hasło dla pliku, aby zaszyfrować eksport i zaimportować je na dowolne konto Bitwarden przy użyciu hasła do odszyfrowania."
+ },
+ "exportTypeHeading": {
+ "message": "Rodzaj eksportu"
+ },
+ "accountRestricted": {
+ "message": "Konto ograniczone"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“Hasło pliku” i “Potwierdź hasło pliku“ nie pasują do siebie."
+ },
"hCaptchaUrl": {
"message": "Adres URL hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Eksportowanie sejfu organizacji"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Zablokowany"
},
diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json
index 225bef631263..77ae4a5592b6 100644
--- a/apps/desktop/src/locales/pt_BR/messages.json
+++ b/apps/desktop/src/locales/pt_BR/messages.json
@@ -1299,12 +1299,42 @@
"message": "Senha atualizada",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Exportar cofre"
},
"fileFormat": {
"message": "Formato do arquivo"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Bloqueado"
},
diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json
index b2ff16748eca..5596e6ee45e6 100644
--- a/apps/desktop/src/locales/pt_PT/messages.json
+++ b/apps/desktop/src/locales/pt_PT/messages.json
@@ -1299,12 +1299,42 @@
"message": "Palavra-passe atualizada a",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Exportar de"
+ },
"exportVault": {
"message": "Exportar cofre"
},
"fileFormat": {
"message": "Formato do ficheiro"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "A exportação deste ficheiro será protegida por uma palavra-passe e exigirá a palavra-passe do ficheiro para ser desencriptada."
+ },
+ "filePassword": {
+ "message": "Palavra-passe do ficheiro"
+ },
+ "exportPasswordDescription": {
+ "message": "Esta palavra-passe será utilizada para exportar e importar este ficheiro"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Utilize a chave de encriptação da sua conta, derivada do nome de utilizador e da palavra-passe mestra da sua conta, para encriptar a exportação e restringir a importação apenas à conta Bitwarden atual."
+ },
+ "passwordProtected": {
+ "message": "Protegido por palavra-passe"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Defina uma palavra-passe do ficheiro para encriptar a exportação e importe-a para qualquer conta Bitwarden utilizando a palavra-passe de desencriptação."
+ },
+ "exportTypeHeading": {
+ "message": "Tipo de exportação"
+ },
+ "accountRestricted": {
+ "message": "Conta restringida"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Palavra-passe do ficheiro\" e \"Confirmar palavra-passe do ficheiro\" não correspondem."
+ },
"hCaptchaUrl": {
"message": "URL do hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "A exportar o cofre da organização"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Bloqueado"
},
diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json
index 27c9bcd12291..9ffe8da928cc 100644
--- a/apps/desktop/src/locales/ro/messages.json
+++ b/apps/desktop/src/locales/ro/messages.json
@@ -1299,12 +1299,42 @@
"message": "Parolă actualizată",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export de seif"
},
"fileFormat": {
"message": "Format de fișier"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "Url-ul hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Blocat"
},
diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json
index e6e621ed55f8..665a18d1cb77 100644
--- a/apps/desktop/src/locales/ru/messages.json
+++ b/apps/desktop/src/locales/ru/messages.json
@@ -1299,12 +1299,42 @@
"message": "Пароль обновлен",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Экспорт из"
+ },
"exportVault": {
"message": "Экспорт хранилища"
},
"fileFormat": {
"message": "Формат файла"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Экспорт этого файла будет защищен паролем, и для расшифровки потребуется пароль файла."
+ },
+ "filePassword": {
+ "message": "Пароль к файлу"
+ },
+ "exportPasswordDescription": {
+ "message": "Этот пароль будет использоваться для экспорта и импорта этого файла"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Использовать ключ шифрования вашего аккаунта, полученный из имени пользователя и мастер-пароля, для шифрования экспорта и ограничения импорта только для текущего аккаунта Bitwarden."
+ },
+ "passwordProtected": {
+ "message": "Пароль защищен"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Установите пароль файла для шифрования экспорта и импортируйте его в любую учетную запись Bitwarden, используя пароль для расшифровки."
+ },
+ "exportTypeHeading": {
+ "message": "Тип экспорта"
+ },
+ "accountRestricted": {
+ "message": "Ограничено аккаунтом"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Пароль к файлу\" и \"Подтверждение пароля к файлу\" не совпадают."
+ },
"hCaptchaUrl": {
"message": "URL hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Экспорт хранилища организации"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Будет экспортировано только хранилище организации, связанное с $ORGANIZATION$. Элементы из личных хранилищ и из других организаций включены не будут.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Заблокировано"
},
diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json
index 829febb7a937..b2c744761fe5 100644
--- a/apps/desktop/src/locales/si/messages.json
+++ b/apps/desktop/src/locales/si/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json
index f6ab99455c44..af48e2ed5290 100644
--- a/apps/desktop/src/locales/sk/messages.json
+++ b/apps/desktop/src/locales/sk/messages.json
@@ -1299,12 +1299,42 @@
"message": "Heslo bolo aktualizované",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Exportovať z"
+ },
"exportVault": {
"message": "Export trezoru"
},
"fileFormat": {
"message": "Formát Súboru"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Tento exportovaný súbor bude chránený heslom a na dešifrovanie bude potrebné heslo súboru."
+ },
+ "filePassword": {
+ "message": "Heslo súboru"
+ },
+ "exportPasswordDescription": {
+ "message": "Toto heslo sa použije na export a import tohto súboru"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Na zašifrovanie exportu a obmedzenie importu len na aktuálny účet Bitwarden použite šifrovací kľúč účtu odvodený z používateľského mena a hlavného hesla účtu."
+ },
+ "passwordProtected": {
+ "message": "Chránené heslom"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Nastavte heslo súboru na zašifrovanie exportu a importujte ho do akéhokoľvek účtu Bitwarden pomocou hesla na dešifrovanie."
+ },
+ "exportTypeHeading": {
+ "message": "Typ exportu"
+ },
+ "accountRestricted": {
+ "message": "Obmedzený účet"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "\"Heslo súboru\" a \"Potvrdiť heslo súboru\" sa nezhodujú."
+ },
"hCaptchaUrl": {
"message": "URL hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exportovanie trezora organizácie"
+ },
+ "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": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Zamknutý"
},
diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json
index 968f34ad747c..9bdec66f19cf 100644
--- a/apps/desktop/src/locales/sl/messages.json
+++ b/apps/desktop/src/locales/sl/messages.json
@@ -1299,12 +1299,42 @@
"message": "Geslo je bilo posodobljeno",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Izvoz trezorja"
},
"fileFormat": {
"message": "Format datoteke"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json
index 7967e25b3f6d..de403629d14d 100644
--- a/apps/desktop/src/locales/sr/messages.json
+++ b/apps/desktop/src/locales/sr/messages.json
@@ -1299,12 +1299,42 @@
"message": "Лозинка ажурирана",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Извоз сефа"
},
"fileFormat": {
"message": "Формат датотеке"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Закључано"
},
diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json
index 6e731f777c5d..9bae4e883dc9 100644
--- a/apps/desktop/src/locales/sv/messages.json
+++ b/apps/desktop/src/locales/sv/messages.json
@@ -1299,12 +1299,42 @@
"message": "Lösenordet uppdaterades",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Exportera från"
+ },
"exportVault": {
"message": "Exportera valv"
},
"fileFormat": {
"message": "Filformat"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha-URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Låst"
},
diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json
index c489ab726024..7b9cd9ef0f17 100644
--- a/apps/desktop/src/locales/te/messages.json
+++ b/apps/desktop/src/locales/te/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export vault"
},
"fileFormat": {
"message": "File format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json
index dce9013765fb..cfc701aa5aa3 100644
--- a/apps/desktop/src/locales/th/messages.json
+++ b/apps/desktop/src/locales/th/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password Updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export Vault"
},
"fileFormat": {
"message": "File Format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha Url",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Locked"
},
diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json
index ad828189877b..224bf36cfd70 100644
--- a/apps/desktop/src/locales/tr/messages.json
+++ b/apps/desktop/src/locales/tr/messages.json
@@ -1299,12 +1299,42 @@
"message": "Parola güncelleme",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Kasayı dışa aktar"
},
"fileFormat": {
"message": "Dosya biçimi"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha adresi",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Kilitli"
},
diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json
index 6503f3c19ab0..546005db20cb 100644
--- a/apps/desktop/src/locales/uk/messages.json
+++ b/apps/desktop/src/locales/uk/messages.json
@@ -1299,12 +1299,42 @@
"message": "Пароль оновлено",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Експортувати з"
+ },
"exportVault": {
"message": "Експортувати сховище"
},
"fileFormat": {
"message": "Формат файлу"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "Цей експортований файл буде захищений паролем, який необхідно ввести для його розшифрування."
+ },
+ "filePassword": {
+ "message": "Пароль файлу"
+ },
+ "exportPasswordDescription": {
+ "message": "Цей пароль буде використано для експортування та імпортування цього файлу"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Використовуйте ключ шифрування свого облікового запису, створений на основі імені користувача й головного пароля, щоб зашифрувати експортовані дані та обмежити можливість імпортування лише до поточного облікового запису Bitwarden."
+ },
+ "passwordProtected": {
+ "message": "Захищено паролем"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Встановіть пароль файлу, щоб зашифрувати експортовані дані та імпортувати до будь-якого облікового запису Bitwarden за допомогою цього пароля."
+ },
+ "exportTypeHeading": {
+ "message": "Тип експорту"
+ },
+ "accountRestricted": {
+ "message": "Обмежено обліковим записом"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "Пароль файлу та підтвердження пароля відрізняються."
+ },
"hCaptchaUrl": {
"message": "URL-адреса hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Експортування сховища організації"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Буде експортовано лише сховище організації, пов'язане з $ORGANIZATION$. Елементи особистих сховищ або інших організацій не будуть включені.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Заблоковано"
},
diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json
index 1a0689b1329f..0fa1d7253af9 100644
--- a/apps/desktop/src/locales/vi/messages.json
+++ b/apps/desktop/src/locales/vi/messages.json
@@ -1299,12 +1299,42 @@
"message": "Password Updated",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "Export Vault"
},
"fileFormat": {
"message": "File Format"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "Url hCaptcha",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "Đã khóa"
},
diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json
index 35cb9ec07ba0..22b96d6e4b66 100644
--- a/apps/desktop/src/locales/zh_CN/messages.json
+++ b/apps/desktop/src/locales/zh_CN/messages.json
@@ -1299,12 +1299,42 @@
"message": "密码更新于",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "导出自"
+ },
"exportVault": {
"message": "导出密码库"
},
"fileFormat": {
"message": "文件格式"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "此文件导出将受密码保护,需要文件密码才能解密。"
+ },
+ "filePassword": {
+ "message": "文件密码"
+ },
+ "exportPasswordDescription": {
+ "message": "此密码将用于导出和导入此文件"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "使用衍生自您账户的用户名和主密码的账户加密密钥,以加密此导出并限制只能导入到当前的 Bitwarden 账户。"
+ },
+ "passwordProtected": {
+ "message": "密码保护"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "设置一个文件密码用来加密此导出,并使用此密码解密以导入到任意 Bitwarden 账户。"
+ },
+ "exportTypeHeading": {
+ "message": "导出类型"
+ },
+ "accountRestricted": {
+ "message": "账户受限"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "「文件密码」与「确认文件密码」不一致。"
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "正在导出组织密码库"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "仅会导出与 $ORGANIZATION$ 关联的组织密码库数据。不包括个人密码库和其他组织中的项目。",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "已锁定"
},
diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json
index 9ff900a41e22..099865217c03 100644
--- a/apps/desktop/src/locales/zh_TW/messages.json
+++ b/apps/desktop/src/locales/zh_TW/messages.json
@@ -1299,12 +1299,42 @@
"message": "密碼更新於",
"description": "ex. Date this password was updated"
},
+ "exportFrom": {
+ "message": "Export from"
+ },
"exportVault": {
"message": "匯出密碼庫"
},
"fileFormat": {
"message": "檔案格式"
},
+ "fileEncryptedExportWarningDesc": {
+ "message": "This file export will be password protected and require the file password to decrypt."
+ },
+ "filePassword": {
+ "message": "File password"
+ },
+ "exportPasswordDescription": {
+ "message": "This password will be used to export and import this file"
+ },
+ "accountRestrictedOptionDescription": {
+ "message": "Use your account encryption key, derived from your account's username and Master Password, to encrypt the export and restrict import to only the current Bitwarden account."
+ },
+ "passwordProtected": {
+ "message": "Password protected"
+ },
+ "passwordProtectedOptionDescription": {
+ "message": "Set a file password to encrypt the export and import it to any Bitwarden account using the password for decryption."
+ },
+ "exportTypeHeading": {
+ "message": "Export type"
+ },
+ "accountRestricted": {
+ "message": "Account restricted"
+ },
+ "filePasswordAndConfirmFilePasswordDoNotMatch": {
+ "message": "“File password” and “Confirm file password“ do not match."
+ },
"hCaptchaUrl": {
"message": "hCaptcha URL",
"description": "hCaptcha is the name of a website, should not be translated"
@@ -2071,6 +2101,18 @@
}
}
},
+ "exportingOrganizationVaultTitle": {
+ "message": "Exporting organization vault"
+ },
+ "exportingOrganizationVaultDesc": {
+ "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.",
+ "placeholders": {
+ "organization": {
+ "content": "$1",
+ "example": "ACME Moving Co."
+ }
+ }
+ },
"locked": {
"message": "已鎖定"
},
diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts
index 16a6cb0601ae..19f65911e87d 100644
--- a/apps/desktop/src/main.ts
+++ b/apps/desktop/src/main.ts
@@ -3,6 +3,7 @@ import * as path from "path";
import { app } from "electron";
import { Subject, firstValueFrom } from "rxjs";
+import { LogoutReason } from "@bitwarden/auth/common";
import { TokenService as TokenServiceAbstraction } from "@bitwarden/common/auth/abstractions/token.service";
import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service";
import { TokenService } from "@bitwarden/common/auth/services/token.service";
@@ -31,6 +32,7 @@ import { DefaultSingleUserStateProvider } from "@bitwarden/common/platform/state
import { DefaultStateProvider } from "@bitwarden/common/platform/state/implementations/default-state.provider";
import { StateEventRegistrarService } from "@bitwarden/common/platform/state/state-event-registrar.service";
import { MemoryStorageService as MemoryStorageServiceForStateProviders } from "@bitwarden/common/platform/state/storage/memory-storage.service";
+import { UserId } from "@bitwarden/common/types/guid";
/* eslint-enable import/no-restricted-paths */
import { DesktopAutofillSettingsService } from "./autofill/services/desktop-autofill-settings.service";
@@ -184,6 +186,7 @@ export class Main {
this.keyGenerationService,
this.encryptService,
this.logService,
+ async (logoutReason: LogoutReason, userId?: UserId) => {},
);
this.migrationRunner = new MigrationRunner(
@@ -209,11 +212,9 @@ export class Main {
);
this.desktopSettingsService = new DesktopSettingsService(stateProvider);
-
const biometricStateService = new DefaultBiometricStateService(stateProvider);
this.windowMain = new WindowMain(
- this.stateService,
biometricStateService,
this.logService,
this.storageService,
diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts
index 64b4bc48d288..e82d16ee9fd4 100644
--- a/apps/desktop/src/main/window.main.ts
+++ b/apps/desktop/src/main/window.main.ts
@@ -6,7 +6,6 @@ import { app, BrowserWindow, ipcMain, nativeTheme, screen, session } from "elect
import { firstValueFrom } from "rxjs";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
-import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service";
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
@@ -38,7 +37,6 @@ export class WindowMain {
readonly defaultHeight = 600;
constructor(
- private stateService: StateService,
private biometricStateService: BiometricStateService,
private logService: LogService,
private storageService: AbstractStorageService,
diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json
index 508c42fa7205..34a4dc99f65d 100644
--- a/apps/desktop/src/package-lock.json
+++ b/apps/desktop/src/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@bitwarden/desktop",
- "version": "2024.5.0",
+ "version": "2024.6.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@bitwarden/desktop",
- "version": "2024.5.0",
+ "version": "2024.6.0",
"license": "GPL-3.0",
"dependencies": {
"@bitwarden/desktop-native": "file:../desktop_native",
diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json
index ea4b95491cba..3a629f37cb0e 100644
--- a/apps/desktop/src/package.json
+++ b/apps/desktop/src/package.json
@@ -2,7 +2,7 @@
"name": "@bitwarden/desktop",
"productName": "Bitwarden",
"description": "A secure and free password manager for all of your devices.",
- "version": "2024.5.0",
+ "version": "2024.6.0",
"author": "Bitwarden Inc. (https://bitwarden.com)",
"homepage": "https://bitwarden.com",
"license": "GPL-3.0",
diff --git a/apps/desktop/src/vault/app/vault/vault.component.ts b/apps/desktop/src/vault/app/vault/vault.component.ts
index 208bbc70f03a..37992ecea0ed 100644
--- a/apps/desktop/src/vault/app/vault/vault.component.ts
+++ b/apps/desktop/src/vault/app/vault/vault.component.ts
@@ -23,7 +23,7 @@ import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broa
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
+import { SyncService } from "@bitwarden/common/platform/sync";
import { TotpService } from "@bitwarden/common/vault/abstractions/totp.service";
import { CipherType } from "@bitwarden/common/vault/enums";
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
diff --git a/apps/desktop/tsconfig.json b/apps/desktop/tsconfig.json
index eb054ba80bab..ad8112db4853 100644
--- a/apps/desktop/tsconfig.json
+++ b/apps/desktop/tsconfig.json
@@ -17,6 +17,9 @@
"@bitwarden/billing": ["../../libs/billing/src"],
"@bitwarden/common/*": ["../../libs/common/src/*"],
"@bitwarden/components": ["../../libs/components/src"],
+ "@bitwarden/generator-components": ["../../libs/tools/generator/components/src"],
+ "@bitwarden/generator-core": ["../../libs/tools/generator/core/src"],
+ "@bitwarden/generator-extensions": ["../../libs/tools/generator/extensions/src"],
"@bitwarden/vault-export-core": [
"../../libs/tools/export/vault-export/vault-export-core/src"
],
diff --git a/apps/desktop/webpack.renderer.js b/apps/desktop/webpack.renderer.js
index 1ebeadef055c..dc3cdf1fef5d 100644
--- a/apps/desktop/webpack.renderer.js
+++ b/apps/desktop/webpack.renderer.js
@@ -24,8 +24,7 @@ const common = {
{
loader: "babel-loader",
options: {
- configFile: false,
- plugins: ["@angular/compiler-cli/linker/babel"],
+ configFile: "../../babel.config.json",
},
},
],
diff --git a/apps/web/package.json b/apps/web/package.json
index 6e5355c7086b..286811dd5c63 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -1,6 +1,6 @@
{
"name": "@bitwarden/web-vault",
- "version": "2024.5.0",
+ "version": "2024.6.0",
"scripts": {
"build:oss": "webpack",
"build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js",
diff --git a/apps/web/src/app/admin-console/common/base.events.component.ts b/apps/web/src/app/admin-console/common/base.events.component.ts
index e14bb62a35da..12c051271e17 100644
--- a/apps/web/src/app/admin-console/common/base.events.component.ts
+++ b/apps/web/src/app/admin-console/common/base.events.component.ts
@@ -97,19 +97,15 @@ export abstract class BaseEventsComponent {
this.loading = true;
let events: EventView[] = [];
let promise: Promise;
- try {
- promise = this.loadAndParseEvents(
- dates[0],
- dates[1],
- clearExisting ? null : this.continuationToken,
- );
+ promise = this.loadAndParseEvents(
+ dates[0],
+ dates[1],
+ clearExisting ? null : this.continuationToken,
+ );
- const result = await promise;
- this.continuationToken = result.continuationToken;
- events = result.events;
- } catch (e) {
- this.logService.error(`Handled exception: ${e}`);
- }
+ const result = await promise;
+ this.continuationToken = result.continuationToken;
+ events = result.events;
if (!clearExisting && this.events != null && this.events.length > 0) {
this.events = this.events.concat(events);
diff --git a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html
index d1a48a78e11b..237e2c6e30c8 100644
--- a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html
+++ b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html
@@ -52,7 +52,7 @@
*ngIf="canShowBillingTab(organization)"
>
-
+
diff --git a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts
index 47ca0998bbcc..4383656bee1e 100644
--- a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts
+++ b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.ts
@@ -1,7 +1,7 @@
import { CommonModule } from "@angular/common";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, RouterModule } from "@angular/router";
-import { map, mergeMap, Observable, Subject, takeUntil } from "rxjs";
+import { combineLatest, map, mergeMap, Observable, Subject, switchMap, takeUntil } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import {
@@ -16,7 +16,8 @@ import {
OrganizationService,
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
-import { PolicyType } from "@bitwarden/common/admin-console/enums";
+import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
+import { PolicyType, ProviderStatusType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
@@ -55,9 +56,14 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
organization$: Observable;
showPaymentAndHistory$: Observable;
hideNewOrgButton$: Observable;
+ organizationIsUnmanaged$: Observable;
private _destroy = new Subject();
+ protected consolidatedBillingEnabled$ = this.configService.getFeatureFlag$(
+ FeatureFlag.EnableConsolidatedBilling,
+ );
+
protected showPaymentMethodWarningBanners$ = this.configService.getFeatureFlag$(
FeatureFlag.ShowPaymentMethodWarningBanners,
);
@@ -68,6 +74,7 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
private platformUtilsService: PlatformUtilsService,
private configService: ConfigService,
private policyService: PolicyService,
+ private providerService: ProviderService,
) {}
async ngOnInit() {
@@ -94,6 +101,24 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
);
this.hideNewOrgButton$ = this.policyService.policyAppliesToActiveUser$(PolicyType.SingleOrg);
+
+ const provider$ = this.organization$.pipe(
+ switchMap((organization) => this.providerService.get$(organization.providerId)),
+ );
+
+ this.organizationIsUnmanaged$ = combineLatest([
+ this.consolidatedBillingEnabled$,
+ this.organization$,
+ provider$,
+ ]).pipe(
+ map(
+ ([consolidatedBillingEnabled, organization, provider]) =>
+ !consolidatedBillingEnabled ||
+ !organization.hasProvider ||
+ !provider ||
+ provider.providerStatus !== ProviderStatusType.Billable,
+ ),
+ );
}
ngOnDestroy() {
diff --git a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html
index 149277b81793..2a092e261009 100644
--- a/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html
+++ b/apps/web/src/app/admin-console/organizations/members/components/member-dialog/member-dialog.component.html
@@ -144,6 +144,7 @@
-
- {{ "editPolicy" | i18n }} - {{ policy.name | i18n }}
-
+
{
- comp.keyType = "organization";
- comp.entityId = this.organizationId;
- comp.postKey = this.organizationApiService.getOrCreateApiKey.bind(
- this.organizationApiService,
- );
- comp.scope = "api.organization";
- comp.grantType = "client_credentials";
- comp.apiKeyTitle = "apiKey";
- comp.apiKeyWarning = "apiKeyWarning";
- comp.apiKeyDescription = "apiKeyDesc";
+ await ApiKeyComponent.open(this.dialogService, {
+ data: {
+ keyType: "organization",
+ entityId: this.organizationId,
+ postKey: this.organizationApiService.getOrCreateApiKey.bind(this.organizationApiService),
+ scope: "api.organization",
+ grantType: "client_credentials",
+ apiKeyTitle: "apiKey",
+ apiKeyWarning: "apiKeyWarning",
+ apiKeyDescription: "apiKeyDesc",
+ },
});
}
async rotateApiKey() {
- await this.modalService.openViewRef(ApiKeyComponent, this.rotateApiKeyModalRef, (comp) => {
- comp.keyType = "organization";
- comp.isRotation = true;
- comp.entityId = this.organizationId;
- comp.postKey = this.organizationApiService.rotateApiKey.bind(this.organizationApiService);
- comp.scope = "api.organization";
- comp.grantType = "client_credentials";
- comp.apiKeyTitle = "apiKey";
- comp.apiKeyWarning = "apiKeyWarning";
- comp.apiKeyDescription = "apiKeyRotateDesc";
+ await ApiKeyComponent.open(this.dialogService, {
+ data: {
+ keyType: "organization",
+ isRotation: true,
+ entityId: this.organizationId,
+ postKey: this.organizationApiService.rotateApiKey.bind(this.organizationApiService),
+ scope: "api.organization",
+ grantType: "client_credentials",
+ apiKeyTitle: "apiKey",
+ apiKeyWarning: "apiKeyWarning",
+ apiKeyDescription: "apiKeyRotateDesc",
+ },
});
}
}
diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts
index 6c71309243eb..c9fbf359f0f6 100644
--- a/apps/web/src/app/app.component.ts
+++ b/apps/web/src/app/app.component.ts
@@ -14,6 +14,7 @@ import {
timer,
} from "rxjs";
+import { LogoutReason } from "@bitwarden/auth/common";
import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service";
import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service";
import { SearchService } from "@bitwarden/common/abstractions/search.service";
@@ -34,13 +35,13 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { BiometricStateService } from "@bitwarden/common/platform/biometrics/biometric-state.service";
import { StateEventRunnerService } from "@bitwarden/common/platform/state";
+import { SyncService } from "@bitwarden/common/platform/sync";
import { PasswordGenerationServiceAbstraction } from "@bitwarden/common/tools/generator/password";
import { UserId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service";
import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction";
-import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
-import { DialogService, ToastService } from "@bitwarden/components";
+import { DialogService, ToastOptions, ToastService } from "@bitwarden/components";
import { PolicyListService } from "./admin-console/core/policy-list.service";
import {
@@ -148,7 +149,7 @@ export class AppComponent implements OnDestroy, OnInit {
this.router.navigate(["/"]);
break;
case "logout":
- await this.logOut(!!message.expired, message.redirect);
+ await this.logOut(message.logoutReason, message.redirect);
break;
case "lockVault":
await this.vaultTimeoutService.lock();
@@ -278,7 +279,34 @@ export class AppComponent implements OnDestroy, OnInit {
this.destroy$.complete();
}
- private async logOut(expired: boolean, redirect = true) {
+ private async displayLogoutReason(logoutReason: LogoutReason) {
+ let toastOptions: ToastOptions;
+ switch (logoutReason) {
+ case "invalidSecurityStamp":
+ case "sessionExpired": {
+ toastOptions = {
+ variant: "warning",
+ title: this.i18nService.t("loggedOut"),
+ message: this.i18nService.t("loginExpired"),
+ };
+ break;
+ }
+ default: {
+ toastOptions = {
+ variant: "info",
+ title: this.i18nService.t("loggedOut"),
+ message: this.i18nService.t("loggedOutDesc"),
+ };
+ break;
+ }
+ }
+
+ this.toastService.showToast(toastOptions);
+ }
+
+ private async logOut(logoutReason: LogoutReason, redirect = true) {
+ await this.displayLogoutReason(logoutReason);
+
await this.eventUploadService.uploadEvents();
const userId = (await this.stateService.getUserId()) as UserId;
@@ -308,14 +336,6 @@ export class AppComponent implements OnDestroy, OnInit {
await this.searchService.clearIndex();
this.authService.logOut(async () => {
- if (expired) {
- this.platformUtilsService.showToast(
- "warning",
- this.i18nService.t("loggedOut"),
- this.i18nService.t("loginExpired"),
- );
- }
-
await this.stateService.clean({ userId: userId });
await this.accountService.clean(userId);
diff --git a/apps/web/src/app/auth/accept-organization.component.ts b/apps/web/src/app/auth/accept-organization.component.ts
deleted file mode 100644
index 52e3b6449402..000000000000
--- a/apps/web/src/app/auth/accept-organization.component.ts
+++ /dev/null
@@ -1,244 +0,0 @@
-import { Component } from "@angular/core";
-import { ActivatedRoute, Params, Router } from "@angular/router";
-
-import { ApiService } from "@bitwarden/common/abstractions/api.service";
-import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
-import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
-import {
- OrganizationUserAcceptInitRequest,
- OrganizationUserAcceptRequest,
-} from "@bitwarden/common/admin-console/abstractions/organization-user/requests";
-import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
-import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
-import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
-import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
-import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.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 { Utils } from "@bitwarden/common/platform/misc/utils";
-import { OrgKey } from "@bitwarden/common/types/key";
-
-import { BaseAcceptComponent } from "../common/base.accept.component";
-
-@Component({
- selector: "app-accept-organization",
- templateUrl: "accept-organization.component.html",
-})
-export class AcceptOrganizationComponent extends BaseAcceptComponent {
- orgName: string;
-
- protected requiredParameters: string[] = ["organizationId", "organizationUserId", "token"];
-
- constructor(
- router: Router,
- platformUtilsService: PlatformUtilsService,
- i18nService: I18nService,
- route: ActivatedRoute,
- stateService: StateService,
- private cryptoService: CryptoService,
- private policyApiService: PolicyApiServiceAbstraction,
- private policyService: PolicyService,
- private logService: LogService,
- private organizationApiService: OrganizationApiServiceAbstraction,
- private organizationUserService: OrganizationUserService,
- private messagingService: MessagingService,
- private apiService: ApiService,
- ) {
- super(router, platformUtilsService, i18nService, route, stateService);
- }
-
- async authedHandler(qParams: Params): Promise {
- const initOrganization =
- qParams.initOrganization != null && qParams.initOrganization.toLocaleLowerCase() === "true";
- if (initOrganization) {
- this.actionPromise = this.acceptInitOrganizationFlow(qParams);
- } else {
- const needsReAuth = (await this.stateService.getOrganizationInvitation()) == null;
- if (needsReAuth) {
- // Accepting an org invite requires authentication from a logged out state
- this.messagingService.send("logout", { redirect: false });
- await this.prepareOrganizationInvitation(qParams);
- return;
- }
-
- // User has already logged in and passed the Master Password policy check
- this.actionPromise = this.acceptFlow(qParams);
- }
-
- await this.actionPromise;
- await this.apiService.refreshIdentityToken();
- await this.stateService.setOrganizationInvitation(null);
- this.platformUtilService.showToast(
- "success",
- this.i18nService.t("inviteAccepted"),
- initOrganization
- ? this.i18nService.t("inviteInitAcceptedDesc")
- : this.i18nService.t("inviteAcceptedDesc"),
- { timeout: 10000 },
- );
- // 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(["/vault"]);
- }
-
- async unauthedHandler(qParams: Params): Promise {
- await this.prepareOrganizationInvitation(qParams);
-
- // In certain scenarios, we want to accelerate the user through the accept org invite process
- // For example, if the user has a BW account already, we want them to be taken to login instead of creation.
- await this.accelerateInviteAcceptIfPossible(qParams);
- }
-
- private async acceptInitOrganizationFlow(qParams: Params): Promise {
- return this.prepareAcceptInitRequest(qParams).then((request) =>
- this.organizationUserService.postOrganizationUserAcceptInit(
- qParams.organizationId,
- qParams.organizationUserId,
- request,
- ),
- );
- }
-
- private async acceptFlow(qParams: Params): Promise {
- return this.prepareAcceptRequest(qParams).then((request) =>
- this.organizationUserService.postOrganizationUserAccept(
- qParams.organizationId,
- qParams.organizationUserId,
- request,
- ),
- );
- }
-
- private async prepareAcceptInitRequest(
- qParams: Params,
- ): Promise {
- const request = new OrganizationUserAcceptInitRequest();
- request.token = qParams.token;
-
- const [encryptedOrgKey, orgKey] = await this.cryptoService.makeOrgKey();
- const [orgPublicKey, encryptedOrgPrivateKey] = await this.cryptoService.makeKeyPair(orgKey);
- const collection = await this.cryptoService.encrypt(
- this.i18nService.t("defaultCollection"),
- orgKey,
- );
-
- request.key = encryptedOrgKey.encryptedString;
- request.keys = new OrganizationKeysRequest(
- orgPublicKey,
- encryptedOrgPrivateKey.encryptedString,
- );
- request.collectionName = collection.encryptedString;
-
- return request;
- }
-
- private async prepareAcceptRequest(qParams: Params): Promise {
- const request = new OrganizationUserAcceptRequest();
- request.token = qParams.token;
-
- if (await this.performResetPasswordAutoEnroll(qParams)) {
- const response = await this.organizationApiService.getKeys(qParams.organizationId);
-
- if (response == null) {
- throw new Error(this.i18nService.t("resetPasswordOrgKeysError"));
- }
-
- const publicKey = Utils.fromB64ToArray(response.publicKey);
-
- // RSA Encrypt user's encKey.key with organization public key
- const userKey = await this.cryptoService.getUserKey();
- const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey);
-
- // Add reset password key to accept request
- request.resetPasswordKey = encryptedKey.encryptedString;
- }
- return request;
- }
-
- private async performResetPasswordAutoEnroll(qParams: Params): Promise {
- let policyList: Policy[] = null;
- try {
- const policies = await this.policyApiService.getPoliciesByToken(
- qParams.organizationId,
- qParams.token,
- qParams.email,
- qParams.organizationUserId,
- );
- policyList = Policy.fromListResponse(policies);
- } catch (e) {
- this.logService.error(e);
- }
-
- if (policyList != null) {
- const result = this.policyService.getResetPasswordPolicyOptions(
- policyList,
- qParams.organizationId,
- );
- // Return true if policy enabled and auto-enroll enabled
- return result[1] && result[0].autoEnrollEnabled;
- }
-
- return false;
- }
-
- private async prepareOrganizationInvitation(qParams: Params): Promise {
- this.orgName = qParams.organizationName;
- if (this.orgName != null) {
- // Fix URL encoding of space issue with Angular
- this.orgName = this.orgName.replace(/\+/g, " ");
- }
- await this.stateService.setOrganizationInvitation(qParams);
- }
-
- private async accelerateInviteAcceptIfPossible(qParams: Params): Promise {
- // Extract the query params we need to make routing acceleration decisions
- const orgSsoIdentifier = qParams.orgSsoIdentifier;
- const orgUserHasExistingUser = this.stringToNullOrBool(qParams.orgUserHasExistingUser);
-
- // if orgUserHasExistingUser is null, short circuit for backwards compatibility w/ older servers
- if (orgUserHasExistingUser == null) {
- return;
- }
-
- // if user exists, send user to login
- if (orgUserHasExistingUser) {
- // 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(["/login"], {
- queryParams: { email: qParams.email },
- });
- return;
- }
-
- // no user exists; so either sign in via SSO and JIT provision one or simply register.
-
- if (orgSsoIdentifier) {
- // We only send sso org identifier if the org has SSO enabled and the SSO policy required.
- // 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(["/sso"], {
- queryParams: { email: qParams.email, identifier: orgSsoIdentifier },
- });
- return;
- }
-
- // if SSO is disabled OR if sso is enabled but the SSO login required policy is not enabled
- // then send user to create account
- // 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(["/register"], {
- queryParams: { email: qParams.email, fromOrgInvite: true },
- });
- return;
- }
-
- private stringToNullOrBool(s: string | undefined): boolean | null {
- if (s === undefined) {
- return null;
- }
- return s.toLowerCase() === "true";
- }
-}
diff --git a/apps/web/src/app/auth/auth.module.ts b/apps/web/src/app/auth/auth.module.ts
index 056b9f161f93..6aa671558a08 100644
--- a/apps/web/src/app/auth/auth.module.ts
+++ b/apps/web/src/app/auth/auth.module.ts
@@ -1,9 +1,10 @@
import { NgModule } from "@angular/core";
+import { AcceptOrganizationInviteModule } from "./organization-invite/accept-organization.module";
import { AuthSettingsModule } from "./settings/settings.module";
@NgModule({
- imports: [AuthSettingsModule],
+ imports: [AuthSettingsModule, AcceptOrganizationInviteModule],
declarations: [],
providers: [],
exports: [AuthSettingsModule],
diff --git a/apps/web/src/app/auth/core/services/webauthn-login/request/webauthn-login-attestation-response.request.ts b/apps/web/src/app/auth/core/services/webauthn-login/request/webauthn-login-attestation-response.request.ts
index ef3d657f2f9c..f7c391b0ee28 100644
--- a/apps/web/src/app/auth/core/services/webauthn-login/request/webauthn-login-attestation-response.request.ts
+++ b/apps/web/src/app/auth/core/services/webauthn-login/request/webauthn-login-attestation-response.request.ts
@@ -20,8 +20,8 @@ export class WebauthnLoginAttestationResponseRequest extends WebauthnLoginAuthen
}
this.response = {
- attestationObject: Utils.fromBufferToB64(credential.response.attestationObject),
- clientDataJson: Utils.fromBufferToB64(credential.response.clientDataJSON),
+ attestationObject: Utils.fromBufferToUrlB64(credential.response.attestationObject),
+ clientDataJson: Utils.fromBufferToUrlB64(credential.response.clientDataJSON),
};
}
}
diff --git a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html
index 4690a4e63a54..3e1db4063166 100644
--- a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html
+++ b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.html
@@ -1,45 +1,39 @@
-
+
-
-
+
- {{ "loading" | i18n }}
+ {{ "loading" | i18n }}
-
-
-
-
{{ "emergencyAccess" | i18n }}
-
-
-
- {{ name }}
-
-
{{ "acceptEmergencyAccess" | i18n }}
-
-
-
-
-
+
+
+ {{ name }}
+
+
{{ "acceptEmergencyAccess" | i18n }}
+
+
diff --git a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts
index 8ff847c3a22c..5a92815c91fa 100644
--- a/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts
+++ b/apps/web/src/app/auth/emergency-access/accept/accept-emergency.component.ts
@@ -1,9 +1,9 @@
import { Component } from "@angular/core";
import { ActivatedRoute, Params, Router } from "@angular/router";
+import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { BaseAcceptComponent } from "../../../common/base.accept.component";
import { SharedModule } from "../../../shared";
@@ -27,10 +27,10 @@ export class AcceptEmergencyComponent extends BaseAcceptComponent {
platformUtilsService: PlatformUtilsService,
i18nService: I18nService,
route: ActivatedRoute,
- stateService: StateService,
+ authService: AuthService,
private emergencyAccessService: EmergencyAccessService,
) {
- super(router, platformUtilsService, i18nService, route, stateService);
+ super(router, platformUtilsService, i18nService, route, authService);
}
async authedHandler(qParams: Params): Promise
{
diff --git a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts
index 2c97bd227f9e..991fe8b59710 100644
--- a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts
+++ b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts
@@ -1,14 +1,27 @@
-import { Component } from "@angular/core";
+import { Component, inject } from "@angular/core";
import { BaseLoginDecryptionOptionsComponent } from "@bitwarden/angular/auth/components/base-login-decryption-options.component";
+
+import { RouterService } from "../../../core";
+import { AcceptOrganizationInviteService } from "../../organization-invite/accept-organization.service";
@Component({
selector: "web-login-decryption-options",
templateUrl: "login-decryption-options.component.html",
})
export class LoginDecryptionOptionsComponent extends BaseLoginDecryptionOptionsComponent {
+ protected routerService = inject(RouterService);
+ protected acceptOrganizationInviteService = inject(AcceptOrganizationInviteService);
+
override async createUser(): Promise {
try {
await super.createUser();
+
+ // Invites from TDE orgs go through here, but the invite is
+ // accepted while being enrolled in admin recovery. So we need to clear
+ // the redirect and stored org invite.
+ await this.routerService.getAndClearLoginRedirectUrl();
+ await this.acceptOrganizationInviteService.clearOrganizationInvitation();
+
await this.router.navigate(["/vault"]);
} catch (error) {
this.validationService.showError(error);
diff --git a/apps/web/src/app/auth/login/login.component.ts b/apps/web/src/app/auth/login/login.component.ts
index 9f628b9389e2..51d46f46a420 100644
--- a/apps/web/src/app/auth/login/login.component.ts
+++ b/apps/web/src/app/auth/login/login.component.ts
@@ -15,12 +15,10 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti
import { PolicyData } from "@bitwarden/common/admin-console/models/data/policy.data";
import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options";
import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
-import { PolicyResponse } from "@bitwarden/common/admin-console/models/response/policy.response";
import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction";
import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction";
import { WebAuthnLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/webauthn/webauthn-login.service.abstraction";
import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result";
-import { ListResponse } from "@bitwarden/common/models/response/list.response";
import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service";
import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
@@ -32,6 +30,8 @@ import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/pass
import { flagEnabled } from "../../../utils/flags";
import { RouterService, StateService } from "../../core";
+import { AcceptOrganizationInviteService } from "../organization-invite/accept-organization.service";
+import { OrganizationInvite } from "../organization-invite/organization-invite";
@Component({
selector: "app-login",
@@ -41,10 +41,11 @@ import { RouterService, StateService } from "../../core";
export class LoginComponent extends BaseLoginComponent implements OnInit {
showResetPasswordAutoEnrollWarning = false;
enforcedPasswordPolicyOptions: MasterPasswordPolicyOptions;
- policies: ListResponse;
+ policies: Policy[];
showPasswordless = false;
constructor(
+ private acceptOrganizationInviteService: AcceptOrganizationInviteService,
devicesApiService: DevicesApiServiceAbstraction,
appIdService: AppIdService,
loginStrategyService: LoginStrategyServiceAbstraction,
@@ -112,37 +113,10 @@ export class LoginComponent extends BaseLoginComponent implements OnInit {
await super.ngOnInit();
});
- const invite = await this.stateService.getOrganizationInvitation();
- if (invite != null) {
- let policyList: Policy[] = null;
- try {
- this.policies = await this.policyApiService.getPoliciesByToken(
- invite.organizationId,
- invite.token,
- invite.email,
- invite.organizationUserId,
- );
- policyList = Policy.fromListResponse(this.policies);
- } catch (e) {
- this.logService.error(e);
- }
-
- if (policyList != null) {
- const resetPasswordPolicy = this.policyService.getResetPasswordPolicyOptions(
- policyList,
- invite.organizationId,
- );
- // Set to true if policy enabled and auto-enroll enabled
- this.showResetPasswordAutoEnrollWarning =
- resetPasswordPolicy[1] && resetPasswordPolicy[0].autoEnrollEnabled;
-
- this.policyService
- .masterPasswordPolicyOptions$(policyList)
- .pipe(takeUntil(this.destroy$))
- .subscribe((enforcedPasswordPolicyOptions) => {
- this.enforcedPasswordPolicyOptions = enforcedPasswordPolicyOptions;
- });
- }
+ // If there's an existing org invite, use it to get the password policies
+ const orgInvite = await this.acceptOrganizationInviteService.getOrganizationInvite();
+ if (orgInvite != null) {
+ await this.initPasswordPolicies(orgInvite);
}
}
@@ -166,50 +140,69 @@ export class LoginComponent extends BaseLoginComponent implements OnInit {
)
) {
const policiesData: { [id: string]: PolicyData } = {};
- this.policies.data.map((p) => (policiesData[p.id] = new PolicyData(p)));
+ this.policies.map((p) => (policiesData[p.id] = PolicyData.fromPolicy(p)));
await this.policyService.replace(policiesData);
- // 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(["update-password"]);
+ await this.router.navigate(["update-password"]);
return;
}
}
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]);
+ await this.router.navigate([this.successRoute]);
}
- goToHint() {
+ async goToHint() {
this.setLoginEmailValues();
- // 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.navigateByUrl("/hint");
+ await this.router.navigateByUrl("/hint");
}
- goToRegister() {
+ async goToRegister() {
const email = this.formGroup.value.email;
if (email) {
- // 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(["/register"], { queryParams: { email: email } });
+ await this.router.navigate(["/register"], { queryParams: { email: email } });
return;
}
- // 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(["/register"]);
+ await this.router.navigate(["/register"]);
}
- protected override handleMigrateEncryptionKey(result: AuthResult): boolean {
+ protected override async handleMigrateEncryptionKey(result: AuthResult): Promise {
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"]);
+ await this.router.navigate(["migrate-legacy-encryption"]);
return true;
}
+
+ private async initPasswordPolicies(invite: OrganizationInvite): Promise {
+ try {
+ this.policies = await this.policyApiService.getPoliciesByToken(
+ invite.organizationId,
+ invite.token,
+ invite.email,
+ invite.organizationUserId,
+ );
+ } catch (e) {
+ this.logService.error(e);
+ }
+
+ if (this.policies == null) {
+ return;
+ }
+ const resetPasswordPolicy = this.policyService.getResetPasswordPolicyOptions(
+ this.policies,
+ invite.organizationId,
+ );
+ // Set to true if policy enabled and auto-enroll enabled
+ this.showResetPasswordAutoEnrollWarning =
+ resetPasswordPolicy[1] && resetPasswordPolicy[0].autoEnrollEnabled;
+
+ this.policyService
+ .masterPasswordPolicyOptions$(this.policies)
+ .pipe(takeUntil(this.destroy$))
+ .subscribe((enforcedPasswordPolicyOptions) => {
+ this.enforcedPasswordPolicyOptions = enforcedPasswordPolicyOptions;
+ });
+ }
}
diff --git a/apps/web/src/app/auth/accept-organization.component.html b/apps/web/src/app/auth/organization-invite/accept-organization.component.html
similarity index 97%
rename from apps/web/src/app/auth/accept-organization.component.html
rename to apps/web/src/app/auth/organization-invite/accept-organization.component.html
index 3aef47df22b6..f9dd3da5ed9a 100644
--- a/apps/web/src/app/auth/accept-organization.component.html
+++ b/apps/web/src/app/auth/organization-invite/accept-organization.component.html
@@ -18,7 +18,7 @@
- {{ orgName }}
+ {{ orgName$ | async }}
{{ email }}
{{ "joinOrganizationDesc" | i18n }}
diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.component.ts b/apps/web/src/app/auth/organization-invite/accept-organization.component.ts
new file mode 100644
index 000000000000..fa5507b216fe
--- /dev/null
+++ b/apps/web/src/app/auth/organization-invite/accept-organization.component.ts
@@ -0,0 +1,94 @@
+import { Component } from "@angular/core";
+import { ActivatedRoute, Params, Router } from "@angular/router";
+
+import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+
+import { BaseAcceptComponent } from "../../common/base.accept.component";
+
+import { AcceptOrganizationInviteService } from "./accept-organization.service";
+import { OrganizationInvite } from "./organization-invite";
+
+@Component({
+ templateUrl: "accept-organization.component.html",
+})
+export class AcceptOrganizationComponent extends BaseAcceptComponent {
+ orgName$ = this.acceptOrganizationInviteService.orgName$;
+ protected requiredParameters: string[] = ["organizationId", "organizationUserId", "token"];
+
+ constructor(
+ router: Router,
+ platformUtilsService: PlatformUtilsService,
+ i18nService: I18nService,
+ route: ActivatedRoute,
+ authService: AuthService,
+ private acceptOrganizationInviteService: AcceptOrganizationInviteService,
+ ) {
+ super(router, platformUtilsService, i18nService, route, authService);
+ }
+
+ async authedHandler(qParams: Params): Promise
{
+ const invite = OrganizationInvite.fromParams(qParams);
+ const success = await this.acceptOrganizationInviteService.validateAndAcceptInvite(invite);
+
+ if (!success) {
+ return;
+ }
+
+ this.platformUtilService.showToast(
+ "success",
+ this.i18nService.t("inviteAccepted"),
+ invite.initOrganization
+ ? this.i18nService.t("inviteInitAcceptedDesc")
+ : this.i18nService.t("inviteAcceptedDesc"),
+ { timeout: 10000 },
+ );
+
+ await this.router.navigate(["/vault"]);
+ }
+
+ async unauthedHandler(qParams: Params): Promise {
+ const invite = OrganizationInvite.fromParams(qParams);
+ await this.acceptOrganizationInviteService.setOrganizationInvitation(invite);
+ await this.accelerateInviteAcceptIfPossible(invite);
+ }
+
+ /**
+ * In certain scenarios, we want to accelerate the user through the accept org invite process
+ * For example, if the user has a BW account already, we want them to be taken to login instead of creation.
+ */
+ private async accelerateInviteAcceptIfPossible(invite: OrganizationInvite): Promise {
+ // if orgUserHasExistingUser is null, we can't determine the user's status
+ // so we don't want to accelerate the process
+ if (invite.orgUserHasExistingUser == null) {
+ return;
+ }
+
+ // if user exists, send user to login
+ if (invite.orgUserHasExistingUser) {
+ await this.router.navigate(["/login"], {
+ queryParams: { email: invite.email },
+ });
+ return;
+ }
+
+ if (invite.orgSsoIdentifier) {
+ // We only send sso org identifier if the org has SSO enabled and the SSO policy required.
+ // Will JIT provision the user.
+ // Note: If the organization has Admin Recovery enabled, the user will be accepted into the org
+ // upon enrollment. The user should not be returned here.
+ await this.router.navigate(["/sso"], {
+ queryParams: { email: invite.email, identifier: invite.orgSsoIdentifier },
+ });
+ return;
+ }
+
+ // if SSO is disabled OR if sso is enabled but the SSO login required policy is not enabled
+ // then send user to create account
+ await this.router.navigate(["/register"], {
+ queryParams: { email: invite.email, fromOrgInvite: true },
+ });
+ return;
+ }
+}
diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.module.ts b/apps/web/src/app/auth/organization-invite/accept-organization.module.ts
new file mode 100644
index 000000000000..3dc0e1448912
--- /dev/null
+++ b/apps/web/src/app/auth/organization-invite/accept-organization.module.ts
@@ -0,0 +1,13 @@
+import { NgModule } from "@angular/core";
+
+import { SharedModule } from "../../shared";
+
+import { AcceptOrganizationComponent } from "./accept-organization.component";
+import { AcceptOrganizationInviteService } from "./accept-organization.service";
+
+@NgModule({
+ declarations: [AcceptOrganizationComponent],
+ imports: [SharedModule],
+ providers: [AcceptOrganizationInviteService],
+})
+export class AcceptOrganizationInviteModule {}
diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts b/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts
new file mode 100644
index 000000000000..97a17a5997fb
--- /dev/null
+++ b/apps/web/src/app/auth/organization-invite/accept-organization.service.spec.ts
@@ -0,0 +1,185 @@
+import { FakeGlobalStateProvider } from "@bitwarden/common/../spec/fake-state-provider";
+import { MockProxy, mock } from "jest-mock-extended";
+
+import { ApiService } from "@bitwarden/common/abstractions/api.service";
+import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
+import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
+import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
+import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
+import { PolicyType } from "@bitwarden/common/admin-console/enums";
+import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
+import { ResetPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/reset-password-policy-options";
+import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
+import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
+import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
+import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
+import { EncString } from "@bitwarden/common/platform/models/domain/enc-string";
+import { FakeGlobalState } from "@bitwarden/common/spec/fake-state";
+import { OrgKey } from "@bitwarden/common/types/key";
+
+import { I18nService } from "../../core/i18n.service";
+
+import {
+ AcceptOrganizationInviteService,
+ ORGANIZATION_INVITE,
+} from "./accept-organization.service";
+import { OrganizationInvite } from "./organization-invite";
+
+describe("AcceptOrganizationInviteService", () => {
+ let sut: AcceptOrganizationInviteService;
+ let apiService: MockProxy;
+ let authService: MockProxy;
+ let cryptoService: MockProxy;
+ let encryptService: MockProxy;
+ let policyApiService: MockProxy;
+ let policyService: MockProxy;
+ let logService: MockProxy;
+ let organizationApiService: MockProxy;
+ let organizationUserService: MockProxy;
+ let i18nService: MockProxy;
+ let globalStateProvider: FakeGlobalStateProvider;
+ let globalState: FakeGlobalState;
+
+ beforeEach(() => {
+ apiService = mock();
+ authService = mock();
+ cryptoService = mock();
+ encryptService = mock();
+ policyApiService = mock();
+ policyService = mock();
+ logService = mock();
+ organizationApiService = mock();
+ organizationUserService = mock();
+ i18nService = mock();
+ globalStateProvider = new FakeGlobalStateProvider();
+ globalState = globalStateProvider.getFake(ORGANIZATION_INVITE);
+
+ sut = new AcceptOrganizationInviteService(
+ apiService,
+ authService,
+ cryptoService,
+ encryptService,
+ policyApiService,
+ policyService,
+ logService,
+ organizationApiService,
+ organizationUserService,
+ i18nService,
+ globalStateProvider,
+ );
+ });
+
+ describe("validateAndAcceptInvite", () => {
+ it("initializes an organization when given an invite where initOrganization is true", async () => {
+ cryptoService.makeOrgKey.mockResolvedValue([
+ { encryptedString: "string" } as EncString,
+ "orgPrivateKey" as unknown as OrgKey,
+ ]);
+ cryptoService.makeKeyPair.mockResolvedValue([
+ "orgPublicKey",
+ { encryptedString: "string" } as EncString,
+ ]);
+ encryptService.encrypt.mockResolvedValue({ encryptedString: "string" } as EncString);
+ const invite = createOrgInvite({ initOrganization: true });
+
+ const result = await sut.validateAndAcceptInvite(invite);
+
+ expect(result).toBe(true);
+ expect(organizationUserService.postOrganizationUserAcceptInit).toHaveBeenCalled();
+ expect(apiService.refreshIdentityToken).toHaveBeenCalled();
+ expect(globalState.nextMock).toHaveBeenCalledWith(null);
+ expect(organizationUserService.postOrganizationUserAccept).not.toHaveBeenCalled();
+ expect(authService.logOut).not.toHaveBeenCalled();
+ });
+
+ it("logs out the user and stores the invite when a master password policy check is required", async () => {
+ const invite = createOrgInvite();
+ policyApiService.getPoliciesByToken.mockResolvedValue([
+ {
+ type: PolicyType.MasterPassword,
+ enabled: true,
+ } as Policy,
+ ]);
+
+ const result = await sut.validateAndAcceptInvite(invite);
+
+ expect(result).toBe(false);
+ expect(authService.logOut).toHaveBeenCalled();
+ expect(globalState.nextMock).toHaveBeenCalledWith(invite);
+ });
+
+ it("clears the stored invite when a master password policy check is required but the stored invite doesn't match the provided one", async () => {
+ const storedInvite = createOrgInvite({ email: "wrongemail@example.com" });
+ const providedInvite = createOrgInvite();
+ await globalState.update(() => storedInvite);
+ policyApiService.getPoliciesByToken.mockResolvedValue([
+ {
+ type: PolicyType.MasterPassword,
+ enabled: true,
+ } as Policy,
+ ]);
+
+ const result = await sut.validateAndAcceptInvite(providedInvite);
+
+ expect(result).toBe(false);
+ expect(authService.logOut).toHaveBeenCalled();
+ expect(globalState.nextMock).toHaveBeenCalledWith(providedInvite);
+ });
+
+ it("accepts the invitation request when the organization doesn't have a master password policy", async () => {
+ const invite = createOrgInvite();
+ policyApiService.getPoliciesByToken.mockResolvedValue([]);
+
+ const result = await sut.validateAndAcceptInvite(invite);
+
+ expect(result).toBe(true);
+ expect(organizationUserService.postOrganizationUserAccept).toHaveBeenCalled();
+ expect(apiService.refreshIdentityToken).toHaveBeenCalled();
+ expect(globalState.nextMock).toHaveBeenCalledWith(null);
+ expect(organizationUserService.postOrganizationUserAcceptInit).not.toHaveBeenCalled();
+ expect(authService.logOut).not.toHaveBeenCalled();
+ });
+
+ it("accepts the invitation request when the org has a master password policy, but the user has already passed it", async () => {
+ const invite = createOrgInvite();
+ policyApiService.getPoliciesByToken.mockResolvedValue([
+ {
+ type: PolicyType.MasterPassword,
+ enabled: true,
+ } as Policy,
+ ]);
+ // an existing invite means the user has already passed the master password policy
+ await globalState.update(() => invite);
+
+ policyService.getResetPasswordPolicyOptions.mockReturnValue([
+ {
+ autoEnrollEnabled: false,
+ } as ResetPasswordPolicyOptions,
+ false,
+ ]);
+
+ const result = await sut.validateAndAcceptInvite(invite);
+
+ expect(result).toBe(true);
+ expect(organizationUserService.postOrganizationUserAccept).toHaveBeenCalled();
+ expect(organizationUserService.postOrganizationUserAcceptInit).not.toHaveBeenCalled();
+ expect(authService.logOut).not.toHaveBeenCalled();
+ });
+ });
+});
+
+function createOrgInvite(custom: Partial = {}): OrganizationInvite {
+ return Object.assign(
+ {
+ email: "user@example.com",
+ initOrganization: false,
+ orgSsoIdentifier: null,
+ orgUserHasExistingUser: false,
+ organizationId: "organizationId",
+ organizationName: "organizationName",
+ organizationUserId: "organizationUserId",
+ token: "token",
+ },
+ custom,
+ );
+}
diff --git a/apps/web/src/app/auth/organization-invite/accept-organization.service.ts b/apps/web/src/app/auth/organization-invite/accept-organization.service.ts
new file mode 100644
index 000000000000..e43023c37d7e
--- /dev/null
+++ b/apps/web/src/app/auth/organization-invite/accept-organization.service.ts
@@ -0,0 +1,248 @@
+import { Injectable } from "@angular/core";
+import { BehaviorSubject, firstValueFrom, map } from "rxjs";
+
+import { ApiService } from "@bitwarden/common/abstractions/api.service";
+import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction";
+import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
+import {
+ OrganizationUserAcceptRequest,
+ OrganizationUserAcceptInitRequest,
+} from "@bitwarden/common/admin-console/abstractions/organization-user/requests";
+import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction";
+import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
+import { PolicyType } from "@bitwarden/common/admin-console/enums";
+import { Policy } from "@bitwarden/common/admin-console/models/domain/policy";
+import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request";
+import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
+import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
+import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service";
+import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
+import { Utils } from "@bitwarden/common/platform/misc/utils";
+import {
+ GlobalState,
+ GlobalStateProvider,
+ KeyDefinition,
+ ORGANIZATION_INVITE_DISK,
+} from "@bitwarden/common/platform/state";
+import { OrgKey } from "@bitwarden/common/types/key";
+
+import { OrganizationInvite } from "./organization-invite";
+
+// We're storing the organization invite for 2 reasons:
+// 1. If the org requires a MP policy check, we need to keep track that the user has already been redirected when they return.
+// 2. The MP policy check happens on login/register flows, we need to store the token to retrieve the policies then.
+export const ORGANIZATION_INVITE = new KeyDefinition(
+ ORGANIZATION_INVITE_DISK,
+ "organizationInvite",
+ {
+ deserializer: (invite) => OrganizationInvite.fromJSON(invite),
+ },
+);
+
+@Injectable()
+export class AcceptOrganizationInviteService {
+ private organizationInvitationState: GlobalState;
+ private orgNameSubject: BehaviorSubject = new BehaviorSubject(null);
+ private policyCache: Policy[];
+
+ // Fix URL encoding of space issue with Angular
+ orgName$ = this.orgNameSubject.pipe(map((orgName) => orgName.replace(/\+/g, " ")));
+
+ constructor(
+ private readonly apiService: ApiService,
+ private readonly authService: AuthService,
+ private readonly cryptoService: CryptoService,
+ private readonly encryptService: EncryptService,
+ private readonly policyApiService: PolicyApiServiceAbstraction,
+ private readonly policyService: PolicyService,
+ private readonly logService: LogService,
+ private readonly organizationApiService: OrganizationApiServiceAbstraction,
+ private readonly organizationUserService: OrganizationUserService,
+ private readonly i18nService: I18nService,
+ private readonly globalStateProvider: GlobalStateProvider,
+ ) {
+ this.organizationInvitationState = this.globalStateProvider.get(ORGANIZATION_INVITE);
+ }
+
+ /** Returns the currently stored organization invite */
+ async getOrganizationInvite(): Promise {
+ return await firstValueFrom(this.organizationInvitationState.state$);
+ }
+
+ /**
+ * Stores a new organization invite
+ * @param invite an organization invite
+ * @throws if the invite is nullish
+ */
+ async setOrganizationInvitation(invite: OrganizationInvite): Promise {
+ if (invite == null) {
+ throw new Error("Invite cannot be null. Use clearOrganizationInvitation instead.");
+ }
+ await this.organizationInvitationState.update(() => invite);
+ }
+
+ /** Clears the currently stored organization invite */
+ async clearOrganizationInvitation(): Promise {
+ await this.organizationInvitationState.update(() => null);
+ }
+
+ /**
+ * Validates and accepts the organization invitation if possible.
+ * Note: Users might need to pass a MP policy check before accepting an invite to an existing organization. If the user
+ * has not passed this check, they will be logged out and the invite will be stored for later use.
+ * @param invite an organization invite
+ * @returns a promise that resolves a boolean indicating if the invite was accepted.
+ */
+ async validateAndAcceptInvite(invite: OrganizationInvite): Promise {
+ if (invite == null) {
+ throw new Error("Invite cannot be null.");
+ }
+
+ // Creation of a new org
+ if (invite.initOrganization) {
+ await this.acceptAndInitOrganization(invite);
+ return true;
+ }
+
+ // Accepting an org invite from existing org
+ if (await this.masterPasswordPolicyCheckRequired(invite)) {
+ await this.setOrganizationInvitation(invite);
+ this.authService.logOut(() => {
+ /* Do nothing */
+ });
+ return false;
+ }
+
+ // We know the user has already logged in and passed a MP policy check
+ await this.accept(invite);
+ return true;
+ }
+
+ private async acceptAndInitOrganization(invite: OrganizationInvite): Promise {
+ await this.prepareAcceptAndInitRequest(invite).then((request) =>
+ this.organizationUserService.postOrganizationUserAcceptInit(
+ invite.organizationId,
+ invite.organizationUserId,
+ request,
+ ),
+ );
+ await this.apiService.refreshIdentityToken();
+ await this.clearOrganizationInvitation();
+ }
+
+ private async prepareAcceptAndInitRequest(
+ invite: OrganizationInvite,
+ ): Promise {
+ const request = new OrganizationUserAcceptInitRequest();
+ request.token = invite.token;
+
+ const [encryptedOrgKey, orgKey] = await this.cryptoService.makeOrgKey();
+ const [orgPublicKey, encryptedOrgPrivateKey] = await this.cryptoService.makeKeyPair(orgKey);
+ const collection = await this.encryptService.encrypt(
+ this.i18nService.t("defaultCollection"),
+ orgKey,
+ );
+
+ request.key = encryptedOrgKey.encryptedString;
+ request.keys = new OrganizationKeysRequest(
+ orgPublicKey,
+ encryptedOrgPrivateKey.encryptedString,
+ );
+ request.collectionName = collection.encryptedString;
+
+ return request;
+ }
+
+ private async accept(invite: OrganizationInvite): Promise {
+ await this.prepareAcceptRequest(invite).then((request) =>
+ this.organizationUserService.postOrganizationUserAccept(
+ invite.organizationId,
+ invite.organizationUserId,
+ request,
+ ),
+ );
+
+ await this.apiService.refreshIdentityToken();
+ await this.clearOrganizationInvitation();
+ }
+
+ private async prepareAcceptRequest(
+ invite: OrganizationInvite,
+ ): Promise {
+ const request = new OrganizationUserAcceptRequest();
+ request.token = invite.token;
+
+ if (await this.resetPasswordEnrollRequired(invite)) {
+ const response = await this.organizationApiService.getKeys(invite.organizationId);
+
+ if (response == null) {
+ throw new Error(this.i18nService.t("resetPasswordOrgKeysError"));
+ }
+
+ const publicKey = Utils.fromB64ToArray(response.publicKey);
+
+ // RSA Encrypt user's encKey.key with organization public key
+ const userKey = await this.cryptoService.getUserKey();
+ const encryptedKey = await this.cryptoService.rsaEncrypt(userKey.key, publicKey);
+
+ // Add reset password key to accept request
+ request.resetPasswordKey = encryptedKey.encryptedString;
+ }
+ return request;
+ }
+
+ private async resetPasswordEnrollRequired(invite: OrganizationInvite): Promise {
+ const policies = await this.getPolicies(invite);
+
+ if (policies == null || policies.length === 0) {
+ return false;
+ }
+
+ const result = this.policyService.getResetPasswordPolicyOptions(
+ policies,
+ invite.organizationId,
+ );
+ // Return true if policy enabled and auto-enroll enabled
+ return result[1] && result[0].autoEnrollEnabled;
+ }
+
+ private async masterPasswordPolicyCheckRequired(invite: OrganizationInvite): Promise {
+ const policies = await this.getPolicies(invite);
+
+ if (policies == null || policies.length === 0) {
+ return false;
+ }
+ const hasMasterPasswordPolicy = policies.some(
+ (p) => p.type === PolicyType.MasterPassword && p.enabled,
+ );
+
+ let storedInvite = await this.getOrganizationInvite();
+ if (storedInvite?.email !== invite.email) {
+ // clear stored invites if the email doesn't match
+ await this.clearOrganizationInvitation();
+ storedInvite = null;
+ }
+ // if we don't have an org invite stored, we know the user hasn't been redirected yet to check the MP policy
+ const hasNotCheckedMasterPasswordYet = storedInvite == null;
+ return hasMasterPasswordPolicy && hasNotCheckedMasterPasswordYet;
+ }
+
+ private async getPolicies(invite: OrganizationInvite): Promise {
+ // if policies are not cached, fetch them
+ if (this.policyCache == null) {
+ try {
+ this.policyCache = await this.policyApiService.getPoliciesByToken(
+ invite.organizationId,
+ invite.token,
+ invite.email,
+ invite.organizationUserId,
+ );
+ } catch (e) {
+ this.logService.error(e);
+ }
+ }
+
+ return this.policyCache;
+ }
+}
diff --git a/apps/web/src/app/auth/organization-invite/organization-invite.ts b/apps/web/src/app/auth/organization-invite/organization-invite.ts
new file mode 100644
index 000000000000..9a0bbf83348e
--- /dev/null
+++ b/apps/web/src/app/auth/organization-invite/organization-invite.ts
@@ -0,0 +1,30 @@
+import { Params } from "@angular/router";
+import { Jsonify } from "type-fest";
+
+export class OrganizationInvite {
+ email: string;
+ initOrganization: boolean;
+ orgSsoIdentifier: string;
+ orgUserHasExistingUser: boolean;
+ organizationId: string;
+ organizationName: string;
+ organizationUserId: string;
+ token: string;
+
+ static fromJSON(json: Jsonify) {
+ return Object.assign(new OrganizationInvite(), json);
+ }
+
+ static fromParams(params: Params): OrganizationInvite {
+ return Object.assign(new OrganizationInvite(), {
+ email: params.email,
+ initOrganization: params.initOrganization?.toLocaleLowerCase() === "true",
+ orgSsoIdentifier: params.orgSsoIdentifier,
+ orgUserHasExistingUser: params.orgUserHasExistingUser?.toLocaleLowerCase() === "true",
+ organizationId: params.organizationId,
+ organizationName: params.organizationName,
+ organizationUserId: params.organizationUserId,
+ token: params.token,
+ });
+ }
+}
diff --git a/apps/web/src/app/auth/recover-two-factor.component.html b/apps/web/src/app/auth/recover-two-factor.component.html
index 11d281b742b3..e3641765800d 100644
--- a/apps/web/src/app/auth/recover-two-factor.component.html
+++ b/apps/web/src/app/auth/recover-two-factor.component.html
@@ -1,76 +1,40 @@
-