diff --git a/.github/workflows/release-desktop-beta.yml b/.github/workflows/release-desktop-beta.yml index b9e2d7a8c85..46f4ffad57d 100644 --- a/.github/workflows/release-desktop-beta.yml +++ b/.github/workflows/release-desktop-beta.yml @@ -955,11 +955,7 @@ jobs: keyvault: "bitwarden-ci" secrets: "aws-electron-access-id, aws-electron-access-key, - aws-electron-bucket-name, - r2-electron-access-id, - r2-electron-access-key, - r2-electron-bucket-name, - cf-prod-account" + aws-electron-bucket-name" - name: Download all artifacts uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4 @@ -985,20 +981,6 @@ jobs: --recursive \ --quiet - - name: Publish artifacts to R2 - env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }} - AWS_DEFAULT_REGION: 'us-east-1' - AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }} - CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }} - working-directory: apps/desktop/artifacts - run: | - aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \ - --recursive \ - --quiet \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com - - name: Update deployment status to Success if: ${{ success() }} uses: chrnorm/deployment-status@9a72af4586197112e0491ea843682b5dc280d806 # v2.0.3 diff --git a/.github/workflows/release-desktop.yml b/.github/workflows/release-desktop.yml index cf857d71772..dc6957d00d6 100644 --- a/.github/workflows/release-desktop.yml +++ b/.github/workflows/release-desktop.yml @@ -115,11 +115,7 @@ jobs: keyvault: "bitwarden-ci" secrets: "aws-electron-access-id, aws-electron-access-key, - aws-electron-bucket-name, - r2-electron-access-id, - r2-electron-access-key, - r2-electron-bucket-name, - cf-prod-account" + aws-electron-bucket-name" - name: Download all artifacts if: ${{ github.event.inputs.release_type != 'Dry Run' }} @@ -169,21 +165,6 @@ jobs: --recursive \ --quiet - - name: Publish artifacts to R2 - if: ${{ github.event.inputs.release_type != 'Dry Run' && github.event.inputs.electron_publish == 'true' }} - env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }} - AWS_DEFAULT_REGION: 'us-east-1' - AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }} - CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }} - working-directory: apps/desktop/artifacts - run: | - aws s3 cp ./ $AWS_S3_BUCKET_NAME/desktop/ \ - --recursive \ - --quiet \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com - - name: Get checksum files uses: bitwarden/gh-actions/get-checksum@main with: diff --git a/.github/workflows/staged-rollout-desktop.yml b/.github/workflows/staged-rollout-desktop.yml index a5b5fc69b19..a6ca2f1e319 100644 --- a/.github/workflows/staged-rollout-desktop.yml +++ b/.github/workflows/staged-rollout-desktop.yml @@ -31,29 +31,21 @@ jobs: keyvault: "bitwarden-ci" secrets: "aws-electron-access-id, aws-electron-access-key, - aws-electron-bucket-name, - r2-electron-access-id, - r2-electron-access-key, - r2-electron-bucket-name, - cf-prod-account" + aws-electron-bucket-name" - - name: Download channel update info files from R2 + - name: Download channel update info files from S3 env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }} - AWS_DEFAULT_REGION: 'us-east-1' - AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }} - CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }} + AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }} + AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }} + AWS_DEFAULT_REGION: 'us-west-2' + AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.aws-electron-bucket-name }} run: | aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest.yml . \ --quiet \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest-linux.yml . \ --quiet \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com aws s3 cp $AWS_S3_BUCKET_NAME/desktop/latest-mac.yml . \ --quiet \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com - name: Check new rollout percentage env: @@ -95,20 +87,3 @@ jobs: aws s3 cp latest-mac.yml $AWS_S3_BUCKET_NAME/desktop/ \ --acl "public-read" - - - name: Publish channel update info files to R2 - env: - AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.r2-electron-access-id }} - AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.r2-electron-access-key }} - AWS_DEFAULT_REGION: 'us-east-1' - AWS_S3_BUCKET_NAME: ${{ steps.retrieve-secrets.outputs.r2-electron-bucket-name }} - CF_ACCOUNT: ${{ steps.retrieve-secrets.outputs.cf-prod-account }} - run: | - aws s3 cp latest.yml $AWS_S3_BUCKET_NAME/desktop/ \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com - - aws s3 cp latest-linux.yml $AWS_S3_BUCKET_NAME/desktop/ \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com - - aws s3 cp latest-mac.yml $AWS_S3_BUCKET_NAME/desktop/ \ - --endpoint-url https://${CF_ACCOUNT}.r2.cloudflarestorage.com diff --git a/.vscode/settings.json b/.vscode/settings.json index 27e3a9b293a..3a70af3481d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,6 @@ "**/locales/*[^n]/messages.json": true, "**/_locales/[^e]*/messages.json": true, "**/_locales/*[^n]/messages.json": true - } + }, + "rust-analyzer.linkedProjects": ["apps/desktop/desktop_native/Cargo.toml"] } diff --git a/apps/browser/package.json b/apps/browser/package.json index ee6d100572d..506f19f279b 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2024.4.1", + "version": "2024.4.2", "scripts": { "build": "webpack", "build:mv3": "cross-env MANIFEST_VERSION=3 webpack", diff --git a/apps/browser/src/_locales/ar/messages.json b/apps/browser/src/_locales/ar/messages.json index e08894be0b1..996142b5ad5 100644 --- a/apps/browser/src/_locales/ar/messages.json +++ b/apps/browser/src/_locales/ar/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "قم بالتسجيل أو إنشاء حساب جديد للوصول إلى خزنتك الآمنة." diff --git a/apps/browser/src/_locales/az/messages.json b/apps/browser/src/_locales/az/messages.json index 1e5062d8c67..a58ada8eb17 100644 --- a/apps/browser/src/_locales/az/messages.json +++ b/apps/browser/src/_locales/az/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Güvənli anbarınıza müraciət etmək üçün giriş edin və ya yeni bir hesab yaradın." diff --git a/apps/browser/src/_locales/be/messages.json b/apps/browser/src/_locales/be/messages.json index 91ff397b3ae..82fd4fa5d4e 100644 --- a/apps/browser/src/_locales/be/messages.json +++ b/apps/browser/src/_locales/be/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Увайдзіце або стварыце новы ўліковы запіс для доступу да бяспечнага сховішча." diff --git a/apps/browser/src/_locales/bg/messages.json b/apps/browser/src/_locales/bg/messages.json index 33be2608b4b..b6d41cb622a 100644 --- a/apps/browser/src/_locales/bg/messages.json +++ b/apps/browser/src/_locales/bg/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Впишете се или създайте нов абонамент, за да достъпите защитен трезор." diff --git a/apps/browser/src/_locales/bn/messages.json b/apps/browser/src/_locales/bn/messages.json index a12308648a4..dec1bc6cfae 100644 --- a/apps/browser/src/_locales/bn/messages.json +++ b/apps/browser/src/_locales/bn/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "আপনার সুরক্ষিত ভল্টে প্রবেশ করতে লগ ইন করুন অথবা একটি নতুন অ্যাকাউন্ট তৈরি করুন।" diff --git a/apps/browser/src/_locales/bs/messages.json b/apps/browser/src/_locales/bs/messages.json index 7f406fabee9..9d3113e3f60 100644 --- a/apps/browser/src/_locales/bs/messages.json +++ b/apps/browser/src/_locales/bs/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Prijavite se ili napravite novi račun da biste pristupili svom sigurnom trezoru." diff --git a/apps/browser/src/_locales/ca/messages.json b/apps/browser/src/_locales/ca/messages.json index 7c8bd63aead..8063ba79d81 100644 --- a/apps/browser/src/_locales/ca/messages.json +++ b/apps/browser/src/_locales/ca/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Inicieu sessió o creeu un compte nou per accedir a la caixa forta." diff --git a/apps/browser/src/_locales/cs/messages.json b/apps/browser/src/_locales/cs/messages.json index bd3c6882df0..ee58f3d2637 100644 --- a/apps/browser/src/_locales/cs/messages.json +++ b/apps/browser/src/_locales/cs/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Pro přístup do Vašeho bezpečného trezoru se přihlaste nebo si vytvořte nový účet." diff --git a/apps/browser/src/_locales/cy/messages.json b/apps/browser/src/_locales/cy/messages.json index c718c1d8765..a80dca5f92e 100644 --- a/apps/browser/src/_locales/cy/messages.json +++ b/apps/browser/src/_locales/cy/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Mewngofnodwch neu crëwch gyfrif newydd i gael mynediad i'ch cell ddiogel." @@ -23,7 +23,7 @@ "message": "Enterprise single sign-on" }, "cancel": { - "message": "Cancel" + "message": "Canslo" }, "close": { "message": "Cau" @@ -318,7 +318,7 @@ "message": "Golygu" }, "view": { - "message": "View" + "message": "Gweld" }, "noItemsInList": { "message": "Does dim eitemau i'w rhestru." @@ -549,10 +549,10 @@ "message": "Ydych chi'n siŵr eich bod am allgofnodi?" }, "yes": { - "message": "Yes" + "message": "Ydw" }, "no": { - "message": "No" + "message": "Na" }, "unexpectedError": { "message": "An unexpected error has occurred." diff --git a/apps/browser/src/_locales/da/messages.json b/apps/browser/src/_locales/da/messages.json index 777c3b484f6..215d79eb217 100644 --- a/apps/browser/src/_locales/da/messages.json +++ b/apps/browser/src/_locales/da/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log ind eller opret en ny konto for at få adgang til din sikre boks." diff --git a/apps/browser/src/_locales/de/messages.json b/apps/browser/src/_locales/de/messages.json index 8f2a59af1e9..fbc193dbaec 100644 --- a/apps/browser/src/_locales/de/messages.json +++ b/apps/browser/src/_locales/de/messages.json @@ -3,12 +3,12 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "Bitwarden Passwortmanager", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Melde dich an oder erstelle ein neues Konto, um auf deinen Tresor zuzugreifen." @@ -173,10 +173,10 @@ "message": "Master-Passwort ändern" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Weiter zur Web-App?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Du kannst dein Master-Passwort in der Bitwarden Web-App ändern." }, "fingerprintPhrase": { "message": "Fingerabdruck-Phrase", @@ -3001,7 +3001,7 @@ "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "Erfolg" }, "removePasskey": { "message": "Passkey entfernen" @@ -3010,21 +3010,21 @@ "message": "Passkey entfernt" }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console." + "message": "Hinweis: Nicht zugeordnete Organisationseinträge sind nicht mehr in der Ansicht aller Tresore sichtbar und nur über die Administrator-Konsole zugänglich." }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and will only be accessible via the Admin Console." + "message": "Hinweis: Ab dem 16. Mai 2024 sind nicht zugewiesene Organisationselemente nicht mehr in der Ansicht aller Tresore sichtbar und nur über die Administrator-Konsole zugänglich." }, "unassignedItemsBannerCTAPartOne": { - "message": "Assign these items to a collection from the", + "message": "Weise diese Einträge einer Sammlung aus der", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", + "message": "zu, um sie sichtbar zu machen.", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "adminConsole": { - "message": "Admin Console" + "message": "Administrator-Konsole" }, "errorAssigningTargetCollection": { "message": "Fehler beim Zuweisen der Ziel-Sammlung." diff --git a/apps/browser/src/_locales/el/messages.json b/apps/browser/src/_locales/el/messages.json index 8c65e61e53f..5c85aeff58b 100644 --- a/apps/browser/src/_locales/el/messages.json +++ b/apps/browser/src/_locales/el/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Συνδεθείτε ή δημιουργήστε ένα νέο λογαριασμό για να αποκτήσετε πρόσβαση στο ασφαλές vault σας." diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 7e6e333689f..1c0b1788957 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/en_GB/messages.json b/apps/browser/src/_locales/en_GB/messages.json index e4d90adf1ab..087cd3faa8d 100644 --- a/apps/browser/src/_locales/en_GB/messages.json +++ b/apps/browser/src/_locales/en_GB/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/en_IN/messages.json b/apps/browser/src/_locales/en_IN/messages.json index 7cc17240d20..f370af7f364 100644 --- a/apps/browser/src/_locales/en_IN/messages.json +++ b/apps/browser/src/_locales/en_IN/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/es/messages.json b/apps/browser/src/_locales/es/messages.json index 3e488bce4c7..9e89f453df8 100644 --- a/apps/browser/src/_locales/es/messages.json +++ b/apps/browser/src/_locales/es/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Identifícate o crea una nueva cuenta para acceder a tu caja fuerte." diff --git a/apps/browser/src/_locales/et/messages.json b/apps/browser/src/_locales/et/messages.json index 785a3e49860..5705a5a0d24 100644 --- a/apps/browser/src/_locales/et/messages.json +++ b/apps/browser/src/_locales/et/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Logi oma olemasolevasse kontosse sisse või loo uus konto." diff --git a/apps/browser/src/_locales/eu/messages.json b/apps/browser/src/_locales/eu/messages.json index 9a07b9d9aea..ee3b5f13292 100644 --- a/apps/browser/src/_locales/eu/messages.json +++ b/apps/browser/src/_locales/eu/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Saioa hasi edo sortu kontu berri bat zure kutxa gotorrera sartzeko." diff --git a/apps/browser/src/_locales/fa/messages.json b/apps/browser/src/_locales/fa/messages.json index c68dc43ef4c..e2f0e96c862 100644 --- a/apps/browser/src/_locales/fa/messages.json +++ b/apps/browser/src/_locales/fa/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "وارد شوید یا یک حساب کاربری بسازید تا به گاوصندوق امن‌تان دسترسی یابید." diff --git a/apps/browser/src/_locales/fi/messages.json b/apps/browser/src/_locales/fi/messages.json index 2cdb6a2379e..746f4f45be5 100644 --- a/apps/browser/src/_locales/fi/messages.json +++ b/apps/browser/src/_locales/fi/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "Kotona, töissä tai reissussa, Bitwarden suojaa helposti kaikki salasanasi, avainkoodisi ja arkaluonteiset tietosi.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Käytä salattua holviasi kirjautumalla sisään tai luo uusi tili." diff --git a/apps/browser/src/_locales/fil/messages.json b/apps/browser/src/_locales/fil/messages.json index 0dfb4a39c91..abb999d032a 100644 --- a/apps/browser/src/_locales/fil/messages.json +++ b/apps/browser/src/_locales/fil/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Maglog-in o gumawa ng bagong account para ma-access ang iyong ligtas na kahadeyero." diff --git a/apps/browser/src/_locales/fr/messages.json b/apps/browser/src/_locales/fr/messages.json index 742e31ee58c..de35f718325 100644 --- a/apps/browser/src/_locales/fr/messages.json +++ b/apps/browser/src/_locales/fr/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Identifiez-vous ou créez un nouveau compte pour accéder à votre coffre sécurisé." diff --git a/apps/browser/src/_locales/gl/messages.json b/apps/browser/src/_locales/gl/messages.json index b4c151eeb03..3dd737f0a8c 100644 --- a/apps/browser/src/_locales/gl/messages.json +++ b/apps/browser/src/_locales/gl/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/he/messages.json b/apps/browser/src/_locales/he/messages.json index 61482da54a6..5d343ae8070 100644 --- a/apps/browser/src/_locales/he/messages.json +++ b/apps/browser/src/_locales/he/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "צור חשבון חדש או התחבר כדי לגשת לכספת המאובטחת שלך." diff --git a/apps/browser/src/_locales/hi/messages.json b/apps/browser/src/_locales/hi/messages.json index b76405eed85..fa4051d3e9e 100644 --- a/apps/browser/src/_locales/hi/messages.json +++ b/apps/browser/src/_locales/hi/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "अपनी सुरक्षित तिजोरी में प्रवेश करने के लिए नया खाता बनाएं या लॉग इन करें।" diff --git a/apps/browser/src/_locales/hr/messages.json b/apps/browser/src/_locales/hr/messages.json index 2dc500bc1ee..c9b8741509b 100644 --- a/apps/browser/src/_locales/hr/messages.json +++ b/apps/browser/src/_locales/hr/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Prijavi se ili stvori novi račun za pristup svojem sigurnom trezoru." diff --git a/apps/browser/src/_locales/hu/messages.json b/apps/browser/src/_locales/hu/messages.json index e47f2cda1fc..5d5b1744354 100644 --- a/apps/browser/src/_locales/hu/messages.json +++ b/apps/browser/src/_locales/hu/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Bejelentkezés vagy új fiók létrehozása a biztonsági széf eléréséhez." diff --git a/apps/browser/src/_locales/id/messages.json b/apps/browser/src/_locales/id/messages.json index d4399d8e15d..b54e854d276 100644 --- a/apps/browser/src/_locales/id/messages.json +++ b/apps/browser/src/_locales/id/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Masuk atau buat akun baru untuk mengakses brankas Anda." diff --git a/apps/browser/src/_locales/it/messages.json b/apps/browser/src/_locales/it/messages.json index 93ae6821909..91d10253a02 100644 --- a/apps/browser/src/_locales/it/messages.json +++ b/apps/browser/src/_locales/it/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Accedi o crea un nuovo account per accedere alla tua cassaforte." diff --git a/apps/browser/src/_locales/ja/messages.json b/apps/browser/src/_locales/ja/messages.json index 52ff21727af..967dc222e50 100644 --- a/apps/browser/src/_locales/ja/messages.json +++ b/apps/browser/src/_locales/ja/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "安全なデータ保管庫へアクセスするためにログインまたはアカウントを作成してください。" diff --git a/apps/browser/src/_locales/ka/messages.json b/apps/browser/src/_locales/ka/messages.json index 2c18502eca3..c73c366195e 100644 --- a/apps/browser/src/_locales/ka/messages.json +++ b/apps/browser/src/_locales/ka/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/km/messages.json b/apps/browser/src/_locales/km/messages.json index 5d1b024c607..b6384bb8408 100644 --- a/apps/browser/src/_locales/km/messages.json +++ b/apps/browser/src/_locales/km/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/kn/messages.json b/apps/browser/src/_locales/kn/messages.json index 047270808e8..178cd7c45f3 100644 --- a/apps/browser/src/_locales/kn/messages.json +++ b/apps/browser/src/_locales/kn/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "ನಿಮ್ಮ ಸುರಕ್ಷಿತ ವಾಲ್ಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಲು ಲಾಗ್ ಇನ್ ಮಾಡಿ ಅಥವಾ ಹೊಸ ಖಾತೆಯನ್ನು ರಚಿಸಿ." diff --git a/apps/browser/src/_locales/ko/messages.json b/apps/browser/src/_locales/ko/messages.json index 4bc4302f8b7..95a7727b830 100644 --- a/apps/browser/src/_locales/ko/messages.json +++ b/apps/browser/src/_locales/ko/messages.json @@ -3,12 +3,12 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "Bitwarden 비밀번호 관리자", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "집에서도, 직장에서도, 이동 중에도 Bitwarden은 비밀번호, 패스키, 민감 정보를 쉽게 보호합니다.", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "안전 보관함에 접근하려면 로그인하거나 새 계정을 만드세요." @@ -173,7 +173,7 @@ "message": "마스터 비밀번호 변경" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "웹 앱에서 계속하시겠용?" }, "changeMasterPasswordOnWebConfirmation": { "message": "You can change your master password on the Bitwarden web app." @@ -688,10 +688,10 @@ "message": "Ask to update a login's password when a change is detected on a website. Applies to all logged in accounts." }, "enableUsePasskeys": { - "message": "Ask to save and use passkeys" + "message": "패스키를 저장 및 사용할지 묻기" }, "usePasskeysDesc": { - "message": "Ask to save new passkeys or log in with passkeys stored in your vault. Applies to all logged in accounts." + "message": "보관함에 새 패스키를 저장하거나 로그인할지 물어봅니다. 모든 로그인된 계정에 적용됩니다." }, "notificationChangeDesc": { "message": "Bitwarden에 저장되어 있는 비밀번호를 이 비밀번호로 변경하시겠습니까?" @@ -2786,55 +2786,55 @@ "message": "Confirm file password" }, "typePasskey": { - "message": "Passkey" + "message": "패스키" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "패스키가 복사되지 않습니다" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "패스키는 복제된 아이템에 복사되지 않습니다. 계속 이 항목을 복제하시겠어요?" }, "passkeyFeatureIsNotImplementedForAccountsWithoutMasterPassword": { - "message": "Verification required by the initiating site. This feature is not yet implemented for accounts without master password." + "message": "사이트에서 인증을 요구합니다. 이 기능은 비밀번호가 없는 계정에서는 아직 지원하지 않습니다." }, "logInWithPasskey": { - "message": "Log in with passkey?" + "message": "패스키로 로그인하시겠어요?" }, "passkeyAlreadyExists": { - "message": "A passkey already exists for this application." + "message": "이미 이 애플리케이션에 해당하는 패스키가 있습니다." }, "noPasskeysFoundForThisApplication": { - "message": "No passkeys found for this application." + "message": "이 애플리케이션에 대한 패스키를 찾을 수 없습니다." }, "noMatchingPasskeyLogin": { - "message": "You do not have a matching login for this site." + "message": "사이트와 일치하는 로그인이 없습니다." }, "confirm": { "message": "Confirm" }, "savePasskey": { - "message": "Save passkey" + "message": "패스키 저장" }, "savePasskeyNewLogin": { - "message": "Save passkey as new login" + "message": "새 로그인으로 패스키 저장" }, "choosePasskey": { - "message": "Choose a login to save this passkey to" + "message": "패스키를 저장할 로그인 선택하기" }, "passkeyItem": { - "message": "Passkey Item" + "message": "패스키 항목" }, "overwritePasskey": { - "message": "Overwrite passkey?" + "message": "비밀번호를 덮어쓰시겠어요?" }, "overwritePasskeyAlert": { - "message": "This item already contains a passkey. Are you sure you want to overwrite the current passkey?" + "message": "이 항목은 이미 패스키가 있습니다. 정말로 현재 패스키를 덮어쓰시겠어요?" }, "featureNotSupported": { "message": "Feature not yet supported" }, "yourPasskeyIsLocked": { - "message": "Authentication required to use passkey. Verify your identity to continue." + "message": "패스키를 사용하려면 인증이 필요합니다. 인증을 진행해주세요." }, "multifactorAuthenticationCancelled": { "message": "Multifactor authentication cancelled" @@ -3004,10 +3004,10 @@ "message": "Success" }, "removePasskey": { - "message": "Remove passkey" + "message": "패스키 제거" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "패스키 제거됨" }, "unassignedItemsBannerNotice": { "message": "Notice: Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console." diff --git a/apps/browser/src/_locales/lt/messages.json b/apps/browser/src/_locales/lt/messages.json index b1a2c857e02..a01c5069e81 100644 --- a/apps/browser/src/_locales/lt/messages.json +++ b/apps/browser/src/_locales/lt/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Prisijunkite arba sukurkite naują paskyrą, kad galėtumėte pasiekti saugyklą." diff --git a/apps/browser/src/_locales/lv/messages.json b/apps/browser/src/_locales/lv/messages.json index 4055693486f..f24f0a93fc9 100644 --- a/apps/browser/src/_locales/lv/messages.json +++ b/apps/browser/src/_locales/lv/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Jāpiesakās vai jāizveido jauns konts, lai piekļūtu drošajai glabātavai." diff --git a/apps/browser/src/_locales/ml/messages.json b/apps/browser/src/_locales/ml/messages.json index d9703137fec..334027b407b 100644 --- a/apps/browser/src/_locales/ml/messages.json +++ b/apps/browser/src/_locales/ml/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "നിങ്ങളുടെ സുരക്ഷിത വാൾട്ടിലേക്കു പ്രവേശിക്കാൻ ലോഗിൻ ചെയ്യുക അല്ലെങ്കിൽ ഒരു പുതിയ അക്കൗണ്ട് സൃഷ്ടിക്കുക." diff --git a/apps/browser/src/_locales/mr/messages.json b/apps/browser/src/_locales/mr/messages.json index f67f617d3b1..b0e9f8abc18 100644 --- a/apps/browser/src/_locales/mr/messages.json +++ b/apps/browser/src/_locales/mr/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "तुमच्या सुरक्षित तिजोरीत पोहचण्यासाठी लॉग इन करा किंवा नवीन खाते उघडा." diff --git a/apps/browser/src/_locales/my/messages.json b/apps/browser/src/_locales/my/messages.json index 5d1b024c607..b6384bb8408 100644 --- a/apps/browser/src/_locales/my/messages.json +++ b/apps/browser/src/_locales/my/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/nb/messages.json b/apps/browser/src/_locales/nb/messages.json index 649163a8dc1..163154b2f2c 100644 --- a/apps/browser/src/_locales/nb/messages.json +++ b/apps/browser/src/_locales/nb/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Logg på eller opprett en ny konto for å få tilgang til ditt sikre hvelv." diff --git a/apps/browser/src/_locales/ne/messages.json b/apps/browser/src/_locales/ne/messages.json index 5d1b024c607..b6384bb8408 100644 --- a/apps/browser/src/_locales/ne/messages.json +++ b/apps/browser/src/_locales/ne/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/nl/messages.json b/apps/browser/src/_locales/nl/messages.json index 5a52b4f7ef7..cd76fc9684e 100644 --- a/apps/browser/src/_locales/nl/messages.json +++ b/apps/browser/src/_locales/nl/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in of maak een nieuw account aan om toegang te krijgen tot je beveiligde kluis." @@ -531,7 +531,7 @@ "message": "Kan de QR-code van de huidige webpagina niet scannen" }, "totpCaptureSuccess": { - "message": "Authenticatie-sleutel toegevoegd" + "message": "Authenticatiesleutel toegevoegd" }, "totpCapture": { "message": "Scan de authenticatie-QR-code van de huidige webpagina" @@ -1673,10 +1673,10 @@ "message": "Browserintegratie is niet ingeschakeld in de Bitwarden-desktopapplicatie. Schakel deze optie in de instellingen binnen de desktop-applicatie in." }, "startDesktopTitle": { - "message": "Bitwarden-desktopapplicatie opstarten" + "message": "Bitwarden desktopapplicatie opstarten" }, "startDesktopDesc": { - "message": "Je moet de Bitwarden-desktopapplicatie starten om deze functie te gebruiken." + "message": "Je moet de Bitwarden desktopapplicatie starten om deze functie te gebruiken." }, "errorEnableBiometricTitle": { "message": "Kon biometrie niet inschakelen" diff --git a/apps/browser/src/_locales/nn/messages.json b/apps/browser/src/_locales/nn/messages.json index 5d1b024c607..b6384bb8408 100644 --- a/apps/browser/src/_locales/nn/messages.json +++ b/apps/browser/src/_locales/nn/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/or/messages.json b/apps/browser/src/_locales/or/messages.json index 5d1b024c607..b6384bb8408 100644 --- a/apps/browser/src/_locales/or/messages.json +++ b/apps/browser/src/_locales/or/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/pl/messages.json b/apps/browser/src/_locales/pl/messages.json index e768a70d528..d3d9106c15e 100644 --- a/apps/browser/src/_locales/pl/messages.json +++ b/apps/browser/src/_locales/pl/messages.json @@ -3,12 +3,12 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "Menedżer Haseł Bitwarden", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Zaloguj się lub utwórz nowe konto, aby uzyskać dostęp do Twojego bezpiecznego sejfu." diff --git a/apps/browser/src/_locales/pt_BR/messages.json b/apps/browser/src/_locales/pt_BR/messages.json index c6e62fbd4f3..417bc977ebe 100644 --- a/apps/browser/src/_locales/pt_BR/messages.json +++ b/apps/browser/src/_locales/pt_BR/messages.json @@ -3,12 +3,12 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "Bitwarden Gerenciador de Senhas", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Inicie a sessão ou crie uma nova conta para acessar seu cofre seguro." @@ -173,10 +173,10 @@ "message": "Alterar Senha Mestra" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Continuar no aplicativo web?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Você pode alterar a sua senha mestra no aplicativo web Bitwarden." }, "fingerprintPhrase": { "message": "Frase Biométrica", @@ -500,10 +500,10 @@ "message": "A sua nova conta foi criada! Agora você pode iniciar a sessão." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Você logou na sua conta com sucesso" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Você pode fechar esta janela" }, "masterPassSent": { "message": "Enviamos um e-mail com a dica da sua senha mestra." @@ -1500,7 +1500,7 @@ "message": "Código PIN inválido." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "Muitas tentativas de entrada de PIN inválidas. Desconectando." }, "unlockWithBiometrics": { "message": "Desbloquear com a biometria" @@ -2005,7 +2005,7 @@ "message": "Selecionar pasta..." }, "noFoldersFound": { - "message": "No folders found", + "message": "Nenhuma pasta encontrada", "description": "Used as a message within the notification bar when no folders are found" }, "orgPermissionsUpdatedMustSetPassword": { @@ -2017,7 +2017,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "Verificação necessária", "description": "Default title for the user verification dialog." }, "hours": { @@ -2652,40 +2652,40 @@ } }, "tryAgain": { - "message": "Try again" + "message": "Tentar novamente" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Verificação necessária para esta ação. Defina um PIN para continuar." }, "setPin": { - "message": "Set PIN" + "message": "Definir PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Verificiar com biometria" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Aguardando confirmação" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Não foi possível completar a biometria." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Precisa de um método diferente?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Usar a senha mestra" }, "usePin": { - "message": "Use PIN" + "message": "Usar PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Usar biometria" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "Digite o código de verificação que foi enviado para o seu e-mail." }, "resendCode": { - "message": "Resend code" + "message": "Reenviar código" }, "total": { "message": "Total" @@ -2700,19 +2700,19 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Inicie o Duo e siga os passos para finalizar o login." }, "duoRequiredForAccount": { - "message": "Duo two-step login is required for your account." + "message": "A autenticação em duas etapas do Duo é necessária para sua conta." }, "popoutTheExtensionToCompleteLogin": { - "message": "Popout the extension to complete login." + "message": "Abra a extensão para concluir o login." }, "popoutExtension": { - "message": "Popout extension" + "message": "Extensão pop-out" }, "launchDuo": { - "message": "Launch Duo" + "message": "Abrir o Duo" }, "importFormatError": { "message": "Os dados não estão formatados corretamente. Por favor, verifique o seu arquivo de importação e tente novamente." @@ -2846,13 +2846,13 @@ "message": "Nome de usuário ou senha incorretos" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Senha incorreta" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Código incorreto" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "PIN incorreto" }, "multifactorAuthenticationFailed": { "message": "Falha na autenticação de múltiplos fatores" @@ -2965,71 +2965,71 @@ "description": "Label indicating the most common import formats" }, "overrideDefaultBrowserAutofillTitle": { - "message": "Make Bitwarden your default password manager?", + "message": "Tornar o Bitwarden seu gerenciador de senhas padrão?", "description": "Dialog title facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutofillDescription": { - "message": "Ignoring this option may cause conflicts between the Bitwarden auto-fill menu and your browser's.", + "message": "Ignorar esta opção pode causar conflitos entre o menu de autopreenchimento do Bitwarden e o do seu navegador.", "description": "Dialog message facilitating the ability to override a chrome browser's default autofill behavior" }, "overrideDefaultBrowserAutoFillSettings": { - "message": "Make Bitwarden your default password manager", + "message": "Faça do Bitwarden seu gerenciador de senhas padrão", "description": "Label for the setting that allows overriding the default browser autofill settings" }, "privacyPermissionAdditionNotGrantedTitle": { - "message": "Unable to set Bitwarden as the default password manager", + "message": "Não é possível definir o Bitwarden como o gerenciador de senhas padrão", "description": "Title for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "privacyPermissionAdditionNotGrantedDescription": { - "message": "You must grant browser privacy permissions to Bitwarden to set it as the default password manager.", + "message": "Você deve conceder permissões de privacidade do navegador ao Bitwarden para defini-lo como o Gerenciador de Senhas padrão.", "description": "Description for the dialog that appears when the user has not granted the extension permission to set privacy settings" }, "makeDefault": { - "message": "Make default", + "message": "Tornar padrão", "description": "Button text for the setting that allows overriding the default browser autofill settings" }, "saveCipherAttemptSuccess": { - "message": "Credentials saved successfully!", + "message": "Credenciais salvas com sucesso!", "description": "Notification message for when saving credentials has succeeded." }, "updateCipherAttemptSuccess": { - "message": "Credentials updated successfully!", + "message": "Credenciais atualizadas com sucesso!", "description": "Notification message for when updating credentials has succeeded." }, "saveCipherAttemptFailed": { - "message": "Error saving credentials. Check console for details.", + "message": "Erro ao salvar credenciais. Verifique o console para detalhes.", "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "Sucesso" }, "removePasskey": { - "message": "Remove passkey" + "message": "Remover senha" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Chave de acesso removida" }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console." + "message": "Aviso: Itens da organização não atribuídos não estão mais visíveis na visualização Todos os Cofres e só são acessíveis por meio do painel de administração." }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and will only be accessible via the Admin Console." + "message": "Aviso: Em 16 de maio, 2024, itens da organização não serão mais visíveis na visualização Todos os Cofres e só serão acessíveis por meio do painel de administração." }, "unassignedItemsBannerCTAPartOne": { - "message": "Assign these items to a collection from the", + "message": "Atribua estes itens a uma coleção da", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", + "message": "para torná-los visíveis.", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "adminConsole": { - "message": "Admin Console" + "message": "Painel de administração" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Erro ao atribuir coleção de destino." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Erro ao atribuir pasta de destino." } } diff --git a/apps/browser/src/_locales/pt_PT/messages.json b/apps/browser/src/_locales/pt_PT/messages.json index 06ba8eed26b..6d6fd702769 100644 --- a/apps/browser/src/_locales/pt_PT/messages.json +++ b/apps/browser/src/_locales/pt_PT/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Inicie sessão ou crie uma nova conta para aceder ao seu cofre seguro." diff --git a/apps/browser/src/_locales/ro/messages.json b/apps/browser/src/_locales/ro/messages.json index b3e0a2066fc..780bf69b938 100644 --- a/apps/browser/src/_locales/ro/messages.json +++ b/apps/browser/src/_locales/ro/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Autentificați-vă sau creați un cont nou pentru a accesa seiful dvs. securizat." diff --git a/apps/browser/src/_locales/ru/messages.json b/apps/browser/src/_locales/ru/messages.json index e594dbdce2c..927095a3f6a 100644 --- a/apps/browser/src/_locales/ru/messages.json +++ b/apps/browser/src/_locales/ru/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Войдите или создайте новый аккаунт для доступа к вашему защищенному хранилищу." diff --git a/apps/browser/src/_locales/si/messages.json b/apps/browser/src/_locales/si/messages.json index 05e2dc3edd4..33b03f574be 100644 --- a/apps/browser/src/_locales/si/messages.json +++ b/apps/browser/src/_locales/si/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "ඔබගේ ආරක්ෂිත සුරක්ෂිතාගාරය වෙත පිවිසීමට හෝ නව ගිණුමක් නිර්මාණය කරන්න." diff --git a/apps/browser/src/_locales/sk/messages.json b/apps/browser/src/_locales/sk/messages.json index eab1d105eb0..c84cfbb778e 100644 --- a/apps/browser/src/_locales/sk/messages.json +++ b/apps/browser/src/_locales/sk/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Prihláste sa, alebo vytvorte nový účet pre prístup k vášmu bezpečnému trezoru." diff --git a/apps/browser/src/_locales/sl/messages.json b/apps/browser/src/_locales/sl/messages.json index 935678efc82..4a6b7cd2140 100644 --- a/apps/browser/src/_locales/sl/messages.json +++ b/apps/browser/src/_locales/sl/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Prijavite se ali ustvarite nov račun za dostop do svojega varnega trezorja." diff --git a/apps/browser/src/_locales/sr/messages.json b/apps/browser/src/_locales/sr/messages.json index 5819546800e..a04a7ecd70d 100644 --- a/apps/browser/src/_locales/sr/messages.json +++ b/apps/browser/src/_locales/sr/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Пријавите се или креирајте нови налог за приступ сефу." @@ -173,10 +173,10 @@ "message": "Промени главну лозинку" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Ићи на веб апликацију?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Можете променити главну лозинку на Bitwarden веб апликацији." }, "fingerprintPhrase": { "message": "Сигурносна Фраза Сефа", @@ -3001,7 +3001,7 @@ "description": "Notification message for when saving credentials has failed." }, "success": { - "message": "Success" + "message": "Успех" }, "removePasskey": { "message": "Уклонити приступачни кључ" @@ -3010,10 +3010,10 @@ "message": "Приступачни кључ је уклоњен" }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console." + "message": "Напомена: Недодељене ставке организације више нису видљиве у приказу Сви сефови и доступне су само преко Админ конзоле." }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and will only be accessible via the Admin Console." + "message": "Напомена: од 16 Маја 2024м недодељене ставке организације више нису видљиве у приказу Сви сефови и доступне су само преко Админ конзоле." }, "unassignedItemsBannerCTAPartOne": { "message": "Assign these items to a collection from the", @@ -3024,12 +3024,12 @@ "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "adminConsole": { - "message": "Admin Console" + "message": "Администраторска конзола" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Грешка при додељивању циљне колекције." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Грешка при додељивању циљне фасцикле." } } diff --git a/apps/browser/src/_locales/sv/messages.json b/apps/browser/src/_locales/sv/messages.json index d96e86b8d3e..2b9ec59ec27 100644 --- a/apps/browser/src/_locales/sv/messages.json +++ b/apps/browser/src/_locales/sv/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Logga in eller skapa ett nytt konto för att komma åt ditt säkra valv." diff --git a/apps/browser/src/_locales/te/messages.json b/apps/browser/src/_locales/te/messages.json index 5d1b024c607..b6384bb8408 100644 --- a/apps/browser/src/_locales/te/messages.json +++ b/apps/browser/src/_locales/te/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." diff --git a/apps/browser/src/_locales/th/messages.json b/apps/browser/src/_locales/th/messages.json index 794d0e6c22d..7e1dda99be8 100644 --- a/apps/browser/src/_locales/th/messages.json +++ b/apps/browser/src/_locales/th/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "ล็อกอิน หรือ สร้างบัญชีใหม่ เพื่อใช้งานตู้นิรภัยของคุณ" diff --git a/apps/browser/src/_locales/tr/messages.json b/apps/browser/src/_locales/tr/messages.json index 8408253b866..8a8bb6ea600 100644 --- a/apps/browser/src/_locales/tr/messages.json +++ b/apps/browser/src/_locales/tr/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Güvenli kasanıza ulaşmak için giriş yapın veya yeni bir hesap oluşturun." diff --git a/apps/browser/src/_locales/uk/messages.json b/apps/browser/src/_locales/uk/messages.json index b590b92041b..27293fc992b 100644 --- a/apps/browser/src/_locales/uk/messages.json +++ b/apps/browser/src/_locales/uk/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Для доступу до сховища увійдіть в обліковий запис, або створіть новий." diff --git a/apps/browser/src/_locales/vi/messages.json b/apps/browser/src/_locales/vi/messages.json index ab1d0d515b7..4eba4ffaeaa 100644 --- a/apps/browser/src/_locales/vi/messages.json +++ b/apps/browser/src/_locales/vi/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "Đăng nhập hoặc tạo tài khoản mới để truy cập kho lưu trữ của bạn." diff --git a/apps/browser/src/_locales/zh_CN/messages.json b/apps/browser/src/_locales/zh_CN/messages.json index a2f856c31b8..3cf2f96da16 100644 --- a/apps/browser/src/_locales/zh_CN/messages.json +++ b/apps/browser/src/_locales/zh_CN/messages.json @@ -3,12 +3,12 @@ "message": "Bitwarden" }, "extName": { - "message": "Bitwarden Password Manager", + "message": "Bitwarden 密码管理器", "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "无论是在家里、工作中还是在外出时,Bitwarden 都可以轻松地保护您的所有密码、通行密钥和敏感信息。", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "登录或者创建一个账户来访问您的安全密码库。" @@ -176,7 +176,7 @@ "message": "前往网页 App 吗?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "您可以在 Bitwarden 网页应用上更改您的主密码。" }, "fingerprintPhrase": { "message": "指纹短语", @@ -3010,17 +3010,17 @@ "message": "通行密钥已移除" }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console." + "message": "注意:未分配的组织项目在「所有密码库」视图中不再可见,只能通过管理控制台访问。" }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and will only be accessible via the Admin Console." + "message": "注意:从 2024 年 5 月 16 日起,未分配的组织项目在「所有密码库」视图中将不再可见,只能通过管理控制台访问。" }, "unassignedItemsBannerCTAPartOne": { "message": "Assign these items to a collection from the", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", + "message": "以使其可见。", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "adminConsole": { diff --git a/apps/browser/src/_locales/zh_TW/messages.json b/apps/browser/src/_locales/zh_TW/messages.json index 1ecfdfc50eb..eb35cd08c77 100644 --- a/apps/browser/src/_locales/zh_TW/messages.json +++ b/apps/browser/src/_locales/zh_TW/messages.json @@ -7,8 +7,8 @@ "description": "Extension name, MUST be less than 40 characters (Safari restriction)" }, "extDesc": { - "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information.", - "description": "Extension description" + "message": "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information", + "description": "Extension description, MUST be less than 112 characters (Safari restriction)" }, "loginOrCreateNewAccount": { "message": "登入或建立帳戶以存取您的安全密碼庫。" diff --git a/apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts b/apps/browser/src/auth/background/service-factories/device-trust-service.factory.ts similarity index 79% rename from apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts rename to apps/browser/src/auth/background/service-factories/device-trust-service.factory.ts index cac6f9bbe8a..106bcbcf72d 100644 --- a/apps/browser/src/auth/background/service-factories/device-trust-crypto-service.factory.ts +++ b/apps/browser/src/auth/background/service-factories/device-trust-service.factory.ts @@ -1,5 +1,5 @@ -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; -import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; +import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesApiServiceInitOptions, @@ -52,9 +52,9 @@ import { userDecryptionOptionsServiceFactory, } from "./user-decryption-options-service.factory"; -type DeviceTrustCryptoServiceFactoryOptions = FactoryOptions; +type DeviceTrustServiceFactoryOptions = FactoryOptions; -export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactoryOptions & +export type DeviceTrustServiceInitOptions = DeviceTrustServiceFactoryOptions & KeyGenerationServiceInitOptions & CryptoFunctionServiceInitOptions & CryptoServiceInitOptions & @@ -67,16 +67,16 @@ export type DeviceTrustCryptoServiceInitOptions = DeviceTrustCryptoServiceFactor SecureStorageServiceInitOptions & UserDecryptionOptionsServiceInitOptions; -export function deviceTrustCryptoServiceFactory( - cache: { deviceTrustCryptoService?: DeviceTrustCryptoServiceAbstraction } & CachedServices, - opts: DeviceTrustCryptoServiceInitOptions, -): Promise { +export function deviceTrustServiceFactory( + cache: { deviceTrustService?: DeviceTrustServiceAbstraction } & CachedServices, + opts: DeviceTrustServiceInitOptions, +): Promise { return factory( cache, - "deviceTrustCryptoService", + "deviceTrustService", opts, async () => - new DeviceTrustCryptoService( + new DeviceTrustService( await keyGenerationServiceFactory(cache, opts), await cryptoFunctionServiceFactory(cache, opts), await cryptoServiceFactory(cache, opts), diff --git a/apps/browser/src/auth/background/service-factories/login-strategy-service.factory.ts b/apps/browser/src/auth/background/service-factories/login-strategy-service.factory.ts index f184072cce5..075ba614b7a 100644 --- a/apps/browser/src/auth/background/service-factories/login-strategy-service.factory.ts +++ b/apps/browser/src/auth/background/service-factories/login-strategy-service.factory.ts @@ -65,9 +65,9 @@ import { AuthRequestServiceInitOptions, } from "./auth-request-service.factory"; import { - deviceTrustCryptoServiceFactory, - DeviceTrustCryptoServiceInitOptions, -} from "./device-trust-crypto-service.factory"; + deviceTrustServiceFactory, + DeviceTrustServiceInitOptions, +} from "./device-trust-service.factory"; import { keyConnectorServiceFactory, KeyConnectorServiceInitOptions, @@ -102,7 +102,7 @@ export type LoginStrategyServiceInitOptions = LoginStrategyServiceFactoryOptions EncryptServiceInitOptions & PolicyServiceInitOptions & PasswordStrengthServiceInitOptions & - DeviceTrustCryptoServiceInitOptions & + DeviceTrustServiceInitOptions & AuthRequestServiceInitOptions & UserDecryptionOptionsServiceInitOptions & GlobalStateProviderInitOptions & @@ -135,7 +135,7 @@ export function loginStrategyServiceFactory( await encryptServiceFactory(cache, opts), await passwordStrengthServiceFactory(cache, opts), await policyServiceFactory(cache, opts), - await deviceTrustCryptoServiceFactory(cache, opts), + await deviceTrustServiceFactory(cache, opts), await authRequestServiceFactory(cache, opts), await internalUserDecryptionOptionServiceFactory(cache, opts), await globalStateProviderFactory(cache, opts), diff --git a/apps/browser/src/auth/popup/lock.component.ts b/apps/browser/src/auth/popup/lock.component.ts index 16c32337cf5..78039d793f5 100644 --- a/apps/browser/src/auth/popup/lock.component.ts +++ b/apps/browser/src/auth/popup/lock.component.ts @@ -11,7 +11,7 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; @@ -60,7 +60,7 @@ export class LockComponent extends BaseLockComponent { passwordStrengthService: PasswordStrengthServiceAbstraction, private authService: AuthService, dialogService: DialogService, - deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + deviceTrustService: DeviceTrustServiceAbstraction, userVerificationService: UserVerificationService, pinCryptoService: PinCryptoServiceAbstraction, private routerService: BrowserRouterService, @@ -85,7 +85,7 @@ export class LockComponent extends BaseLockComponent { policyService, passwordStrengthService, dialogService, - deviceTrustCryptoService, + deviceTrustService, userVerificationService, pinCryptoService, biometricStateService, diff --git a/apps/browser/src/auth/popup/login-via-auth-request.component.ts b/apps/browser/src/auth/popup/login-via-auth-request.component.ts index 52f311ce7b7..158296058e5 100644 --- a/apps/browser/src/auth/popup/login-via-auth-request.component.ts +++ b/apps/browser/src/auth/popup/login-via-auth-request.component.ts @@ -12,7 +12,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AnonymousHubService } from "@bitwarden/common/auth/abstractions/anonymous-hub.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -47,7 +47,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { stateService: StateService, loginEmailService: LoginEmailServiceAbstraction, syncService: SyncService, - deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + deviceTrustService: DeviceTrustServiceAbstraction, authRequestService: AuthRequestServiceAbstraction, loginStrategyService: LoginStrategyServiceAbstraction, accountService: AccountService, @@ -69,7 +69,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { validationService, stateService, loginEmailService, - deviceTrustCryptoService, + deviceTrustService, authRequestService, loginStrategyService, accountService, diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index fa1add06028..dc93de7803d 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -30,7 +30,7 @@ import { ProviderService } from "@bitwarden/common/admin-console/services/provid import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service"; import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service"; @@ -45,7 +45,7 @@ import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/for import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { AvatarService } from "@bitwarden/common/auth/services/avatar.service"; -import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation"; +import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesServiceImplementation } from "@bitwarden/common/auth/services/devices/devices.service.implementation"; import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; @@ -318,7 +318,7 @@ export default class MainBackground { configApiService: ConfigApiServiceAbstraction; devicesApiService: DevicesApiServiceAbstraction; devicesService: DevicesServiceAbstraction; - deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction; + deviceTrustService: DeviceTrustServiceAbstraction; authRequestService: AuthRequestServiceAbstraction; accountService: AccountServiceAbstraction; globalStateProvider: GlobalStateProvider; @@ -612,7 +612,7 @@ export default class MainBackground { this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.stateProvider); this.devicesApiService = new DevicesApiServiceImplementation(this.apiService); - this.deviceTrustCryptoService = new DeviceTrustCryptoService( + this.deviceTrustService = new DeviceTrustService( this.keyGenerationService, this.cryptoFunctionService, this.cryptoService, @@ -670,7 +670,7 @@ export default class MainBackground { this.encryptService, this.passwordStrengthService, this.policyService, - this.deviceTrustCryptoService, + this.deviceTrustService, this.authRequestService, this.userDecryptionOptionsService, this.globalStateProvider, @@ -1096,7 +1096,8 @@ export default class MainBackground { async bootstrap() { this.containerService.attachToGlobal(self); - await this.stateService.init({ runMigrations: !this.isPrivateMode }); + // Only the "true" background should run migrations + await this.stateService.init({ runMigrations: !this.popupOnlyContext }); // This is here instead of in in the InitService b/c we don't plan for // side effects to run in the Browser InitService. @@ -1106,20 +1107,22 @@ export default class MainBackground { await (this.eventUploadService as EventUploadService).init(true); this.twoFactorService.init(); - if (!this.popupOnlyContext) { - await this.vaultTimeoutService.init(true); - this.fido2Background.init(); - await this.runtimeBackground.init(); - await this.notificationBackground.init(); - this.filelessImporterBackground.init(); - await this.commandsBackground.init(); - await this.overlayBackground.init(); - await this.tabsBackground.init(); - this.contextMenusBackground?.init(); - await this.idleBackground.init(); - if (BrowserApi.isManifestVersion(2)) { - await this.webRequestBackground.init(); - } + if (this.popupOnlyContext) { + return; + } + + await this.vaultTimeoutService.init(true); + this.fido2Background.init(); + await this.runtimeBackground.init(); + await this.notificationBackground.init(); + this.filelessImporterBackground.init(); + await this.commandsBackground.init(); + await this.overlayBackground.init(); + await this.tabsBackground.init(); + this.contextMenusBackground?.init(); + await this.idleBackground.init(); + if (BrowserApi.isManifestVersion(2)) { + await this.webRequestBackground.init(); } if (this.platformUtilsService.isFirefox() && !this.isPrivateMode) { diff --git a/apps/browser/src/background/runtime.background.ts b/apps/browser/src/background/runtime.background.ts index f457889e963..294346fe9f9 100644 --- a/apps/browser/src/background/runtime.background.ts +++ b/apps/browser/src/background/runtime.background.ts @@ -10,7 +10,7 @@ import { SystemService } from "@bitwarden/common/platform/abstractions/system.se import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherType } from "@bitwarden/common/vault/enums"; -import { MessageListener } from "../../../../libs/common/src/platform/messaging"; +import { MessageListener, isExternalMessage } from "../../../../libs/common/src/platform/messaging"; import { closeUnlockPopout, openSsoAuthResultPopout, @@ -266,7 +266,9 @@ export default class RuntimeBackground { break; } case "reloadPopup": - this.messagingService.send("reloadPopup"); + if (isExternalMessage(msg)) { + this.messagingService.send("reloadPopup"); + } break; case "emailVerificationRequired": this.messagingService.send("showDialog", { diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 78f1e2cc419..18bfaf8acbd 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.4.1", + "version": "2024.4.2", "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 cdd0869fc52..c0c88706b80 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.4.1", + "version": "2024.4.2", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", @@ -59,7 +59,6 @@ "clipboardRead", "clipboardWrite", "idle", - "alarms", "scripting", "offscreen" ], diff --git a/apps/browser/src/platform/background/service-factories/state-service.factory.ts b/apps/browser/src/platform/background/service-factories/state-service.factory.ts index 5567e009901..026a29668eb 100644 --- a/apps/browser/src/platform/background/service-factories/state-service.factory.ts +++ b/apps/browser/src/platform/background/service-factories/state-service.factory.ts @@ -30,7 +30,6 @@ import { type StateServiceFactoryOptions = FactoryOptions & { stateServiceOptions: { - useAccountCache?: boolean; stateFactory: StateFactory; }; }; @@ -64,7 +63,6 @@ export async function stateServiceFactory( await environmentServiceFactory(cache, opts), await tokenServiceFactory(cache, opts), await migrationRunnerFactory(cache, opts), - opts.stateServiceOptions.useAccountCache, ), ); // TODO: If we run migration through a chrome installed/updated event we can turn off running migrations diff --git a/apps/browser/src/platform/services/browser-state.service.spec.ts b/apps/browser/src/platform/services/browser-state.service.spec.ts index 8f43998321d..f06126dcf5c 100644 --- a/apps/browser/src/platform/services/browser-state.service.spec.ts +++ b/apps/browser/src/platform/services/browser-state.service.spec.ts @@ -27,7 +27,6 @@ describe("Browser State Service", () => { let diskStorageService: MockProxy; let logService: MockProxy; let stateFactory: MockProxy>; - let useAccountCache: boolean; let environmentService: MockProxy; let tokenService: MockProxy; let migrationRunner: MockProxy; @@ -46,8 +45,6 @@ describe("Browser State Service", () => { environmentService = mock(); tokenService = mock(); migrationRunner = mock(); - // turn off account cache for tests - useAccountCache = false; state = new State(new GlobalState()); state.accounts[userId] = new Account({ @@ -78,7 +75,6 @@ describe("Browser State Service", () => { environmentService, tokenService, migrationRunner, - useAccountCache, ); }); diff --git a/apps/browser/src/platform/services/default-browser-state.service.ts b/apps/browser/src/platform/services/default-browser-state.service.ts index f1f306dbc0d..b9cd2190764 100644 --- a/apps/browser/src/platform/services/default-browser-state.service.ts +++ b/apps/browser/src/platform/services/default-browser-state.service.ts @@ -15,7 +15,6 @@ import { MigrationRunner } from "@bitwarden/common/platform/services/migration-r import { StateService as BaseStateService } from "@bitwarden/common/platform/services/state.service"; import { Account } from "../../models/account"; -import { BrowserApi } from "../browser/browser-api"; import { browserSession, sessionSync } from "../decorators/session-sync-observable"; import { BrowserStateService } from "./abstractions/browser-state.service"; @@ -45,7 +44,6 @@ export class DefaultBrowserStateService environmentService: EnvironmentService, tokenService: TokenService, migrationRunner: MigrationRunner, - useAccountCache = true, ) { super( storageService, @@ -57,45 +55,7 @@ export class DefaultBrowserStateService environmentService, tokenService, migrationRunner, - useAccountCache, ); - - // TODO: This is a hack to fix having a disk cache on both the popup and - // the background page that can get out of sync. We need to work out the - // best way to handle caching with multiple instances of the state service. - if (useAccountCache) { - BrowserApi.storageChangeListener((changes, namespace) => { - if (namespace === "local") { - for (const key of Object.keys(changes)) { - if (key !== "accountActivity" && this.accountDiskCache.value[key]) { - this.deleteDiskCache(key); - } - } - } - }); - - BrowserApi.addListener( - chrome.runtime.onMessage, - (message: { command: string }, _, respond) => { - if (message.command === "initializeDiskCache") { - respond(JSON.stringify(this.accountDiskCache.value)); - } - }, - ); - } - } - - override async initAccountState(): Promise { - if (this.isRecoveredSession && this.useAccountCache) { - // request cache initialization - - const response = await BrowserApi.sendMessageWithResponse("initializeDiskCache"); - this.accountDiskCache.next(JSON.parse(response)); - - return; - } - - await super.initAccountState(); } async addAccount(account: Account) { diff --git a/apps/browser/src/platform/services/local-backed-session-storage.service.ts b/apps/browser/src/platform/services/local-backed-session-storage.service.ts index 5432e8d918b..0fa359181dc 100644 --- a/apps/browser/src/platform/services/local-backed-session-storage.service.ts +++ b/apps/browser/src/platform/services/local-backed-session-storage.service.ts @@ -92,9 +92,16 @@ export class LocalBackedSessionStorageService // This is for observation purposes only. At some point, we don't want to write to local session storage if the value is the same. if (this.platformUtilsService.isDev()) { const existingValue = this.cache[key] as T; - if (this.compareValues(existingValue, obj)) { - this.logService.warning(`Possible unnecessary write to local session storage. Key: ${key}`); - this.logService.warning(obj as any); + try { + if (this.compareValues(existingValue, obj)) { + this.logService.warning( + `Possible unnecessary write to local session storage. Key: ${key}`, + ); + this.logService.warning(obj as any); + } + } catch (err) { + this.logService.warning(`Error while comparing values for key: ${key}`); + this.logService.warning(err); } } diff --git a/apps/browser/src/popup/services/init.service.ts b/apps/browser/src/popup/services/init.service.ts index c9e6d66c2af..ee842565d75 100644 --- a/apps/browser/src/popup/services/init.service.ts +++ b/apps/browser/src/popup/services/init.service.ts @@ -22,7 +22,7 @@ export class InitService { init() { return async () => { - await this.stateService.init(); + await this.stateService.init({ runMigrations: false }); // Browser background is responsible for migrations await this.i18nService.init(); if (!BrowserPopupUtils.inPopup(window)) { diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index a7da6b76127..38068d18495 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -28,7 +28,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; @@ -250,8 +250,8 @@ const safeProviders: SafeProvider[] = [ deps: [], }), safeProvider({ - provide: DeviceTrustCryptoServiceAbstraction, - useFactory: getBgService("deviceTrustCryptoService"), + provide: DeviceTrustServiceAbstraction, + useFactory: getBgService("deviceTrustService"), deps: [], }), safeProvider({ diff --git a/apps/browser/store/locales/de/copy.resx b/apps/browser/store/locales/de/copy.resx index 2267c6c85ed..eb3ab2afd48 100644 --- a/apps/browser/store/locales/de/copy.resx +++ b/apps/browser/store/locales/de/copy.resx @@ -121,55 +121,55 @@ Bitwarden Passwort-Manager - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Zu Hause, am Arbeitsplatz oder unterwegs schützt Bitwarden einfach alle deine Passwörter, Passkeys und vertraulichen Informationen. - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + Ausgezeichnet als bester Passwortmanager von PCMag, WIRED, The Verge, CNET, G2 und vielen anderen! -SECURE YOUR DIGITAL LIFE -Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. +SCHÜTZE DEIN DIGITALES LEBEN +Sicher dein digitales Leben und schütze dich vor Passwortdiebstählen, indem du individuelle, sichere Passwörter für jedes Konto erstellest und speicherst. Verwalte alles in einem Ende-zu-Ende verschlüsselten Passwort-Tresor, auf den nur du Zugriff hast. -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +ZUGRIFF AUF DEINE DATEN, ÜBERALL, JEDERZEIT UND AUF JEDEM GERÄT +Verwalte, speichere, sichere und teile einfach eine unbegrenzte Anzahl von Passwörtern auf einer unbegrenzten Anzahl von Geräten ohne Einschränkungen. -EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE -Utilize Bitwarden for free with no ads or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. +JEDER SOLLTE DIE MÖGLICHKEIT HABEN, ONLINE GESCHÜTZT ZU BLEIBEN +Verwende Bitwarden kostenlos, ohne Werbung oder Datenverkauf. Bitwarden glaubt, dass jeder die Möglichkeit haben sollte, online geschützt zu bleiben. Premium-Abos bieten Zugang zu erweiterten Funktionen. -EMPOWER YOUR TEAMS WITH BITWARDEN -Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. +STÄRKE DEINE TEAMS MIT BITWARDEN +Tarife für Teams und Enterprise enthalten professionelle Business-Funktionen. Einige Beispiele sind SSO-Integration, Selbst-Hosting, Directory-Integration und SCIM-Bereitstellung, globale Richtlinien, API-Zugang, Ereignisprotokolle und mehr. -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +Nutze Bitwarden, um deine Mitarbeiter abzusichern und sensible Informationen mit Kollegen zu teilen. -More reasons to choose Bitwarden: +Weitere Gründe, Bitwarden zu wählen: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Weltklasse-Verschlüsselung +Passwörter werden mit fortschrittlicher Ende-zu-Ende-Verschlüsselung (AES-256 bit, salted hashtag und PBKDF2 SHA-256) geschützt, damit deine Daten sicher und geheim bleiben. -3rd-party Audits -Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. +3rd-Party-Prüfungen +Bitwarden führt regelmäßig umfassende Sicherheitsprüfungen durch Dritte von namhaften Sicherheitsfirmen durch. Diese jährlichen Prüfungen umfassen Quellcode-Bewertungen und Penetration-Tests für Bitwarden-IPs, Server und Webanwendungen. -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +Erweiterte 2FA +Schütze deine Zugangsdaten mit einem Authentifikator eines Drittanbieters, per E-Mail verschickten Codes oder FIDO2 WebAuthn-Zugangsadaten wie einem Hardware-Sicherheitsschlüssel oder Passkey. Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +Übertrage Daten direkt an andere, während die Ende-zu-Ende-Verschlüsselung beibehalten wird und die Verbreitung begrenzt werden kann. -Built-in Generator -Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. +Eingebauter Generator +Erstelle lange, komplexe und eindeutige Passwörter und eindeutige Benutzernamen für jede Website, die du besuchst. Integriere E-Mail-Alias-Anbieter für zusätzlichen Datenschutz. -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +Globale Übersetzungen +Es gibt Bitwarden-Übersetzungen für mehr als 60 Sprachen, die von der weltweiten Community über Crowdin übersetzt werden. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Plattformübergreifende Anwendungen +Schütze und teile sensible Daten in deinem Bitwarden Tresor von jedem Browser, mobilen Gerät oder Desktop-Betriebssystem und mehr. -Bitwarden secures more than just passwords -End-to-end encrypted credential management solutions from Bitwarden empower organizations to secure everything, including developer secrets and passkey experiences. Visit Bitwarden.com to learn more about Bitwarden Secrets Manager and Bitwarden Passwordless.dev! +Bitwarden schützt mehr als nur Passwörter +Ende-zu-Ende verschlüsselte Zugangsverwaltungs-Lösungen von Bitwarden ermöglicht es Organisationen, alles zu sichern, einschließlich Entwicklergeheimnissen und Passkeys. Besuche Bitwarden.com, um mehr über den Bitwarden Secrets Manager und Bitwarden Passwordless.dev zu erfahren! - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Zu Hause, am Arbeitsplatz oder unterwegs schützt Bitwarden einfach alle deine Passwörter, Passkeys und vertraulichen Informationen. Synchronisiere und greife auf deinen Tresor von unterschiedlichen Geräten aus zu diff --git a/apps/browser/store/locales/ko/copy.resx b/apps/browser/store/locales/ko/copy.resx index fdfb93ad6ae..595663b1cae 100644 --- a/apps/browser/store/locales/ko/copy.resx +++ b/apps/browser/store/locales/ko/copy.resx @@ -121,7 +121,7 @@ Bitwarden Password Manager - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + 집에서도, 직장에서도, 이동 중에도 Bitwarden은 비밀번호, 패스키, 민감 정보를 쉽게 보호합니다. Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! @@ -169,7 +169,7 @@ End-to-end encrypted credential management solutions from Bitwarden empower orga - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + 집에서도, 직장에서도, 이동 중에도 Bitwarden은 비밀번호, 패스키, 민감 정보를 쉽게 보호합니다. 여러 기기에서 보관함에 접근하고 동기화할 수 있습니다. diff --git a/apps/browser/store/locales/pl/copy.resx b/apps/browser/store/locales/pl/copy.resx index 60709c7d4d1..5641c68c488 100644 --- a/apps/browser/store/locales/pl/copy.resx +++ b/apps/browser/store/locales/pl/copy.resx @@ -118,58 +118,58 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + Menedżer Haseł Bitwarden - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + W domu, w pracy, lub w ruchu, Bitwarden z łatwością zabezpiecza wszystkie Twoje hasła, passkeys i poufne informacje. - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + Uznany za najlepszego menedżera haseł przez PCMag, WIRED, The Verge, CNET, G2 i wielu innych! -SECURE YOUR DIGITAL LIFE -Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. +ZABEZPIECZ SWOJE CYFROWE ŻYCIE +Zabezpiecz swoje cyfrowe życie i chroń przed naruszeniami danych, generując i zapisując unikalne, silne hasła do każdego konta. Przechowuj wszystko w zaszyfrowanym end-to-end magazynie haseł, do którego tylko Ty masz dostęp. -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +DOSTĘP DO SWOICH DANYCH W KAŻDYM MIEJSCU, W DOWOLNYM CZASIE, NA KAŻDYM URZĄDZENIU +Z łatwością zarządzaj, przechowuj, zabezpieczaj i udostępniaj nieograniczoną liczbę haseł na nieograniczonej liczbie urządzeń. -EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE -Utilize Bitwarden for free with no ads or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. +KAŻDY POWINIEN POSIADAĆ NARZĘDZIA ABY ZACHOWAĆ BEZPIECZEŃSTWO W INTERNECIE +Korzystaj z Bitwarden za darmo, bez reklam i sprzedawania Twoich danych. Bitwarden wierzy, że każdy powinien mieć możliwość zachowania bezpieczeństwa w Internecie. Plany premium oferują dostęp do zaawansowanych funkcji. -EMPOWER YOUR TEAMS WITH BITWARDEN -Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. +WZMOCNIJ SWOJE ZESPOŁY DZIĘKI BITWARDEN +Plany dla Zespołów i Enterprise oferują profesjonalne funkcje biznesowe. Na przykład obejmują integrację z SSO, własny hosting, integrację katalogów i udostępnianie SCIM, zasady globalne, dostęp do API, dzienniki zdarzeń i inne. -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +Użyj Bitwarden, aby zabezpieczyć swoich pracowników i udostępniać poufne informacje współpracownikom. -More reasons to choose Bitwarden: +Więcej powodów, aby wybrać Bitwarden: -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +Szyfrowanie na światowym poziomie +Hasła są chronione za pomocą zaawansowanego, kompleksowego szyfrowania (AES-256-bitowy, solony hashtag i PBKDF2 SHA-256), dzięki czemu Twoje dane pozostają bezpieczne i prywatne. -3rd-party Audits -Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. +Audyty stron trzecich +Bitwarden regularnie przeprowadza kompleksowe audyty bezpieczeństwa stron trzecich we współpracy ze znanymi firmami security. Te coroczne audyty obejmują ocenę kodu źródłowego i testy penetracyjne adresów IP Bitwarden, serwerów i aplikacji internetowych. -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +Zaawansowane 2FA +Zabezpiecz swój login za pomocą zewnętrznego narzędzia uwierzytelniającego, kodów przesłanych pocztą elektroniczną lub poświadczeń FIDO2 WebAuthn, takich jak sprzętowy klucz bezpieczeństwa lub hasło. -Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +Bitwarden Wyślij +Przesyłaj dane bezpośrednio do innych, zachowując kompleksowe szyfrowane bezpieczeństwo i ograniczając ryzyko. -Built-in Generator -Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. +Wbudowany generator +Twórz długie, złożone i różne hasła oraz unikalne nazwy użytkowników dla każdej odwiedzanej witryny. Zintegruj się z dostawcami aliasów e-mail, aby uzyskać dodatkową prywatność. -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +Tłumaczenia globalne +Istnieją tłumaczenia Bitwarden na ponad 60 języków, tłumaczone przez globalną społeczność za pośrednictwem Crowdin. -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +Aplikacje wieloplatformowe +Zabezpiecz i udostępniaj poufne dane w swoim Sejfie Bitwarden z dowolnej przeglądarki, urządzenia mobilnego lub systemu operacyjnego na komputerze stacjonarnym i nie tylko. -Bitwarden secures more than just passwords -End-to-end encrypted credential management solutions from Bitwarden empower organizations to secure everything, including developer secrets and passkey experiences. Visit Bitwarden.com to learn more about Bitwarden Secrets Manager and Bitwarden Passwordless.dev! +Bitwarden zabezpiecza nie tylko hasła +Rozwiązania do zarządzania danymi zaszyfrownaymi end-to-end od firmy Bitwarden umożliwiają organizacjom zabezpieczanie wszystkiego, w tym tajemnic programistów i kluczy dostępu. Odwiedź Bitwarden.com, aby dowiedzieć się więcej o Mendżerze Sekretów Bitwarden i Bitwarden Passwordless.dev! - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + W domu, w pracy, lub w ruchu, Bitwarden z łatwością zabezpiecza wszystkie Twoje hasła, passkeys i poufne informacje. Synchronizacja i dostęp do sejfu z różnych urządzeń diff --git a/apps/browser/store/locales/pt_BR/copy.resx b/apps/browser/store/locales/pt_BR/copy.resx index 8b99c436d05..067f9357b23 100644 --- a/apps/browser/store/locales/pt_BR/copy.resx +++ b/apps/browser/store/locales/pt_BR/copy.resx @@ -118,10 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + Gerenciador de Senhas Bitwarden - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Em casa, no trabalho, ou em qualquer lugar, o Bitwarden protege facilmente todas as suas senhas, senhas e informações confidenciais. Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! @@ -169,7 +169,7 @@ End-to-end encrypted credential management solutions from Bitwarden empower orga - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + Em casa, no trabalho, ou em qualquer lugar, o Bitwarden protege facilmente todas as suas senhas, senhas e informações confidenciais. Sincronize e acesse o seu cofre através de múltiplos dispositivos diff --git a/apps/browser/store/locales/zh_CN/copy.resx b/apps/browser/store/locales/zh_CN/copy.resx index 94543f8f6f7..d010cb1a7bf 100644 --- a/apps/browser/store/locales/zh_CN/copy.resx +++ b/apps/browser/store/locales/zh_CN/copy.resx @@ -118,58 +118,56 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Bitwarden Password Manager + Bitwarden 密码管理器 - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + 无论是在家里、工作中还是在外出时,Bitwarden 都可以轻松地保护您的所有密码、通行密钥和敏感信息。 - Recognized as the best password manager by PCMag, WIRED, The Verge, CNET, G2, and more! + 被 PCMag、WIRED、The Verge、CNET、G2 等评为最佳密码管理器! -SECURE YOUR DIGITAL LIFE -Secure your digital life and protect against data breaches by generating and saving unique, strong passwords for every account. Maintain everything in an end-to-end encrypted password vault that only you can access. +保护您的数字生活 +通过为每个账户生成并保存独特而强大的密码,保护您的数字生活并防范数据泄露。所有内容保存在只有您可以访问的端对端加密的密码库中。 -ACCESS YOUR DATA, ANYWHERE, ANYTIME, ON ANY DEVICE -Easily manage, store, secure, and share unlimited passwords across unlimited devices without restrictions. +随时随地在任何设备上访问您的数据 +不受任何限制跨无限数量的设备轻松管理、存储、保护和分享不限数量的密码。 -EVERYONE SHOULD HAVE THE TOOLS TO STAY SAFE ONLINE -Utilize Bitwarden for free with no ads or selling data. Bitwarden believes everyone should have the ability to stay safe online. Premium plans offer access to advanced features. +每个人都应该拥有的保持在线安全的工具 +使用 Bitwarden 是免费的,没有广告,不会出售数据。Bitwarden 相信每个人都应该拥有保持在线安全的能力。高级计划提供了堆高级功能的访问。 -EMPOWER YOUR TEAMS WITH BITWARDEN -Plans for Teams and Enterprise come with professional business features. Some examples include SSO integration, self-hosting, directory integration and SCIM provisioning, global policies, API access, event logs, and more. +通过 BITWARDEN 为您的团队提供支持 +团队和企业计划具有专业的商业功能。例如 SSO 集成、自托管、目录集成和 SCIM 配置、全局策略、API 访问、事件日志等。 -Use Bitwarden to secure your workforce and share sensitive information with colleagues. +使用 Bitwarden 保护您的团队,并与同事共享敏感信息。 +选择 Bitwarden 的更多理由: -More reasons to choose Bitwarden: +世界级加密 +密码受到先进的端对端加密(AES-256 位、加盐哈希标签和 PBKDF2 SHA-256)保护,使您的数据保持安全和私密。 -World-Class Encryption -Passwords are protected with advanced end-to-end encryption (AES-256 bit, salted hashtag, and PBKDF2 SHA-256) so your data stays secure and private. +第三方审计 +Bitwarden 定期与知名的安全公司进行全面的第三方安全审计。这些年度审核包括对 Bitwarden IP、服务器和 Web 应用程序的源代码评估和渗透测试。 -3rd-party Audits -Bitwarden regularly conducts comprehensive third-party security audits with notable security firms. These annual audits include source code assessments and penetration testing across Bitwarden IPs, servers, and web applications. - -Advanced 2FA -Secure your login with a third-party authenticator, emailed codes, or FIDO2 WebAuthn credentials such as a hardware security key or passkey. +高级两步验证 +使用第三方身份验证器、通过电子邮件发送代码或 FIDO2 WebAuthn 凭据(如硬件安全钥匙或通行密钥)保护您的登录。 Bitwarden Send -Transmit data directly to others while maintaining end-to-end encrypted security and limiting exposure. +直接传输数据给他人,同时保持端对端加密的安全性并防止曝露。 -Built-in Generator -Create long, complex, and distinct passwords and unique usernames for every site you visit. Integrate with email alias providers for additional privacy. +内置生成器 +为您访问的每个网站创建长、复杂且独特的密码和用户名。与电子邮件别名提供商集成,增加隐私保护。 -Global Translations -Bitwarden translations exist for more than 60 languages, translated by the global community though Crowdin. +全球翻译 +Bitwarden 的翻译涵盖 60 多种语言,由全球社区通过 Crowdin 翻译。 -Cross-Platform Applications -Secure and share sensitive data within your Bitwarden Vault from any browser, mobile device, or desktop OS, and more. +跨平台应用程序 +从任何浏览器、移动设备或桌面操作系统中安全地访问和共享 Bitwarden 密码库中的敏感数据。 -Bitwarden secures more than just passwords -End-to-end encrypted credential management solutions from Bitwarden empower organizations to secure everything, including developer secrets and passkey experiences. Visit Bitwarden.com to learn more about Bitwarden Secrets Manager and Bitwarden Passwordless.dev! - +Bitwarden 保护的不仅仅是密码 +Bitwarden 的端对端加密凭据管理解决方案使组织能够保护所有内容,包括开发人员机密和通行密钥体验。访问 Bitwarden.com 了解更多关于Bitwarden Secrets Manager 和 Bitwarden Passwordless.dev 的信息! - At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information. + 无论是在家里、工作中还是在外出时,Bitwarden 都可以轻松地保护您的所有密码、通行密钥和敏感信息。 从多台设备同步和访问密码库 diff --git a/apps/cli/package.json b/apps/cli/package.json index 690842d831d..b06caacfd48 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.3.1", + "version": "2024.4.0", "keywords": [ "bitwarden", "password", diff --git a/apps/cli/src/bw.ts b/apps/cli/src/bw.ts index 437f807bc61..be3ad9ea0e1 100644 --- a/apps/cli/src/bw.ts +++ b/apps/cli/src/bw.ts @@ -28,13 +28,13 @@ import { ProviderApiService } from "@bitwarden/common/admin-console/services/pro import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { AvatarService } from "@bitwarden/common/auth/services/avatar.service"; -import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation"; +import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; import { MasterPasswordService } from "@bitwarden/common/auth/services/master-password/master-password.service"; @@ -77,6 +77,7 @@ import { MigrationBuilderService } from "@bitwarden/common/platform/services/mig import { MigrationRunner } from "@bitwarden/common/platform/services/migration-runner"; import { StateService } from "@bitwarden/common/platform/services/state.service"; import { StorageServiceProvider } from "@bitwarden/common/platform/services/storage-service.provider"; +import { UserKeyInitService } from "@bitwarden/common/platform/services/user-key-init.service"; import { ActiveUserStateProvider, DerivedStateProvider, @@ -217,7 +218,7 @@ export class Main { syncNotifierService: SyncNotifierService; sendApiService: SendApiService; devicesApiService: DevicesApiServiceAbstraction; - deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction; + deviceTrustService: DeviceTrustServiceAbstraction; authRequestService: AuthRequestService; configApiService: ConfigApiServiceAbstraction; configService: ConfigService; @@ -233,6 +234,7 @@ export class Main { biometricStateService: BiometricStateService; billingAccountProfileStateService: BillingAccountProfileStateService; providerApiService: ProviderApiServiceAbstraction; + userKeyInitService: UserKeyInitService; constructor() { let p = null; @@ -460,7 +462,7 @@ export class Main { this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.stateProvider); this.devicesApiService = new DevicesApiServiceImplementation(this.apiService); - this.deviceTrustCryptoService = new DeviceTrustCryptoService( + this.deviceTrustService = new DeviceTrustService( this.keyGenerationService, this.cryptoFunctionService, this.cryptoService, @@ -505,7 +507,7 @@ export class Main { this.encryptService, this.passwordStrengthService, this.policyService, - this.deviceTrustCryptoService, + this.deviceTrustService, this.authRequestService, this.userDecryptionOptionsService, this.globalStateProvider, @@ -692,6 +694,12 @@ export class Main { ); this.providerApiService = new ProviderApiService(this.apiService); + + this.userKeyInitService = new UserKeyInitService( + this.accountService, + this.cryptoService, + this.logService, + ); } async run() { @@ -735,6 +743,7 @@ export class Main { this.containerService.attachToGlobal(global); await this.i18nService.init(); this.twoFactorService.init(); + this.userKeyInitService.listenForActiveUserChangesToSetUserKey(); } } diff --git a/apps/desktop/electron-builder.json b/apps/desktop/electron-builder.json index 4f0d05581c0..960d56b0362 100644 --- a/apps/desktop/electron-builder.json +++ b/apps/desktop/electron-builder.json @@ -228,7 +228,8 @@ "artifactName": "${productName}-${version}-${arch}.${ext}" }, "snap": { - "summary": "After installation enable required `password-manager-service` by running `sudo snap connect bitwarden:password-manager-service`.", + "summary": "Bitwarden is a secure and free password manager for all of your devices.", + "description": "**Installation**\nBitwarden requires access to the `password-manager-service`. Please enable it through permissions or by running `sudo snap connect bitwarden:password-manager-service` after installation. See https://btwrdn.com/install-snap for details.", "autoStart": true, "base": "core22", "confinement": "strict", diff --git a/apps/desktop/native-messaging-test-runner/package-lock.json b/apps/desktop/native-messaging-test-runner/package-lock.json index e2961eb9eed..747d8ec9811 100644 --- a/apps/desktop/native-messaging-test-runner/package-lock.json +++ b/apps/desktop/native-messaging-test-runner/package-lock.json @@ -20,15 +20,17 @@ "devDependencies": { "@tsconfig/node16": "1.0.4", "@types/node": "18.19.29", - "@types/node-ipc": "9.2.0", + "@types/node-ipc": "9.2.3", "typescript": "4.7.4" } }, "../../../libs/common": { + "name": "@bitwarden/common", "version": "0.0.0", "license": "GPL-3.0" }, "../../../libs/node": { + "name": "@bitwarden/node", "version": "0.0.0", "license": "GPL-3.0", "dependencies": { @@ -105,9 +107,9 @@ } }, "node_modules/@types/node-ipc": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.2.0.tgz", - "integrity": "sha512-0v1oucUgINvWPhknecSBE5xkz74sVgeZgiL/LkWXNTSzFaGspEToA4oR56hjza0Jkk6DsS2EiNU3M2R2KQza9A==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.2.3.tgz", + "integrity": "sha512-/MvSiF71fYf3+zwqkh/zkVkZj1hl1Uobre9EMFy08mqfJNAmpR0vmPgOUdEIDVgifxHj6G1vYMPLSBLLxoDACQ==", "dev": true, "dependencies": { "@types/node": "*" diff --git a/apps/desktop/native-messaging-test-runner/package.json b/apps/desktop/native-messaging-test-runner/package.json index c5726131199..72b2587a4ae 100644 --- a/apps/desktop/native-messaging-test-runner/package.json +++ b/apps/desktop/native-messaging-test-runner/package.json @@ -25,7 +25,7 @@ "devDependencies": { "@tsconfig/node16": "1.0.4", "@types/node": "18.19.29", - "@types/node-ipc": "9.2.0", + "@types/node-ipc": "9.2.3", "typescript": "4.7.4" }, "_moduleAliases": { diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 4bb0ab2d931..5e098eb2135 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.4.2", + "version": "2024.4.3", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index d1d51c0f1c2..c15743ba5cd 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -4,7 +4,6 @@ import { Subject, merge } from "rxjs"; import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; import { SECURE_STORAGE, - STATE_SERVICE_USE_CACHE, LOCALES_DIRECTORY, SYSTEM_LANGUAGE, MEMORY_STORAGE, @@ -205,7 +204,6 @@ const safeProviders: SafeProvider[] = [ EnvironmentService, TokenService, MigrationRunner, - STATE_SERVICE_USE_CACHE, ], }), safeProvider({ diff --git a/apps/desktop/src/auth/lock.component.spec.ts b/apps/desktop/src/auth/lock.component.spec.ts index c125eba022f..480e443eab1 100644 --- a/apps/desktop/src/auth/lock.component.spec.ts +++ b/apps/desktop/src/auth/lock.component.spec.ts @@ -13,7 +13,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeou import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; @@ -145,8 +145,8 @@ describe("LockComponent", () => { useValue: mock(), }, { - provide: DeviceTrustCryptoServiceAbstraction, - useValue: mock(), + provide: DeviceTrustServiceAbstraction, + useValue: mock(), }, { provide: UserVerificationService, diff --git a/apps/desktop/src/auth/lock.component.ts b/apps/desktop/src/auth/lock.component.ts index 16b58c5bbed..b8feef4ab52 100644 --- a/apps/desktop/src/auth/lock.component.ts +++ b/apps/desktop/src/auth/lock.component.ts @@ -10,7 +10,7 @@ import { VaultTimeoutService } from "@bitwarden/common/abstractions/vault-timeou import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { DeviceType } from "@bitwarden/common/enums"; @@ -58,7 +58,7 @@ export class LockComponent extends BaseLockComponent { passwordStrengthService: PasswordStrengthServiceAbstraction, logService: LogService, dialogService: DialogService, - deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + deviceTrustService: DeviceTrustServiceAbstraction, userVerificationService: UserVerificationService, pinCryptoService: PinCryptoServiceAbstraction, biometricStateService: BiometricStateService, @@ -82,7 +82,7 @@ export class LockComponent extends BaseLockComponent { policyService, passwordStrengthService, dialogService, - deviceTrustCryptoService, + deviceTrustService, userVerificationService, pinCryptoService, biometricStateService, diff --git a/apps/desktop/src/auth/login/login-via-auth-request.component.ts b/apps/desktop/src/auth/login/login-via-auth-request.component.ts index 0a339030ba2..2d0f560205b 100644 --- a/apps/desktop/src/auth/login/login-via-auth-request.component.ts +++ b/apps/desktop/src/auth/login/login-via-auth-request.component.ts @@ -13,7 +13,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AnonymousHubService } from "@bitwarden/common/auth/abstractions/anonymous-hub.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -55,7 +55,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { syncService: SyncService, stateService: StateService, loginEmailService: LoginEmailServiceAbstraction, - deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + deviceTrustService: DeviceTrustServiceAbstraction, authRequestService: AuthRequestServiceAbstraction, loginStrategyService: LoginStrategyServiceAbstraction, accountService: AccountService, @@ -77,7 +77,7 @@ export class LoginViaAuthRequestComponent extends BaseLoginWithDeviceComponent { validationService, stateService, loginEmailService, - deviceTrustCryptoService, + deviceTrustService, authRequestService, loginStrategyService, accountService, diff --git a/apps/desktop/src/locales/af/messages.json b/apps/desktop/src/locales/af/messages.json index afdfc90d766..97067b788a5 100644 --- a/apps/desktop/src/locales/af/messages.json +++ b/apps/desktop/src/locales/af/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/ar/messages.json b/apps/desktop/src/locales/ar/messages.json index 7869b0894bc..2d25269fffe 100644 --- a/apps/desktop/src/locales/ar/messages.json +++ b/apps/desktop/src/locales/ar/messages.json @@ -2697,6 +2697,9 @@ "message": "تنسيقات مشتركة", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/az/messages.json b/apps/desktop/src/locales/az/messages.json index d4cea4f06ec..1ecd18eee75 100644 --- a/apps/desktop/src/locales/az/messages.json +++ b/apps/desktop/src/locales/az/messages.json @@ -2697,6 +2697,9 @@ "message": "Ortaq formatlar", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Uğurlu" + }, "troubleshooting": { "message": "Problemlərin aradan qaldırılması" }, diff --git a/apps/desktop/src/locales/be/messages.json b/apps/desktop/src/locales/be/messages.json index 53e3ec2d127..e0133e5a742 100644 --- a/apps/desktop/src/locales/be/messages.json +++ b/apps/desktop/src/locales/be/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/bg/messages.json b/apps/desktop/src/locales/bg/messages.json index f4886c420f6..d53034d61c4 100644 --- a/apps/desktop/src/locales/bg/messages.json +++ b/apps/desktop/src/locales/bg/messages.json @@ -2697,6 +2697,9 @@ "message": "Често използвани формати", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Успех" + }, "troubleshooting": { "message": "Отстраняване на проблеми" }, diff --git a/apps/desktop/src/locales/bn/messages.json b/apps/desktop/src/locales/bn/messages.json index abd2c1cfaed..626734ebffc 100644 --- a/apps/desktop/src/locales/bn/messages.json +++ b/apps/desktop/src/locales/bn/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/bs/messages.json b/apps/desktop/src/locales/bs/messages.json index 825bd6344e0..9d5685cca90 100644 --- a/apps/desktop/src/locales/bs/messages.json +++ b/apps/desktop/src/locales/bs/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/ca/messages.json b/apps/desktop/src/locales/ca/messages.json index 6c48d6cb0b6..d8c0f32948b 100644 --- a/apps/desktop/src/locales/ca/messages.json +++ b/apps/desktop/src/locales/ca/messages.json @@ -2697,6 +2697,9 @@ "message": "Formats comuns", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Resolució de problemes" }, diff --git a/apps/desktop/src/locales/cs/messages.json b/apps/desktop/src/locales/cs/messages.json index 550b10a31c1..e68fe8fffc4 100644 --- a/apps/desktop/src/locales/cs/messages.json +++ b/apps/desktop/src/locales/cs/messages.json @@ -2697,6 +2697,9 @@ "message": "Společné formáty", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Úspěch" + }, "troubleshooting": { "message": "Řešení problémů" }, diff --git a/apps/desktop/src/locales/cy/messages.json b/apps/desktop/src/locales/cy/messages.json index b1cc9e63d31..62f2e608bbf 100644 --- a/apps/desktop/src/locales/cy/messages.json +++ b/apps/desktop/src/locales/cy/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/da/messages.json b/apps/desktop/src/locales/da/messages.json index f2a84a3c293..0e578a6f66e 100644 --- a/apps/desktop/src/locales/da/messages.json +++ b/apps/desktop/src/locales/da/messages.json @@ -2697,6 +2697,9 @@ "message": "Almindelige formater", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Gennemført" + }, "troubleshooting": { "message": "Fejlfinding" }, diff --git a/apps/desktop/src/locales/de/messages.json b/apps/desktop/src/locales/de/messages.json index e5e3945abca..d04c2795f33 100644 --- a/apps/desktop/src/locales/de/messages.json +++ b/apps/desktop/src/locales/de/messages.json @@ -1633,10 +1633,10 @@ "message": "Browser-Integration wird nicht unterstützt" }, "browserIntegrationErrorTitle": { - "message": "Error enabling browser integration" + "message": "Fehler beim Aktivieren der Browser-Integration" }, "browserIntegrationErrorDesc": { - "message": "An error has occurred while enabling browser integration." + "message": "Beim Aktivieren der Browser-Integration ist ein Fehler aufgetreten." }, "browserIntegrationMasOnlyDesc": { "message": "Leider wird die Browser-Integration derzeit nur in der Mac App Store Version unterstützt." @@ -2697,6 +2697,9 @@ "message": "Gängigste Formate", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Erfolg" + }, "troubleshooting": { "message": "Problembehandlung" }, diff --git a/apps/desktop/src/locales/el/messages.json b/apps/desktop/src/locales/el/messages.json index 41e6a62a2fd..87360c33ce0 100644 --- a/apps/desktop/src/locales/el/messages.json +++ b/apps/desktop/src/locales/el/messages.json @@ -2697,6 +2697,9 @@ "message": "Κοινές μορφές", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Αντιμετώπιση Προβλημάτων" }, diff --git a/apps/desktop/src/locales/en_GB/messages.json b/apps/desktop/src/locales/en_GB/messages.json index 2658610df37..5c8c32b7c14 100644 --- a/apps/desktop/src/locales/en_GB/messages.json +++ b/apps/desktop/src/locales/en_GB/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/en_IN/messages.json b/apps/desktop/src/locales/en_IN/messages.json index 0542da9ddc8..abfa0b1c0da 100644 --- a/apps/desktop/src/locales/en_IN/messages.json +++ b/apps/desktop/src/locales/en_IN/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/eo/messages.json b/apps/desktop/src/locales/eo/messages.json index 1c4cc4f0bef..427f08f8052 100644 --- a/apps/desktop/src/locales/eo/messages.json +++ b/apps/desktop/src/locales/eo/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/es/messages.json b/apps/desktop/src/locales/es/messages.json index ec5da442931..f7df93bdd72 100644 --- a/apps/desktop/src/locales/es/messages.json +++ b/apps/desktop/src/locales/es/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/et/messages.json b/apps/desktop/src/locales/et/messages.json index 3850cc1d858..02cd737baac 100644 --- a/apps/desktop/src/locales/et/messages.json +++ b/apps/desktop/src/locales/et/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/eu/messages.json b/apps/desktop/src/locales/eu/messages.json index b21108b6add..2067b2dcc2e 100644 --- a/apps/desktop/src/locales/eu/messages.json +++ b/apps/desktop/src/locales/eu/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/fa/messages.json b/apps/desktop/src/locales/fa/messages.json index 08356d410d7..ef34f8222ae 100644 --- a/apps/desktop/src/locales/fa/messages.json +++ b/apps/desktop/src/locales/fa/messages.json @@ -2697,6 +2697,9 @@ "message": "فرمت‌های رایج", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/fi/messages.json b/apps/desktop/src/locales/fi/messages.json index fca24c197a1..517b437d030 100644 --- a/apps/desktop/src/locales/fi/messages.json +++ b/apps/desktop/src/locales/fi/messages.json @@ -2697,6 +2697,9 @@ "message": "Yleiset muodot", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Onnistui" + }, "troubleshooting": { "message": "Vianetsintä" }, diff --git a/apps/desktop/src/locales/fil/messages.json b/apps/desktop/src/locales/fil/messages.json index 6d5f85fca8c..d28a4b568c3 100644 --- a/apps/desktop/src/locales/fil/messages.json +++ b/apps/desktop/src/locales/fil/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/fr/messages.json b/apps/desktop/src/locales/fr/messages.json index 1097624b147..86550b736f3 100644 --- a/apps/desktop/src/locales/fr/messages.json +++ b/apps/desktop/src/locales/fr/messages.json @@ -2697,6 +2697,9 @@ "message": "Formats communs", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Résolution de problèmes" }, diff --git a/apps/desktop/src/locales/gl/messages.json b/apps/desktop/src/locales/gl/messages.json index 90648699c0f..889a2beeee0 100644 --- a/apps/desktop/src/locales/gl/messages.json +++ b/apps/desktop/src/locales/gl/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/he/messages.json b/apps/desktop/src/locales/he/messages.json index 73599c012ee..3b155ffdf3e 100644 --- a/apps/desktop/src/locales/he/messages.json +++ b/apps/desktop/src/locales/he/messages.json @@ -2697,6 +2697,9 @@ "message": "תסדירים נפוצים", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/hi/messages.json b/apps/desktop/src/locales/hi/messages.json index 4f8bb9b4bb8..af28c666813 100644 --- a/apps/desktop/src/locales/hi/messages.json +++ b/apps/desktop/src/locales/hi/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/hr/messages.json b/apps/desktop/src/locales/hr/messages.json index 220c8bfab23..01983d5891e 100644 --- a/apps/desktop/src/locales/hr/messages.json +++ b/apps/desktop/src/locales/hr/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/hu/messages.json b/apps/desktop/src/locales/hu/messages.json index 149d48284ed..5c91fb4b944 100644 --- a/apps/desktop/src/locales/hu/messages.json +++ b/apps/desktop/src/locales/hu/messages.json @@ -2697,6 +2697,9 @@ "message": "Általános formátumok", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Hibaelhárítás" }, diff --git a/apps/desktop/src/locales/id/messages.json b/apps/desktop/src/locales/id/messages.json index 3194b0f7d31..2173224f541 100644 --- a/apps/desktop/src/locales/id/messages.json +++ b/apps/desktop/src/locales/id/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/it/messages.json b/apps/desktop/src/locales/it/messages.json index 08ae2d9da85..93882cf6985 100644 --- a/apps/desktop/src/locales/it/messages.json +++ b/apps/desktop/src/locales/it/messages.json @@ -2697,6 +2697,9 @@ "message": "Formati comuni", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Successo" + }, "troubleshooting": { "message": "Risoluzione problemi" }, diff --git a/apps/desktop/src/locales/ja/messages.json b/apps/desktop/src/locales/ja/messages.json index b07eab20cc7..ab6c0be95f7 100644 --- a/apps/desktop/src/locales/ja/messages.json +++ b/apps/desktop/src/locales/ja/messages.json @@ -2697,6 +2697,9 @@ "message": "一般的な形式", "description": "Label indicating the most common import formats" }, + "success": { + "message": "成功" + }, "troubleshooting": { "message": "トラブルシューティング" }, diff --git a/apps/desktop/src/locales/ka/messages.json b/apps/desktop/src/locales/ka/messages.json index 90648699c0f..889a2beeee0 100644 --- a/apps/desktop/src/locales/ka/messages.json +++ b/apps/desktop/src/locales/ka/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/km/messages.json b/apps/desktop/src/locales/km/messages.json index 90648699c0f..889a2beeee0 100644 --- a/apps/desktop/src/locales/km/messages.json +++ b/apps/desktop/src/locales/km/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/kn/messages.json b/apps/desktop/src/locales/kn/messages.json index 162cba3a75e..eb0cbcf6be7 100644 --- a/apps/desktop/src/locales/kn/messages.json +++ b/apps/desktop/src/locales/kn/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/ko/messages.json b/apps/desktop/src/locales/ko/messages.json index 09b1767af0b..8e50ade96cd 100644 --- a/apps/desktop/src/locales/ko/messages.json +++ b/apps/desktop/src/locales/ko/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/lt/messages.json b/apps/desktop/src/locales/lt/messages.json index de77aa8fbf3..e9de6970054 100644 --- a/apps/desktop/src/locales/lt/messages.json +++ b/apps/desktop/src/locales/lt/messages.json @@ -2697,6 +2697,9 @@ "message": "Dažni formatai", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/lv/messages.json b/apps/desktop/src/locales/lv/messages.json index 521a0afcf20..aa057f54ab6 100644 --- a/apps/desktop/src/locales/lv/messages.json +++ b/apps/desktop/src/locales/lv/messages.json @@ -2697,6 +2697,9 @@ "message": "Izplatīti veidoli", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Sarežģījumu novēršana" }, diff --git a/apps/desktop/src/locales/me/messages.json b/apps/desktop/src/locales/me/messages.json index ed458379b8b..1f49961b469 100644 --- a/apps/desktop/src/locales/me/messages.json +++ b/apps/desktop/src/locales/me/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/ml/messages.json b/apps/desktop/src/locales/ml/messages.json index b94b9d1b796..96811b9dba8 100644 --- a/apps/desktop/src/locales/ml/messages.json +++ b/apps/desktop/src/locales/ml/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/mr/messages.json b/apps/desktop/src/locales/mr/messages.json index 90648699c0f..889a2beeee0 100644 --- a/apps/desktop/src/locales/mr/messages.json +++ b/apps/desktop/src/locales/mr/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/my/messages.json b/apps/desktop/src/locales/my/messages.json index 5142c8e61f7..0ee0db69ef2 100644 --- a/apps/desktop/src/locales/my/messages.json +++ b/apps/desktop/src/locales/my/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/nb/messages.json b/apps/desktop/src/locales/nb/messages.json index e190cfc236a..7bf132bdac1 100644 --- a/apps/desktop/src/locales/nb/messages.json +++ b/apps/desktop/src/locales/nb/messages.json @@ -2697,6 +2697,9 @@ "message": "Vanlige formater", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/ne/messages.json b/apps/desktop/src/locales/ne/messages.json index bd58a18b0d3..13e14668054 100644 --- a/apps/desktop/src/locales/ne/messages.json +++ b/apps/desktop/src/locales/ne/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/nl/messages.json b/apps/desktop/src/locales/nl/messages.json index 3ca07307105..b5f2a413d6f 100644 --- a/apps/desktop/src/locales/nl/messages.json +++ b/apps/desktop/src/locales/nl/messages.json @@ -2697,6 +2697,9 @@ "message": "Veelvoorkomende formaten", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Probleemoplossing" }, diff --git a/apps/desktop/src/locales/nn/messages.json b/apps/desktop/src/locales/nn/messages.json index 12e11b32c11..35e7173d74a 100644 --- a/apps/desktop/src/locales/nn/messages.json +++ b/apps/desktop/src/locales/nn/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/or/messages.json b/apps/desktop/src/locales/or/messages.json index 73635585516..cd83d2ea698 100644 --- a/apps/desktop/src/locales/or/messages.json +++ b/apps/desktop/src/locales/or/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/pl/messages.json b/apps/desktop/src/locales/pl/messages.json index df7a158a3a9..250c557309c 100644 --- a/apps/desktop/src/locales/pl/messages.json +++ b/apps/desktop/src/locales/pl/messages.json @@ -2697,6 +2697,9 @@ "message": "Popularne formaty", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Sukces" + }, "troubleshooting": { "message": "Rozwiązywanie problemów" }, diff --git a/apps/desktop/src/locales/pt_BR/messages.json b/apps/desktop/src/locales/pt_BR/messages.json index f651e0b0607..12db01d8cd1 100644 --- a/apps/desktop/src/locales/pt_BR/messages.json +++ b/apps/desktop/src/locales/pt_BR/messages.json @@ -561,10 +561,10 @@ "message": "A sua nova conta foi criada! Agora você pode iniciar a sessão." }, "youSuccessfullyLoggedIn": { - "message": "You successfully logged in" + "message": "Você logou na sua conta com sucesso" }, "youMayCloseThisWindow": { - "message": "You may close this window" + "message": "Você pode fechar esta janela" }, "masterPassSent": { "message": "Enviamos um e-mail com a dica da sua senha mestra." @@ -801,10 +801,10 @@ "message": "Alterar Senha Mestra" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Continuar no aplicativo web?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Você pode alterar a sua senha mestra no aplicativo web Bitwarden." }, "fingerprintPhrase": { "message": "Frase biométrica", @@ -1402,7 +1402,7 @@ "message": "Código PIN inválido." }, "tooManyInvalidPinEntryAttemptsLoggingOut": { - "message": "Too many invalid PIN entry attempts. Logging out." + "message": "Muitas tentativas de entrada de PIN inválidas. Desconectando." }, "unlockWithWindowsHello": { "message": "Desbloquear com o Windows Hello" @@ -1557,7 +1557,7 @@ "description": "Used as a card title description on the set password page to explain why the user is there" }, "verificationRequired": { - "message": "Verification required", + "message": "Verificação necessária", "description": "Default title for the user verification dialog." }, "currentMasterPass": { @@ -1633,10 +1633,10 @@ "message": "Integração com o navegador não suportado" }, "browserIntegrationErrorTitle": { - "message": "Error enabling browser integration" + "message": "Erro ao ativar a integração do navegador" }, "browserIntegrationErrorDesc": { - "message": "An error has occurred while enabling browser integration." + "message": "Ocorreu um erro ao permitir a integração do navegador." }, "browserIntegrationMasOnlyDesc": { "message": "Infelizmente, por ora, a integração do navegador só é suportada na versão da Mac App Store." @@ -1654,10 +1654,10 @@ "message": "Ative uma camada adicional de segurança, exigindo validação de frase de impressão digital ao estabelecer uma ligação entre o computador e o navegador. Quando ativado, isto requer intervenção do usuário e verificação cada vez que uma conexão é estabelecida." }, "enableHardwareAcceleration": { - "message": "Use hardware acceleration" + "message": "Utilizar aceleração de hardware" }, "enableHardwareAccelerationDesc": { - "message": "By default this setting is ON. Turn OFF only if you experience graphical issues. Restart is required." + "message": "Por padrão esta configuração está ativada. Desligar apenas se tiver problemas gráficos. Reiniciar é necessário." }, "approve": { "message": "Aprovar" @@ -1898,40 +1898,40 @@ "message": "A sua senha mestra não atende a uma ou mais das políticas da sua organização. Para acessar o cofre, você deve atualizar a sua senha mestra agora. O processo desconectará você da sessão atual, exigindo que você inicie a sessão novamente. Sessões ativas em outros dispositivos podem continuar ativas por até uma hora." }, "tryAgain": { - "message": "Try again" + "message": "Tentar novamente" }, "verificationRequiredForActionSetPinToContinue": { - "message": "Verification required for this action. Set a PIN to continue." + "message": "Verificação necessária para esta ação. Defina um PIN para continuar." }, "setPin": { - "message": "Set PIN" + "message": "Definir PIN" }, "verifyWithBiometrics": { - "message": "Verify with biometrics" + "message": "Verificiar com biometria" }, "awaitingConfirmation": { - "message": "Awaiting confirmation" + "message": "Aguardando confirmação" }, "couldNotCompleteBiometrics": { - "message": "Could not complete biometrics." + "message": "Não foi possível completar a biometria." }, "needADifferentMethod": { - "message": "Need a different method?" + "message": "Precisa de um método diferente?" }, "useMasterPassword": { - "message": "Use master password" + "message": "Usar a senha mestra" }, "usePin": { - "message": "Use PIN" + "message": "Usar PIN" }, "useBiometrics": { - "message": "Use biometrics" + "message": "Usar biometria" }, "enterVerificationCodeSentToEmail": { - "message": "Enter the verification code that was sent to your email." + "message": "Digite o código de verificação que foi enviado para o seu e-mail." }, "resendCode": { - "message": "Resend code" + "message": "Reenviar código" }, "hours": { "message": "Horas" @@ -2541,13 +2541,13 @@ } }, "launchDuoAndFollowStepsToFinishLoggingIn": { - "message": "Launch Duo and follow the steps to finish logging in." + "message": "Inicie o Duo e siga os passos para finalizar o login." }, "duoRequiredByOrgForAccount": { - "message": "Duo two-step login is required for your account." + "message": "A autenticação em duas etapas do Duo é necessária para sua conta." }, "launchDuo": { - "message": "Launch Duo in Browser" + "message": "Iniciar o Duo no navegador" }, "importFormatError": { "message": "Os dados não estão formatados corretamente. Por favor, verifique o seu arquivo de importação e tente novamente." @@ -2630,13 +2630,13 @@ "message": "Nome de usuário ou senha incorretos" }, "incorrectPassword": { - "message": "Incorrect password" + "message": "Senha incorreta" }, "incorrectCode": { - "message": "Incorrect code" + "message": "Código incorreto" }, "incorrectPin": { - "message": "Incorrect PIN" + "message": "PIN incorreto" }, "multifactorAuthenticationFailed": { "message": "Falha na autenticação de múltiplos fatores" @@ -2697,25 +2697,28 @@ "message": "Formatos comuns", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { - "message": "Troubleshooting" + "message": "Solução de problemas" }, "disableHardwareAccelerationRestart": { - "message": "Disable hardware acceleration and restart" + "message": "Desativar aceleração de hardware e reiniciar" }, "enableHardwareAccelerationRestart": { - "message": "Enable hardware acceleration and restart" + "message": "Ativar aceleração de hardware e reiniciar" }, "removePasskey": { - "message": "Remove passkey" + "message": "Remover senha" }, "passkeyRemoved": { - "message": "Passkey removed" + "message": "Chave de acesso removida" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Erro ao atribuir coleção de destino." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Erro ao atribuir pasta de destino." } } diff --git a/apps/desktop/src/locales/pt_PT/messages.json b/apps/desktop/src/locales/pt_PT/messages.json index 4e58dad2cf3..14f0ec5d2f7 100644 --- a/apps/desktop/src/locales/pt_PT/messages.json +++ b/apps/desktop/src/locales/pt_PT/messages.json @@ -2697,6 +2697,9 @@ "message": "Formatos comuns", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Com sucesso" + }, "troubleshooting": { "message": "Resolução de problemas" }, diff --git a/apps/desktop/src/locales/ro/messages.json b/apps/desktop/src/locales/ro/messages.json index 3fe73f28a75..978f57eb9b7 100644 --- a/apps/desktop/src/locales/ro/messages.json +++ b/apps/desktop/src/locales/ro/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/ru/messages.json b/apps/desktop/src/locales/ru/messages.json index cc182812a6b..c9b3b95b39c 100644 --- a/apps/desktop/src/locales/ru/messages.json +++ b/apps/desktop/src/locales/ru/messages.json @@ -2697,6 +2697,9 @@ "message": "Основные форматы", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Успешно" + }, "troubleshooting": { "message": "Устранение проблем" }, diff --git a/apps/desktop/src/locales/si/messages.json b/apps/desktop/src/locales/si/messages.json index 261ae1c9b8d..3d439971442 100644 --- a/apps/desktop/src/locales/si/messages.json +++ b/apps/desktop/src/locales/si/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/sk/messages.json b/apps/desktop/src/locales/sk/messages.json index 6ef52a83eef..6499486b9d5 100644 --- a/apps/desktop/src/locales/sk/messages.json +++ b/apps/desktop/src/locales/sk/messages.json @@ -2697,6 +2697,9 @@ "message": "Bežné formáty", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Úspech" + }, "troubleshooting": { "message": "Riešenie problémov" }, diff --git a/apps/desktop/src/locales/sl/messages.json b/apps/desktop/src/locales/sl/messages.json index 8c9c158c87b..8cb06dcf0ca 100644 --- a/apps/desktop/src/locales/sl/messages.json +++ b/apps/desktop/src/locales/sl/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/sr/messages.json b/apps/desktop/src/locales/sr/messages.json index edafdb55a28..04b7e4cf298 100644 --- a/apps/desktop/src/locales/sr/messages.json +++ b/apps/desktop/src/locales/sr/messages.json @@ -801,10 +801,10 @@ "message": "Промени главну лозинку" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "Ићи на веб апликацију?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "Можете променити главну лозинку на Bitwarden веб апликацији." }, "fingerprintPhrase": { "message": "Сигурносна Фраза Сефа", @@ -1633,10 +1633,10 @@ "message": "Интеграција са претраживачем није подржана" }, "browserIntegrationErrorTitle": { - "message": "Error enabling browser integration" + "message": "Грешка при омогућавању интеграције прегледача" }, "browserIntegrationErrorDesc": { - "message": "An error has occurred while enabling browser integration." + "message": "Дошло је до грешке при омогућавању интеграције прегледача." }, "browserIntegrationMasOnlyDesc": { "message": "Нажалост, интеграција прегледача за сада је подржана само у верзији Mac App Store." @@ -2697,6 +2697,9 @@ "message": "Уобичајени формати", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Решавање проблема" }, @@ -2713,9 +2716,9 @@ "message": "Приступачни кључ је уклоњен" }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Грешка при додељивању циљне колекције." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Грешка при додељивању циљне фасцикле." } } diff --git a/apps/desktop/src/locales/sv/messages.json b/apps/desktop/src/locales/sv/messages.json index 6342424fd44..bd21c0f328a 100644 --- a/apps/desktop/src/locales/sv/messages.json +++ b/apps/desktop/src/locales/sv/messages.json @@ -2697,6 +2697,9 @@ "message": "Vanliga format", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Felsökning" }, diff --git a/apps/desktop/src/locales/te/messages.json b/apps/desktop/src/locales/te/messages.json index 90648699c0f..889a2beeee0 100644 --- a/apps/desktop/src/locales/te/messages.json +++ b/apps/desktop/src/locales/te/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/th/messages.json b/apps/desktop/src/locales/th/messages.json index 5b6a1b9d0b7..f1cd5351f7f 100644 --- a/apps/desktop/src/locales/th/messages.json +++ b/apps/desktop/src/locales/th/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/tr/messages.json b/apps/desktop/src/locales/tr/messages.json index 42a8f207c73..3e7229c41b8 100644 --- a/apps/desktop/src/locales/tr/messages.json +++ b/apps/desktop/src/locales/tr/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Sorun giderme" }, diff --git a/apps/desktop/src/locales/uk/messages.json b/apps/desktop/src/locales/uk/messages.json index ac7b7c32435..9ee76520933 100644 --- a/apps/desktop/src/locales/uk/messages.json +++ b/apps/desktop/src/locales/uk/messages.json @@ -2697,6 +2697,9 @@ "message": "Поширені формати", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Успішно" + }, "troubleshooting": { "message": "Усунення проблем" }, diff --git a/apps/desktop/src/locales/vi/messages.json b/apps/desktop/src/locales/vi/messages.json index aac9995db13..0c0e6f6df73 100644 --- a/apps/desktop/src/locales/vi/messages.json +++ b/apps/desktop/src/locales/vi/messages.json @@ -2697,6 +2697,9 @@ "message": "Common formats", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "Troubleshooting" }, diff --git a/apps/desktop/src/locales/zh_CN/messages.json b/apps/desktop/src/locales/zh_CN/messages.json index 0560466cf81..9837be29e3d 100644 --- a/apps/desktop/src/locales/zh_CN/messages.json +++ b/apps/desktop/src/locales/zh_CN/messages.json @@ -801,10 +801,10 @@ "message": "修改主密码" }, "continueToWebApp": { - "message": "Continue to web app?" + "message": "前往网页 App 吗?" }, "changeMasterPasswordOnWebConfirmation": { - "message": "You can change your master password on the Bitwarden web app." + "message": "您可以在 Bitwarden 网页应用上更改您的主密码。" }, "fingerprintPhrase": { "message": "指纹短语", @@ -2697,6 +2697,9 @@ "message": "常规格式", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "故障排除" }, diff --git a/apps/desktop/src/locales/zh_TW/messages.json b/apps/desktop/src/locales/zh_TW/messages.json index 9eb12e23cf8..5f768b0a43e 100644 --- a/apps/desktop/src/locales/zh_TW/messages.json +++ b/apps/desktop/src/locales/zh_TW/messages.json @@ -2697,6 +2697,9 @@ "message": "常見格式", "description": "Label indicating the most common import formats" }, + "success": { + "message": "Success" + }, "troubleshooting": { "message": "疑難排解" }, diff --git a/apps/desktop/src/main.ts b/apps/desktop/src/main.ts index bffd2002ff1..da4c14b4aa6 100644 --- a/apps/desktop/src/main.ts +++ b/apps/desktop/src/main.ts @@ -205,7 +205,6 @@ export class Main { this.environmentService, this.tokenService, this.migrationRunner, - false, // Do not use disk caching because this will get out of sync with the renderer service ); this.desktopSettingsService = new DesktopSettingsService(stateProvider); diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index 11b38bd2738..d6945fd16e1 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.4.2", + "version": "2024.4.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.4.2", + "version": "2024.4.3", "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 a65dab016ca..fa190af9a69 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.4.2", + "version": "2024.4.3", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/apps/web/package.json b/apps/web/package.json index 55fe0987d72..434712cdf4a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2024.4.1", + "version": "2024.4.2", "scripts": { "build:oss": "webpack", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/apps/web/src/app/admin-console/organizations/members/people.component.ts b/apps/web/src/app/admin-console/organizations/members/people.component.ts index 0df247d7b09..af04d83c34d 100644 --- a/apps/web/src/app/admin-console/organizations/members/people.component.ts +++ b/apps/web/src/app/admin-console/organizations/members/people.component.ts @@ -37,7 +37,7 @@ import { import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { OrganizationKeysRequest } from "@bitwarden/common/admin-console/models/request/organization-keys.request"; -import { OrganizationBillingServiceAbstraction as OrganizationBillingService } from "@bitwarden/common/billing/abstractions/organization-billing.service"; +import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction"; import { ProductType } from "@bitwarden/common/enums"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -121,7 +121,7 @@ export class PeopleComponent extends BasePeopleComponent { private groupService: GroupService, private collectionService: CollectionService, organizationManagementPreferencesService: OrganizationManagementPreferencesService, - private organizationBillingService: OrganizationBillingService, + private billingApiService: BillingApiServiceAbstraction, ) { super( apiService, @@ -190,10 +190,11 @@ export class PeopleComponent extends BasePeopleComponent { .find((p) => p.organizationId === this.organization.id); this.orgResetPasswordPolicyEnabled = resetPasswordPolicy?.enabled; - this.orgIsOnSecretsManagerStandalone = - await this.organizationBillingService.isOnSecretsManagerStandalone( - this.organization.id, - ); + const billingMetadata = await this.billingApiService.getOrganizationBillingMetadata( + this.organization.id, + ); + + this.orgIsOnSecretsManagerStandalone = billingMetadata.isOnSecretsManagerStandalone; await this.load(); diff --git a/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.html b/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.html index 3286c086894..d0be72a52e6 100644 --- a/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.html +++ b/apps/web/src/app/admin-console/organizations/policies/two-factor-authentication.component.html @@ -2,15 +2,7 @@ {{ "twoStepLoginPolicyWarning" | i18n }} -
-
- - -
-
+ + + {{ "turnOn" | i18n }} + diff --git a/apps/web/src/app/auth/key-rotation/user-key-rotation.service.spec.ts b/apps/web/src/app/auth/key-rotation/user-key-rotation.service.spec.ts index 0997f188641..ed665fe7732 100644 --- a/apps/web/src/app/auth/key-rotation/user-key-rotation.service.spec.ts +++ b/apps/web/src/app/auth/key-rotation/user-key-rotation.service.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -42,7 +42,7 @@ describe("KeyRotationService", () => { let mockSendService: MockProxy; let mockEmergencyAccessService: MockProxy; let mockResetPasswordService: MockProxy; - let mockDeviceTrustCryptoService: MockProxy; + let mockDeviceTrustService: MockProxy; let mockCryptoService: MockProxy; let mockEncryptService: MockProxy; let mockStateService: MockProxy; @@ -60,7 +60,7 @@ describe("KeyRotationService", () => { mockSendService = mock(); mockEmergencyAccessService = mock(); mockResetPasswordService = mock(); - mockDeviceTrustCryptoService = mock(); + mockDeviceTrustService = mock(); mockCryptoService = mock(); mockEncryptService = mock(); mockStateService = mock(); @@ -74,7 +74,7 @@ describe("KeyRotationService", () => { mockSendService, mockEmergencyAccessService, mockResetPasswordService, - mockDeviceTrustCryptoService, + mockDeviceTrustService, mockCryptoService, mockEncryptService, mockStateService, diff --git a/apps/web/src/app/auth/key-rotation/user-key-rotation.service.ts b/apps/web/src/app/auth/key-rotation/user-key-rotation.service.ts index f5812d341a5..2ff48809a07 100644 --- a/apps/web/src/app/auth/key-rotation/user-key-rotation.service.ts +++ b/apps/web/src/app/auth/key-rotation/user-key-rotation.service.ts @@ -2,7 +2,7 @@ import { Injectable } from "@angular/core"; import { firstValueFrom } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -33,7 +33,7 @@ export class UserKeyRotationService { private sendService: SendService, private emergencyAccessService: EmergencyAccessService, private resetPasswordService: OrganizationUserResetPasswordService, - private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + private deviceTrustService: DeviceTrustServiceAbstraction, private cryptoService: CryptoService, private encryptService: EncryptService, private stateService: StateService, @@ -96,7 +96,7 @@ export class UserKeyRotationService { } const activeAccount = await firstValueFrom(this.accountService.activeAccount$); - await this.deviceTrustCryptoService.rotateDevicesTrust( + await this.deviceTrustService.rotateDevicesTrust( activeAccount.id, newUserKey, masterPasswordHash, diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index a2747647564..7a956500399 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -5,7 +5,6 @@ import { SafeProvider, safeProvider } from "@bitwarden/angular/platform/utils/sa import { SECURE_STORAGE, STATE_FACTORY, - STATE_SERVICE_USE_CACHE, LOCALES_DIRECTORY, SYSTEM_LANGUAGE, MEMORY_STORAGE, @@ -78,10 +77,6 @@ const safeProviders: SafeProvider[] = [ provide: STATE_FACTORY, useValue: new StateFactory(GlobalState, Account), }), - safeProvider({ - provide: STATE_SERVICE_USE_CACHE, - useValue: false, - }), safeProvider({ provide: I18nServiceAbstraction, useClass: I18nService, diff --git a/apps/web/src/app/core/state/state.service.ts b/apps/web/src/app/core/state/state.service.ts index 1ae62d8591d..185509e1502 100644 --- a/apps/web/src/app/core/state/state.service.ts +++ b/apps/web/src/app/core/state/state.service.ts @@ -4,7 +4,6 @@ import { MEMORY_STORAGE, SECURE_STORAGE, STATE_FACTORY, - STATE_SERVICE_USE_CACHE, } from "@bitwarden/angular/services/injection-tokens"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; @@ -34,7 +33,6 @@ export class StateService extends BaseStateService { environmentService: EnvironmentService, tokenService: TokenService, migrationRunner: MigrationRunner, - @Inject(STATE_SERVICE_USE_CACHE) useAccountCache = true, ) { super( storageService, @@ -46,7 +44,6 @@ export class StateService extends BaseStateService { environmentService, tokenService, migrationRunner, - useAccountCache, ); } diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts index a25ba6edbcf..2c20328336b 100644 --- a/apps/web/src/app/vault/individual-vault/vault.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault.component.ts @@ -679,6 +679,14 @@ export class VaultComponent implements OnInit, OnDestroy { } else if (result.action === CollectionDialogAction.Deleted) { await this.collectionService.delete(result.collection?.id); this.refresh(); + // Navigate away if we deleted the collection we were viewing + if (this.selectedCollection?.node.id === c?.id) { + void this.router.navigate([], { + queryParams: { collectionId: this.selectedCollection.parent?.node.id ?? null }, + queryParamsHandling: "merge", + replaceUrl: true, + }); + } } } @@ -710,9 +718,7 @@ export class VaultComponent implements OnInit, OnDestroy { ); // Navigate away if we deleted the collection we were viewing if (this.selectedCollection?.node.id === collection.id) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate([], { + void this.router.navigate([], { queryParams: { collectionId: this.selectedCollection.parent?.node.id ?? null }, queryParamsHandling: "merge", replaceUrl: true, diff --git a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts index c4c67759c7f..a5cd4680081 100644 --- a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts +++ b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts @@ -80,7 +80,7 @@ export class VaultHeaderComponent implements OnInit { ? this.i18nService.t("collections").toLowerCase() : this.i18nService.t("vault").toLowerCase(); - if (this.collection !== undefined) { + if (this.collection != null) { return this.collection.node.name; } diff --git a/apps/web/src/app/vault/org-vault/vault.component.ts b/apps/web/src/app/vault/org-vault/vault.component.ts index 587758dda13..9de404e9698 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -958,11 +958,9 @@ export class VaultComponent implements OnInit, OnDestroy { this.i18nService.t("deletedCollectionId", collection.name), ); - // Navigate away if we deleted the colletion we were viewing + // Navigate away if we deleted the collection we were viewing if (this.selectedCollection?.node.id === collection.id) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate([], { + void this.router.navigate([], { queryParams: { collectionId: this.selectedCollection.parent?.node.id ?? null }, queryParamsHandling: "merge", replaceUrl: true, @@ -1095,6 +1093,18 @@ export class VaultComponent implements OnInit, OnDestroy { result.action === CollectionDialogAction.Deleted ) { this.refresh(); + + // If we deleted the selected collection, navigate up/away + if ( + result.action === CollectionDialogAction.Deleted && + this.selectedCollection?.node.id === c?.id + ) { + void this.router.navigate([], { + queryParams: { collectionId: this.selectedCollection.parent?.node.id ?? null }, + queryParamsHandling: "merge", + replaceUrl: true, + }); + } } } diff --git a/apps/web/src/locales/az/messages.json b/apps/web/src/locales/az/messages.json index d53278e93a7..c3ae7b07b6d 100644 --- a/apps/web/src/locales/az/messages.json +++ b/apps/web/src/locales/az/messages.json @@ -8042,12 +8042,12 @@ "message": "Bu kolleksiya yalnız admin konsolundan əlçatandır" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Təşkilat Menyusuna keç" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Anbar elementini seç" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Kolleksiya elementini seç" } } diff --git a/apps/web/src/locales/bg/messages.json b/apps/web/src/locales/bg/messages.json index f4ee30ba957..e0d0f001742 100644 --- a/apps/web/src/locales/bg/messages.json +++ b/apps/web/src/locales/bg/messages.json @@ -8042,12 +8042,12 @@ "message": "Тази колекция е достъпна само през административната конзола" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Превключване на менюто на организацията" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Изберете елемент от трезора" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Изберете елемент от колекцията" } } diff --git a/apps/web/src/locales/cs/messages.json b/apps/web/src/locales/cs/messages.json index b6e62aef9aa..72e621b1a55 100644 --- a/apps/web/src/locales/cs/messages.json +++ b/apps/web/src/locales/cs/messages.json @@ -8036,18 +8036,18 @@ "message": "Nový klient byl úspěšně vytvořen" }, "noAccess": { - "message": "No access" + "message": "Žádný přístup" }, "collectionAdminConsoleManaged": { - "message": "This collection is only accessible from the admin console" + "message": "Tato kolekce je přístupná pouze z konzole administrátora" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Přepnout menu organizace" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Vybrat položku trezoru" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Vybrat položku kolekce" } } diff --git a/apps/web/src/locales/da/messages.json b/apps/web/src/locales/da/messages.json index e5042229fe8..4c8cbf108a4 100644 --- a/apps/web/src/locales/da/messages.json +++ b/apps/web/src/locales/da/messages.json @@ -8042,12 +8042,12 @@ "message": "Denne samling er kun tilgængelig via Admin-konsol" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Skift Organisationsmenu" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Vælg boksemne" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Vælg samlingsemne" } } diff --git a/apps/web/src/locales/de/messages.json b/apps/web/src/locales/de/messages.json index bd2e0946f61..1c7dd343293 100644 --- a/apps/web/src/locales/de/messages.json +++ b/apps/web/src/locales/de/messages.json @@ -4951,7 +4951,7 @@ "message": "Erstelle eine neue Kunden-Organisation, die dir als Anbieter zugeordnet wird. Du kannst auf diese Organisation zugreifen und diese verwalten." }, "newClient": { - "message": "New client" + "message": "Neuer Kunde" }, "addExistingOrganization": { "message": "Bestehende Organisation hinzufügen" @@ -7607,7 +7607,7 @@ "message": "Anbieterportal" }, "success": { - "message": "Success" + "message": "Erfolg" }, "viewCollection": { "message": "Sammlung anzeigen" @@ -7907,30 +7907,30 @@ "message": "Du kannst dich nicht selbst zu einer Gruppe hinzufügen." }, "unassignedItemsBannerSelfHost": { - "message": "Notice: On May 2, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible." + "message": "Hinweis: Ab dem 2. Mai 2024 werden nicht zugewiesene Organisationseinträge nicht mehr geräteübergreifend in der Ansicht aller Tresore sichtbar sein und sind nur über die Administrator-Konsole zugänglich. Weise diese Elemente einer Sammlung aus der Administrator-Konsole zu, um sie sichtbar zu machen." }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in your All Vaults view across devices and are now only accessible via the Admin Console." + "message": "Hinweis: Nicht zugewiesene Organisationseinträge sind nicht mehr geräteübergreifend in der Ansicht aller Tresore sichtbar und nun nur über die Administrator-Konsole zugänglich." }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console." + "message": "Hinweis: Ab dem 16. Mai 2024 werden nicht zugewiesene Organisationseinträge nicht mehr geräteübergreifend in der Ansicht aller Tresore sichtbar sein und nur über die Administrator-Konsole zugänglich." }, "unassignedItemsBannerCTAPartOne": { - "message": "Assign these items to a collection from the", + "message": "Weise diese Einträge einer Sammlung aus der", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", + "message": "zu, um sie sichtbar zu machen.", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "deleteProvider": { - "message": "Delete provider" + "message": "Anbieter löschen" }, "deleteProviderConfirmation": { - "message": "Deleting a provider is permanent and irreversible. Enter your master password to confirm the deletion of the provider and all associated data." + "message": "Das Löschen eines Anbieters ist dauerhaft und unwiderruflich. Gib dein Master-Passwort ein, um die Löschung des Anbieters und aller zugehörigen Daten zu bestätigen." }, "deleteProviderName": { - "message": "Cannot delete $ID$", + "message": "Kann $ID$ nicht löschen", "placeholders": { "id": { "content": "$1", @@ -7939,7 +7939,7 @@ } }, "deleteProviderWarningDesc": { - "message": "You must unlink all clients before you can delete $ID$", + "message": "Du musst die Verknüpfung zu allen Kunden aufheben, bevor du $ID$ löschen kannst", "placeholders": { "id": { "content": "$1", @@ -7948,16 +7948,16 @@ } }, "providerDeleted": { - "message": "Provider deleted" + "message": "Anbieter gelöscht" }, "providerDeletedDesc": { - "message": "The Provider and all associated data has been deleted." + "message": "Der Anbieter und alle zugehörigen Daten wurden gelöscht." }, "deleteProviderRecoverConfirmDesc": { - "message": "You have requested to delete this Provider. Use the button below to confirm." + "message": "Du hast die Löschung dieses Anbieters angefragt. Verwende den Button unten, um dies zu bestätigen." }, "deleteProviderWarning": { - "message": "Deleting your provider is permanent. It cannot be undone." + "message": "Die Löschung deines Anbieters ist dauerhaft. Sie kann nicht widerrufen werden." }, "errorAssigningTargetCollection": { "message": "Fehler beim Zuweisen der Ziel-Sammlung." @@ -7966,88 +7966,88 @@ "message": "Fehler beim Zuweisen des Ziel-Ordners." }, "integrationsAndSdks": { - "message": "Integrations & SDKs", + "message": "Integrationen & SDKs", "description": "The title for the section that deals with integrations and SDKs." }, "integrations": { - "message": "Integrations" + "message": "Integrationen" }, "integrationsDesc": { - "message": "Automatically sync secrets from Bitwarden Secrets Manager to a third-party service." + "message": "Geheimnisse des Bitwarden Secrets Managers automatisch mit einem Drittanbieter-Dienst synchronisieren." }, "sdks": { "message": "SDKs" }, "sdksDesc": { - "message": "Use Bitwarden Secrets Manager SDK in the following programming languages to build your own applications." + "message": "Verwende das Bitwarden Secrets Manager SDK in den folgenden Programmiersprachen, um deine eigenen Anwendungen zu erstellen." }, "setUpGithubActions": { - "message": "Set up Github Actions" + "message": "GitHub Actions einrichten" }, "setUpGitlabCICD": { - "message": "Set up GitLab CI/CD" + "message": "GitLab CI/CD einrichten" }, "setUpAnsible": { - "message": "Set up Ansible" + "message": "Ansible einrichten" }, "cSharpSDKRepo": { - "message": "View C# repository" + "message": "C#-Repository anzeigen" }, "cPlusPlusSDKRepo": { - "message": "View C++ repository" + "message": "C++-Repository anzeigen" }, "jsWebAssemblySDKRepo": { - "message": "View JS WebAssembly repository" + "message": "JS WebAssembly-Repository anzeigen" }, "javaSDKRepo": { - "message": "View Java repository" + "message": "Java-Repository anzeigen" }, "pythonSDKRepo": { - "message": "View Python repository" + "message": "Python-Repository anzeigen" }, "phpSDKRepo": { - "message": "View php repository" + "message": "PHP-Repository anzeigen" }, "rubySDKRepo": { - "message": "View Ruby repository" + "message": "Ruby-Repository anzeigen" }, "goSDKRepo": { - "message": "View Go repository" + "message": "Go-Repository anzeigen" }, "createNewClientToManageAsProvider": { - "message": "Create a new client organization to manage as a Provider. Additional seats will be reflected in the next billing cycle." + "message": "Erstelle eine neue Kunden-Organisation, um sie als Anbieter zu verwalten. Zusätzliche Benutzerplätze werden im nächsten Abrechnungszeitraum berücksichtigt." }, "selectAPlan": { - "message": "Select a plan" + "message": "Ein Abo auswählen" }, "thirtyFivePercentDiscount": { - "message": "35% Discount" + "message": "35% Rabatt" }, "monthPerMember": { "message": "month per member" }, "seats": { - "message": "Seats" + "message": "Benutzerplätze" }, "addOrganization": { - "message": "Add organization" + "message": "Organisation hinzufügen" }, "createdNewClient": { - "message": "Successfully created new client" + "message": "Neuer Kunde erfolgreich erstellt" }, "noAccess": { - "message": "No access" + "message": "Kein Zugriff" }, "collectionAdminConsoleManaged": { - "message": "This collection is only accessible from the admin console" + "message": "Diese Sammlung ist nur über die Administrator-Konsole zugänglich" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Organisationsmenü umschalten" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Tresor-Eintrag auswählen" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Sammlungseintrag auswählen" } } diff --git a/apps/web/src/locales/fr/messages.json b/apps/web/src/locales/fr/messages.json index 1f1f3438974..ffb1fe436b1 100644 --- a/apps/web/src/locales/fr/messages.json +++ b/apps/web/src/locales/fr/messages.json @@ -8042,12 +8042,12 @@ "message": "Cette collection n'est accessible qu'à partir de la Console Admin" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Afficher/masquer le Menu de l'Organisation" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Sélectionner un élément du coffre" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Sélectionner un élément de la collection" } } diff --git a/apps/web/src/locales/hu/messages.json b/apps/web/src/locales/hu/messages.json index b85733325b6..008a20b4f06 100644 --- a/apps/web/src/locales/hu/messages.json +++ b/apps/web/src/locales/hu/messages.json @@ -8042,12 +8042,12 @@ "message": "Ez a gyűjtemény csak az adminisztrátori konzolról érhető el." }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Szervezeti menü váltás" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Széf elem választás" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Gyűjtemény elem választás" } } diff --git a/apps/web/src/locales/ja/messages.json b/apps/web/src/locales/ja/messages.json index a701dd6e8df..18617433207 100644 --- a/apps/web/src/locales/ja/messages.json +++ b/apps/web/src/locales/ja/messages.json @@ -8042,12 +8042,12 @@ "message": "このコレクションは管理コンソールからのみアクセス可能です" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "組織メニューの切り替え" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "保管庫のアイテムを選択" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "コレクションのアイテムを選択" } } diff --git a/apps/web/src/locales/lv/messages.json b/apps/web/src/locales/lv/messages.json index b20f3502314..1ad03eeb825 100644 --- a/apps/web/src/locales/lv/messages.json +++ b/apps/web/src/locales/lv/messages.json @@ -7741,22 +7741,22 @@ "description": "The date header used when a subscription is cancelled." }, "machineAccountsCannotCreate": { - "message": "Machine accounts cannot be created in suspended organizations. Please contact your organization owner for assistance." + "message": "Mašīnu kontus nav iespējams izveidot apturētās apvienībās. Lūgums vērsties pie savas apvienības īpašnieka pēc palīdzības." }, "machineAccount": { - "message": "Machine account", + "message": "Mašīnas konts", "description": "A machine user which can be used to automate processes and access secrets in the system." }, "machineAccounts": { - "message": "Machine accounts", + "message": "Mašīnu konti", "description": "The title for the section that deals with machine accounts." }, "newMachineAccount": { - "message": "New machine account", + "message": "Jauns mašīnas konts", "description": "Title for creating a new machine account." }, "machineAccountsNoItemsMessage": { - "message": "Create a new machine account to get started automating secret access.", + "message": "Jāizveido jauns mašīnas konts, lai sāktu automatizēt piekļuvi noslēpumiem.", "description": "Message to encourage the user to start creating machine accounts." }, "machineAccountsNoItemsTitle": { @@ -7764,19 +7764,19 @@ "description": "Title to indicate that there are no machine accounts to display." }, "deleteMachineAccounts": { - "message": "Delete machine accounts", + "message": "Izdzēst mašīnu kontus", "description": "Title for the action to delete one or multiple machine accounts." }, "deleteMachineAccount": { - "message": "Delete machine account", + "message": "Izdzēst mašīnas kontu", "description": "Title for the action to delete a single machine account." }, "viewMachineAccount": { - "message": "View machine account", + "message": "Skatīt mašīnas kontu", "description": "Action to view the details of a machine account." }, "deleteMachineAccountDialogMessage": { - "message": "Deleting machine account $MACHINE_ACCOUNT$ is permanent and irreversible.", + "message": "Mašīnas konta $MACHINE_ACCOUNT$ izdzēšana ir paliekoša un neatgriezeniska.", "placeholders": { "machine_account": { "content": "$1", @@ -7785,10 +7785,10 @@ } }, "deleteMachineAccountsDialogMessage": { - "message": "Deleting machine accounts is permanent and irreversible." + "message": "Mašīnu kontu izdzēšana ir paliekoša un neatgriezeniska." }, "deleteMachineAccountsConfirmMessage": { - "message": "Delete $COUNT$ machine accounts", + "message": "Izdzēst $COUNT$ mašīnu kontu(s)", "placeholders": { "count": { "content": "$1", @@ -7797,60 +7797,60 @@ } }, "deleteMachineAccountToast": { - "message": "Machine account deleted" + "message": "Mašīnas konts ir izdzēsts" }, "deleteMachineAccountsToast": { - "message": "Machine accounts deleted" + "message": "Mašīnu konti ir izdzēsti" }, "searchMachineAccounts": { - "message": "Search machine accounts", + "message": "Meklēt mašīnu kontus", "description": "Placeholder text for searching machine accounts." }, "editMachineAccount": { - "message": "Edit machine account", + "message": "Labot mašīnas kontu", "description": "Title for editing a machine account." }, "machineAccountName": { - "message": "Machine account name", + "message": "Mašīnas konta nosaukums", "description": "Label for the name of a machine account" }, "machineAccountCreated": { - "message": "Machine account created", + "message": "Mašīnas konts ir izveidots", "description": "Notifies that a new machine account has been created" }, "machineAccountUpdated": { - "message": "Machine account updated", + "message": "Mašīnas konts ir atjaunināts", "description": "Notifies that a machine account has been updated" }, "projectMachineAccountsDescription": { - "message": "Grant machine accounts access to this project." + "message": "Piešķirt mašīnau kontiem piekļuvi šim projektam." }, "projectMachineAccountsSelectHint": { - "message": "Type or select machine accounts" + "message": "Ievadīt vai atlasīt mašīnu kontus" }, "projectEmptyMachineAccountAccessPolicies": { - "message": "Add machine accounts to grant access" + "message": "Jāpievieno mašīnu konti, lai piešķirtu piekļuvi" }, "machineAccountPeopleDescription": { - "message": "Grant groups or people access to this machine account." + "message": "Piešķirt kopām vai cilvēkiem piekļuvi šim mašīnas kontam." }, "machineAccountProjectsDescription": { - "message": "Assign projects to this machine account. " + "message": "Piešķirt projektus šim mašīnas kontam. " }, "createMachineAccount": { - "message": "Create a machine account" + "message": "Izveidot mašīnas kontu" }, "maPeopleWarningMessage": { - "message": "Removing people from a machine account does not remove the access tokens they created. For security best practice, it is recommended to revoke access tokens created by people removed from a machine account." + "message": "Cilvēku noņemšana no mašīnas konta nenoņem to izveidotās piekļuves pilnvaras. Labākajai drošības pieejai ir ieteicams atsaukt piekļuves pilnvaras, kuras ir izveidojuši cilvēki, kuri ir noņemti no mašīnas konta." }, "smAccessRemovalWarningMaTitle": { - "message": "Remove access to this machine account" + "message": "Noņemt piekļuvi šim mašīnas kontam" }, "smAccessRemovalWarningMaMessage": { - "message": "This action will remove your access to the machine account." + "message": "Šī darbība noņems piekļuvi mašīnas kontam." }, "machineAccountsIncluded": { - "message": "$COUNT$ machine accounts included", + "message": "Iekļauti $COUNT$ mašīnu konti", "placeholders": { "count": { "content": "$1", @@ -7859,7 +7859,7 @@ } }, "additionalMachineAccountCost": { - "message": "$COST$ per month for additional machine accounts", + "message": "$COST$ mēnesī par papildu mašīnu kontiem", "placeholders": { "cost": { "content": "$1", @@ -7868,10 +7868,10 @@ } }, "additionalMachineAccounts": { - "message": "Additional machine accounts" + "message": "Papildu mašīnu konti" }, "includedMachineAccounts": { - "message": "Your plan comes with $COUNT$ machine accounts.", + "message": "Plānā ir iekļauti $COUNT$ mašīnu konti.", "placeholders": { "count": { "content": "$1", @@ -7880,7 +7880,7 @@ } }, "addAdditionalMachineAccounts": { - "message": "You can add additional machine accounts for $COST$ per month.", + "message": "Papildu mašīnu kontus var pievienot par $COST$ mēnesī.", "placeholders": { "cost": { "content": "$1", @@ -7889,25 +7889,25 @@ } }, "limitMachineAccounts": { - "message": "Limit machine accounts (optional)" + "message": "Ierobežot mašīnu kontus (izvēles)" }, "limitMachineAccountsDesc": { - "message": "Set a limit for your machine accounts. Once this limit is reached, you will not be able to create new machine accounts." + "message": "Uzstāda mašīnu kontu skaita ierobežojumu. Tiklīdz tas ir sasniegts, nebūs iespējams izveidot jaunus mašīnu kontus." }, "machineAccountLimit": { - "message": "Machine account limit (optional)" + "message": "Mašīnu kontu skaita ierobežojums (izvēles)" }, "maxMachineAccountCost": { - "message": "Max potential machine account cost" + "message": "Lielākās iespējamās mašīnas konta izmaksas" }, "machineAccountAccessUpdated": { - "message": "Machine account access updated" + "message": "Mašīnas konta piekļuve ir atjaunināta" }, "restrictedGroupAccessDesc": { "message": "Sevi nevar pievienot kopai." }, "unassignedItemsBannerSelfHost": { - "message": "Notice: On May 2, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible." + "message": "Jāņem vērā: no 2024. gada 2. maija nepiešķirti apvienības vienumi vairs nebūs redzami skatā \"Visas glabātavas\" dažādās ierīcēs un būs sasniedzami tikai no pārvaldības konsoles, kur šie vienumi jāpiešķir krājumam, lai padarītu tos redzamus." }, "unassignedItemsBannerNotice": { "message": "Jāņem vērā: nepiešķirti apvienības vienumi vairs nav redzami skatā \"Visas glabātavas\" dažādās ierīcēs un tagad ir pieejami tikai pārvaldības konsolē." @@ -7966,74 +7966,74 @@ "message": "Kļūda mērķa mapes piešķiršanā." }, "integrationsAndSdks": { - "message": "Integrations & SDKs", + "message": "Integrācijas un izstrādātāju rīkkopas", "description": "The title for the section that deals with integrations and SDKs." }, "integrations": { - "message": "Integrations" + "message": "Integrācijas" }, "integrationsDesc": { - "message": "Automatically sync secrets from Bitwarden Secrets Manager to a third-party service." + "message": "Automātiski sinhronizēt noslēpumus no Bitwarden Noslēpumu pārvaldnieka uz trešās puses pakalpojumu." }, "sdks": { - "message": "SDKs" + "message": "Izstrādātāju rīkkopas" }, "sdksDesc": { - "message": "Use Bitwarden Secrets Manager SDK in the following programming languages to build your own applications." + "message": "Bitwarden Noslēpumu pārvaldnieka izstrādātāju rīkkopa ir izmantojama ar zemāk esošajām programmēšanas valodām, lai veidotu pats savas lietotnes." }, "setUpGithubActions": { - "message": "Set up Github Actions" + "message": "Iestatīt GitHub darbības" }, "setUpGitlabCICD": { - "message": "Set up GitLab CI/CD" + "message": "Iestatīt GitLab CI/CD" }, "setUpAnsible": { - "message": "Set up Ansible" + "message": "Iestatīt Ansible" }, "cSharpSDKRepo": { - "message": "View C# repository" + "message": "Skatīt C# glabātavu" }, "cPlusPlusSDKRepo": { - "message": "View C++ repository" + "message": "Skatīt C++ glabātavu" }, "jsWebAssemblySDKRepo": { - "message": "View JS WebAssembly repository" + "message": "Skatīt JS WebAssembly glabātavu" }, "javaSDKRepo": { - "message": "View Java repository" + "message": "Skatīt Java glabātavu" }, "pythonSDKRepo": { - "message": "View Python repository" + "message": "Skatīt Python glabātavu" }, "phpSDKRepo": { - "message": "View php repository" + "message": "Skatīt PHP glabātavu" }, "rubySDKRepo": { - "message": "View Ruby repository" + "message": "Skatīt Ruby glabātavu" }, "goSDKRepo": { - "message": "View Go repository" + "message": "Skatīt Go glabātavu" }, "createNewClientToManageAsProvider": { - "message": "Create a new client organization to manage as a Provider. Additional seats will be reflected in the next billing cycle." + "message": "Izveidot jaunu klienta apvienību, ko pārvaldīt kā nodrošinātājam. Papildu vietas tiks atspoguļotas nākamajā norēķinu posmā." }, "selectAPlan": { - "message": "Select a plan" + "message": "Atlasīt plānu" }, "thirtyFivePercentDiscount": { - "message": "35% Discount" + "message": "35% atlaide" }, "monthPerMember": { - "message": "month per member" + "message": "mēnesī par dalībnieku" }, "seats": { - "message": "Seats" + "message": "Vietas" }, "addOrganization": { - "message": "Add organization" + "message": "Pievienot apvienību" }, "createdNewClient": { - "message": "Successfully created new client" + "message": "Veiksmīgi izveidots jauns klients" }, "noAccess": { "message": "Nav piekļuves" @@ -8042,12 +8042,12 @@ "message": "Šis krājums ir pieejams tikai pārvaldības konsolē" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Pārslēgt apvienību izvēlni" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Atlasīt glabātavas vienumu" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Atlasīt krājuma vienumu" } } diff --git a/apps/web/src/locales/pl/messages.json b/apps/web/src/locales/pl/messages.json index c54b72c21cd..8fc603c1d5e 100644 --- a/apps/web/src/locales/pl/messages.json +++ b/apps/web/src/locales/pl/messages.json @@ -4053,7 +4053,7 @@ "message": "Wszystkie funkcje zespołów oraz:" }, "includeAllTeamsStarterFeatures": { - "message": "All Teams Starter features, plus:" + "message": "Wszystkie funkcje z Teams Starter, plus:" }, "chooseMonthlyOrAnnualBilling": { "message": "Wybierz miesięczną lub roczną płatność" @@ -6737,7 +6737,7 @@ } }, "teamsStarterPlanInvLimitReachedManageBilling": { - "message": "Teams Starter plans may have up to $SEATCOUNT$ members. Upgrade to your plan to invite more members.", + "message": "Plan Teams Starter może mieć maksymalnie $SEATCOUNT$ członków. Przejdź na wyższy plan, aby zaprosić więcej członków.", "placeholders": { "seatcount": { "content": "$1", @@ -6746,7 +6746,7 @@ } }, "teamsStarterPlanInvLimitReachedNoManageBilling": { - "message": "Teams Starter plans may have up to $SEATCOUNT$ members. Contact your organization owner to upgrade your plan and invite more members.", + "message": "Plan Teams Starter może mieć maksymalnie $SEATCOUNT$ członków. Skontaktuj się z właścicielem organizacji, aby przejść na wyższy plan i zaprosić więcej członków.", "placeholders": { "seatcount": { "content": "$1", diff --git a/apps/web/src/locales/pt_BR/messages.json b/apps/web/src/locales/pt_BR/messages.json index 2b296694bb9..06b117ed069 100644 --- a/apps/web/src/locales/pt_BR/messages.json +++ b/apps/web/src/locales/pt_BR/messages.json @@ -627,10 +627,10 @@ "message": "Iniciar sessão com a chave de acesso" }, "invalidPasskeyPleaseTryAgain": { - "message": "Invalid Passkey. Please try again." + "message": "Senha inválida. Por favor, tente novamente." }, "twoFactorForPasskeysNotSupportedOnClientUpdateToLogIn": { - "message": "2FA for passkeys is not supported. Update the app to log in." + "message": "2FA para senhas não é suportada. Atualize o aplicativo para iniciar a sessão." }, "loginWithPasskeyInfo": { "message": "Use uma senha gerada que fará o login automaticamente sem uma senha. Biometrias como reconhecimento facial ou impressão digital, ou outro método de segurança FIDO2 verificarão sua identidade." @@ -1359,11 +1359,11 @@ "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. (Optional second half: You may need to wait until your administrator confirms your organization membership.)" }, "onboardingImportDataDetailsPartTwoNoOrgs": { - "message": " instead.", + "message": " em vez disso.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead." }, "onboardingImportDataDetailsPartTwoWithOrgs": { - "message": " instead. You may need to wait until your administrator confirms your organization membership.", + "message": " em vez disso, você pode precisar esperar até que o seu administrador confirme a sua associação à organização.", "description": "This will be part of a larger sentence, that will read like this: If you don't have any data to import, you can create a new item instead. You may need to wait until your administrator confirms your organization membership." }, "importError": { @@ -2802,10 +2802,10 @@ "message": "CLI" }, "bitWebVault": { - "message": "Bitwarden Web vault" + "message": "Cofre Web do Bitwarden" }, "bitSecretsManager": { - "message": "Bitwarden Secrets Manager" + "message": "Gerenciador de Segredos Bitwarden" }, "loggedIn": { "message": "Conectado(a)." @@ -3489,7 +3489,7 @@ "message": "Defina um limite de vagas para sua assinatura. Quando esse limite for atingido, você não poderá convidar novos usuários." }, "limitSmSubscriptionDesc": { - "message": "Set a seat limit for your Secrets Manager subscription. Once this limit is reached, you will not be able to invite new members." + "message": "Defina um limite de assento para sua assinatura do Gerenciador Secretos. Uma vez que este limite for atingido, você não poderá convidar novos membros." }, "maxSeatLimit": { "message": "Limite Máximo de Vaga (opcional)", @@ -3621,7 +3621,7 @@ "message": "Atualizar Chave de Criptografia" }, "updateEncryptionSchemeDesc": { - "message": "We've changed the encryption scheme to provide better security. Update your encryption key now by entering your master password below." + "message": "Alteramos o esquema de criptografia para fornecer melhor segurança. Atualize sua chave de criptografia agora digitando sua senha mestra abaixo." }, "updateEncryptionKeyWarning": { "message": "Depois de atualizar sua chave de criptografia, é necessário encerrar e iniciar a sessão em todos os aplicativos do Bitwarden que você está usando atualmente (como o aplicativo móvel ou as extensões do navegador). Não encerrar e iniciar sessão (que baixa sua nova chave de criptografia) pode resultar em corrupção de dados. Nós tentaremos desconectá-lo automaticamente, mas isso pode demorar um pouco." @@ -3678,7 +3678,7 @@ "message": "Escolha quando o tempo limite do seu cofre irá se esgotar e execute a ação selecionada." }, "vaultTimeoutLogoutDesc": { - "message": "Choose when your vault will be logged out." + "message": "Escolha quando seu cofre será desconectado." }, "oneMinute": { "message": "1 minuto" @@ -4083,7 +4083,7 @@ "message": "Identificador SSO" }, "ssoIdentifierHintPartOne": { - "message": "Provide this ID to your members to login with SSO. To bypass this step, set up ", + "message": "Forneça esse ID aos seus membros para logar com SSO. Para ignorar essa etapa, configure ", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Provide this ID to your members to login with SSO. To bypass this step, set up Domain verification'" }, "unlinkSso": { @@ -4695,7 +4695,7 @@ "message": "Inscrito na recuperação de conta" }, "withdrawAccountRecovery": { - "message": "Withdraw from account recovery" + "message": "Retirar da recuperação de conta" }, "enrollPasswordResetSuccess": { "message": "Inscrição com sucesso!" @@ -4704,7 +4704,7 @@ "message": "Retirada com sucesso!" }, "eventEnrollAccountRecovery": { - "message": "User $ID$ enrolled in account recovery.", + "message": "O usuário $ID$ se inscreveu na recuperação de conta.", "placeholders": { "id": { "content": "$1", @@ -4713,7 +4713,7 @@ } }, "eventWithdrawAccountRecovery": { - "message": "User $ID$ withdrew from account recovery.", + "message": "O usuário $ID$ retirou da recuperação de conta.", "placeholders": { "id": { "content": "$1", @@ -4887,7 +4887,7 @@ "message": "Erro" }, "accountRecoveryManageUsers": { - "message": "Manage users must also be granted with the manage account recovery permission" + "message": "Gerenciar usuários também devem ser concedidos com a permissão de gerenciar a recuperação de contas" }, "setupProvider": { "message": "Configuração do Provedor" @@ -5117,7 +5117,7 @@ "message": "Ativar preenchimento automático" }, "activateAutofillPolicyDesc": { - "message": "Activate the auto-fill on page load setting on the browser extension for all existing and new members." + "message": "Ative o autopreenchimento na configuração de carregamento de página na extensão do navegador para todos os membros existentes e novos." }, "experimentalFeature": { "message": "Sites comprometidos ou não confiáveis podem tomar vantagem do autopreenchimento ao carregar a página." @@ -5432,7 +5432,7 @@ "message": "Conector de Chave" }, "memberDecryptionKeyConnectorDescStart": { - "message": "Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The", + "message": "Conecte o login com SSO ao seu servidor de chave de descriptografia auto-hospedado. Usando essa opção, os membros não precisarão usar suas senhas mestres para descriptografar os dados", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The require SSO authentication and single organization policies are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.'" }, "memberDecryptionKeyConnectorDescLink": { @@ -5440,7 +5440,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The require SSO authentication and single organization policies are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.'" }, "memberDecryptionKeyConnectorDescEnd": { - "message": "are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.", + "message": "são necessários para configurar a descriptografia do conector chave. Contacte o suporte do Bitwarden para configurar a assistência.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Connect login with SSO to your self-hosted decryption key server. Using this option, members won’t need to use their master passwords to decrypt vault data. The require SSO authentication and single organization policies are required to set up Key Connector decryption. Contact Bitwarden Support for set up assistance.'" }, "keyConnectorPolicyRestriction": { @@ -5637,7 +5637,7 @@ } }, "exportingOrganizationVaultDesc": { - "message": "Only the organization vault associated with $ORGANIZATION$ will be exported. Items in individual vaults or other organizations will not be included.", + "message": "Apenas o cofre da organização associado com $ORGANIZATION$ será exportado. Itens do cofre pessoal e itens de outras organizações não serão incluídos.", "placeholders": { "organization": { "content": "$1", @@ -6707,10 +6707,10 @@ "message": "Convidar membro" }, "needsConfirmation": { - "message": "Needs confirmation" + "message": "Precisa de confirmação" }, "memberRole": { - "message": "Member role" + "message": "Função de membro" }, "moreFromBitwarden": { "message": "Mais do Bitwarden" @@ -6719,7 +6719,7 @@ "message": "Trocar Produtos" }, "freeOrgInvLimitReachedManageBilling": { - "message": "Free organizations may have up to $SEATCOUNT$ members. Upgrade to a paid plan to invite more members.", + "message": "Organizações gratuitas podem ter até $SEATCOUNT$ membros. Faça upgrade para um plano pago para convidar mais membros.", "placeholders": { "seatcount": { "content": "$1", @@ -6728,7 +6728,7 @@ } }, "freeOrgInvLimitReachedNoManageBilling": { - "message": "Free organizations may have up to $SEATCOUNT$ members. Contact your organization owner to upgrade.", + "message": "Organizações gratuitas podem ter até $SEATCOUNT$ membros. Entre em contato com o proprietário da sua organização para fazer upgrade.", "placeholders": { "seatcount": { "content": "$1", @@ -6737,7 +6737,7 @@ } }, "teamsStarterPlanInvLimitReachedManageBilling": { - "message": "Teams Starter plans may have up to $SEATCOUNT$ members. Upgrade to your plan to invite more members.", + "message": "Planos de Times Starter podem ter até $SEATCOUNT$ membros. Atualize para o seu plano para convidar mais membros.", "placeholders": { "seatcount": { "content": "$1", @@ -6755,7 +6755,7 @@ } }, "freeOrgMaxCollectionReachedManageBilling": { - "message": "Free organizations may have up to $COLLECTIONCOUNT$ collections. Upgrade to a paid plan to add more collections.", + "message": "Organizações gratuitas podem ter até $COLLECTIONCOUNT$ coleções. Faça o upgrade para um plano pago para adicionar mais coleções.", "placeholders": { "COLLECTIONCOUNT": { "content": "$1", @@ -6764,7 +6764,7 @@ } }, "freeOrgMaxCollectionReachedNoManageBilling": { - "message": "Free organizations may have up to $COLLECTIONCOUNT$ collections. Contact your organization owner to upgrade.", + "message": "Organizações gratuitas podem ter até $COLLECTIONCOUNT$ membros. Entre em contato com o proprietário da sua organização para fazer upgrade.", "placeholders": { "COLLECTIONCOUNT": { "content": "$1", @@ -6779,10 +6779,10 @@ "message": "Exportar dados" }, "exportingOrganizationSecretDataTitle": { - "message": "Exporting Organization Secret Data" + "message": "Exportando dados secretos da organização" }, "exportingOrganizationSecretDataDescription": { - "message": "Only the Secrets Manager data associated with $ORGANIZATION$ will be exported. Items in other products or from other organizations will not be included.", + "message": "Apenas o cofre da organização associado com $ORGANIZATION$ será exportado. Itens do cofre pessoal e itens de outras organizações não serão incluídos.", "placeholders": { "ORGANIZATION": { "content": "$1", @@ -6812,7 +6812,7 @@ "message": "Upload manual" }, "manualUploadDesc": { - "message": "If you do not want to opt into billing sync, manually upload your license here." + "message": "Se você não deseja optar pela sincronização de cobrança, carregue sua licença manualmente aqui." }, "syncLicense": { "message": "Sincronizar licença" @@ -6827,13 +6827,13 @@ "message": "Última sincronização de licença" }, "billingSyncHelp": { - "message": "Billing Sync help" + "message": "Ajuda da Sincronização de faturamento" }, "licensePaidFeaturesHelp": { - "message": "License paid features help" + "message": "Ajuda dos recursos de licença paga" }, "selfHostGracePeriodHelp": { - "message": "After your subscription expires, you have 60 days to apply an updated license file to your organization. Grace period ends $GRACE_PERIOD_END_DATE$.", + "message": "Após a expiração da assinatura, você tem 60 dias para aplicar um arquivo de licença atualizado à sua organização. Fim do período de carência $GRACE_PERIOD_END_DATE$.", "placeholders": { "GRACE_PERIOD_END_DATE": { "content": "$1", @@ -6845,28 +6845,28 @@ "message": "Enviar licença" }, "projectPeopleDescription": { - "message": "Grant groups or people access to this project." + "message": "Conceder acesso a este projeto ou grupos de pessoas." }, "projectPeopleSelectHint": { - "message": "Type or select people or groups" + "message": "Digite ou selecione pessoas ou grupos" }, "projectServiceAccountsDescription": { - "message": "Grant service accounts access to this project." + "message": "Conceder acesso a contas de serviço a este projeto." }, "projectServiceAccountsSelectHint": { - "message": "Type or select service accounts" + "message": "Digite ou selecione contas de serviço" }, "projectEmptyPeopleAccessPolicies": { - "message": "Add people or groups to start collaborating" + "message": "Adicione pessoas ou grupos para começar a colaborar" }, "projectEmptyServiceAccountAccessPolicies": { "message": "Adicione contas de serviço para conceder acesso" }, "serviceAccountPeopleDescription": { - "message": "Grant groups or people access to this service account." + "message": "Conceder acesso a esta conta de serviço a grupos ou pessoas." }, "serviceAccountProjectsDescription": { - "message": "Assign projects to this service account. " + "message": "Atribuir projetos para esta conta de serviço. " }, "serviceAccountEmptyProjectAccesspolicies": { "message": "Adicionar projetos para conceder acesso" @@ -6878,13 +6878,13 @@ "message": "Grupo/Usuário" }, "lowKdfIterations": { - "message": "Low KDF Iterations" + "message": "Iterações KDF baixas" }, "updateLowKdfIterationsDesc": { - "message": "Update your encryption settings to meet new security recommendations and improve account protection." + "message": "Atualize suas configurações de criptografia para atender às novas recomendações de segurança e melhorar a proteção da conta." }, "changeKdfLoggedOutWarning": { - "message": "Proceeding will log you out of all active sessions. You will need to log back in and complete two-step login setup. We recommend exporting your vault before changing your encryption settings to prevent data loss." + "message": "O processo desconectará você de todas as sessões ativas. Você precisará iniciar a sessão novamente e concluir a configuração de login em duas etapas. Recomendamos exportar seu cofre antes de alterar suas configurações de criptografia para evitar perda de dados." }, "secretsManager": { "message": "Gerenciador de Segredos" @@ -6924,7 +6924,7 @@ "message": "Ocorreu um erro ao tentar ler o arquivo de importação" }, "accessedSecret": { - "message": "Accessed secret $SECRET_ID$.", + "message": "$SECRET_ID$ secreto acessado.", "placeholders": { "secret_id": { "content": "$1", @@ -6996,10 +6996,10 @@ "message": "Seleção é necessária." }, "saPeopleWarningTitle": { - "message": "Access tokens still available" + "message": "Tokens de acesso ainda disponíveis" }, "saPeopleWarningMessage": { - "message": "Removing people from a service account does not remove the access tokens they created. For security best practice, it is recommended to revoke access tokens created by people removed from a service account." + "message": "Remover pessoas de uma conta de serviço não remove os tokens de acesso que criaram. Para a melhor prática de segurança, é recomendável revogar os tokens de acesso criados por pessoas removidas de uma conta de serviço." }, "smAccessRemovalWarningProjectTitle": { "message": "Remover acesso para esse projeto" @@ -7008,10 +7008,10 @@ "message": "Esta ação removerá seu acesso ao projeto." }, "smAccessRemovalWarningSaTitle": { - "message": "Remove access to this service account" + "message": "Remover acesso a essa conta de serviço" }, "smAccessRemovalWarningSaMessage": { - "message": "This action will remove your access to the service account." + "message": "Essa ação removerá seu acesso à conta de serviço." }, "removeAccess": { "message": "Remover acesso" @@ -7023,16 +7023,16 @@ "message": "Senha mestre exposta" }, "exposedMasterPasswordDesc": { - "message": "Password found in a data breach. Use a unique password to protect your account. Are you sure you want to use an exposed password?" + "message": "A senha foi encontrada em violação de dados. Use uma senha única para proteger sua conta. Tem certeza de que deseja usar uma senha exposta?" }, "weakAndExposedMasterPassword": { - "message": "Weak and Exposed Master Password" + "message": "Senha Mestra Fraca e Exposta" }, "weakAndBreachedMasterPasswordDesc": { - "message": "Weak password identified and found in a data breach. Use a strong and unique password to protect your account. Are you sure you want to use this password?" + "message": "Senha fraca identificada e encontrada em um vazamento de dados. Use uma senha forte e única para proteger a sua conta. Tem certeza de que deseja usar essa senha?" }, "characterMinimum": { - "message": "$LENGTH$ character minimum", + "message": "Mínimo de $LENGTH$ caracteres", "placeholders": { "length": { "content": "$1", @@ -7041,7 +7041,7 @@ } }, "masterPasswordMinimumlength": { - "message": "Master password must be at least $LENGTH$ characters long.", + "message": "A senha mestra deve ter pelo menos $LENGTH$ caracteres.", "placeholders": { "length": { "content": "$1", @@ -7057,14 +7057,14 @@ "message": "Descartar" }, "notAvailableForFreeOrganization": { - "message": "This feature is not available for free organizations. Contact your organization owner to upgrade." + "message": "Este recurso não está disponível para organizações gratuitas. Entre em contato com o seu proprietário para atualizar." }, "smProjectSecretsNoItemsNoAccess": { - "message": "Contact your organization's admin to manage secrets for this project.", + "message": "Entre em contato com o administrador da sua organização para gerenciar segredos para este projeto.", "description": "The message shown to the user under a project's secrets tab when the user only has read access to the project." }, "enforceOnLoginDesc": { - "message": "Require existing members to change their passwords" + "message": "Exigir que os membros existentes alterem suas senhas" }, "smProjectDeleteAccessRestricted": { "message": "Você não tem permissão para excluir este projeto", @@ -7081,16 +7081,16 @@ "message": "Sessão iniciada" }, "deviceApprovalRequired": { - "message": "Device approval required. Select an approval option below:" + "message": "Aprovação do dispositivo necessária. Selecione uma opção de aprovação abaixo:" }, "rememberThisDevice": { "message": "Lembrar deste dispositivo" }, "uncheckIfPublicDevice": { - "message": "Uncheck if using a public device" + "message": "Desmarque se estiver usando um dispositivo público" }, "approveFromYourOtherDevice": { - "message": "Approve from your other device" + "message": "Aprovar do seu outro dispositivo" }, "requestAdminApproval": { "message": "Solicitar aprovação do administrador" @@ -7099,17 +7099,17 @@ "message": "Aprovar com a senha mestre" }, "trustedDeviceEncryption": { - "message": "Trusted device encryption" + "message": "Criptografia de dispositivo confiável" }, "trustedDevices": { "message": "Dispositivos confiáveis" }, "memberDecryptionOptionTdeDescriptionPartOne": { - "message": "Once authenticated, members will decrypt vault data using a key stored on their device. The", + "message": "Uma vez autenticados, os membros descriptografarão os dados do cofre usando uma chave armazenada no seu dispositivo", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO Required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionLinkOne": { - "message": "single organization", + "message": "organização única", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionPartTwo": { @@ -7117,7 +7117,7 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionLinkTwo": { - "message": "SSO required", + "message": "Necessário SSO", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionPartThree": { @@ -7125,11 +7125,11 @@ "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionLinkThree": { - "message": "account recovery administration", + "message": "gerenciar recuperação de conta", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "memberDecryptionOptionTdeDescriptionPartFour": { - "message": "policy with automatic enrollment will turn on when this option is used.", + "message": "política com inscrição automática será ativada quando esta opção for utilizada.", "description": "This will be used as part of a larger sentence, broken up to include links. The full sentence will read 'Once authenticated, members will decrypt vault data using a key stored on their device. The single organization policy, SSO required policy, and account recovery administration policy with automatic enrollment will turn on when this option is used.'" }, "orgPermissionsUpdatedMustSetPassword": { @@ -7157,7 +7157,7 @@ "message": "Recuperar conta" }, "updatedTempPassword": { - "message": "User updated a password issued through account recovery." + "message": "O usuário atualizou uma senha emitida através da recuperação de conta." }, "activatedAccessToSecretsManager": { "message": "Acesso ativado ao Gerenciador de Segredos", @@ -7232,7 +7232,7 @@ "message": "Remover membros que não têm senhas mestres sem definir uma para eles pode restringir o acesso à sua conta completa." }, "approvedAuthRequest": { - "message": "Approved device for $ID$.", + "message": "Dispositivo aprovado para $ID$.", "placeholders": { "id": { "content": "$1", @@ -7241,7 +7241,7 @@ } }, "rejectedAuthRequest": { - "message": "Denied device for $ID$.", + "message": "Dispositivo negado para $ID$.", "placeholders": { "id": { "content": "$1", @@ -7250,7 +7250,7 @@ } }, "requestedDeviceApproval": { - "message": "Requested device approval." + "message": "Aprovação do dispositivo solicitada." }, "startYour7DayFreeTrialOfBitwardenFor": { "message": "Comece o seu período de teste gratuito de 7 dias do Bitwarden para $ORG$", @@ -7262,7 +7262,7 @@ } }, "startYour7DayFreeTrialOfBitwardenSecretsManagerFor": { - "message": "Start your 7-Day free trial of Bitwarden Secrets Manager for $ORG$", + "message": "Inicie o seu período de teste gratuito de 7 dias do Bitwarden Secrets Manager para $ORG$", "placeholders": { "org": { "content": "$1", @@ -7280,19 +7280,19 @@ "message": "Sinalização de região selecionada" }, "accountSuccessfullyCreated": { - "message": "Account successfully created!" + "message": "Conta criada com sucesso!" }, "adminApprovalRequested": { - "message": "Admin approval requested" + "message": "Aprovação do administrador necessária" }, "adminApprovalRequestSentToAdmins": { - "message": "Your request has been sent to your admin." + "message": "Seu pedido foi enviado para seu administrador." }, "youWillBeNotifiedOnceApproved": { - "message": "You will be notified once approved." + "message": "Será notificado assim que for aprovado." }, "troubleLoggingIn": { - "message": "Trouble logging in?" + "message": "Problemas em efetuar login?" }, "loginApproved": { "message": "Sessão aprovada" @@ -7324,10 +7324,10 @@ } }, "secretsManagerForPlanDesc": { - "message": "For engineering and DevOps teams to manage secrets throughout the software development lifecycle." + "message": "Para equipes de engenharia e DevOps gerenciar segredos durante todo o ciclo de vida do desenvolvimento de software." }, "free2PersonOrganization": { - "message": "Free 2-person Organizations" + "message": "Organizações gratuitas com 2 pessoas" }, "unlimitedSecrets": { "message": "Segredos ilimitados" @@ -7366,7 +7366,7 @@ "message": "Assine o Gerenciador de Segredos" }, "addSecretsManagerUpgradeDesc": { - "message": "Add Secrets Manager to your upgraded plan to maintain access to any secrets created with your previous plan." + "message": "Adicione o Gerenciador de Segredos ao seu plano atualizado para manter o acesso a todos os segredos criados com seu plano anterior." }, "additionalServiceAccounts": { "message": "Contas de serviço adicionais" @@ -7420,13 +7420,13 @@ "message": "Limitar contas de serviço (opcional)" }, "limitServiceAccountsDesc": { - "message": "Set a limit for your service accounts. Once this limit is reached, you will not be able to create new service accounts." + "message": "Defina um limite para suas contas de máquina. Quando este limite for atingido, você não poderá criar novas contas de máquina." }, "serviceAccountLimit": { "message": "Limite de contas de serviço (opcional)" }, "maxServiceAccountCost": { - "message": "Max potential service account cost" + "message": "Custo máximo da conta de serviço potencial" }, "loggedInExclamation": { "message": "Conectado!" @@ -7459,10 +7459,10 @@ "message": "Chave de acesso" }, "passkeyNotCopied": { - "message": "Passkey will not be copied" + "message": "A senha não será copiada" }, "passkeyNotCopiedAlert": { - "message": "The passkey will not be copied to the cloned item. Do you want to continue cloning this item?" + "message": "A senha não será copiada para o item clonado. Deseja continuar clonando este item?" }, "modifiedCollectionManagement": { "message": "Definição de gerenciamento da coleção $ID$ modificada.", @@ -7484,7 +7484,7 @@ "message": "Use a extensão para salvar rapidamente credenciais e formulários de autopreenchimento sem abrir o aplicativo web." }, "projectAccessUpdated": { - "message": "Project access updated" + "message": "Acesso ao projeto atualizado" }, "unexpectedErrorSend": { "message": "Ocorreu um erro inesperado ao carregar este Envio. Tente novamente mais tarde." @@ -7505,7 +7505,7 @@ "message": "Você não tem acesso para gerenciar esta coleção." }, "grantCollectionAccess": { - "message": "Grant groups or members access to this collection." + "message": "Conceder acesso de grupos ou membros a esta coleção." }, "grantCollectionAccessMembersOnly": { "message": "Conceder acesso a essa coleção." @@ -8042,12 +8042,12 @@ "message": "This collection is only accessible from the admin console" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Alternar Menu da Organização" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Selecionar item do cofre" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Selecionar item da coleção" } } diff --git a/apps/web/src/locales/ru/messages.json b/apps/web/src/locales/ru/messages.json index 67b23b0e89c..213a9d1965d 100644 --- a/apps/web/src/locales/ru/messages.json +++ b/apps/web/src/locales/ru/messages.json @@ -8042,12 +8042,12 @@ "message": "Эта коллекция доступна только из консоли администратора" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Переключить меню организации" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Выбрать элемент хранилища" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Выбрать элемент коллекции" } } diff --git a/apps/web/src/locales/sk/messages.json b/apps/web/src/locales/sk/messages.json index 756723129ff..652b1b08fda 100644 --- a/apps/web/src/locales/sk/messages.json +++ b/apps/web/src/locales/sk/messages.json @@ -8042,12 +8042,12 @@ "message": "Táto zbierka je dostupná iba z administrátorskej konzoly" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Prepnúť menu organizácie" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Vyberte položku z trezora" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Vyberte položku zo zbierky" } } diff --git a/apps/web/src/locales/sr/messages.json b/apps/web/src/locales/sr/messages.json index f927113fad9..de563afe509 100644 --- a/apps/web/src/locales/sr/messages.json +++ b/apps/web/src/locales/sr/messages.json @@ -7607,7 +7607,7 @@ "message": "Портал провајдера" }, "success": { - "message": "Success" + "message": "Успех" }, "viewCollection": { "message": "Преглед колекције" @@ -7904,16 +7904,16 @@ "message": "Приступ налога машине ажуриран" }, "restrictedGroupAccessDesc": { - "message": "You cannot add yourself to a group." + "message": "Не можете да се додате у групу." }, "unassignedItemsBannerSelfHost": { - "message": "Notice: On May 2, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible." + "message": "Обавештење: 2. маја 2024. недодељене ставке организације више неће бити видљиве у вашем приказу Сви сефови на свим уређајима и биће им доступне само преко Админ конзоле. Доделите ове ставке колекцији са Админ конзолом да бисте их учинили видљивим." }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in your All Vaults view across devices and are now only accessible via the Admin Console." + "message": "Напомена: Недодељене ставке организације више нису видљиве у вашем приказу Сви сефови на свим уређајима и сада су доступне само преко Админ конзоле." }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console." + "message": "Обавештење: 16. маја 2024. недодељене ставке организације више неће бити видљиве у вашем приказу Сви сефови на свим уређајима и биће им доступне само преко Админ конзоле." }, "unassignedItemsBannerCTAPartOne": { "message": "Assign these items to a collection from the", @@ -7924,13 +7924,13 @@ "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "deleteProvider": { - "message": "Delete provider" + "message": "Избриши провајдера" }, "deleteProviderConfirmation": { - "message": "Deleting a provider is permanent and irreversible. Enter your master password to confirm the deletion of the provider and all associated data." + "message": "Брисање провајдера је трајно и неповратно. Унесите своју главну лозинку да бисте потврдили брисање провајдера и свих повезаних података." }, "deleteProviderName": { - "message": "Cannot delete $ID$", + "message": "Не може да се избрише $ID$", "placeholders": { "id": { "content": "$1", @@ -7939,7 +7939,7 @@ } }, "deleteProviderWarningDesc": { - "message": "You must unlink all clients before you can delete $ID$", + "message": "Морате прекинути везу са свим клијентима да бисте могли да избришете $ID$", "placeholders": { "id": { "content": "$1", @@ -7948,106 +7948,106 @@ } }, "providerDeleted": { - "message": "Provider deleted" + "message": "Провајдер је избрисан" }, "providerDeletedDesc": { - "message": "The Provider and all associated data has been deleted." + "message": "Провајдер и сви повезани подаци су избрисани." }, "deleteProviderRecoverConfirmDesc": { - "message": "You have requested to delete this Provider. Use the button below to confirm." + "message": "Захтевали сте брисање овог провајдера. Користите дугме испод да потврдите." }, "deleteProviderWarning": { - "message": "Deleting your provider is permanent. It cannot be undone." + "message": "Брисање провајдера је трајно. Не може се поништити." }, "errorAssigningTargetCollection": { - "message": "Error assigning target collection." + "message": "Грешка при додељивању циљне колекције." }, "errorAssigningTargetFolder": { - "message": "Error assigning target folder." + "message": "Грешка при додељивању циљне фасцикле." }, "integrationsAndSdks": { - "message": "Integrations & SDKs", + "message": "Интеграције & SDK", "description": "The title for the section that deals with integrations and SDKs." }, "integrations": { - "message": "Integrations" + "message": "Интеграције" }, "integrationsDesc": { - "message": "Automatically sync secrets from Bitwarden Secrets Manager to a third-party service." + "message": "Аутоматски синхронизујте тајне од Bitwarden Secrets Manager са сервисима треће стране." }, "sdks": { - "message": "SDKs" + "message": "SDK" }, "sdksDesc": { - "message": "Use Bitwarden Secrets Manager SDK in the following programming languages to build your own applications." + "message": "Употребите Bitwarden Secrets Manager SDK на следећим програмским језицима да направите сопствене апликације." }, "setUpGithubActions": { - "message": "Set up Github Actions" + "message": "Подесити акције GitHub-а" }, "setUpGitlabCICD": { - "message": "Set up GitLab CI/CD" + "message": "Подесити GitLab CI/CD" }, "setUpAnsible": { - "message": "Set up Ansible" + "message": "Подесити Ansible" }, "cSharpSDKRepo": { - "message": "View C# repository" + "message": "Преглед C# спремишта" }, "cPlusPlusSDKRepo": { - "message": "View C++ repository" + "message": "Преглед C++ спремишта" }, "jsWebAssemblySDKRepo": { - "message": "View JS WebAssembly repository" + "message": "Преглед JS WebAssembly спремишта" }, "javaSDKRepo": { - "message": "View Java repository" + "message": "Преглед Java спремишта" }, "pythonSDKRepo": { - "message": "View Python repository" + "message": "Преглед Python спремишта" }, "phpSDKRepo": { - "message": "View php repository" + "message": "Преглед php спремишта" }, "rubySDKRepo": { - "message": "View Ruby repository" + "message": "Преглед Ruby спремишта" }, "goSDKRepo": { - "message": "View Go repository" + "message": "Преглед Go спремишта" }, "createNewClientToManageAsProvider": { - "message": "Create a new client organization to manage as a Provider. Additional seats will be reflected in the next billing cycle." + "message": "Креирајте нову клијентску организацију којом ћете управљати као добављач. Додатна места ће се одразити у следећем обрачунском циклусу." }, "selectAPlan": { - "message": "Select a plan" + "message": "Изаберите пакет" }, "thirtyFivePercentDiscount": { - "message": "35% Discount" + "message": "Попуст од 35%" }, "monthPerMember": { - "message": "month per member" + "message": "месечно по члану" }, "seats": { - "message": "Seats" + "message": "Места" }, "addOrganization": { - "message": "Add organization" + "message": "Додај организацију" }, "createdNewClient": { - "message": "Successfully created new client" + "message": "Нови клијент је успешно креиран" }, "noAccess": { - "message": "No access" + "message": "Немате приступ" }, "collectionAdminConsoleManaged": { - "message": "This collection is only accessible from the admin console" + "message": "Овој колекцији се може приступити само са администраторске конзоле" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Укључи мени Организација" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Изаберите ставку сефа" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Изаберите ставку колекције" } } diff --git a/apps/web/src/locales/uk/messages.json b/apps/web/src/locales/uk/messages.json index c9434d72d61..e7b9722c9da 100644 --- a/apps/web/src/locales/uk/messages.json +++ b/apps/web/src/locales/uk/messages.json @@ -8042,12 +8042,12 @@ "message": "Ця збірка доступна тільки з консолі адміністратора" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "Перемкнути меню організації" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "Вибрати елемент сховища" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "Вибрати елемент збірки" } } diff --git a/apps/web/src/locales/zh_CN/messages.json b/apps/web/src/locales/zh_CN/messages.json index a9a0d854577..292041624c6 100644 --- a/apps/web/src/locales/zh_CN/messages.json +++ b/apps/web/src/locales/zh_CN/messages.json @@ -7907,20 +7907,20 @@ "message": "您不能将自己添加到群组。" }, "unassignedItemsBannerSelfHost": { - "message": "Notice: On May 2, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible." + "message": "注意:从 2024 年 5 月 2 日起,未分配的组织项目在您所有设备的「所有密码库」视图中将不再可见,只能通过管理控制台访问。通过管理控制台将这些项目分配给集合以使其可见。" }, "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in your All Vaults view across devices and are now only accessible via the Admin Console." + "message": "注意:未分配的组织项目在您所有设备的「所有密码库」视图中不再可见,现在只能通过管理控制台访问。" }, "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console." + "message": "注意:从 2024 年 5 月 2 日起,未分配的组织项目在您所有设备的「所有密码库」视图中将不再可见,只能通过管理控制台访问。" }, "unassignedItemsBannerCTAPartOne": { "message": "Assign these items to a collection from the", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", + "message": "以使其可见。", "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." }, "deleteProvider": { @@ -7966,88 +7966,88 @@ "message": "分配目标文件夹时出错。" }, "integrationsAndSdks": { - "message": "Integrations & SDKs", + "message": "集成和 SDK", "description": "The title for the section that deals with integrations and SDKs." }, "integrations": { - "message": "Integrations" + "message": "集成" }, "integrationsDesc": { - "message": "Automatically sync secrets from Bitwarden Secrets Manager to a third-party service." + "message": "通过 Bitwarden 机密管理器将机密自动同步到第三方服务。" }, "sdks": { - "message": "SDKs" + "message": "SDK" }, "sdksDesc": { - "message": "Use Bitwarden Secrets Manager SDK in the following programming languages to build your own applications." + "message": "使用以下编程语言的 Bitwarden 机密管理器 SDK 来构建您自己的应用程序。" }, "setUpGithubActions": { - "message": "Set up Github Actions" + "message": "设置 Github Actions" }, "setUpGitlabCICD": { - "message": "Set up GitLab CI/CD" + "message": "设置 GitLab CI/CD" }, "setUpAnsible": { - "message": "Set up Ansible" + "message": "设置 Ansible" }, "cSharpSDKRepo": { - "message": "View C# repository" + "message": "查看 C# 存储库" }, "cPlusPlusSDKRepo": { - "message": "View C++ repository" + "message": "查看 C++ 存储库" }, "jsWebAssemblySDKRepo": { - "message": "View JS WebAssembly repository" + "message": "查看 JS WebAssembly 存储库" }, "javaSDKRepo": { - "message": "View Java repository" + "message": "查看 Java 存储库" }, "pythonSDKRepo": { - "message": "View Python repository" + "message": "查看 Python 存储库" }, "phpSDKRepo": { - "message": "View php repository" + "message": "查看 php 存储库" }, "rubySDKRepo": { - "message": "View Ruby repository" + "message": "查看 Ruby 存储库" }, "goSDKRepo": { - "message": "View Go repository" + "message": "查看 Go 存储库" }, "createNewClientToManageAsProvider": { - "message": "Create a new client organization to manage as a Provider. Additional seats will be reflected in the next billing cycle." + "message": "创建一个新的客户组织作为提供商来管理。附加席位将反映在下一个计费周期中。" }, "selectAPlan": { "message": "选择套餐" }, "thirtyFivePercentDiscount": { - "message": "35% Discount" + "message": "35% 折扣" }, "monthPerMember": { "message": "month per member" }, "seats": { - "message": "Seats" + "message": "席位" }, "addOrganization": { - "message": "Add organization" + "message": "添加组织" }, "createdNewClient": { "message": "Successfully created new client" }, "noAccess": { - "message": "No access" + "message": "暂无权限" }, "collectionAdminConsoleManaged": { - "message": "This collection is only accessible from the admin console" + "message": "此集合只能从管理控制台访问" }, "organizationOptionsMenu": { - "message": "Toggle Organization Menu" + "message": "切换组织菜单" }, "vaultItemSelect": { - "message": "Select vault item" + "message": "选择密码库项目" }, "collectionItemSelect": { - "message": "Select collection item" + "message": "选择集合项目" } } diff --git a/bitwarden_license/bit-web/src/app/admin-console/policies/activate-autofill.component.html b/bitwarden_license/bit-web/src/app/admin-console/policies/activate-autofill.component.html index 9f08e98daea..94f2e8a422d 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/policies/activate-autofill.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/policies/activate-autofill.component.html @@ -5,15 +5,7 @@ }} -
-
- - -
-
+ + + {{ "turnOn" | i18n }} + diff --git a/libs/angular/src/auth/components/base-login-decryption-options.component.ts b/libs/angular/src/auth/components/base-login-decryption-options.component.ts index 8345bb99396..0e58c03a54d 100644 --- a/libs/angular/src/auth/components/base-login-decryption-options.component.ts +++ b/libs/angular/src/auth/components/base-login-decryption-options.component.ts @@ -23,7 +23,7 @@ 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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; @@ -93,7 +93,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { protected apiService: ApiService, protected i18nService: I18nService, protected validationService: ValidationService, - protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + protected deviceTrustService: DeviceTrustServiceAbstraction, protected platformUtilsService: PlatformUtilsService, protected userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, protected passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction, @@ -156,7 +156,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { } private async setRememberDeviceDefaultValue() { - const rememberDeviceFromState = await this.deviceTrustCryptoService.getShouldTrustDevice( + const rememberDeviceFromState = await this.deviceTrustService.getShouldTrustDevice( this.activeAccountId, ); @@ -169,9 +169,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { this.rememberDevice.valueChanges .pipe( switchMap((value) => - defer(() => - this.deviceTrustCryptoService.setShouldTrustDevice(this.activeAccountId, value), - ), + defer(() => this.deviceTrustService.setShouldTrustDevice(this.activeAccountId, value)), ), takeUntil(this.destroy$), ) @@ -288,7 +286,7 @@ export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { await this.passwordResetEnrollmentService.enroll(this.data.organizationId); if (this.rememberDeviceForm.value.rememberDevice) { - await this.deviceTrustCryptoService.trustDevice(this.activeAccountId); + await this.deviceTrustService.trustDevice(this.activeAccountId); } } catch (error) { this.validationService.showError(error); diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index 9c2ed55357f..927fbb27b16 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -11,7 +11,7 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; @@ -74,7 +74,7 @@ export class LockComponent implements OnInit, OnDestroy { protected policyService: InternalPolicyService, protected passwordStrengthService: PasswordStrengthServiceAbstraction, protected dialogService: DialogService, - protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + protected deviceTrustService: DeviceTrustServiceAbstraction, protected userVerificationService: UserVerificationService, protected pinCryptoService: PinCryptoServiceAbstraction, protected biometricStateService: BiometricStateService, @@ -277,7 +277,7 @@ export class LockComponent implements OnInit, OnDestroy { // Now that we have a decrypted user key in memory, we can check if we // need to establish trust on the current device const activeAccount = await firstValueFrom(this.accountService.activeAccount$); - await this.deviceTrustCryptoService.trustDeviceIfRequired(activeAccount.id); + await this.deviceTrustService.trustDeviceIfRequired(activeAccount.id); await this.doContinue(evaluatePasswordAfterUnlock); } diff --git a/libs/angular/src/auth/components/login-via-auth-request.component.ts b/libs/angular/src/auth/components/login-via-auth-request.component.ts index 5a1180cd38c..a60468e244a 100644 --- a/libs/angular/src/auth/components/login-via-auth-request.component.ts +++ b/libs/angular/src/auth/components/login-via-auth-request.component.ts @@ -12,7 +12,7 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AnonymousHubService } from "@bitwarden/common/auth/abstractions/anonymous-hub.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthRequestType } from "@bitwarden/common/auth/enums/auth-request-type"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable"; @@ -86,7 +86,7 @@ export class LoginViaAuthRequestComponent private validationService: ValidationService, private stateService: StateService, private loginEmailService: LoginEmailServiceAbstraction, - private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + private deviceTrustService: DeviceTrustServiceAbstraction, private authRequestService: AuthRequestServiceAbstraction, private loginStrategyService: LoginStrategyServiceAbstraction, private accountService: AccountService, @@ -221,7 +221,8 @@ export class LoginViaAuthRequestComponent } // Request still pending response from admin - // So, create hub connection so that any approvals will be received via push notification + // set keypair and create hub connection so that any approvals will be received via push notification + this.authRequestKeyPair = { privateKey: adminAuthReqStorable.privateKey, publicKey: null }; await this.anonymousHubService.createHubConnection(adminAuthReqStorable.id); } @@ -401,7 +402,7 @@ export class LoginViaAuthRequestComponent // Now that we have a decrypted user key in memory, we can check if we // need to establish trust on the current device const activeAccount = await firstValueFrom(this.accountService.activeAccount$); - await this.deviceTrustCryptoService.trustDeviceIfRequired(activeAccount.id); + await this.deviceTrustService.trustDeviceIfRequired(activeAccount.id); // TODO: don't forget to use auto enrollment service everywhere we trust device diff --git a/libs/angular/src/auth/guards/lock.guard.ts b/libs/angular/src/auth/guards/lock.guard.ts index 6f71d77a63d..8cd5290ebc8 100644 --- a/libs/angular/src/auth/guards/lock.guard.ts +++ b/libs/angular/src/auth/guards/lock.guard.ts @@ -8,7 +8,7 @@ import { import { firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { ClientType } from "@bitwarden/common/enums"; @@ -30,7 +30,7 @@ export function lockGuard(): CanActivateFn { ) => { const authService = inject(AuthService); const cryptoService = inject(CryptoService); - const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction); + const deviceTrustService = inject(DeviceTrustServiceAbstraction); const platformUtilService = inject(PlatformUtilsService); const messagingService = inject(MessagingService); const router = inject(Router); @@ -53,7 +53,7 @@ export function lockGuard(): CanActivateFn { // User is authN and in locked state. - const tdeEnabled = await firstValueFrom(deviceTrustCryptoService.supportsDeviceTrust$); + const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$); // Create special exception which allows users to go from the login-initiated page to the lock page for the approve w/ MP flow // The MP check is necessary to prevent direct manual navigation from other locked state pages for users who don't have a MP diff --git a/libs/angular/src/auth/guards/redirect.guard.ts b/libs/angular/src/auth/guards/redirect.guard.ts index ca9152186d0..0c43673c349 100644 --- a/libs/angular/src/auth/guards/redirect.guard.ts +++ b/libs/angular/src/auth/guards/redirect.guard.ts @@ -3,7 +3,7 @@ import { CanActivateFn, Router } from "@angular/router"; import { firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -31,7 +31,7 @@ export function redirectGuard(overrides: Partial = {}): CanActiv return async (route) => { const authService = inject(AuthService); const cryptoService = inject(CryptoService); - const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction); + const deviceTrustService = inject(DeviceTrustServiceAbstraction); const router = inject(Router); const authStatus = await authService.getAuthStatus(); @@ -46,7 +46,7 @@ export function redirectGuard(overrides: Partial = {}): CanActiv // If locked, TDE is enabled, and the user hasn't decrypted yet, then redirect to the // login decryption options component. - const tdeEnabled = await firstValueFrom(deviceTrustCryptoService.supportsDeviceTrust$); + const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$); const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$); if (authStatus === AuthenticationStatus.Locked && tdeEnabled && !everHadUserKey) { return router.createUrlTree([routes.notDecrypted], { queryParams: route.queryParams }); diff --git a/libs/angular/src/auth/guards/tde-decryption-required.guard.ts b/libs/angular/src/auth/guards/tde-decryption-required.guard.ts index 146c6e19a21..524ce7dce50 100644 --- a/libs/angular/src/auth/guards/tde-decryption-required.guard.ts +++ b/libs/angular/src/auth/guards/tde-decryption-required.guard.ts @@ -8,7 +8,7 @@ import { import { firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; @@ -22,11 +22,11 @@ export function tdeDecryptionRequiredGuard(): CanActivateFn { return async (_: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { const authService = inject(AuthService); const cryptoService = inject(CryptoService); - const deviceTrustCryptoService = inject(DeviceTrustCryptoServiceAbstraction); + const deviceTrustService = inject(DeviceTrustServiceAbstraction); const router = inject(Router); const authStatus = await authService.getAuthStatus(); - const tdeEnabled = await firstValueFrom(deviceTrustCryptoService.supportsDeviceTrust$); + const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$); const everHadUserKey = await firstValueFrom(cryptoService.everHadUserKey$); if (authStatus !== AuthenticationStatus.Locked || !tdeEnabled || everHadUserKey) { return router.createUrlTree(["/"]); diff --git a/libs/angular/src/services/injection-tokens.ts b/libs/angular/src/services/injection-tokens.ts index 6fffe722fbd..413fc5b5306 100644 --- a/libs/angular/src/services/injection-tokens.ts +++ b/libs/angular/src/services/injection-tokens.ts @@ -36,7 +36,6 @@ export const MEMORY_STORAGE = new SafeInjectionToken("SECURE_STORAGE"); export const STATE_FACTORY = new SafeInjectionToken("STATE_FACTORY"); -export const STATE_SERVICE_USE_CACHE = new SafeInjectionToken("STATE_SERVICE_USE_CACHE"); export const LOGOUT_CALLBACK = new SafeInjectionToken< (expired: boolean, userId?: string) => Promise >("LOGOUT_CALLBACK"); diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 27b182de5dc..42879a84241 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -60,7 +60,7 @@ import { import { AnonymousHubService as AnonymousHubServiceAbstraction } from "@bitwarden/common/auth/abstractions/anonymous-hub.service"; import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service"; import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service"; @@ -82,7 +82,7 @@ import { AccountServiceImplementation } from "@bitwarden/common/auth/services/ac import { AnonymousHubService } from "@bitwarden/common/auth/services/anonymous-hub.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { AvatarService } from "@bitwarden/common/auth/services/avatar.service"; -import { DeviceTrustCryptoService } from "@bitwarden/common/auth/services/device-trust-crypto.service.implementation"; +import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesServiceImplementation } from "@bitwarden/common/auth/services/devices/devices.service.implementation"; import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; @@ -269,7 +269,6 @@ import { SafeInjectionToken, SECURE_STORAGE, STATE_FACTORY, - STATE_SERVICE_USE_CACHE, SUPPORTS_SECURE_STORAGE, SYSTEM_LANGUAGE, SYSTEM_THEME_OBSERVABLE, @@ -313,10 +312,6 @@ const safeProviders: SafeProvider[] = [ provide: STATE_FACTORY, useValue: new StateFactory(GlobalState, Account), }), - safeProvider({ - provide: STATE_SERVICE_USE_CACHE, - useValue: true, - }), safeProvider({ provide: LOGOUT_CALLBACK, useFactory: @@ -390,7 +385,7 @@ const safeProviders: SafeProvider[] = [ EncryptService, PasswordStrengthServiceAbstraction, PolicyServiceAbstraction, - DeviceTrustCryptoServiceAbstraction, + DeviceTrustServiceAbstraction, AuthRequestServiceAbstraction, InternalUserDecryptionOptionsServiceAbstraction, GlobalStateProvider, @@ -691,7 +686,6 @@ const safeProviders: SafeProvider[] = [ EnvironmentService, TokenServiceAbstraction, MigrationRunner, - STATE_SERVICE_USE_CACHE, ], }), safeProvider({ @@ -955,8 +949,8 @@ const safeProviders: SafeProvider[] = [ deps: [DevicesApiServiceAbstraction], }), safeProvider({ - provide: DeviceTrustCryptoServiceAbstraction, - useClass: DeviceTrustCryptoService, + provide: DeviceTrustServiceAbstraction, + useClass: DeviceTrustService, deps: [ KeyGenerationServiceAbstraction, CryptoFunctionServiceAbstraction, @@ -1064,7 +1058,6 @@ const safeProviders: SafeProvider[] = [ useClass: OrganizationBillingService, deps: [ ApiServiceAbstraction, - BillingApiServiceAbstraction, CryptoServiceAbstraction, EncryptService, I18nServiceAbstraction, diff --git a/libs/angular/src/vault/components/view.component.ts b/libs/angular/src/vault/components/view.component.ts index 42349737f0d..27d6e14b118 100644 --- a/libs/angular/src/vault/components/view.component.ts +++ b/libs/angular/src/vault/components/view.component.ts @@ -9,7 +9,7 @@ import { OnInit, Output, } from "@angular/core"; -import { firstValueFrom, Subject, takeUntil } from "rxjs"; +import { firstValueFrom } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; @@ -69,7 +69,6 @@ export class ViewComponent implements OnDestroy, OnInit { private totpInterval: any; private previousCipherId: string; private passwordReprompted = false; - private directiveIsDestroyed$ = new Subject(); get fido2CredentialCreationDateValue(): string { const dateCreated = this.i18nService.t("dateCreated"); @@ -119,19 +118,11 @@ export class ViewComponent implements OnDestroy, OnInit { } }); }); - - this.billingAccountProfileStateService.hasPremiumFromAnySource$ - .pipe(takeUntil(this.directiveIsDestroyed$)) - .subscribe((canAccessPremium: boolean) => { - this.canAccessPremium = canAccessPremium; - }); } ngOnDestroy() { this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); this.cleanUp(); - this.directiveIsDestroyed$.next(true); - this.directiveIsDestroyed$.complete(); } async load() { @@ -141,6 +132,9 @@ export class ViewComponent implements OnDestroy, OnInit { this.cipher = await cipher.decrypt( await this.cipherService.getKeyForCipherKeyDecryption(cipher), ); + this.canAccessPremium = await firstValueFrom( + this.billingAccountProfileStateService.hasPremiumFromAnySource$, + ); this.showPremiumRequiredTotp = this.cipher.login.totp && !this.canAccessPremium && !this.cipher.organizationUseTotp; diff --git a/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts index 0ce6c9fed76..4e0b1ac3acc 100644 --- a/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response"; @@ -42,7 +42,7 @@ describe("AuthRequestLoginStrategy", () => { let stateService: MockProxy; let twoFactorService: MockProxy; let userDecryptionOptions: MockProxy; - let deviceTrustCryptoService: MockProxy; + let deviceTrustService: MockProxy; let billingAccountProfileStateService: MockProxy; const mockUserId = Utils.newGuid() as UserId; @@ -75,7 +75,7 @@ describe("AuthRequestLoginStrategy", () => { stateService = mock(); twoFactorService = mock(); userDecryptionOptions = mock(); - deviceTrustCryptoService = mock(); + deviceTrustService = mock(); billingAccountProfileStateService = mock(); accountService = mockAccountServiceWith(mockUserId); @@ -99,7 +99,7 @@ describe("AuthRequestLoginStrategy", () => { stateService, twoFactorService, userDecryptionOptions, - deviceTrustCryptoService, + deviceTrustService, billingAccountProfileStateService, ); @@ -132,7 +132,7 @@ describe("AuthRequestLoginStrategy", () => { ); expect(cryptoService.setMasterKeyEncryptedUserKey).toHaveBeenCalledWith(tokenResponse.key); expect(cryptoService.setUserKey).toHaveBeenCalledWith(userKey); - expect(deviceTrustCryptoService.trustDeviceIfRequired).toHaveBeenCalled(); + expect(deviceTrustService.trustDeviceIfRequired).toHaveBeenCalled(); expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey); }); @@ -160,6 +160,6 @@ describe("AuthRequestLoginStrategy", () => { expect(cryptoService.setPrivateKey).toHaveBeenCalledWith(tokenResponse.privateKey); // trustDeviceIfRequired should be called - expect(deviceTrustCryptoService.trustDeviceIfRequired).not.toHaveBeenCalled(); + expect(deviceTrustService.trustDeviceIfRequired).not.toHaveBeenCalled(); }); }); diff --git a/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts b/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts index 4035a7be58c..5220e432de7 100644 --- a/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts +++ b/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts @@ -3,7 +3,6 @@ import { Jsonify } from "type-fest"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; @@ -18,6 +17,7 @@ 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 { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction"; import { UserId } from "@bitwarden/common/types/guid"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; @@ -61,7 +61,7 @@ export class AuthRequestLoginStrategy extends LoginStrategy { stateService: StateService, twoFactorService: TwoFactorService, userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction, - private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + private deviceTrustService: DeviceTrustServiceAbstraction, billingAccountProfileStateService: BillingAccountProfileStateService, ) { super( @@ -147,7 +147,7 @@ export class AuthRequestLoginStrategy extends LoginStrategy { await this.trySetUserKeyWithMasterKey(); // Establish trust if required after setting user key - await this.deviceTrustCryptoService.trustDeviceIfRequired(userId); + await this.deviceTrustService.trustDeviceIfRequired(userId); } } diff --git a/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts index b78ad6dea62..df33415247f 100644 --- a/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts @@ -1,7 +1,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; @@ -50,7 +50,7 @@ describe("SsoLoginStrategy", () => { let twoFactorService: MockProxy; let userDecryptionOptionsService: MockProxy; let keyConnectorService: MockProxy; - let deviceTrustCryptoService: MockProxy; + let deviceTrustService: MockProxy; let authRequestService: MockProxy; let i18nService: MockProxy; let billingAccountProfileStateService: MockProxy; @@ -82,7 +82,7 @@ describe("SsoLoginStrategy", () => { twoFactorService = mock(); userDecryptionOptionsService = mock(); keyConnectorService = mock(); - deviceTrustCryptoService = mock(); + deviceTrustService = mock(); authRequestService = mock(); i18nService = mock(); billingAccountProfileStateService = mock(); @@ -106,7 +106,7 @@ describe("SsoLoginStrategy", () => { twoFactorService, userDecryptionOptionsService, keyConnectorService, - deviceTrustCryptoService, + deviceTrustService, authRequestService, i18nService, billingAccountProfileStateService, @@ -209,8 +209,8 @@ describe("SsoLoginStrategy", () => { ); apiService.postIdentityToken.mockResolvedValue(idTokenResponse); - deviceTrustCryptoService.getDeviceKey.mockResolvedValue(mockDeviceKey); - deviceTrustCryptoService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey); + deviceTrustService.getDeviceKey.mockResolvedValue(mockDeviceKey); + deviceTrustService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey); const cryptoSvcSetUserKeySpy = jest.spyOn(cryptoService, "setUserKey"); @@ -218,8 +218,8 @@ describe("SsoLoginStrategy", () => { await ssoLoginStrategy.logIn(credentials); // Assert - expect(deviceTrustCryptoService.getDeviceKey).toHaveBeenCalledTimes(1); - expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).toHaveBeenCalledTimes(1); + expect(deviceTrustService.getDeviceKey).toHaveBeenCalledTimes(1); + expect(deviceTrustService.decryptUserKeyWithDeviceKey).toHaveBeenCalledTimes(1); expect(cryptoSvcSetUserKeySpy).toHaveBeenCalledTimes(1); expect(cryptoSvcSetUserKeySpy).toHaveBeenCalledWith(mockUserKey); }); @@ -232,8 +232,8 @@ describe("SsoLoginStrategy", () => { ); apiService.postIdentityToken.mockResolvedValue(idTokenResponse); // Set deviceKey to be null - deviceTrustCryptoService.getDeviceKey.mockResolvedValue(null); - deviceTrustCryptoService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey); + deviceTrustService.getDeviceKey.mockResolvedValue(null); + deviceTrustService.decryptUserKeyWithDeviceKey.mockResolvedValue(mockUserKey); // Act await ssoLoginStrategy.logIn(credentials); @@ -254,7 +254,7 @@ describe("SsoLoginStrategy", () => { // Arrange const idTokenResponse = mockIdTokenResponseWithModifiedTrustedDeviceOption(valueName, null); apiService.postIdentityToken.mockResolvedValue(idTokenResponse); - deviceTrustCryptoService.getDeviceKey.mockResolvedValue(mockDeviceKey); + deviceTrustService.getDeviceKey.mockResolvedValue(mockDeviceKey); // Act await ssoLoginStrategy.logIn(credentials); @@ -271,9 +271,9 @@ describe("SsoLoginStrategy", () => { userDecryptionOptsServerResponseWithTdeOption, ); apiService.postIdentityToken.mockResolvedValue(idTokenResponse); - deviceTrustCryptoService.getDeviceKey.mockResolvedValue(mockDeviceKey); + deviceTrustService.getDeviceKey.mockResolvedValue(mockDeviceKey); // Set userKey to be null - deviceTrustCryptoService.decryptUserKeyWithDeviceKey.mockResolvedValue(null); + deviceTrustService.decryptUserKeyWithDeviceKey.mockResolvedValue(null); // Act await ssoLoginStrategy.logIn(credentials); @@ -321,7 +321,7 @@ describe("SsoLoginStrategy", () => { await ssoLoginStrategy.logIn(credentials); expect(authRequestService.setKeysAfterDecryptingSharedMasterKeyAndHash).toHaveBeenCalled(); - expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled(); + expect(deviceTrustService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled(); }); it("sets the user key from approved admin request if exists", async () => { @@ -338,7 +338,7 @@ describe("SsoLoginStrategy", () => { await ssoLoginStrategy.logIn(credentials); expect(authRequestService.setUserKeyAfterDecryptingSharedUserKey).toHaveBeenCalled(); - expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled(); + expect(deviceTrustService.decryptUserKeyWithDeviceKey).not.toHaveBeenCalled(); }); it("attempts to establish a trusted device if successful", async () => { @@ -355,7 +355,7 @@ describe("SsoLoginStrategy", () => { await ssoLoginStrategy.logIn(credentials); expect(authRequestService.setUserKeyAfterDecryptingSharedUserKey).toHaveBeenCalled(); - expect(deviceTrustCryptoService.trustDeviceIfRequired).toHaveBeenCalled(); + expect(deviceTrustService.trustDeviceIfRequired).toHaveBeenCalled(); }); it("clears the admin auth request if server returns a 404, meaning it was deleted", async () => { @@ -369,7 +369,7 @@ describe("SsoLoginStrategy", () => { authRequestService.setKeysAfterDecryptingSharedMasterKeyAndHash, ).not.toHaveBeenCalled(); expect(authRequestService.setUserKeyAfterDecryptingSharedUserKey).not.toHaveBeenCalled(); - expect(deviceTrustCryptoService.trustDeviceIfRequired).not.toHaveBeenCalled(); + expect(deviceTrustService.trustDeviceIfRequired).not.toHaveBeenCalled(); }); it("attempts to login with a trusted device if admin auth request isn't successful", async () => { @@ -382,11 +382,11 @@ describe("SsoLoginStrategy", () => { }; apiService.getAuthRequest.mockResolvedValue(adminAuthResponse as AuthRequestResponse); cryptoService.hasUserKey.mockResolvedValue(false); - deviceTrustCryptoService.getDeviceKey.mockResolvedValue("DEVICE_KEY" as any); + deviceTrustService.getDeviceKey.mockResolvedValue("DEVICE_KEY" as any); await ssoLoginStrategy.logIn(credentials); - expect(deviceTrustCryptoService.decryptUserKeyWithDeviceKey).toHaveBeenCalled(); + expect(deviceTrustService.decryptUserKeyWithDeviceKey).toHaveBeenCalled(); }); }); }); diff --git a/libs/auth/src/common/login-strategies/sso-login.strategy.ts b/libs/auth/src/common/login-strategies/sso-login.strategy.ts index d8efd789840..dc63f0fae1d 100644 --- a/libs/auth/src/common/login-strategies/sso-login.strategy.ts +++ b/libs/auth/src/common/login-strategies/sso-login.strategy.ts @@ -3,7 +3,6 @@ import { Jsonify } from "type-fest"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; @@ -22,6 +21,7 @@ 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 { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction"; import { UserId } from "@bitwarden/common/types/guid"; import { @@ -94,7 +94,7 @@ export class SsoLoginStrategy extends LoginStrategy { twoFactorService: TwoFactorService, userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction, private keyConnectorService: KeyConnectorService, - private deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + private deviceTrustService: DeviceTrustServiceAbstraction, private authRequestService: AuthRequestServiceAbstraction, private i18nService: I18nService, billingAccountProfileStateService: BillingAccountProfileStateService, @@ -298,7 +298,7 @@ export class SsoLoginStrategy extends LoginStrategy { if (await this.cryptoService.hasUserKey()) { // Now that we have a decrypted user key in memory, we can check if we // need to establish trust on the current device - await this.deviceTrustCryptoService.trustDeviceIfRequired(userId); + await this.deviceTrustService.trustDeviceIfRequired(userId); // if we successfully decrypted the user key, we can delete the admin auth request out of state // TODO: eventually we post and clean up DB as well once consumed on client @@ -314,7 +314,7 @@ export class SsoLoginStrategy extends LoginStrategy { const userId = (await this.stateService.getUserId()) as UserId; - const deviceKey = await this.deviceTrustCryptoService.getDeviceKey(userId); + const deviceKey = await this.deviceTrustService.getDeviceKey(userId); const encDevicePrivateKey = trustedDeviceOption?.encryptedPrivateKey; const encUserKey = trustedDeviceOption?.encryptedUserKey; @@ -322,7 +322,7 @@ export class SsoLoginStrategy extends LoginStrategy { return; } - const userKey = await this.deviceTrustCryptoService.decryptUserKeyWithDeviceKey( + const userKey = await this.deviceTrustService.decryptUserKeyWithDeviceKey( userId, encDevicePrivateKey, encUserKey, diff --git a/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts b/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts index fcc0220d0ab..33708885e26 100644 --- a/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts +++ b/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts @@ -2,7 +2,7 @@ import { MockProxy, mock } from "jest-mock-extended"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; @@ -62,7 +62,7 @@ describe("LoginStrategyService", () => { let encryptService: MockProxy; let passwordStrengthService: MockProxy; let policyService: MockProxy; - let deviceTrustCryptoService: MockProxy; + let deviceTrustService: MockProxy; let authRequestService: MockProxy; let userDecryptionOptionsService: MockProxy; let billingAccountProfileStateService: MockProxy; @@ -90,7 +90,7 @@ describe("LoginStrategyService", () => { encryptService = mock(); passwordStrengthService = mock(); policyService = mock(); - deviceTrustCryptoService = mock(); + deviceTrustService = mock(); authRequestService = mock(); userDecryptionOptionsService = mock(); billingAccountProfileStateService = mock(); @@ -114,7 +114,7 @@ describe("LoginStrategyService", () => { encryptService, passwordStrengthService, policyService, - deviceTrustCryptoService, + deviceTrustService, authRequestService, userDecryptionOptionsService, stateProvider, diff --git a/libs/auth/src/common/services/login-strategies/login-strategy.service.ts b/libs/auth/src/common/services/login-strategies/login-strategy.service.ts index a8bd7bc2ff2..aee74e66078 100644 --- a/libs/auth/src/common/services/login-strategies/login-strategy.service.ts +++ b/libs/auth/src/common/services/login-strategies/login-strategy.service.ts @@ -10,7 +10,6 @@ import { import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustCryptoServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust-crypto.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; @@ -36,6 +35,7 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { GlobalState, GlobalStateProvider } from "@bitwarden/common/platform/state"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { MasterKey } from "@bitwarden/common/types/key"; @@ -100,7 +100,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction { protected encryptService: EncryptService, protected passwordStrengthService: PasswordStrengthServiceAbstraction, protected policyService: PolicyService, - protected deviceTrustCryptoService: DeviceTrustCryptoServiceAbstraction, + protected deviceTrustService: DeviceTrustServiceAbstraction, protected authRequestService: AuthRequestServiceAbstraction, protected userDecryptionOptionsService: InternalUserDecryptionOptionsServiceAbstraction, protected stateProvider: GlobalStateProvider, @@ -371,7 +371,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction { this.twoFactorService, this.userDecryptionOptionsService, this.keyConnectorService, - this.deviceTrustCryptoService, + this.deviceTrustService, this.authRequestService, this.i18nService, this.billingAccountProfileStateService, @@ -410,7 +410,7 @@ export class LoginStrategyService implements LoginStrategyServiceAbstraction { this.stateService, this.twoFactorService, this.userDecryptionOptionsService, - this.deviceTrustCryptoService, + this.deviceTrustService, this.billingAccountProfileStateService, ); case AuthenticationType.WebAuthn: diff --git a/libs/common/src/abstractions/api.service.ts b/libs/common/src/abstractions/api.service.ts index 9b3160ee19d..c1a0e1f9cd9 100644 --- a/libs/common/src/abstractions/api.service.ts +++ b/libs/common/src/abstractions/api.service.ts @@ -103,6 +103,7 @@ import { EventResponse } from "../models/response/event.response"; import { ListResponse } from "../models/response/list.response"; import { ProfileResponse } from "../models/response/profile.response"; import { UserKeyResponse } from "../models/response/user-key.response"; +import { UserId } from "../types/guid"; import { AttachmentRequest } from "../vault/models/request/attachment.request"; import { CipherBulkDeleteRequest } from "../vault/models/request/cipher-bulk-delete.request"; import { CipherBulkMoveRequest } from "../vault/models/request/cipher-bulk-move.request"; @@ -451,7 +452,13 @@ export abstract class ApiService { end: string, token: string, ) => Promise>; - postEventsCollect: (request: EventRequest[]) => Promise; + + /** + * Posts events for a user + * @param request The array of events to upload + * @param userId The optional user id the events belong to. If no user id is provided the active user id is used. + */ + postEventsCollect: (request: EventRequest[], userId?: UserId) => Promise; deleteSsoUser: (organizationId: string) => Promise; getSsoUserIdentifier: () => Promise; diff --git a/libs/common/src/auth/abstractions/device-trust-crypto.service.abstraction.ts b/libs/common/src/auth/abstractions/device-trust.service.abstraction.ts similarity index 89% rename from libs/common/src/auth/abstractions/device-trust-crypto.service.abstraction.ts rename to libs/common/src/auth/abstractions/device-trust.service.abstraction.ts index 53fe2140353..123f7103386 100644 --- a/libs/common/src/auth/abstractions/device-trust-crypto.service.abstraction.ts +++ b/libs/common/src/auth/abstractions/device-trust.service.abstraction.ts @@ -3,9 +3,10 @@ import { Observable } from "rxjs"; import { EncString } from "../../platform/models/domain/enc-string"; import { UserId } from "../../types/guid"; import { DeviceKey, UserKey } from "../../types/key"; -import { DeviceResponse } from "../abstractions/devices/responses/device.response"; -export abstract class DeviceTrustCryptoServiceAbstraction { +import { DeviceResponse } from "./devices/responses/device.response"; + +export abstract class DeviceTrustServiceAbstraction { supportsDeviceTrust$: Observable; /** * @description Retrieves the users choice to trust the device which can only happen after decryption diff --git a/libs/common/src/auth/services/device-trust-crypto.service.implementation.ts b/libs/common/src/auth/services/device-trust.service.implementation.ts similarity index 98% rename from libs/common/src/auth/services/device-trust-crypto.service.implementation.ts rename to libs/common/src/auth/services/device-trust.service.implementation.ts index 6fb58eab289..ccf87acaf85 100644 --- a/libs/common/src/auth/services/device-trust-crypto.service.implementation.ts +++ b/libs/common/src/auth/services/device-trust.service.implementation.ts @@ -17,7 +17,7 @@ import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypt import { DEVICE_TRUST_DISK_LOCAL, StateProvider, UserKeyDefinition } from "../../platform/state"; import { UserId } from "../../types/guid"; import { UserKey, DeviceKey } from "../../types/key"; -import { DeviceTrustCryptoServiceAbstraction } from "../abstractions/device-trust-crypto.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "../abstractions/device-trust.service.abstraction"; import { DeviceResponse } from "../abstractions/devices/responses/device.response"; import { DevicesApiServiceAbstraction } from "../abstractions/devices-api.service.abstraction"; import { SecretVerificationRequest } from "../models/request/secret-verification.request"; @@ -42,7 +42,7 @@ export const SHOULD_TRUST_DEVICE = new UserKeyDefinition( }, ); -export class DeviceTrustCryptoService implements DeviceTrustCryptoServiceAbstraction { +export class DeviceTrustService implements DeviceTrustServiceAbstraction { private readonly platformSupportsSecureStorage = this.platformUtilsService.supportsSecureStorage(); private readonly deviceKeySecureStorageKey: string = "_deviceKey"; diff --git a/libs/common/src/auth/services/device-trust-crypto.service.spec.ts b/libs/common/src/auth/services/device-trust.service.spec.ts similarity index 86% rename from libs/common/src/auth/services/device-trust-crypto.service.spec.ts rename to libs/common/src/auth/services/device-trust.service.spec.ts index af147b3481d..12b8cf2eaaa 100644 --- a/libs/common/src/auth/services/device-trust-crypto.service.spec.ts +++ b/libs/common/src/auth/services/device-trust.service.spec.ts @@ -33,11 +33,11 @@ import { ProtectedDeviceResponse } from "../models/response/protected-device.res import { SHOULD_TRUST_DEVICE, DEVICE_KEY, - DeviceTrustCryptoService, -} from "./device-trust-crypto.service.implementation"; + DeviceTrustService, +} from "./device-trust.service.implementation"; -describe("deviceTrustCryptoService", () => { - let deviceTrustCryptoService: DeviceTrustCryptoService; +describe("deviceTrustService", () => { + let deviceTrustService: DeviceTrustService; const keyGenerationService = mock(); const cryptoFunctionService = mock(); @@ -70,11 +70,11 @@ describe("deviceTrustCryptoService", () => { jest.clearAllMocks(); const supportsSecureStorage = false; // default to false; tests will override as needed // By default all the tests will have a mocked active user in state provider. - deviceTrustCryptoService = createDeviceTrustCryptoService(mockUserId, supportsSecureStorage); + deviceTrustService = createDeviceTrustService(mockUserId, supportsSecureStorage); }); it("instantiates", () => { - expect(deviceTrustCryptoService).not.toBeFalsy(); + expect(deviceTrustService).not.toBeFalsy(); }); describe("User Trust Device Choice For Decryption", () => { @@ -84,7 +84,7 @@ describe("deviceTrustCryptoService", () => { await stateProvider.setUserState(SHOULD_TRUST_DEVICE, newValue, mockUserId); - const result = await deviceTrustCryptoService.getShouldTrustDevice(mockUserId); + const result = await deviceTrustService.getShouldTrustDevice(mockUserId); expect(result).toEqual(newValue); }); @@ -95,9 +95,9 @@ describe("deviceTrustCryptoService", () => { await stateProvider.setUserState(SHOULD_TRUST_DEVICE, false, mockUserId); const newValue = true; - await deviceTrustCryptoService.setShouldTrustDevice(mockUserId, newValue); + await deviceTrustService.setShouldTrustDevice(mockUserId, newValue); - const result = await deviceTrustCryptoService.getShouldTrustDevice(mockUserId); + const result = await deviceTrustService.getShouldTrustDevice(mockUserId); expect(result).toEqual(newValue); }); }); @@ -105,25 +105,25 @@ describe("deviceTrustCryptoService", () => { describe("trustDeviceIfRequired", () => { it("should trust device and reset when getShouldTrustDevice returns true", async () => { - jest.spyOn(deviceTrustCryptoService, "getShouldTrustDevice").mockResolvedValue(true); - jest.spyOn(deviceTrustCryptoService, "trustDevice").mockResolvedValue({} as DeviceResponse); - jest.spyOn(deviceTrustCryptoService, "setShouldTrustDevice").mockResolvedValue(); + jest.spyOn(deviceTrustService, "getShouldTrustDevice").mockResolvedValue(true); + jest.spyOn(deviceTrustService, "trustDevice").mockResolvedValue({} as DeviceResponse); + jest.spyOn(deviceTrustService, "setShouldTrustDevice").mockResolvedValue(); - await deviceTrustCryptoService.trustDeviceIfRequired(mockUserId); + await deviceTrustService.trustDeviceIfRequired(mockUserId); - expect(deviceTrustCryptoService.getShouldTrustDevice).toHaveBeenCalledTimes(1); - expect(deviceTrustCryptoService.trustDevice).toHaveBeenCalledTimes(1); - expect(deviceTrustCryptoService.setShouldTrustDevice).toHaveBeenCalledWith(mockUserId, false); + expect(deviceTrustService.getShouldTrustDevice).toHaveBeenCalledTimes(1); + expect(deviceTrustService.trustDevice).toHaveBeenCalledTimes(1); + expect(deviceTrustService.setShouldTrustDevice).toHaveBeenCalledWith(mockUserId, false); }); it("should not trust device nor reset when getShouldTrustDevice returns false", async () => { const getShouldTrustDeviceSpy = jest - .spyOn(deviceTrustCryptoService, "getShouldTrustDevice") + .spyOn(deviceTrustService, "getShouldTrustDevice") .mockResolvedValue(false); - const trustDeviceSpy = jest.spyOn(deviceTrustCryptoService, "trustDevice"); - const setShouldTrustDeviceSpy = jest.spyOn(deviceTrustCryptoService, "setShouldTrustDevice"); + const trustDeviceSpy = jest.spyOn(deviceTrustService, "trustDevice"); + const setShouldTrustDeviceSpy = jest.spyOn(deviceTrustService, "setShouldTrustDevice"); - await deviceTrustCryptoService.trustDeviceIfRequired(mockUserId); + await deviceTrustService.trustDeviceIfRequired(mockUserId); expect(getShouldTrustDeviceSpy).toHaveBeenCalledTimes(1); expect(trustDeviceSpy).not.toHaveBeenCalled(); @@ -151,7 +151,7 @@ describe("deviceTrustCryptoService", () => { it("returns null when there is not an existing device key", async () => { await stateProvider.setUserState(DEVICE_KEY, null, mockUserId); - const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId); + const deviceKey = await deviceTrustService.getDeviceKey(mockUserId); expect(deviceKey).toBeNull(); expect(secureStorageService.get).not.toHaveBeenCalled(); @@ -160,7 +160,7 @@ describe("deviceTrustCryptoService", () => { it("returns the device key when there is an existing device key", async () => { await stateProvider.setUserState(DEVICE_KEY, existingDeviceKey, mockUserId); - const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId); + const deviceKey = await deviceTrustService.getDeviceKey(mockUserId); expect(deviceKey).not.toBeNull(); expect(deviceKey).toBeInstanceOf(SymmetricCryptoKey); @@ -172,17 +172,14 @@ describe("deviceTrustCryptoService", () => { describe("Secure Storage supported", () => { beforeEach(() => { const supportsSecureStorage = true; - deviceTrustCryptoService = createDeviceTrustCryptoService( - mockUserId, - supportsSecureStorage, - ); + deviceTrustService = createDeviceTrustService(mockUserId, supportsSecureStorage); }); it("returns null when there is not an existing device key for the passed in user id", async () => { secureStorageService.get.mockResolvedValue(null); // Act - const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId); + const deviceKey = await deviceTrustService.getDeviceKey(mockUserId); // Assert expect(deviceKey).toBeNull(); @@ -193,7 +190,7 @@ describe("deviceTrustCryptoService", () => { secureStorageService.get.mockResolvedValue(existingDeviceKeyB64); // Act - const deviceKey = await deviceTrustCryptoService.getDeviceKey(mockUserId); + const deviceKey = await deviceTrustService.getDeviceKey(mockUserId); // Assert expect(deviceKey).not.toBeNull(); @@ -203,7 +200,7 @@ describe("deviceTrustCryptoService", () => { }); it("throws an error when no user id is passed in", async () => { - await expect(deviceTrustCryptoService.getDeviceKey(null)).rejects.toThrow( + await expect(deviceTrustService.getDeviceKey(null)).rejects.toThrow( "UserId is required. Cannot get device key.", ); }); @@ -220,7 +217,7 @@ describe("deviceTrustCryptoService", () => { // TypeScript will allow calling private methods if the object is of type 'any' // This is a hacky workaround, but it allows for cleaner tests - await (deviceTrustCryptoService as any).setDeviceKey(mockUserId, newDeviceKey); + await (deviceTrustService as any).setDeviceKey(mockUserId, newDeviceKey); expect(stateProvider.mock.setUserState).toHaveBeenLastCalledWith( DEVICE_KEY, @@ -232,10 +229,7 @@ describe("deviceTrustCryptoService", () => { describe("Secure Storage supported", () => { beforeEach(() => { const supportsSecureStorage = true; - deviceTrustCryptoService = createDeviceTrustCryptoService( - mockUserId, - supportsSecureStorage, - ); + deviceTrustService = createDeviceTrustService(mockUserId, supportsSecureStorage); }); it("successfully sets the device key in secure storage", async () => { @@ -251,7 +245,7 @@ describe("deviceTrustCryptoService", () => { // Act // TypeScript will allow calling private methods if the object is of type 'any' // This is a hacky workaround, but it allows for cleaner tests - await (deviceTrustCryptoService as any).setDeviceKey(mockUserId, newDeviceKey); + await (deviceTrustService as any).setDeviceKey(mockUserId, newDeviceKey); // Assert expect(stateProvider.mock.setUserState).not.toHaveBeenCalledTimes(2); @@ -268,9 +262,9 @@ describe("deviceTrustCryptoService", () => { new Uint8Array(deviceKeyBytesLength) as CsprngArray, ) as DeviceKey; - await expect( - (deviceTrustCryptoService as any).setDeviceKey(null, newDeviceKey), - ).rejects.toThrow("UserId is required. Cannot set device key."); + await expect((deviceTrustService as any).setDeviceKey(null, newDeviceKey)).rejects.toThrow( + "UserId is required. Cannot set device key.", + ); }); }); @@ -285,7 +279,7 @@ describe("deviceTrustCryptoService", () => { // TypeScript will allow calling private methods if the object is of type 'any' // This is a hacky workaround, but it allows for cleaner tests - const deviceKey = await (deviceTrustCryptoService as any).makeDeviceKey(); + const deviceKey = await (deviceTrustService as any).makeDeviceKey(); expect(keyGenSvcGenerateKeySpy).toHaveBeenCalledTimes(1); expect(keyGenSvcGenerateKeySpy).toHaveBeenCalledWith(deviceKeyBytesLength * 8); @@ -362,7 +356,7 @@ describe("deviceTrustCryptoService", () => { // TypeScript will allow calling private methods if the object is of type 'any' makeDeviceKeySpy = jest - .spyOn(deviceTrustCryptoService as any, "makeDeviceKey") + .spyOn(deviceTrustService as any, "makeDeviceKey") .mockResolvedValue(mockDeviceKey); rsaGenerateKeyPairSpy = jest @@ -398,7 +392,7 @@ describe("deviceTrustCryptoService", () => { }); it("calls the required methods with the correct arguments and returns a DeviceResponse", async () => { - const response = await deviceTrustCryptoService.trustDevice(mockUserId); + const response = await deviceTrustService.trustDevice(mockUserId); expect(makeDeviceKeySpy).toHaveBeenCalledTimes(1); expect(rsaGenerateKeyPairSpy).toHaveBeenCalledTimes(1); @@ -429,7 +423,7 @@ describe("deviceTrustCryptoService", () => { // setup the spy to return null cryptoSvcGetUserKeySpy.mockResolvedValue(null); // check if the expected error is thrown - await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow( + await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow( "User symmetric key not found", ); @@ -439,7 +433,7 @@ describe("deviceTrustCryptoService", () => { // setup the spy to return undefined cryptoSvcGetUserKeySpy.mockResolvedValue(undefined); // check if the expected error is thrown - await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow( + await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow( "User symmetric key not found", ); }); @@ -479,9 +473,7 @@ describe("deviceTrustCryptoService", () => { it(`throws an error if ${method} fails`, async () => { const methodSpy = spy(); methodSpy.mockRejectedValue(new Error(errorText)); - await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow( - errorText, - ); + await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow(errorText); }); test.each([null, undefined])( @@ -489,14 +481,14 @@ describe("deviceTrustCryptoService", () => { async (invalidValue) => { const methodSpy = spy(); methodSpy.mockResolvedValue(invalidValue); - await expect(deviceTrustCryptoService.trustDevice(mockUserId)).rejects.toThrow(); + await expect(deviceTrustService.trustDevice(mockUserId)).rejects.toThrow(); }, ); }, ); it("throws an error when a null user id is passed in", async () => { - await expect(deviceTrustCryptoService.trustDevice(null)).rejects.toThrow( + await expect(deviceTrustService.trustDevice(null)).rejects.toThrow( "UserId is required. Cannot trust device.", ); }); @@ -530,7 +522,7 @@ describe("deviceTrustCryptoService", () => { it("throws an error when a null user id is passed in", async () => { await expect( - deviceTrustCryptoService.decryptUserKeyWithDeviceKey( + deviceTrustService.decryptUserKeyWithDeviceKey( null, mockEncryptedDevicePrivateKey, mockEncryptedUserKey, @@ -540,7 +532,7 @@ describe("deviceTrustCryptoService", () => { }); it("returns null when device key isn't provided", async () => { - const result = await deviceTrustCryptoService.decryptUserKeyWithDeviceKey( + const result = await deviceTrustService.decryptUserKeyWithDeviceKey( mockUserId, mockEncryptedDevicePrivateKey, mockEncryptedUserKey, @@ -558,7 +550,7 @@ describe("deviceTrustCryptoService", () => { .spyOn(cryptoService, "rsaDecrypt") .mockResolvedValue(new Uint8Array(userKeyBytesLength)); - const result = await deviceTrustCryptoService.decryptUserKeyWithDeviceKey( + const result = await deviceTrustService.decryptUserKeyWithDeviceKey( mockUserId, mockEncryptedDevicePrivateKey, mockEncryptedUserKey, @@ -574,9 +566,9 @@ describe("deviceTrustCryptoService", () => { const decryptToBytesSpy = jest .spyOn(encryptService, "decryptToBytes") .mockRejectedValue(new Error("Decryption error")); - const setDeviceKeySpy = jest.spyOn(deviceTrustCryptoService as any, "setDeviceKey"); + const setDeviceKeySpy = jest.spyOn(deviceTrustService as any, "setDeviceKey"); - const result = await deviceTrustCryptoService.decryptUserKeyWithDeviceKey( + const result = await deviceTrustService.decryptUserKeyWithDeviceKey( mockUserId, mockEncryptedDevicePrivateKey, mockEncryptedUserKey, @@ -606,7 +598,7 @@ describe("deviceTrustCryptoService", () => { it("throws an error when a null user id is passed in", async () => { await expect( - deviceTrustCryptoService.rotateDevicesTrust(null, fakeNewUserKey, ""), + deviceTrustService.rotateDevicesTrust(null, fakeNewUserKey, ""), ).rejects.toThrow("UserId is required. Cannot rotate device's trust."); }); @@ -615,7 +607,7 @@ describe("deviceTrustCryptoService", () => { stateProvider.activeUser.getFake(DEVICE_KEY); deviceKeyState.nextState(null); - await deviceTrustCryptoService.rotateDevicesTrust(mockUserId, fakeNewUserKey, ""); + await deviceTrustService.rotateDevicesTrust(mockUserId, fakeNewUserKey, ""); expect(devicesApiService.updateTrust).not.toHaveBeenCalled(); }); @@ -691,7 +683,7 @@ describe("deviceTrustCryptoService", () => { ); }); - await deviceTrustCryptoService.rotateDevicesTrust( + await deviceTrustService.rotateDevicesTrust( mockUserId, fakeNewUserKey, "my_password_hash", @@ -713,10 +705,7 @@ describe("deviceTrustCryptoService", () => { }); // Helpers - function createDeviceTrustCryptoService( - mockUserId: UserId | null, - supportsSecureStorage: boolean, - ) { + function createDeviceTrustService(mockUserId: UserId | null, supportsSecureStorage: boolean) { accountService = mockAccountServiceWith(mockUserId); stateProvider = new FakeStateProvider(accountService); @@ -725,7 +714,7 @@ describe("deviceTrustCryptoService", () => { decryptionOptions.next({} as any); userDecryptionOptionsService.userDecryptionOptions$ = decryptionOptions; - return new DeviceTrustCryptoService( + return new DeviceTrustService( keyGenerationService, cryptoFunctionService, cryptoService, diff --git a/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts b/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts index 15f0d4b551b..063b3c370b0 100644 --- a/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts +++ b/libs/common/src/billing/abstractions/billilng-api.service.abstraction.ts @@ -1,4 +1,5 @@ import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request"; +import { OrganizationBillingMetadataResponse } from "../../billing/models/response/organization-billing-metadata.response"; import { OrganizationBillingStatusResponse } from "../../billing/models/response/organization-billing-status.response"; import { OrganizationSubscriptionResponse } from "../../billing/models/response/organization-subscription.response"; import { PlanResponse } from "../../billing/models/response/plan.response"; @@ -12,13 +13,15 @@ export abstract class BillingApiServiceAbstraction { organizationId: string, request: SubscriptionCancellationRequest, ) => Promise; - cancelPremiumUserSubscription: (request: SubscriptionCancellationRequest) => Promise; createClientOrganization: ( providerId: string, request: CreateClientOrganizationRequest, ) => Promise; getBillingStatus: (id: string) => Promise; + getOrganizationBillingMetadata: ( + organizationId: string, + ) => Promise; getOrganizationSubscription: ( organizationId: string, ) => Promise; diff --git a/libs/common/src/billing/abstractions/organization-billing.service.ts b/libs/common/src/billing/abstractions/organization-billing.service.ts index 0917025eec1..d19724b600a 100644 --- a/libs/common/src/billing/abstractions/organization-billing.service.ts +++ b/libs/common/src/billing/abstractions/organization-billing.service.ts @@ -41,8 +41,6 @@ export type SubscriptionInformation = { }; export abstract class OrganizationBillingServiceAbstraction { - isOnSecretsManagerStandalone: (organizationId: string) => Promise; - purchaseSubscription: (subscription: SubscriptionInformation) => Promise; startFree: (subscription: SubscriptionInformation) => Promise; diff --git a/libs/common/src/billing/models/response/organization-billing-metadata.response.ts b/libs/common/src/billing/models/response/organization-billing-metadata.response.ts new file mode 100644 index 00000000000..33d7907fa88 --- /dev/null +++ b/libs/common/src/billing/models/response/organization-billing-metadata.response.ts @@ -0,0 +1,10 @@ +import { BaseResponse } from "../../../models/response/base.response"; + +export class OrganizationBillingMetadataResponse extends BaseResponse { + isOnSecretsManagerStandalone: boolean; + + constructor(response: any) { + super(response); + this.isOnSecretsManagerStandalone = this.getResponseProperty("IsOnSecretsManagerStandalone"); + } +} diff --git a/libs/common/src/billing/services/billing-api.service.ts b/libs/common/src/billing/services/billing-api.service.ts index 1c119b971da..d21c1c9046a 100644 --- a/libs/common/src/billing/services/billing-api.service.ts +++ b/libs/common/src/billing/services/billing-api.service.ts @@ -1,3 +1,5 @@ +import { OrganizationBillingMetadataResponse } from "@bitwarden/common/billing/models/response/organization-billing-metadata.response"; + import { ApiService } from "../../abstractions/api.service"; import { BillingApiServiceAbstraction } from "../../billing/abstractions/billilng-api.service.abstraction"; import { SubscriptionCancellationRequest } from "../../billing/models/request/subscription-cancellation.request"; @@ -53,6 +55,20 @@ export class BillingApiService implements BillingApiServiceAbstraction { return new OrganizationBillingStatusResponse(r); } + async getOrganizationBillingMetadata( + organizationId: string, + ): Promise { + const r = await this.apiService.send( + "GET", + "/organizations/" + organizationId + "/billing/metadata", + null, + true, + true, + ); + + return new OrganizationBillingMetadataResponse(r); + } + async getOrganizationSubscription( organizationId: string, ): Promise { diff --git a/libs/common/src/billing/services/organization-billing.service.ts b/libs/common/src/billing/services/organization-billing.service.ts index fb2084bb6a7..6b326472c97 100644 --- a/libs/common/src/billing/services/organization-billing.service.ts +++ b/libs/common/src/billing/services/organization-billing.service.ts @@ -9,7 +9,6 @@ import { I18nService } from "../../platform/abstractions/i18n.service"; import { EncString } from "../../platform/models/domain/enc-string"; import { OrgKey } from "../../types/key"; import { SyncService } from "../../vault/abstractions/sync/sync.service.abstraction"; -import { BillingApiServiceAbstraction as BillingApiService } from "../abstractions/billilng-api.service.abstraction"; import { OrganizationBillingServiceAbstraction, OrganizationInformation, @@ -29,7 +28,6 @@ interface OrganizationKeys { export class OrganizationBillingService implements OrganizationBillingServiceAbstraction { constructor( private apiService: ApiService, - private billingApiService: BillingApiService, private cryptoService: CryptoService, private encryptService: EncryptService, private i18nService: I18nService, @@ -37,19 +35,6 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs private syncService: SyncService, ) {} - async isOnSecretsManagerStandalone(organizationId: string): Promise { - const response = await this.billingApiService.getOrganizationSubscription(organizationId); - if (response.customerDiscount?.id === "sm-standalone") { - const productIds = response.subscription.items.map((item) => item.productId); - return ( - response.customerDiscount?.appliesTo.filter((appliesToProductId) => - productIds.includes(appliesToProductId), - ).length > 0 - ); - } - return false; - } - async purchaseSubscription(subscription: SubscriptionInformation): Promise { const request = new OrganizationCreateRequest(); diff --git a/libs/common/src/platform/services/state.service.ts b/libs/common/src/platform/services/state.service.ts index d0a55d7a47c..0c7cdd22d29 100644 --- a/libs/common/src/platform/services/state.service.ts +++ b/libs/common/src/platform/services/state.service.ts @@ -65,8 +65,6 @@ export class StateService< private hasBeenInited = false; protected isRecoveredSession = false; - protected accountDiskCache = new BehaviorSubject>({}); - // default account serializer, must be overridden by child class protected accountDeserializer = Account.fromJSON as (json: Jsonify) => TAccount; @@ -80,7 +78,6 @@ export class StateService< protected environmentService: EnvironmentService, protected tokenService: TokenService, private migrationRunner: MigrationRunner, - protected useAccountCache: boolean = true, ) {} async init(initOptions: InitOptions = {}): Promise { @@ -115,14 +112,19 @@ export class StateService< return; } + // Get all likely authenticated accounts + const authenticatedAccounts = ( + (await this.storageService.get(keys.authenticatedAccounts)) ?? [] + ).filter((account) => account != null); + await this.updateState(async (state) => { - state.authenticatedAccounts = - (await this.storageService.get(keys.authenticatedAccounts)) ?? []; - for (const i in state.authenticatedAccounts) { - if (i != null) { - state = await this.syncAccountFromDisk(state.authenticatedAccounts[i]); - } + for (const i in authenticatedAccounts) { + state = await this.syncAccountFromDisk(authenticatedAccounts[i]); } + + // After all individual accounts have been added + state.authenticatedAccounts = authenticatedAccounts; + const storedActiveUser = await this.storageService.get(keys.activeUserId); if (storedActiveUser != null) { state.activeUserId = storedActiveUser; @@ -973,13 +975,6 @@ export class StateService< return null; } - if (this.useAccountCache) { - const cachedAccount = this.accountDiskCache.value[options.userId]; - if (cachedAccount != null) { - return cachedAccount; - } - } - const account = options?.useSecureStorage ? (await this.secureStorageService.get(options.userId, options)) ?? (await this.storageService.get( @@ -987,8 +982,6 @@ export class StateService< this.reconcileOptions(options, { htmlStorageLocation: HtmlStorageLocation.Local }), )) : await this.storageService.get(options.userId, options); - - this.setDiskCache(options.userId, account); return account; } @@ -1018,8 +1011,6 @@ export class StateService< : this.storageService; await storageLocation.save(`${options.userId}`, account, options); - - this.deleteDiskCache(options.userId); } protected async saveAccountToMemory(account: TAccount): Promise { @@ -1219,9 +1210,6 @@ export class StateService< await this.updateState(async (state) => { userId = userId ?? state.activeUserId; delete state.accounts[userId]; - - this.deleteDiskCache(userId); - return state; }); } @@ -1335,20 +1323,6 @@ export class StateService< return await this.setState(updatedState); }); } - - private setDiskCache(key: string, value: TAccount, options?: StorageOptions) { - if (this.useAccountCache) { - this.accountDiskCache.value[key] = value; - this.accountDiskCache.next(this.accountDiskCache.value); - } - } - - protected deleteDiskCache(key: string) { - if (this.useAccountCache) { - delete this.accountDiskCache.value[key]; - this.accountDiskCache.next(this.accountDiskCache.value); - } - } } function withPrototypeForArrayMembers( diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index e8135f3d6c2..84fa7bd0773 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -118,6 +118,7 @@ import { EnvironmentService } from "../platform/abstractions/environment.service import { PlatformUtilsService } from "../platform/abstractions/platform-utils.service"; import { StateService } from "../platform/abstractions/state.service"; import { Utils } from "../platform/misc/utils"; +import { UserId } from "../types/guid"; import { AttachmentRequest } from "../vault/models/request/attachment.request"; import { CipherBulkDeleteRequest } from "../vault/models/request/cipher-bulk-delete.request"; import { CipherBulkMoveRequest } from "../vault/models/request/cipher-bulk-move.request"; @@ -1423,8 +1424,8 @@ export class ApiService implements ApiServiceAbstraction { return new ListResponse(r, EventResponse); } - async postEventsCollect(request: EventRequest[]): Promise { - const authHeader = await this.getActiveBearerToken(); + async postEventsCollect(request: EventRequest[], userId?: UserId): Promise { + const authHeader = await this.tokenService.getAccessToken(userId); const headers = new Headers({ "Device-Type": this.deviceType, Authorization: "Bearer " + authHeader, diff --git a/libs/common/src/services/event/event-upload.service.ts b/libs/common/src/services/event/event-upload.service.ts index 6f229751bf1..c87d3b2024d 100644 --- a/libs/common/src/services/event/event-upload.service.ts +++ b/libs/common/src/services/event/event-upload.service.ts @@ -70,7 +70,7 @@ export class EventUploadService implements EventUploadServiceAbstraction { return req; }); try { - await this.apiService.postEventsCollect(request); + await this.apiService.postEventsCollect(request, userId); } catch (e) { this.logService.error(e); // Add the events back to state if there was an error and they were not uploaded. diff --git a/libs/common/src/state-migrations/migrate.ts b/libs/common/src/state-migrations/migrate.ts index f9a87347317..2d8ef1619e5 100644 --- a/libs/common/src/state-migrations/migrate.ts +++ b/libs/common/src/state-migrations/migrate.ts @@ -49,7 +49,7 @@ import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org- import { KeyConnectorMigrator } from "./migrations/50-move-key-connector-to-state-provider"; import { RememberedEmailMigrator } from "./migrations/51-move-remembered-email-to-state-providers"; import { DeleteInstalledVersion } from "./migrations/52-delete-installed-version"; -import { DeviceTrustCryptoServiceStateProviderMigrator } from "./migrations/53-migrate-device-trust-crypto-svc-to-state-providers"; +import { DeviceTrustServiceStateProviderMigrator } from "./migrations/53-migrate-device-trust-svc-to-state-providers"; import { SendMigrator } from "./migrations/54-move-encrypted-sends"; import { MoveMasterKeyStateToProviderMigrator } from "./migrations/55-move-master-key-state-to-provider"; import { AuthRequestMigrator } from "./migrations/56-move-auth-requests"; @@ -117,7 +117,7 @@ export function createMigrationBuilder() { .with(KeyConnectorMigrator, 49, 50) .with(RememberedEmailMigrator, 50, 51) .with(DeleteInstalledVersion, 51, 52) - .with(DeviceTrustCryptoServiceStateProviderMigrator, 52, 53) + .with(DeviceTrustServiceStateProviderMigrator, 52, 53) .with(SendMigrator, 53, 54) .with(MoveMasterKeyStateToProviderMigrator, 54, 55) .with(AuthRequestMigrator, 55, 56) diff --git a/libs/common/src/state-migrations/migrations/53-migrate-device-trust-crypto-svc-to-state-providers.spec.ts b/libs/common/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.spec.ts similarity index 92% rename from libs/common/src/state-migrations/migrations/53-migrate-device-trust-crypto-svc-to-state-providers.spec.ts rename to libs/common/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.spec.ts index 79366a47167..343fbd03d9d 100644 --- a/libs/common/src/state-migrations/migrations/53-migrate-device-trust-crypto-svc-to-state-providers.spec.ts +++ b/libs/common/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.spec.ts @@ -5,9 +5,9 @@ import { mockMigrationHelper } from "../migration-helper.spec"; import { DEVICE_KEY, - DeviceTrustCryptoServiceStateProviderMigrator, + DeviceTrustServiceStateProviderMigrator, SHOULD_TRUST_DEVICE, -} from "./53-migrate-device-trust-crypto-svc-to-state-providers"; +} from "./53-migrate-device-trust-svc-to-state-providers"; // Represents data in state service pre-migration function preMigrationJson() { @@ -79,14 +79,14 @@ function rollbackJSON() { }; } -describe("DeviceTrustCryptoServiceStateProviderMigrator", () => { +describe("DeviceTrustServiceStateProviderMigrator", () => { let helper: MockProxy; - let sut: DeviceTrustCryptoServiceStateProviderMigrator; + let sut: DeviceTrustServiceStateProviderMigrator; describe("migrate", () => { beforeEach(() => { helper = mockMigrationHelper(preMigrationJson(), 52); - sut = new DeviceTrustCryptoServiceStateProviderMigrator(52, 53); + sut = new DeviceTrustServiceStateProviderMigrator(52, 53); }); // it should remove deviceKey and trustDeviceChoiceForDecryption from all accounts @@ -126,7 +126,7 @@ describe("DeviceTrustCryptoServiceStateProviderMigrator", () => { describe("rollback", () => { beforeEach(() => { helper = mockMigrationHelper(rollbackJSON(), 53); - sut = new DeviceTrustCryptoServiceStateProviderMigrator(52, 53); + sut = new DeviceTrustServiceStateProviderMigrator(52, 53); }); it("should null out newly migrated entries in state provider framework", async () => { diff --git a/libs/common/src/state-migrations/migrations/53-migrate-device-trust-crypto-svc-to-state-providers.ts b/libs/common/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.ts similarity index 94% rename from libs/common/src/state-migrations/migrations/53-migrate-device-trust-crypto-svc-to-state-providers.ts rename to libs/common/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.ts index e19c7b3fa5a..b6d2c19b156 100644 --- a/libs/common/src/state-migrations/migrations/53-migrate-device-trust-crypto-svc-to-state-providers.ts +++ b/libs/common/src/state-migrations/migrations/53-migrate-device-trust-svc-to-state-providers.ts @@ -16,7 +16,7 @@ type ExpectedAccountType = { }; export const DEVICE_KEY: KeyDefinitionLike = { - key: "deviceKey", // matches KeyDefinition.key in DeviceTrustCryptoService + key: "deviceKey", // matches KeyDefinition.key in DeviceTrustService stateDefinition: { name: "deviceTrust", // matches StateDefinition.name in StateDefinitions }, @@ -29,7 +29,7 @@ export const SHOULD_TRUST_DEVICE: KeyDefinitionLike = { }, }; -export class DeviceTrustCryptoServiceStateProviderMigrator extends Migrator<52, 53> { +export class DeviceTrustServiceStateProviderMigrator extends Migrator<52, 53> { async migrate(helper: MigrationHelper): Promise { const accounts = await helper.getAccounts(); async function migrateAccount(userId: string, account: ExpectedAccountType): Promise { diff --git a/libs/common/src/state-migrations/migrations/58-remove-refresh-token-migrated-state-provider-flag.ts b/libs/common/src/state-migrations/migrations/58-remove-refresh-token-migrated-state-provider-flag.ts index 9c6d3776fe8..1fb36092677 100644 --- a/libs/common/src/state-migrations/migrations/58-remove-refresh-token-migrated-state-provider-flag.ts +++ b/libs/common/src/state-migrations/migrations/58-remove-refresh-token-migrated-state-provider-flag.ts @@ -4,7 +4,7 @@ import { IRREVERSIBLE, Migrator } from "../migrator"; type ExpectedAccountType = NonNullable; export const REFRESH_TOKEN_MIGRATED_TO_SECURE_STORAGE: KeyDefinitionLike = { - key: "refreshTokenMigratedToSecureStorage", // matches KeyDefinition.key in DeviceTrustCryptoService + key: "refreshTokenMigratedToSecureStorage", // matches KeyDefinition.key stateDefinition: { name: "token", // matches StateDefinition.name in StateDefinitions }, diff --git a/libs/components/src/card/card.component.ts b/libs/components/src/card/card.component.ts new file mode 100644 index 00000000000..da61d536642 --- /dev/null +++ b/libs/components/src/card/card.component.ts @@ -0,0 +1,15 @@ +import { CommonModule } from "@angular/common"; +import { ChangeDetectionStrategy, Component } from "@angular/core"; + +@Component({ + selector: "bit-card", + standalone: true, + imports: [CommonModule], + template: ``, + changeDetection: ChangeDetectionStrategy.OnPush, + host: { + class: + "tw-box-border tw-block tw-bg-background tw-text-main tw-border-solid tw-border-b tw-border-0 tw-border-b-secondary-300 tw-rounded-lg tw-py-4 tw-px-3", + }, +}) +export class CardComponent {} diff --git a/libs/components/src/card/card.stories.ts b/libs/components/src/card/card.stories.ts new file mode 100644 index 00000000000..702a8aeb631 --- /dev/null +++ b/libs/components/src/card/card.stories.ts @@ -0,0 +1,62 @@ +import { Meta, StoryObj, componentWrapperDecorator, moduleMetadata } from "@storybook/angular"; + +import { SectionComponent } from "../section"; +import { TypographyModule } from "../typography"; + +import { CardComponent } from "./card.component"; + +export default { + title: "Component Library/Card", + component: CardComponent, + decorators: [ + moduleMetadata({ + imports: [TypographyModule, SectionComponent], + }), + componentWrapperDecorator( + (story) => `
${story}
`, + ), + ], +} as Meta; + +type Story = StoryObj; + +/** Cards are presentational containers. */ +export const Default: Story = { + render: (args) => ({ + props: args, + template: /*html*/ ` + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex.

+
+ `, + }), +}; + +/** Cards are often paired with [Sections](/docs/component-library-section--docs). */ +export const WithinSections: Story = { + render: (args) => ({ + props: args, + template: /*html*/ ` + +

Bar

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex.

+
+
+ + +

Bar

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex.

+
+
+ + +

Bar

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae congue risus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc elementum odio nibh, eget pellentesque sem ornare vitae. Etiam vel ante et velit fringilla egestas a sed sem. Fusce molestie nisl et nisi accumsan dapibus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed eu risus ex.

+
+
+ `, + }), +}; diff --git a/libs/components/src/card/index.ts b/libs/components/src/card/index.ts new file mode 100644 index 00000000000..8151bac4c8b --- /dev/null +++ b/libs/components/src/card/index.ts @@ -0,0 +1 @@ +export * from "./card.component"; diff --git a/libs/components/src/index.ts b/libs/components/src/index.ts index 527d5f36153..36185911a6b 100644 --- a/libs/components/src/index.ts +++ b/libs/components/src/index.ts @@ -7,6 +7,7 @@ export * from "./breadcrumbs"; export * from "./button"; export { ButtonType } from "./shared/button-like.abstraction"; export * from "./callout"; +export * from "./card"; export * from "./checkbox"; export * from "./color-password"; export * from "./container"; diff --git a/libs/components/src/section/section.component.ts b/libs/components/src/section/section.component.ts index a681dcf7d95..a60e232eec7 100644 --- a/libs/components/src/section/section.component.ts +++ b/libs/components/src/section/section.component.ts @@ -6,7 +6,7 @@ import { Component } from "@angular/core"; standalone: true, imports: [CommonModule], template: ` -
+
`, diff --git a/libs/components/src/section/section.stories.ts b/libs/components/src/section/section.stories.ts index fb9948e9bec..65b6a67d476 100644 --- a/libs/components/src/section/section.stories.ts +++ b/libs/components/src/section/section.stories.ts @@ -17,7 +17,7 @@ export default { type Story = StoryObj; -/** Sections are simple containers that apply a bottom margin. They often contain a heading. */ +/** Sections are simple containers that apply a responsive bottom margin. They often contain a heading. */ export const Default: Story = { render: (args) => ({ props: args, diff --git a/libs/components/src/styles.scss b/libs/components/src/styles.scss index f03d2dd3409..ae97838e09f 100644 --- a/libs/components/src/styles.scss +++ b/libs/components/src/styles.scss @@ -47,3 +47,8 @@ $card-icons-base: "../../src/billing/images/cards/"; @import "bootstrap/scss/_print"; @import "multi-select/scss/bw.theme.scss"; + +// Workaround for https://bitwarden.atlassian.net/browse/CL-110 +#storybook-docs pre.prismjs { + color: white; +} diff --git a/package-lock.json b/package-lock.json index d72ba9cb19b..ad27ada66bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -111,7 +111,7 @@ "@types/node": "18.19.29", "@types/node-fetch": "2.6.4", "@types/node-forge": "1.3.11", - "@types/node-ipc": "9.2.0", + "@types/node-ipc": "9.2.3", "@types/papaparse": "5.3.14", "@types/proper-lockfile": "4.1.4", "@types/react": "16.14.57", @@ -193,11 +193,11 @@ }, "apps/browser": { "name": "@bitwarden/browser", - "version": "2024.4.1" + "version": "2024.4.2" }, "apps/cli": { "name": "@bitwarden/cli", - "version": "2024.3.1", + "version": "2024.4.0", "license": "GPL-3.0-only", "dependencies": { "@koa/multer": "3.0.2", @@ -233,7 +233,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.4.2", + "version": "2024.4.3", "hasInstallScript": true, "license": "GPL-3.0" }, @@ -247,7 +247,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2024.4.1" + "version": "2024.4.2" }, "libs/admin-console": { "name": "@bitwarden/admin-console", @@ -10544,9 +10544,9 @@ } }, "node_modules/@types/node-ipc": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.2.0.tgz", - "integrity": "sha512-0v1oucUgINvWPhknecSBE5xkz74sVgeZgiL/LkWXNTSzFaGspEToA4oR56hjza0Jkk6DsS2EiNU3M2R2KQza9A==", + "version": "9.2.3", + "resolved": "https://registry.npmjs.org/@types/node-ipc/-/node-ipc-9.2.3.tgz", + "integrity": "sha512-/MvSiF71fYf3+zwqkh/zkVkZj1hl1Uobre9EMFy08mqfJNAmpR0vmPgOUdEIDVgifxHj6G1vYMPLSBLLxoDACQ==", "dev": true, "dependencies": { "@types/node": "*" diff --git a/package.json b/package.json index 057e737903a..09065b234e3 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "@types/node": "18.19.29", "@types/node-fetch": "2.6.4", "@types/node-forge": "1.3.11", - "@types/node-ipc": "9.2.0", + "@types/node-ipc": "9.2.3", "@types/papaparse": "5.3.14", "@types/proper-lockfile": "4.1.4", "@types/react": "16.14.57",